1c6249bb2SBram Moolenaar" Vim completion script
2c6249bb2SBram Moolenaar" Language:             Ruby
3fc1421ebSBram Moolenaar" Maintainer:           Mark Guzman <[email protected]>
4*ec7944aaSBram Moolenaar" URL:                  https://github.com/vim-ruby/vim-ruby
5c6249bb2SBram Moolenaar" Release Coordinator:  Doug Kearns <[email protected]>
61d68952aSBram Moolenaar" Maintainer Version:   0.8.1
7c6249bb2SBram Moolenaar" ----------------------------------------------------------------------------
8c6249bb2SBram Moolenaar"
9c6249bb2SBram Moolenaar" Ruby IRB/Complete author: Keiju ISHITSUKA([email protected])
10c6249bb2SBram Moolenaar" ----------------------------------------------------------------------------
11c6249bb2SBram Moolenaar
12eb3593b3SBram Moolenaar" {{{ requirement checks
13*ec7944aaSBram Moolenaar
14*ec7944aaSBram Moolenaarfunction! s:ErrMsg(msg)
15*ec7944aaSBram Moolenaar    echohl ErrorMsg
16*ec7944aaSBram Moolenaar    echo a:msg
17*ec7944aaSBram Moolenaar    echohl None
18*ec7944aaSBram Moolenaarendfunction
19*ec7944aaSBram Moolenaar
20c6249bb2SBram Moolenaarif !has('ruby')
21*ec7944aaSBram Moolenaar    call s:ErrMsg( "Error: Rubycomplete requires vim compiled with +ruby" )
22*ec7944aaSBram Moolenaar    call s:ErrMsg( "Error: falling back to syntax completion" )
239964e468SBram Moolenaar    " lets fall back to syntax completion
249964e468SBram Moolenaar    setlocal omnifunc=syntaxcomplete#Complete
25c6249bb2SBram Moolenaar    finish
26c6249bb2SBram Moolenaarendif
27c6249bb2SBram Moolenaar
28c6249bb2SBram Moolenaarif version < 700
29*ec7944aaSBram Moolenaar    call s:ErrMsg( "Error: Required vim >= 7.0" )
30c6249bb2SBram Moolenaar    finish
31c6249bb2SBram Moolenaarendif
32eb3593b3SBram Moolenaar" }}} requirement checks
33c6249bb2SBram Moolenaar
349964e468SBram Moolenaar" {{{ configuration failsafe initialization
35eb3593b3SBram Moolenaarif !exists("g:rubycomplete_rails")
36eb3593b3SBram Moolenaar    let g:rubycomplete_rails = 0
37eb3593b3SBram Moolenaarendif
38fc1421ebSBram Moolenaar
39eb3593b3SBram Moolenaarif !exists("g:rubycomplete_classes_in_global")
40eb3593b3SBram Moolenaar    let g:rubycomplete_classes_in_global = 0
41eb3593b3SBram Moolenaarendif
42eb3593b3SBram Moolenaar
439964e468SBram Moolenaarif !exists("g:rubycomplete_buffer_loading")
44a7241f5fSBram Moolenaar    let g:rubycomplete_buffer_loading = 0
459964e468SBram Moolenaarendif
469964e468SBram Moolenaar
479964e468SBram Moolenaarif !exists("g:rubycomplete_include_object")
489964e468SBram Moolenaar    let g:rubycomplete_include_object = 0
499964e468SBram Moolenaarendif
509964e468SBram Moolenaar
519964e468SBram Moolenaarif !exists("g:rubycomplete_include_objectspace")
529964e468SBram Moolenaar    let g:rubycomplete_include_objectspace = 0
539964e468SBram Moolenaarendif
549964e468SBram Moolenaar" }}} configuration failsafe initialization
559964e468SBram Moolenaar
56eb3593b3SBram Moolenaar" {{{ vim-side support functions
579964e468SBram Moolenaarlet s:rubycomplete_debug = 0
589964e468SBram Moolenaar
599964e468SBram Moolenaarfunction! s:dprint(msg)
609964e468SBram Moolenaar    if s:rubycomplete_debug == 1
619964e468SBram Moolenaar        echom a:msg
629964e468SBram Moolenaar    endif
639964e468SBram Moolenaarendfunction
649964e468SBram Moolenaar
659964e468SBram Moolenaarfunction! s:GetBufferRubyModule(name, ...)
669964e468SBram Moolenaar    if a:0 == 1
679964e468SBram Moolenaar        let [snum,enum] = s:GetBufferRubyEntity(a:name, "module", a:1)
689964e468SBram Moolenaar    else
699964e468SBram Moolenaar        let [snum,enum] = s:GetBufferRubyEntity(a:name, "module")
709964e468SBram Moolenaar    endif
71fc1421ebSBram Moolenaar    return snum . '..' . enum
72fc1421ebSBram Moolenaarendfunction
73fc1421ebSBram Moolenaar
749964e468SBram Moolenaarfunction! s:GetBufferRubyClass(name, ...)
759964e468SBram Moolenaar    if a:0 >= 1
769964e468SBram Moolenaar        let [snum,enum] = s:GetBufferRubyEntity(a:name, "class", a:1)
779964e468SBram Moolenaar    else
789964e468SBram Moolenaar        let [snum,enum] = s:GetBufferRubyEntity(a:name, "class")
799964e468SBram Moolenaar    endif
80fc1421ebSBram Moolenaar    return snum . '..' . enum
81fc1421ebSBram Moolenaarendfunction
82fc1421ebSBram Moolenaar
839964e468SBram Moolenaarfunction! s:GetBufferRubySingletonMethods(name)
84fc1421ebSBram Moolenaarendfunction
85fc1421ebSBram Moolenaar
869964e468SBram Moolenaarfunction! s:GetBufferRubyEntity( name, type, ... )
879964e468SBram Moolenaar    let lastpos = getpos(".")
889964e468SBram Moolenaar    let lastline = lastpos
899964e468SBram Moolenaar    if (a:0 >= 1)
909964e468SBram Moolenaar        let lastline = [ 0, a:1, 0, 0 ]
919964e468SBram Moolenaar        call cursor( a:1, 0 )
929964e468SBram Moolenaar    endif
939964e468SBram Moolenaar
94fc1421ebSBram Moolenaar    let stopline = 1
959964e468SBram Moolenaar
969964e468SBram Moolenaar    let crex = '^\s*\<' . a:type . '\>\s*\<' . a:name . '\>\s*\(<\s*.*\s*\)\?'
979964e468SBram Moolenaar    let [lnum,lcol] = searchpos( crex, 'w' )
989964e468SBram Moolenaar    "let [lnum,lcol] = searchpairpos( crex . '\zs', '', '\(end\|}\)', 'w' )
999964e468SBram Moolenaar
100fc1421ebSBram Moolenaar    if lnum == 0 && lcol == 0
1019964e468SBram Moolenaar        call cursor(lastpos[1], lastpos[2])
102fc1421ebSBram Moolenaar        return [0,0]
103fc1421ebSBram Moolenaar    endif
104fc1421ebSBram Moolenaar
1059964e468SBram Moolenaar    let curpos = getpos(".")
1069964e468SBram Moolenaar    let [enum,ecol] = searchpairpos( crex, '', '\(end\|}\)', 'wr' )
1079964e468SBram Moolenaar    call cursor(lastpos[1], lastpos[2])
1089964e468SBram Moolenaar
109fc1421ebSBram Moolenaar    if lnum > enum
1109964e468SBram Moolenaar        return [0,0]
111fc1421ebSBram Moolenaar    endif
112fc1421ebSBram Moolenaar    " we found a the class def
113fc1421ebSBram Moolenaar    return [lnum,enum]
114fc1421ebSBram Moolenaarendfunction
115fc1421ebSBram Moolenaar
1169964e468SBram Moolenaarfunction! s:IsInClassDef()
1179964e468SBram Moolenaar    return s:IsPosInClassDef( line('.') )
1189964e468SBram Moolenaarendfunction
119fc1421ebSBram Moolenaar
1209964e468SBram Moolenaarfunction! s:IsPosInClassDef(pos)
1219964e468SBram Moolenaar    let [snum,enum] = s:GetBufferRubyEntity( '.*', "class" )
1229964e468SBram Moolenaar    let ret = 'nil'
1239964e468SBram Moolenaar
1249964e468SBram Moolenaar    if snum < a:pos && a:pos < enum
125fc1421ebSBram Moolenaar        let ret = snum . '..' . enum
126fc1421ebSBram Moolenaar    endif
127fc1421ebSBram Moolenaar
128fc1421ebSBram Moolenaar    return ret
129fc1421ebSBram Moolenaarendfunction
130fc1421ebSBram Moolenaar
1319964e468SBram Moolenaarfunction! s:GetRubyVarType(v)
132c6249bb2SBram Moolenaar    let stopline = 1
133c6249bb2SBram Moolenaar    let vtp = ''
134c6249bb2SBram Moolenaar    let pos = getpos('.')
135*ec7944aaSBram Moolenaar    let sstr = '^\s*#\s*@var\s*'.escape(a:v, '*').'\>\s\+[^ \t]\+\s*$'
1369964e468SBram Moolenaar    let [lnum,lcol] = searchpos(sstr,'nb',stopline)
137c6249bb2SBram Moolenaar    if lnum != 0 && lcol != 0
138c6249bb2SBram Moolenaar        call setpos('.',pos)
139c6249bb2SBram Moolenaar        let str = getline(lnum)
1409964e468SBram Moolenaar        let vtp = substitute(str,sstr,'\1','')
141c6249bb2SBram Moolenaar        return vtp
142c6249bb2SBram Moolenaar    endif
143c6249bb2SBram Moolenaar    call setpos('.',pos)
1449964e468SBram Moolenaar    let ctors = '\(now\|new\|open\|get_instance'
1459964e468SBram Moolenaar    if exists('g:rubycomplete_rails') && g:rubycomplete_rails == 1 && s:rubycomplete_rails_loaded == 1
1469964e468SBram Moolenaar        let ctors = ctors.'\|find\|create'
147551dbcc9SBram Moolenaar    else
148551dbcc9SBram Moolenaar    endif
1499964e468SBram Moolenaar    let ctors = ctors.'\)'
150551dbcc9SBram Moolenaar
1519964e468SBram Moolenaar    let fstr = '=\s*\([^ \t]\+.' . ctors .'\>\|[\[{"''/]\|%[xwQqr][(\[{@]\|[A-Za-z0-9@:\-()\.]\+...\?\|lambda\|&\)'
1529964e468SBram Moolenaar    let sstr = ''.a:v.'\>\s*[+\-*/]*'.fstr
1539964e468SBram Moolenaar    let [lnum,lcol] = searchpos(sstr,'nb',stopline)
154c6249bb2SBram Moolenaar    if lnum != 0 && lcol != 0
1559964e468SBram Moolenaar        let str = matchstr(getline(lnum),fstr,lcol)
156c6249bb2SBram Moolenaar        let str = substitute(str,'^=\s*','','')
1579964e468SBram Moolenaar
158c6249bb2SBram Moolenaar        call setpos('.',pos)
1599964e468SBram Moolenaar        if str == '"' || str == '''' || stridx(tolower(str), '%q[') != -1
160c6249bb2SBram Moolenaar            return 'String'
1619964e468SBram Moolenaar        elseif str == '[' || stridx(str, '%w[') != -1
162c6249bb2SBram Moolenaar            return 'Array'
163c6249bb2SBram Moolenaar        elseif str == '{'
164c6249bb2SBram Moolenaar            return 'Hash'
165fc1421ebSBram Moolenaar        elseif str == '/' || str == '%r{'
166fc1421ebSBram Moolenaar            return 'Regexp'
167d8fc5c0bSBram Moolenaar        elseif strlen(str) >= 4 && stridx(str,'..') != -1
168d8fc5c0bSBram Moolenaar            return 'Range'
1699964e468SBram Moolenaar        elseif stridx(str, 'lambda') != -1 || str == '&'
1709964e468SBram Moolenaar            return 'Proc'
171c6249bb2SBram Moolenaar        elseif strlen(str) > 4
172c6249bb2SBram Moolenaar            let l = stridx(str,'.')
173c6249bb2SBram Moolenaar            return str[0:l-1]
174c6249bb2SBram Moolenaar        end
175c6249bb2SBram Moolenaar        return ''
176c6249bb2SBram Moolenaar    endif
177c6249bb2SBram Moolenaar    call setpos('.',pos)
178c6249bb2SBram Moolenaar    return ''
179fc1421ebSBram Moolenaarendfunction
180c6249bb2SBram Moolenaar
181eb3593b3SBram Moolenaar"}}} vim-side support functions
182eb3593b3SBram Moolenaar
1839964e468SBram Moolenaar"{{{ vim-side completion function
1849964e468SBram Moolenaarfunction! rubycomplete#Init()
1859964e468SBram Moolenaar    execute "ruby VimRubyCompletion.preload_rails"
1869964e468SBram Moolenaarendfunction
1879964e468SBram Moolenaar
188c6249bb2SBram Moolenaarfunction! rubycomplete#Complete(findstart, base)
189c6249bb2SBram Moolenaar     "findstart = 1 when we need to get the text length
190c6249bb2SBram Moolenaar    if a:findstart
191c6249bb2SBram Moolenaar        let line = getline('.')
192c6249bb2SBram Moolenaar        let idx = col('.')
193c6249bb2SBram Moolenaar        while idx > 0
194c6249bb2SBram Moolenaar            let idx -= 1
195c6249bb2SBram Moolenaar            let c = line[idx-1]
196c6249bb2SBram Moolenaar            if c =~ '\w'
197c6249bb2SBram Moolenaar                continue
198c6249bb2SBram Moolenaar            elseif ! c =~ '\.'
199c6249bb2SBram Moolenaar                idx = -1
200c6249bb2SBram Moolenaar                break
201c6249bb2SBram Moolenaar            else
202c6249bb2SBram Moolenaar                break
203c6249bb2SBram Moolenaar            endif
204c6249bb2SBram Moolenaar        endwhile
205c6249bb2SBram Moolenaar
206c6249bb2SBram Moolenaar        return idx
207c6249bb2SBram Moolenaar    "findstart = 0 when we need to return the list of completions
208c6249bb2SBram Moolenaar    else
209fc1421ebSBram Moolenaar        let g:rubycomplete_completions = []
2109964e468SBram Moolenaar        execute "ruby VimRubyCompletion.get_completions('" . a:base . "')"
211fc1421ebSBram Moolenaar        return g:rubycomplete_completions
212c6249bb2SBram Moolenaar    endif
213c6249bb2SBram Moolenaarendfunction
2149964e468SBram Moolenaar"}}} vim-side completion function
215c6249bb2SBram Moolenaar
2169964e468SBram Moolenaar"{{{ ruby-side code
217c6249bb2SBram Moolenaarfunction! s:DefRuby()
218c6249bb2SBram Moolenaarruby << RUBYEOF
219eb3593b3SBram Moolenaar# {{{ ruby completion
220fc1421ebSBram Moolenaar
2219964e468SBram Moolenaarbegin
2229964e468SBram Moolenaar    require 'rubygems' # let's assume this is safe...?
2239964e468SBram Moolenaarrescue Exception
2249964e468SBram Moolenaar    #ignore?
2259964e468SBram Moolenaarend
2269964e468SBram Moolenaarclass VimRubyCompletion
2279964e468SBram Moolenaar# {{{ constants
2289964e468SBram Moolenaar  @@debug = false
2299964e468SBram Moolenaar  @@ReservedWords = [
230c6249bb2SBram Moolenaar        "BEGIN", "END",
231c6249bb2SBram Moolenaar        "alias", "and",
232c6249bb2SBram Moolenaar        "begin", "break",
233c6249bb2SBram Moolenaar        "case", "class",
234c6249bb2SBram Moolenaar        "def", "defined", "do",
235c6249bb2SBram Moolenaar        "else", "elsif", "end", "ensure",
236c6249bb2SBram Moolenaar        "false", "for",
237c6249bb2SBram Moolenaar        "if", "in",
238c6249bb2SBram Moolenaar        "module",
239c6249bb2SBram Moolenaar        "next", "nil", "not",
240c6249bb2SBram Moolenaar        "or",
241c6249bb2SBram Moolenaar        "redo", "rescue", "retry", "return",
242c6249bb2SBram Moolenaar        "self", "super",
243c6249bb2SBram Moolenaar        "then", "true",
244c6249bb2SBram Moolenaar        "undef", "unless", "until",
245c6249bb2SBram Moolenaar        "when", "while",
246c6249bb2SBram Moolenaar        "yield",
247c6249bb2SBram Moolenaar      ]
248c6249bb2SBram Moolenaar
2499964e468SBram Moolenaar  @@Operators = [ "%", "&", "*", "**", "+",  "-",  "/",
250c6249bb2SBram Moolenaar        "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>",
251c6249bb2SBram Moolenaar        "[]", "[]=", "^", ]
2529964e468SBram Moolenaar# }}} constants
253c6249bb2SBram Moolenaar
2549964e468SBram Moolenaar# {{{ buffer analysis magic
255c6249bb2SBram Moolenaar  def load_requires
256eb3593b3SBram Moolenaar    buf = VIM::Buffer.current
257eb3593b3SBram Moolenaar    enum = buf.line_number
258c6249bb2SBram Moolenaar    nums = Range.new( 1, enum )
259c6249bb2SBram Moolenaar    nums.each do |x|
260eb3593b3SBram Moolenaar      ln = buf[x]
261c6249bb2SBram Moolenaar      begin
262c6249bb2SBram Moolenaar        eval( "require %s" % $1 ) if /.*require\s*(.*)$/.match( ln )
263c6249bb2SBram Moolenaar      rescue Exception
264c6249bb2SBram Moolenaar        #ignore?
265c6249bb2SBram Moolenaar      end
266c6249bb2SBram Moolenaar    end
267c6249bb2SBram Moolenaar  end
268c6249bb2SBram Moolenaar
269fc1421ebSBram Moolenaar  def load_buffer_class(name)
2709964e468SBram Moolenaar    dprint "load_buffer_class(%s) START" % name
2719964e468SBram Moolenaar    classdef = get_buffer_entity(name, 's:GetBufferRubyClass("%s")')
272fc1421ebSBram Moolenaar    return if classdef == nil
273fc1421ebSBram Moolenaar
274fc1421ebSBram Moolenaar    pare = /^\s*class\s*(.*)\s*<\s*(.*)\s*\n/.match( classdef )
2759964e468SBram Moolenaar    load_buffer_class( $2 ) if pare != nil  && $2 != name # load parent class if needed
276fc1421ebSBram Moolenaar
277*ec7944aaSBram Moolenaar    mixre = /.*\n\s*(include|prepend)\s*(.*)\s*\n/.match( classdef )
2789964e468SBram Moolenaar    load_buffer_module( $2 ) if mixre != nil && $2 != name # load mixins if needed
279fc1421ebSBram Moolenaar
2809964e468SBram Moolenaar    begin
281fc1421ebSBram Moolenaar      eval classdef
2829964e468SBram Moolenaar    rescue Exception
2839964e468SBram Moolenaar      VIM::evaluate( "s:ErrMsg( 'Problem loading class \"%s\", was it already completed?' )" % name )
2849964e468SBram Moolenaar    end
2859964e468SBram Moolenaar    dprint "load_buffer_class(%s) END" % name
286fc1421ebSBram Moolenaar  end
287fc1421ebSBram Moolenaar
288fc1421ebSBram Moolenaar  def load_buffer_module(name)
2899964e468SBram Moolenaar    dprint "load_buffer_module(%s) START" % name
2909964e468SBram Moolenaar    classdef = get_buffer_entity(name, 's:GetBufferRubyModule("%s")')
291fc1421ebSBram Moolenaar    return if classdef == nil
292fc1421ebSBram Moolenaar
2939964e468SBram Moolenaar    begin
294fc1421ebSBram Moolenaar      eval classdef
2959964e468SBram Moolenaar    rescue Exception
2969964e468SBram Moolenaar      VIM::evaluate( "s:ErrMsg( 'Problem loading module \"%s\", was it already completed?' )" % name )
2979964e468SBram Moolenaar    end
2989964e468SBram Moolenaar    dprint "load_buffer_module(%s) END" % name
299fc1421ebSBram Moolenaar  end
300fc1421ebSBram Moolenaar
301fc1421ebSBram Moolenaar  def get_buffer_entity(name, vimfun)
3029964e468SBram Moolenaar    loading_allowed = VIM::evaluate("exists('g:rubycomplete_buffer_loading') && g:rubycomplete_buffer_loading")
303c236c16dSBram Moolenaar    return nil if loading_allowed.to_i.zero?
304d8fc5c0bSBram Moolenaar    return nil if /(\"|\')+/.match( name )
305eb3593b3SBram Moolenaar    buf = VIM::Buffer.current
306fc1421ebSBram Moolenaar    nums = eval( VIM::evaluate( vimfun % name ) )
307fc1421ebSBram Moolenaar    return nil if nums == nil
308fc1421ebSBram Moolenaar    return nil if nums.min == nums.max && nums.min == 0
309fc1421ebSBram Moolenaar
3109964e468SBram Moolenaar    dprint "get_buffer_entity START"
3119964e468SBram Moolenaar    visited = []
3129964e468SBram Moolenaar    clscnt = 0
3139964e468SBram Moolenaar    bufname = VIM::Buffer.current.name
314fc1421ebSBram Moolenaar    classdef = ""
3159964e468SBram Moolenaar    cur_line = VIM::Buffer.current.line_number
3169964e468SBram Moolenaar    while (nums != nil && !(nums.min == 0 && nums.max == 0) )
3179964e468SBram Moolenaar      dprint "visited: %s" % visited.to_s
3189964e468SBram Moolenaar      break if visited.index( nums )
3199964e468SBram Moolenaar      visited << nums
3209964e468SBram Moolenaar
321fc1421ebSBram Moolenaar      nums.each do |x|
322fc1421ebSBram Moolenaar        if x != cur_line
3239964e468SBram Moolenaar          next if x == 0
324eb3593b3SBram Moolenaar          ln = buf[x]
3259964e468SBram Moolenaar          if /^\s*(module|class|def|include)\s+/.match(ln)
3269964e468SBram Moolenaar            clscnt += 1 if $1 == "class"
3271d68952aSBram Moolenaar            #dprint "\$1$1
328fc1421ebSBram Moolenaar            classdef += "%s\n" % ln
3299964e468SBram Moolenaar            classdef += "end\n" if /def\s+/.match(ln)
3309964e468SBram Moolenaar            dprint ln
3319964e468SBram Moolenaar          end
332fc1421ebSBram Moolenaar        end
333fc1421ebSBram Moolenaar      end
334fc1421ebSBram Moolenaar
3359964e468SBram Moolenaar      nm = "%s(::.*)*\", %s, \"" % [ name, nums.last ]
3369964e468SBram Moolenaar      nums = eval( VIM::evaluate( vimfun % nm ) )
3379964e468SBram Moolenaar      dprint "nm: \"%s\"" % nm
3389964e468SBram Moolenaar      dprint "vimfun: %s" % (vimfun % nm)
3399964e468SBram Moolenaar      dprint "got nums: %s" % nums.to_s
3409964e468SBram Moolenaar    end
3419964e468SBram Moolenaar    if classdef.length > 1
3429964e468SBram Moolenaar        classdef += "end\n"*clscnt
3439964e468SBram Moolenaar        # classdef = "class %s\n%s\nend\n" % [ bufname.gsub( /\/|\\/, "_" ), classdef ]
3449964e468SBram Moolenaar    end
3459964e468SBram Moolenaar
3469964e468SBram Moolenaar    dprint "get_buffer_entity END"
3479964e468SBram Moolenaar    dprint "classdef====start"
3489964e468SBram Moolenaar    lns = classdef.split( "\n" )
3499964e468SBram Moolenaar    lns.each { |x| dprint x }
3509964e468SBram Moolenaar    dprint "classdef====end"
351fc1421ebSBram Moolenaar    return classdef
352fc1421ebSBram Moolenaar  end
353fc1421ebSBram Moolenaar
354d8fc5c0bSBram Moolenaar  def get_var_type( receiver )
355d8fc5c0bSBram Moolenaar    if /(\"|\')+/.match( receiver )
356d8fc5c0bSBram Moolenaar      "String"
357d8fc5c0bSBram Moolenaar    else
3589964e468SBram Moolenaar      VIM::evaluate("s:GetRubyVarType('%s')" % receiver)
359d8fc5c0bSBram Moolenaar    end
360d8fc5c0bSBram Moolenaar  end
361d8fc5c0bSBram Moolenaar
3629964e468SBram Moolenaar  def dprint( txt )
3639964e468SBram Moolenaar    print txt if @@debug
3649964e468SBram Moolenaar  end
3659964e468SBram Moolenaar
366*ec7944aaSBram Moolenaar  def escape_vim_singlequote_string(str)
367*ec7944aaSBram Moolenaar    str.to_s.gsub(/'/,"\\'")
368*ec7944aaSBram Moolenaar  end
369*ec7944aaSBram Moolenaar
3709964e468SBram Moolenaar  def get_buffer_entity_list( type )
371eb3593b3SBram Moolenaar    # this will be a little expensive.
3729964e468SBram Moolenaar    loading_allowed = VIM::evaluate("exists('g:rubycomplete_buffer_loading') && g:rubycomplete_buffer_loading")
3739964e468SBram Moolenaar    allow_aggressive_load = VIM::evaluate("exists('g:rubycomplete_classes_in_global') && g:rubycomplete_classes_in_global")
374c236c16dSBram Moolenaar    return [] if allow_aggressive_load.to_i.zero? || loading_allowed.to_i.zero?
375eb3593b3SBram Moolenaar
376eb3593b3SBram Moolenaar    buf = VIM::Buffer.current
377eb3593b3SBram Moolenaar    eob = buf.length
378eb3593b3SBram Moolenaar    ret = []
379eb3593b3SBram Moolenaar    rg = 1..eob
3809964e468SBram Moolenaar    re = eval( "/^\s*%s\s*([A-Za-z0-9_:-]*)(\s*<\s*([A-Za-z0-9_:-]*))?\s*/" % type )
381eb3593b3SBram Moolenaar
382eb3593b3SBram Moolenaar    rg.each do |x|
3839964e468SBram Moolenaar      if re.match( buf[x] )
3849964e468SBram Moolenaar        next if type == "def" && eval( VIM::evaluate("s:IsPosInClassDef(%s)" % x) ) != nil
385eb3593b3SBram Moolenaar        ret.push $1
386eb3593b3SBram Moolenaar      end
387eb3593b3SBram Moolenaar    end
388eb3593b3SBram Moolenaar
389eb3593b3SBram Moolenaar    return ret
390eb3593b3SBram Moolenaar  end
391eb3593b3SBram Moolenaar
3929964e468SBram Moolenaar  def get_buffer_modules
3939964e468SBram Moolenaar    return get_buffer_entity_list( "modules" )
3949964e468SBram Moolenaar  end
3959964e468SBram Moolenaar
3969964e468SBram Moolenaar  def get_buffer_methods
3979964e468SBram Moolenaar    return get_buffer_entity_list( "def" )
3989964e468SBram Moolenaar  end
3999964e468SBram Moolenaar
4009964e468SBram Moolenaar  def get_buffer_classes
4019964e468SBram Moolenaar    return get_buffer_entity_list( "class" )
4029964e468SBram Moolenaar  end
4039964e468SBram Moolenaar
4049964e468SBram Moolenaar
4059964e468SBram Moolenaar  def load_rails
4069964e468SBram Moolenaar    allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails")
407c236c16dSBram Moolenaar    return if allow_rails.to_i.zero?
408fc1421ebSBram Moolenaar
409fc1421ebSBram Moolenaar    buf_path = VIM::evaluate('expand("%:p")')
410fc1421ebSBram Moolenaar    file_name = VIM::evaluate('expand("%:t")')
4119964e468SBram Moolenaar    vim_dir = VIM::evaluate('getcwd()')
4129964e468SBram Moolenaar    file_dir = buf_path.gsub( file_name, '' )
4139964e468SBram Moolenaar    file_dir.gsub!( /\\/, "/" )
4149964e468SBram Moolenaar    vim_dir.gsub!( /\\/, "/" )
4159964e468SBram Moolenaar    vim_dir << "/"
4169964e468SBram Moolenaar    dirs = [ vim_dir, file_dir ]
4179964e468SBram Moolenaar    sdirs = [ "", "./", "../", "../../", "../../../", "../../../../" ]
4189964e468SBram Moolenaar    rails_base = nil
419fc1421ebSBram Moolenaar
4209964e468SBram Moolenaar    dirs.each do |dir|
4219964e468SBram Moolenaar      sdirs.each do |sub|
4229964e468SBram Moolenaar        trail = "%s%s" % [ dir, sub ]
4239964e468SBram Moolenaar        tcfg = "%sconfig" % trail
4249964e468SBram Moolenaar
4259964e468SBram Moolenaar        if File.exists?( tcfg )
4269964e468SBram Moolenaar          rails_base = trail
427fc1421ebSBram Moolenaar          break
428fc1421ebSBram Moolenaar        end
429fc1421ebSBram Moolenaar      end
4309964e468SBram Moolenaar      break if rails_base
4319964e468SBram Moolenaar    end
432eb3593b3SBram Moolenaar
4339964e468SBram Moolenaar    return if rails_base == nil
4349964e468SBram Moolenaar    $:.push rails_base unless $:.index( rails_base )
435551dbcc9SBram Moolenaar
4369964e468SBram Moolenaar    rails_config = rails_base + "config/"
4379964e468SBram Moolenaar    rails_lib = rails_base + "lib/"
4389964e468SBram Moolenaar    $:.push rails_config unless $:.index( rails_config )
4399964e468SBram Moolenaar    $:.push rails_lib unless $:.index( rails_lib )
4409964e468SBram Moolenaar
4419964e468SBram Moolenaar    bootfile = rails_config + "boot.rb"
4429964e468SBram Moolenaar    envfile = rails_config + "environment.rb"
443551dbcc9SBram Moolenaar    if File.exists?( bootfile ) && File.exists?( envfile )
444551dbcc9SBram Moolenaar      begin
445eb3593b3SBram Moolenaar        require bootfile
446551dbcc9SBram Moolenaar        require envfile
4479964e468SBram Moolenaar        begin
448551dbcc9SBram Moolenaar          require 'console_app'
449551dbcc9SBram Moolenaar          require 'console_with_helpers'
4509964e468SBram Moolenaar        rescue Exception
4519964e468SBram Moolenaar          dprint "Rails 1.1+ Error %s" % $!
4529964e468SBram Moolenaar          # assume 1.0
4539964e468SBram Moolenaar        end
4549964e468SBram Moolenaar        #eval( "Rails::Initializer.run" ) #not necessary?
4559964e468SBram Moolenaar        VIM::command('let s:rubycomplete_rails_loaded = 1')
4569964e468SBram Moolenaar        dprint "rails loaded"
4579964e468SBram Moolenaar      rescue Exception
4589964e468SBram Moolenaar        dprint "Rails Error %s" % $!
4599964e468SBram Moolenaar        VIM::evaluate( "s:ErrMsg('Error loading rails environment')" )
460551dbcc9SBram Moolenaar      end
461eb3593b3SBram Moolenaar    end
462fc1421ebSBram Moolenaar  end
463fc1421ebSBram Moolenaar
464fc1421ebSBram Moolenaar  def get_rails_helpers
4659964e468SBram Moolenaar    allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails")
4669964e468SBram Moolenaar    rails_loaded = VIM::evaluate('s:rubycomplete_rails_loaded')
467c236c16dSBram Moolenaar    return [] if allow_rails.to_i.zero? || rails_loaded.to_i.zero?
4689964e468SBram Moolenaar
4699964e468SBram Moolenaar    buf_path = VIM::evaluate('expand("%:p")')
4709964e468SBram Moolenaar    buf_path.gsub!( /\\/, "/" )
4719964e468SBram Moolenaar    path_elm = buf_path.split( "/" )
4729964e468SBram Moolenaar    dprint "buf_path: %s" % buf_path
4739964e468SBram Moolenaar    types = [ "app", "db", "lib", "test", "components", "script" ]
4749964e468SBram Moolenaar
4759964e468SBram Moolenaar    i = nil
4769964e468SBram Moolenaar    ret = []
4779964e468SBram Moolenaar    type = nil
4789964e468SBram Moolenaar    types.each do |t|
4799964e468SBram Moolenaar      i = path_elm.index( t )
4809964e468SBram Moolenaar      break if i
4819964e468SBram Moolenaar    end
4829964e468SBram Moolenaar    type = path_elm[i]
4839964e468SBram Moolenaar    type.downcase!
4849964e468SBram Moolenaar
4859964e468SBram Moolenaar    dprint "type: %s" % type
4869964e468SBram Moolenaar    case type
4879964e468SBram Moolenaar      when "app"
4889964e468SBram Moolenaar        i += 1
4899964e468SBram Moolenaar        subtype = path_elm[i]
4909964e468SBram Moolenaar        subtype.downcase!
4919964e468SBram Moolenaar
4929964e468SBram Moolenaar        dprint "subtype: %s" % subtype
4939964e468SBram Moolenaar        case subtype
4949964e468SBram Moolenaar          when "views"
4959964e468SBram Moolenaar            ret += ActionView::Base.instance_methods
4969964e468SBram Moolenaar            ret += ActionView::Base.methods
4979964e468SBram Moolenaar          when "controllers"
4989964e468SBram Moolenaar            ret += ActionController::Base.instance_methods
4999964e468SBram Moolenaar            ret += ActionController::Base.methods
5009964e468SBram Moolenaar          when "models"
5019964e468SBram Moolenaar            ret += ActiveRecord::Base.instance_methods
5029964e468SBram Moolenaar            ret += ActiveRecord::Base.methods
5039964e468SBram Moolenaar        end
5049964e468SBram Moolenaar
5059964e468SBram Moolenaar      when "db"
5069964e468SBram Moolenaar        ret += ActiveRecord::ConnectionAdapters::SchemaStatements.instance_methods
5079964e468SBram Moolenaar        ret += ActiveRecord::ConnectionAdapters::SchemaStatements.methods
5089964e468SBram Moolenaar    end
5099964e468SBram Moolenaar
5109964e468SBram Moolenaar
5119964e468SBram Moolenaar    return ret
5129964e468SBram Moolenaar  end
5139964e468SBram Moolenaar
5149964e468SBram Moolenaar  def add_rails_columns( cls )
5159964e468SBram Moolenaar    allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails")
5169964e468SBram Moolenaar    rails_loaded = VIM::evaluate('s:rubycomplete_rails_loaded')
517c236c16dSBram Moolenaar    return [] if allow_rails.to_i.zero? || rails_loaded.to_i.zero?
5189964e468SBram Moolenaar
5199964e468SBram Moolenaar    begin
5209964e468SBram Moolenaar        eval( "#{cls}.establish_connection" )
5219964e468SBram Moolenaar        return [] unless eval( "#{cls}.ancestors.include?(ActiveRecord::Base).to_s" )
5229964e468SBram Moolenaar        col = eval( "#{cls}.column_names" )
5239964e468SBram Moolenaar        return col if col
5249964e468SBram Moolenaar    rescue
5259964e468SBram Moolenaar        dprint "add_rails_columns err: (cls: %s) %s" % [ cls, $! ]
5269964e468SBram Moolenaar        return []
5279964e468SBram Moolenaar    end
5289964e468SBram Moolenaar    return []
5299964e468SBram Moolenaar  end
5309964e468SBram Moolenaar
5319964e468SBram Moolenaar  def clean_sel(sel, msg)
532*ec7944aaSBram Moolenaar    ret = sel.reject{|x|x.nil?}.uniq
533*ec7944aaSBram Moolenaar    ret = ret.grep(/^#{Regexp.quote(msg)}/) if msg != nil
534*ec7944aaSBram Moolenaar    ret
5359964e468SBram Moolenaar  end
5369964e468SBram Moolenaar
5379964e468SBram Moolenaar  def get_rails_view_methods
5389964e468SBram Moolenaar    allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails")
5399964e468SBram Moolenaar    rails_loaded = VIM::evaluate('s:rubycomplete_rails_loaded')
540c236c16dSBram Moolenaar    return [] if allow_rails.to_i.zero? || rails_loaded.to_i.zero?
5419964e468SBram Moolenaar
5429964e468SBram Moolenaar    buf_path = VIM::evaluate('expand("%:p")')
5439964e468SBram Moolenaar    buf_path.gsub!( /\\/, "/" )
5449964e468SBram Moolenaar    pelm = buf_path.split( "/" )
5459964e468SBram Moolenaar    idx = pelm.index( "views" )
5469964e468SBram Moolenaar
5479964e468SBram Moolenaar    return [] unless idx
5489964e468SBram Moolenaar    idx += 1
5499964e468SBram Moolenaar
5509964e468SBram Moolenaar    clspl = pelm[idx].camelize.pluralize
5519964e468SBram Moolenaar    cls = clspl.singularize
5529964e468SBram Moolenaar
5539964e468SBram Moolenaar    ret = []
5549964e468SBram Moolenaar    begin
5559964e468SBram Moolenaar      ret += eval( "#{cls}.instance_methods" )
5569964e468SBram Moolenaar      ret += eval( "#{clspl}Helper.instance_methods" )
5579964e468SBram Moolenaar    rescue Exception
5589964e468SBram Moolenaar      dprint "Error: Unable to load rails view helpers for %s: %s" % [ cls, $! ]
5599964e468SBram Moolenaar    end
5609964e468SBram Moolenaar
5619964e468SBram Moolenaar    return ret
5629964e468SBram Moolenaar  end
5639964e468SBram Moolenaar# }}} buffer analysis magic
5649964e468SBram Moolenaar
5659964e468SBram Moolenaar# {{{ main completion code
5669964e468SBram Moolenaar  def self.preload_rails
5679964e468SBram Moolenaar    a = VimRubyCompletion.new
5689964e468SBram Moolenaar    require 'Thread'
5699964e468SBram Moolenaar    Thread.new(a) do |b|
5709964e468SBram Moolenaar      begin
5719964e468SBram Moolenaar      b.load_rails
5729964e468SBram Moolenaar      rescue
5739964e468SBram Moolenaar      end
5749964e468SBram Moolenaar    end
5759964e468SBram Moolenaar    a.load_rails
5769964e468SBram Moolenaar  rescue
5779964e468SBram Moolenaar  end
5789964e468SBram Moolenaar
5799964e468SBram Moolenaar  def self.get_completions(base)
5809964e468SBram Moolenaar    b = VimRubyCompletion.new
5819964e468SBram Moolenaar    b.get_completions base
582fc1421ebSBram Moolenaar  end
583fc1421ebSBram Moolenaar
584c6249bb2SBram Moolenaar  def get_completions(base)
5859964e468SBram Moolenaar    loading_allowed = VIM::evaluate("exists('g:rubycomplete_buffer_loading') && g:rubycomplete_buffer_loading")
586c236c16dSBram Moolenaar    if loading_allowed.to_i == 1
587c6249bb2SBram Moolenaar      load_requires
588fc1421ebSBram Moolenaar      load_rails
5899964e468SBram Moolenaar    end
590fc1421ebSBram Moolenaar
591fc1421ebSBram Moolenaar    input = VIM::Buffer.current.line
592d8fc5c0bSBram Moolenaar    cpos = VIM::Window.current.cursor[1] - 1
5939964e468SBram Moolenaar    input = input[0..cpos]
594d8fc5c0bSBram Moolenaar    input += base
5959964e468SBram Moolenaar    input.sub!(/.*[ \t\n\"\\'`><=;|&{(]/, '') # Readline.basic_word_break_characters
5969964e468SBram Moolenaar    input.sub!(/self\./, '')
5979964e468SBram Moolenaar    input.sub!(/.*((\.\.[\[(]?)|([\[(]))/, '')
598c6249bb2SBram Moolenaar
5999964e468SBram Moolenaar    dprint 'input %s' % input
600d8fc5c0bSBram Moolenaar    message = nil
601d8fc5c0bSBram Moolenaar    receiver = nil
6029964e468SBram Moolenaar    methods = []
6039964e468SBram Moolenaar    variables = []
6049964e468SBram Moolenaar    classes = []
6059964e468SBram Moolenaar    constants = []
606c6249bb2SBram Moolenaar
607c6249bb2SBram Moolenaar    case input
608d8fc5c0bSBram Moolenaar      when /^(\/[^\/]*\/)\.([^.]*)$/ # Regexp
609c6249bb2SBram Moolenaar        receiver = $1
610c6249bb2SBram Moolenaar        message = Regexp.quote($2)
6119964e468SBram Moolenaar        methods = Regexp.instance_methods(true)
612c6249bb2SBram Moolenaar
613d8fc5c0bSBram Moolenaar      when /^([^\]]*\])\.([^.]*)$/ # Array
614c6249bb2SBram Moolenaar        receiver = $1
615c6249bb2SBram Moolenaar        message = Regexp.quote($2)
6169964e468SBram Moolenaar        methods = Array.instance_methods(true)
617c6249bb2SBram Moolenaar
618d8fc5c0bSBram Moolenaar      when /^([^\}]*\})\.([^.]*)$/ # Proc or Hash
619c6249bb2SBram Moolenaar        receiver = $1
620c6249bb2SBram Moolenaar        message = Regexp.quote($2)
6219964e468SBram Moolenaar        methods = Proc.instance_methods(true) | Hash.instance_methods(true)
622c6249bb2SBram Moolenaar
623d8fc5c0bSBram Moolenaar      when /^(:[^:.]*)$/ # Symbol
6249964e468SBram Moolenaar        dprint "symbol"
625c6249bb2SBram Moolenaar        if Symbol.respond_to?(:all_symbols)
626d8fc5c0bSBram Moolenaar          receiver = $1
6279964e468SBram Moolenaar          message = $1.sub( /:/, '' )
6289964e468SBram Moolenaar          methods = Symbol.all_symbols.collect{|s| s.id2name}
6299964e468SBram Moolenaar          methods.delete_if { |c| c.match( /'/ ) }
630c6249bb2SBram Moolenaar        end
631c6249bb2SBram Moolenaar
632d8fc5c0bSBram Moolenaar      when /^::([A-Z][^:\.\(]*)$/ # Absolute Constant or class methods
6339964e468SBram Moolenaar        dprint "const or cls"
634c6249bb2SBram Moolenaar        receiver = $1
6359964e468SBram Moolenaar        methods = Object.constants
6369964e468SBram Moolenaar        methods.grep(/^#{receiver}/).collect{|e| "::" + e}
637c6249bb2SBram Moolenaar
6381d68952aSBram Moolenaar      when /^(((::)?[A-Z][^:.\(]*)+?)::?([^:.]*)$/ # Constant or class methods
639c6249bb2SBram Moolenaar        receiver = $1
640c6249bb2SBram Moolenaar        message = Regexp.quote($4)
6419964e468SBram Moolenaar        dprint "const or cls 2 [recv: \'%s\', msg: \'%s\']" % [ receiver, message ]
6429964e468SBram Moolenaar        load_buffer_class( receiver )
643c6249bb2SBram Moolenaar        begin
6449964e468SBram Moolenaar          classes = eval("#{receiver}.constants")
6459964e468SBram Moolenaar          #methods = eval("#{receiver}.methods")
646c6249bb2SBram Moolenaar        rescue Exception
6479964e468SBram Moolenaar          dprint "exception: %s" % $!
6489964e468SBram Moolenaar          methods = []
649c6249bb2SBram Moolenaar        end
6509964e468SBram Moolenaar        methods.grep(/^#{message}/).collect{|e| receiver + "::" + e}
651c6249bb2SBram Moolenaar
652d8fc5c0bSBram Moolenaar      when /^(:[^:.]+)\.([^.]*)$/ # Symbol
6539964e468SBram Moolenaar        dprint "symbol"
654c6249bb2SBram Moolenaar        receiver = $1
655c6249bb2SBram Moolenaar        message = Regexp.quote($2)
6569964e468SBram Moolenaar        methods = Symbol.instance_methods(true)
657c6249bb2SBram Moolenaar
658d8fc5c0bSBram Moolenaar      when /^([0-9_]+(\.[0-9_]+)?(e[0-9]+)?)\.([^.]*)$/ # Numeric
6599964e468SBram Moolenaar        dprint "numeric"
660c6249bb2SBram Moolenaar        receiver = $1
661c6249bb2SBram Moolenaar        message = Regexp.quote($4)
662c6249bb2SBram Moolenaar        begin
6639964e468SBram Moolenaar          methods = eval(receiver).methods
664c6249bb2SBram Moolenaar        rescue Exception
6659964e468SBram Moolenaar          methods = []
666c6249bb2SBram Moolenaar        end
667c6249bb2SBram Moolenaar
668d8fc5c0bSBram Moolenaar      when /^(\$[^.]*)$/ #global
6699964e468SBram Moolenaar        dprint "global"
6709964e468SBram Moolenaar        methods = global_variables.grep(Regexp.new(Regexp.quote($1)))
671c6249bb2SBram Moolenaar
6721d68952aSBram Moolenaar      when /^((\.?[^.]+)+?)\.([^.]*)$/ # variable
6739964e468SBram Moolenaar        dprint "variable"
674c6249bb2SBram Moolenaar        receiver = $1
675c6249bb2SBram Moolenaar        message = Regexp.quote($3)
676fc1421ebSBram Moolenaar        load_buffer_class( receiver )
677c6249bb2SBram Moolenaar
678c6249bb2SBram Moolenaar        cv = eval("self.class.constants")
679d8fc5c0bSBram Moolenaar        vartype = get_var_type( receiver )
6809964e468SBram Moolenaar        dprint "vartype: %s" % vartype
681c6249bb2SBram Moolenaar        if vartype != ''
682fc1421ebSBram Moolenaar          load_buffer_class( vartype )
683fc1421ebSBram Moolenaar
684fc1421ebSBram Moolenaar          begin
6859964e468SBram Moolenaar            methods = eval("#{vartype}.instance_methods")
6869964e468SBram Moolenaar            variables = eval("#{vartype}.instance_variables")
687fc1421ebSBram Moolenaar          rescue Exception
6889964e468SBram Moolenaar            dprint "load_buffer_class err: %s" % $!
689fc1421ebSBram Moolenaar          end
690c6249bb2SBram Moolenaar        elsif (cv).include?(receiver)
691c6249bb2SBram Moolenaar          # foo.func and foo is local var.
6929964e468SBram Moolenaar          methods = eval("#{receiver}.methods")
6939964e468SBram Moolenaar          vartype = receiver
694c6249bb2SBram Moolenaar        elsif /^[A-Z]/ =~ receiver and /\./ !~ receiver
6959964e468SBram Moolenaar          vartype = receiver
696c6249bb2SBram Moolenaar          # Foo::Bar.func
697c6249bb2SBram Moolenaar          begin
6989964e468SBram Moolenaar            methods = eval("#{receiver}.methods")
699c6249bb2SBram Moolenaar          rescue Exception
700c6249bb2SBram Moolenaar          end
701c6249bb2SBram Moolenaar        else
702c6249bb2SBram Moolenaar          # func1.func2
703c6249bb2SBram Moolenaar          ObjectSpace.each_object(Module){|m|
704c6249bb2SBram Moolenaar            next if m.name != "IRB::Context" and
705c6249bb2SBram Moolenaar              /^(IRB|SLex|RubyLex|RubyToken)/ =~ m.name
7069964e468SBram Moolenaar            methods.concat m.instance_methods(false)
707c6249bb2SBram Moolenaar          }
708c6249bb2SBram Moolenaar        end
7099964e468SBram Moolenaar        variables += add_rails_columns( "#{vartype}" ) if vartype && vartype.length > 0
710c6249bb2SBram Moolenaar
711d8fc5c0bSBram Moolenaar      when /^\(?\s*[A-Za-z0-9:^@.%\/+*\(\)]+\.\.\.?[A-Za-z0-9:^@.%\/+*\(\)]+\s*\)?\.([^.]*)/
712d8fc5c0bSBram Moolenaar        message = $1
7139964e468SBram Moolenaar        methods = Range.instance_methods(true)
714c6249bb2SBram Moolenaar
715d8fc5c0bSBram Moolenaar      when /^\.([^.]*)$/ # unknown(maybe String)
716c6249bb2SBram Moolenaar        message = Regexp.quote($1)
7179964e468SBram Moolenaar        methods = String.instance_methods(true)
718c6249bb2SBram Moolenaar
719c6249bb2SBram Moolenaar    else
7209964e468SBram Moolenaar      dprint "default/other"
7219964e468SBram Moolenaar      inclass = eval( VIM::evaluate("s:IsInClassDef()") )
722c6249bb2SBram Moolenaar
723fc1421ebSBram Moolenaar      if inclass != nil
7249964e468SBram Moolenaar        dprint "inclass"
725fc1421ebSBram Moolenaar        classdef = "%s\n" % VIM::Buffer.current[ inclass.min ]
726fc1421ebSBram Moolenaar        found = /^\s*class\s*([A-Za-z0-9_-]*)(\s*<\s*([A-Za-z0-9_:-]*))?\s*\n$/.match( classdef )
727fc1421ebSBram Moolenaar
728fc1421ebSBram Moolenaar        if found != nil
729fc1421ebSBram Moolenaar          receiver = $1
730fc1421ebSBram Moolenaar          message = input
731fc1421ebSBram Moolenaar          load_buffer_class( receiver )
732eb3593b3SBram Moolenaar          begin
7339964e468SBram Moolenaar            methods = eval( "#{receiver}.instance_methods" )
7349964e468SBram Moolenaar            variables += add_rails_columns( "#{receiver}" )
735eb3593b3SBram Moolenaar          rescue Exception
736eb3593b3SBram Moolenaar            found = nil
737eb3593b3SBram Moolenaar          end
738fc1421ebSBram Moolenaar        end
739fc1421ebSBram Moolenaar      end
740fc1421ebSBram Moolenaar
741fc1421ebSBram Moolenaar      if inclass == nil || found == nil
7429964e468SBram Moolenaar        dprint "inclass == nil"
7439964e468SBram Moolenaar        methods = get_buffer_methods
7449964e468SBram Moolenaar        methods += get_rails_view_methods
7459964e468SBram Moolenaar
7469964e468SBram Moolenaar        cls_const = Class.constants
7479964e468SBram Moolenaar        constants = cls_const.select { |c| /^[A-Z_-]+$/.match( c ) }
7489964e468SBram Moolenaar        classes = eval("self.class.constants") - constants
7499964e468SBram Moolenaar        classes += get_buffer_classes
7509964e468SBram Moolenaar        classes += get_buffer_modules
7519964e468SBram Moolenaar
7529964e468SBram Moolenaar        include_objectspace = VIM::evaluate("exists('g:rubycomplete_include_objectspace') && g:rubycomplete_include_objectspace")
7539964e468SBram Moolenaar        ObjectSpace.each_object(Class) { |cls| classes << cls.to_s } if include_objectspace == "1"
754d8fc5c0bSBram Moolenaar        message = receiver = input
755d8fc5c0bSBram Moolenaar      end
7569964e468SBram Moolenaar
7579964e468SBram Moolenaar      methods += get_rails_helpers
7589964e468SBram Moolenaar      methods += Kernel.public_methods
759d8fc5c0bSBram Moolenaar    end
760d8fc5c0bSBram Moolenaar
7619964e468SBram Moolenaar
7629964e468SBram Moolenaar    include_object = VIM::evaluate("exists('g:rubycomplete_include_object') && g:rubycomplete_include_object")
7639964e468SBram Moolenaar    methods = clean_sel( methods, message )
7649964e468SBram Moolenaar    methods = (methods-Object.instance_methods) if include_object == "0"
7659964e468SBram Moolenaar    rbcmeth = (VimRubyCompletion.instance_methods-Object.instance_methods) # lets remove those rubycomplete methods
7669964e468SBram Moolenaar    methods = (methods-rbcmeth)
7679964e468SBram Moolenaar
7689964e468SBram Moolenaar    variables = clean_sel( variables, message )
7699964e468SBram Moolenaar    classes = clean_sel( classes, message ) - ["VimRubyCompletion"]
7709964e468SBram Moolenaar    constants = clean_sel( constants, message )
7719964e468SBram Moolenaar
7729964e468SBram Moolenaar    valid = []
773*ec7944aaSBram Moolenaar    valid += methods.collect { |m| { :name => m.to_s, :type => 'm' } }
774*ec7944aaSBram Moolenaar    valid += variables.collect { |v| { :name => v.to_s, :type => 'v' } }
775*ec7944aaSBram Moolenaar    valid += classes.collect { |c| { :name => c.to_s, :type => 't' } }
776*ec7944aaSBram Moolenaar    valid += constants.collect { |d| { :name => d.to_s, :type => 'd' } }
7779964e468SBram Moolenaar    valid.sort! { |x,y| x[:name] <=> y[:name] }
778c6249bb2SBram Moolenaar
779c6249bb2SBram Moolenaar    outp = ""
780fc1421ebSBram Moolenaar
781fc1421ebSBram Moolenaar    rg = 0..valid.length
782fc1421ebSBram Moolenaar    rg.step(150) do |x|
783fc1421ebSBram Moolenaar      stpos = 0+x
784fc1421ebSBram Moolenaar      enpos = 150+x
785*ec7944aaSBram Moolenaar      valid[stpos..enpos].each { |c| outp += "{'word':'%s','item':'%s','kind':'%s'}," % [ c[:name], c[:name], c[:type] ].map{|x|escape_vim_singlequote_string(x)} }
786c6249bb2SBram Moolenaar      outp.sub!(/,$/, '')
787fc1421ebSBram Moolenaar
788fc1421ebSBram Moolenaar      VIM::command("call extend(g:rubycomplete_completions, [%s])" % outp)
789fc1421ebSBram Moolenaar      outp = ""
790fc1421ebSBram Moolenaar    end
791c6249bb2SBram Moolenaar  end
7929964e468SBram Moolenaar# }}} main completion code
793c6249bb2SBram Moolenaar
7949964e468SBram Moolenaarend # VimRubyCompletion
795eb3593b3SBram Moolenaar# }}} ruby completion
796c6249bb2SBram MoolenaarRUBYEOF
797c6249bb2SBram Moolenaarendfunction
798c6249bb2SBram Moolenaar
7999964e468SBram Moolenaarlet s:rubycomplete_rails_loaded = 0
800fc1421ebSBram Moolenaar
801c6249bb2SBram Moolenaarcall s:DefRuby()
8029964e468SBram Moolenaar"}}} ruby-side code
8039964e468SBram Moolenaar
8049964e468SBram Moolenaar
8059964e468SBram Moolenaar" vim:tw=78:sw=4:ts=8:et:fdm=marker:ft=vim:norl:
806