1c6249bb2SBram Moolenaar" Vim completion script
2c6249bb2SBram Moolenaar" Language:				Ruby
3fc1421ebSBram Moolenaar" Maintainer:			Mark Guzman <[email protected]>
4c6249bb2SBram Moolenaar" Info:					$Id$
5c6249bb2SBram Moolenaar" URL:					http://vim-ruby.rubyforge.org
6c6249bb2SBram Moolenaar" Anon CVS:				See above site
7c6249bb2SBram Moolenaar" Release Coordinator:	Doug Kearns <[email protected]>
8c6249bb2SBram Moolenaar" ----------------------------------------------------------------------------
9c6249bb2SBram Moolenaar"
10c6249bb2SBram Moolenaar" Ruby IRB/Complete author: Keiju ISHITSUKA([email protected])
11c6249bb2SBram Moolenaar" ----------------------------------------------------------------------------
12c6249bb2SBram Moolenaar
13*eb3593b3SBram Moolenaar" {{{ requirement checks
14c6249bb2SBram Moolenaarif !has('ruby')
15fc1421ebSBram Moolenaar    echohl ErrorMsg
16c6249bb2SBram Moolenaar    echo "Error: Required vim compiled with +ruby"
17fc1421ebSBram Moolenaar    echohl None
18c6249bb2SBram Moolenaar    finish
19c6249bb2SBram Moolenaarendif
20c6249bb2SBram Moolenaar
21c6249bb2SBram Moolenaarif version < 700
22fc1421ebSBram Moolenaar    echohl ErrorMsg
23c6249bb2SBram Moolenaar    echo "Error: Required vim >= 7.0"
24fc1421ebSBram Moolenaar    echohl None
25c6249bb2SBram Moolenaar    finish
26c6249bb2SBram Moolenaarendif
27*eb3593b3SBram Moolenaar" }}} requirement checks
28c6249bb2SBram Moolenaar
29*eb3593b3SBram Moolenaarif !exists("g:rubycomplete_rails")
30*eb3593b3SBram Moolenaar    let g:rubycomplete_rails = 0
31*eb3593b3SBram Moolenaarendif
32fc1421ebSBram Moolenaar
33*eb3593b3SBram Moolenaarif !exists("g:rubycomplete_classes_in_global")
34*eb3593b3SBram Moolenaar    let g:rubycomplete_classes_in_global = 0
35*eb3593b3SBram Moolenaarendif
36*eb3593b3SBram Moolenaar
37*eb3593b3SBram Moolenaar" {{{ vim-side support functions
38fc1421ebSBram Moolenaarfunction! GetBufferRubyModule(name)
39fc1421ebSBram Moolenaar    let [snum,enum] = GetBufferRubyEntity(a:name, "module")
40fc1421ebSBram Moolenaar    return snum . '..' . enum
41fc1421ebSBram Moolenaarendfunction
42fc1421ebSBram Moolenaar
43fc1421ebSBram Moolenaarfunction! GetBufferRubyClass(name)
44fc1421ebSBram Moolenaar    let [snum,enum] = GetBufferRubyEntity(a:name, "class")
45fc1421ebSBram Moolenaar    return snum . '..' . enum
46fc1421ebSBram Moolenaarendfunction
47fc1421ebSBram Moolenaar
48fc1421ebSBram Moolenaarfunction! GetBufferRubySingletonMethods(name)
49fc1421ebSBram Moolenaarendfunction
50fc1421ebSBram Moolenaar
51fc1421ebSBram Moolenaarfunction! GetBufferRubyEntity( name, type )
52fc1421ebSBram Moolenaar    let stopline = 1
53fc1421ebSBram Moolenaar    let crex = '^\s*' . a:type . '\s*' . a:name . '\s*\(<\s*.*\s*\)\?\n*\(\(\s\|#\).*\n*\)*\n*\s*end$'
54fc1421ebSBram Moolenaar    let [lnum,lcol] = searchpos( crex, 'nbw')
55fc1421ebSBram Moolenaar    if lnum == 0 && lcol == 0
56fc1421ebSBram Moolenaar        return [0,0]
57fc1421ebSBram Moolenaar    endif
58fc1421ebSBram Moolenaar
59fc1421ebSBram Moolenaar    let [enum,ecol] = searchpos( crex, 'nebw')
60fc1421ebSBram Moolenaar    if lnum > enum
61fc1421ebSBram Moolenaar        let realdef = getline( lnum )
62fc1421ebSBram Moolenaar        let crexb = '^' . realdef . '\n*\(\(\s\|#\).*\n*\)*\n*\s*end$'
63fc1421ebSBram Moolenaar        let [enum,ecol] = searchpos( crexb, 'necw' )
64fc1421ebSBram Moolenaar    endif
65fc1421ebSBram Moolenaar    " we found a the class def
66fc1421ebSBram Moolenaar    return [lnum,enum]
67fc1421ebSBram Moolenaarendfunction
68fc1421ebSBram Moolenaar
69fc1421ebSBram Moolenaarfunction! IsInClassDef()
70fc1421ebSBram Moolenaar    let [snum,enum] = GetBufferRubyEntity( '.*', "class" )
71fc1421ebSBram Moolenaar    let ret = 'nil'
72fc1421ebSBram Moolenaar    let pos = line('.')
73fc1421ebSBram Moolenaar
74fc1421ebSBram Moolenaar    if snum < pos && pos < enum
75fc1421ebSBram Moolenaar        let ret = snum . '..' . enum
76fc1421ebSBram Moolenaar    endif
77fc1421ebSBram Moolenaar
78fc1421ebSBram Moolenaar    return ret
79fc1421ebSBram Moolenaarendfunction
80fc1421ebSBram Moolenaar
81fc1421ebSBram Moolenaarfunction! GetRubyVarType(v)
82c6249bb2SBram Moolenaar	let stopline = 1
83c6249bb2SBram Moolenaar	let vtp = ''
84c6249bb2SBram Moolenaar	let pos = getpos('.')
85c6249bb2SBram Moolenaar	let [lnum,lcol] = searchpos('^\s*#\s*@var\s*'.a:v.'\>\s\+[^ \t]\+\s*$','nb',stopline)
86c6249bb2SBram Moolenaar	if lnum != 0 && lcol != 0
87c6249bb2SBram Moolenaar		call setpos('.',pos)
88c6249bb2SBram Moolenaar		let str = getline(lnum)
89c6249bb2SBram Moolenaar		let vtp = substitute(str,'^\s*#\s*@var\s*'.a:v.'\>\s\+\([^ \t]\+\)\s*$','\1','')
90c6249bb2SBram Moolenaar		return vtp
91c6249bb2SBram Moolenaar	endif
92c6249bb2SBram Moolenaar	call setpos('.',pos)
93fc1421ebSBram Moolenaar    let [lnum,lcol] = searchpos(''.a:v.'\>\s*[+\-*/]*=\s*\([^ \t]\+.\(now\|new\|open\|get_instance\)\>\|[\[{"''/]\|%r{\)','nb',stopline)
94c6249bb2SBram Moolenaar	if lnum != 0 && lcol != 0
95fc1421ebSBram Moolenaar        let str = matchstr(getline(lnum),'=\s*\([^ \t]\+.\(now\|new\|open\|get_instance\)\>\|[\[{"''/]\|%r{\)',lcol)
96c6249bb2SBram Moolenaar		let str = substitute(str,'^=\s*','','')
97c6249bb2SBram Moolenaar		call setpos('.',pos)
98c6249bb2SBram Moolenaar		if str == '"' || str == ''''
99c6249bb2SBram Moolenaar			return 'String'
100c6249bb2SBram Moolenaar		elseif str == '['
101c6249bb2SBram Moolenaar			return 'Array'
102c6249bb2SBram Moolenaar		elseif str == '{'
103c6249bb2SBram Moolenaar			return 'Hash'
104fc1421ebSBram Moolenaar        elseif str == '/' || str == '%r{'
105fc1421ebSBram Moolenaar            return 'Regexp'
106c6249bb2SBram Moolenaar		elseif strlen(str) > 4
107c6249bb2SBram Moolenaar            let l = stridx(str,'.')
108c6249bb2SBram Moolenaar			return str[0:l-1]
109c6249bb2SBram Moolenaar		end
110c6249bb2SBram Moolenaar		return ''
111c6249bb2SBram Moolenaar	endif
112c6249bb2SBram Moolenaar	call setpos('.',pos)
113c6249bb2SBram Moolenaar    return ''
114fc1421ebSBram Moolenaarendfunction
115c6249bb2SBram Moolenaar
116*eb3593b3SBram Moolenaar"}}} vim-side support functions
117*eb3593b3SBram Moolenaar
118c6249bb2SBram Moolenaarfunction! rubycomplete#Complete(findstart, base)
119c6249bb2SBram Moolenaar     "findstart = 1 when we need to get the text length
120c6249bb2SBram Moolenaar    if a:findstart
121c6249bb2SBram Moolenaar        let line = getline('.')
122c6249bb2SBram Moolenaar        let idx = col('.')
123c6249bb2SBram Moolenaar        while idx > 0
124c6249bb2SBram Moolenaar            let idx -= 1
125c6249bb2SBram Moolenaar            let c = line[idx-1]
126c6249bb2SBram Moolenaar            if c =~ '\w'
127c6249bb2SBram Moolenaar                continue
128c6249bb2SBram Moolenaar            elseif ! c =~ '\.'
129c6249bb2SBram Moolenaar                idx = -1
130c6249bb2SBram Moolenaar                break
131c6249bb2SBram Moolenaar            else
132c6249bb2SBram Moolenaar                break
133c6249bb2SBram Moolenaar            endif
134c6249bb2SBram Moolenaar        endwhile
135c6249bb2SBram Moolenaar
136c6249bb2SBram Moolenaar        return idx
137c6249bb2SBram Moolenaar    "findstart = 0 when we need to return the list of completions
138c6249bb2SBram Moolenaar    else
139fc1421ebSBram Moolenaar        let g:rubycomplete_completions = []
140c6249bb2SBram Moolenaar        execute "ruby get_completions('" . a:base . "')"
141fc1421ebSBram Moolenaar        return g:rubycomplete_completions
142c6249bb2SBram Moolenaar    endif
143c6249bb2SBram Moolenaarendfunction
144c6249bb2SBram Moolenaar
145c6249bb2SBram Moolenaar
146c6249bb2SBram Moolenaarfunction! s:DefRuby()
147c6249bb2SBram Moolenaarruby << RUBYEOF
148*eb3593b3SBram Moolenaar# {{{ ruby completion
149fc1421ebSBram MoolenaarRailsWords = [
150fc1421ebSBram Moolenaar      "has_many", "has_one",
151fc1421ebSBram Moolenaar      "belongs_to",
152fc1421ebSBram Moolenaar    ]
153fc1421ebSBram Moolenaar
154c6249bb2SBram MoolenaarReservedWords = [
155c6249bb2SBram Moolenaar      "BEGIN", "END",
156c6249bb2SBram Moolenaar      "alias", "and",
157c6249bb2SBram Moolenaar      "begin", "break",
158c6249bb2SBram Moolenaar      "case", "class",
159c6249bb2SBram Moolenaar      "def", "defined", "do",
160c6249bb2SBram Moolenaar      "else", "elsif", "end", "ensure",
161c6249bb2SBram Moolenaar      "false", "for",
162c6249bb2SBram Moolenaar      "if", "in",
163c6249bb2SBram Moolenaar      "module",
164c6249bb2SBram Moolenaar      "next", "nil", "not",
165c6249bb2SBram Moolenaar      "or",
166c6249bb2SBram Moolenaar      "redo", "rescue", "retry", "return",
167c6249bb2SBram Moolenaar      "self", "super",
168c6249bb2SBram Moolenaar      "then", "true",
169c6249bb2SBram Moolenaar      "undef", "unless", "until",
170c6249bb2SBram Moolenaar      "when", "while",
171c6249bb2SBram Moolenaar      "yield",
172c6249bb2SBram Moolenaar    ]
173c6249bb2SBram Moolenaar
174c6249bb2SBram MoolenaarOperators = [ "%", "&", "*", "**", "+",  "-",  "/",
175c6249bb2SBram Moolenaar      "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>",
176c6249bb2SBram Moolenaar      "[]", "[]=", "^", ]
177c6249bb2SBram Moolenaar
178c6249bb2SBram Moolenaar
179c6249bb2SBram Moolenaardef load_requires
180*eb3593b3SBram Moolenaar  buf = VIM::Buffer.current
181*eb3593b3SBram Moolenaar  enum = buf.line_number
182c6249bb2SBram Moolenaar  nums = Range.new( 1, enum )
183c6249bb2SBram Moolenaar  nums.each do |x|
184*eb3593b3SBram Moolenaar    ln = buf[x]
185c6249bb2SBram Moolenaar    begin
186c6249bb2SBram Moolenaar      eval( "require %s" % $1 ) if /.*require\s*(.*)$/.match( ln )
187c6249bb2SBram Moolenaar    rescue Exception
188c6249bb2SBram Moolenaar      #ignore?
189c6249bb2SBram Moolenaar    end
190c6249bb2SBram Moolenaar  end
191c6249bb2SBram Moolenaarend
192c6249bb2SBram Moolenaar
193fc1421ebSBram Moolenaardef load_buffer_class(name)
194fc1421ebSBram Moolenaar  classdef = get_buffer_entity(name, 'GetBufferRubyClass("%s")')
195fc1421ebSBram Moolenaar  return if classdef == nil
196fc1421ebSBram Moolenaar
197fc1421ebSBram Moolenaar  pare = /^\s*class\s*(.*)\s*<\s*(.*)\s*\n/.match( classdef )
198fc1421ebSBram Moolenaar  load_buffer_class( $2 ) if pare != nil
199fc1421ebSBram Moolenaar
200fc1421ebSBram Moolenaar  mixre = /.*\n\s*include\s*(.*)\s*\n/.match( classdef )
201fc1421ebSBram Moolenaar  load_buffer_module( $2 ) if mixre != nil
202fc1421ebSBram Moolenaar
203fc1421ebSBram Moolenaar  eval classdef
204fc1421ebSBram Moolenaarend
205fc1421ebSBram Moolenaar
206fc1421ebSBram Moolenaardef load_buffer_module(name)
207fc1421ebSBram Moolenaar  classdef = get_buffer_entity(name, 'GetBufferRubyModule("%s")')
208fc1421ebSBram Moolenaar  return if classdef == nil
209fc1421ebSBram Moolenaar
210fc1421ebSBram Moolenaar  eval classdef
211fc1421ebSBram Moolenaarend
212fc1421ebSBram Moolenaar
213fc1421ebSBram Moolenaardef get_buffer_entity(name, vimfun)
214*eb3593b3SBram Moolenaar  buf = VIM::Buffer.current
215fc1421ebSBram Moolenaar  nums = eval( VIM::evaluate( vimfun % name ) )
216fc1421ebSBram Moolenaar  return nil if nums == nil
217fc1421ebSBram Moolenaar  return nil if nums.min == nums.max && nums.min == 0
218fc1421ebSBram Moolenaar
219fc1421ebSBram Moolenaar  cur_line = VIM::Buffer.current.line_number
220fc1421ebSBram Moolenaar  classdef = ""
221fc1421ebSBram Moolenaar  nums.each do |x|
222fc1421ebSBram Moolenaar    if x != cur_line
223*eb3593b3SBram Moolenaar      ln = buf[x]
224fc1421ebSBram Moolenaar      classdef += "%s\n" % ln
225fc1421ebSBram Moolenaar    end
226fc1421ebSBram Moolenaar  end
227fc1421ebSBram Moolenaar
228fc1421ebSBram Moolenaar  return classdef
229fc1421ebSBram Moolenaarend
230fc1421ebSBram Moolenaar
231*eb3593b3SBram Moolenaardef get_buffer_classes()
232*eb3593b3SBram Moolenaar  # this will be a little expensive.
233*eb3593b3SBram Moolenaar  allow_aggressive_load = VIM::evaluate('g:rubycomplete_classes_in_global')
234*eb3593b3SBram Moolenaar  return [] if allow_aggressive_load != '1'
235*eb3593b3SBram Moolenaar
236*eb3593b3SBram Moolenaar  buf = VIM::Buffer.current
237*eb3593b3SBram Moolenaar  eob = buf.length
238*eb3593b3SBram Moolenaar  ret = []
239*eb3593b3SBram Moolenaar  rg = 1..eob
240*eb3593b3SBram Moolenaar
241*eb3593b3SBram Moolenaar  rg.each do |x|
242*eb3593b3SBram Moolenaar    if /^\s*class\s*([A-Za-z0-9_-]*)(\s*<\s*([A-Za-z0-9_:-]*))?\s*/.match( buf[x] )
243*eb3593b3SBram Moolenaar      ret.push $1
244*eb3593b3SBram Moolenaar    end
245*eb3593b3SBram Moolenaar  end
246*eb3593b3SBram Moolenaar
247*eb3593b3SBram Moolenaar  return ret
248*eb3593b3SBram Moolenaarend
249*eb3593b3SBram Moolenaar
250fc1421ebSBram Moolenaardef load_rails()
251fc1421ebSBram Moolenaar  allow_rails = VIM::evaluate('g:rubycomplete_rails')
252fc1421ebSBram Moolenaar  return if allow_rails != '1'
253fc1421ebSBram Moolenaar
254fc1421ebSBram Moolenaar  buf_path = VIM::evaluate('expand("%:p")')
255fc1421ebSBram Moolenaar  file_name = VIM::evaluate('expand("%:t")')
256fc1421ebSBram Moolenaar  path = buf_path.gsub( file_name, '' )
257fc1421ebSBram Moolenaar  path.gsub!( /\\/, "/" )
258fc1421ebSBram Moolenaar  pup = [ "../", "../../", "../../../", "../../../../" ]
259fc1421ebSBram Moolenaar  pok = nil
260fc1421ebSBram Moolenaar
261fc1421ebSBram Moolenaar  pup.each do |sup|
262fc1421ebSBram Moolenaar    tpok = "%s%sconfig" % [ path, sup ]
263fc1421ebSBram Moolenaar    if File.exists?( tpok )
264fc1421ebSBram Moolenaar        pok = tpok
265fc1421ebSBram Moolenaar        break
266fc1421ebSBram Moolenaar    end
267fc1421ebSBram Moolenaar  end
268*eb3593b3SBram Moolenaar
269*eb3593b3SBram Moolenaar  return if pok == nil
270fc1421ebSBram Moolenaar  bootfile = pok + "/boot.rb"
271*eb3593b3SBram Moolenaar  if File.exists?( bootfile )
272*eb3593b3SBram Moolenaar    require bootfile
273*eb3593b3SBram Moolenaar    VIM::evaluate('let g:rubycomplete_rails_loaded = 1')
274*eb3593b3SBram Moolenaar  end
275fc1421ebSBram Moolenaarend
276fc1421ebSBram Moolenaar
277fc1421ebSBram Moolenaardef get_rails_helpers
278fc1421ebSBram Moolenaar  allow_rails = VIM::evaluate('g:rubycomplete_rails')
279*eb3593b3SBram Moolenaar  rails_loaded = VIM::evaluate('g:rubycomplete_rails_loaded')
280*eb3593b3SBram Moolenaar  return [] if allow_rails != '1' || rails_loaded != '1'
281fc1421ebSBram Moolenaar  return RailsWords
282fc1421ebSBram Moolenaarend
283fc1421ebSBram Moolenaar
284c6249bb2SBram Moolenaardef get_completions(base)
285c6249bb2SBram Moolenaar  load_requires
286fc1421ebSBram Moolenaar  load_rails
287fc1421ebSBram Moolenaar
288c6249bb2SBram Moolenaar  input = VIM::evaluate('expand("<cWORD>")')
289c6249bb2SBram Moolenaar  input += base
290fc1421ebSBram Moolenaar  input.lstrip!
291fc1421ebSBram Moolenaar  if input.length == 0
292fc1421ebSBram Moolenaar    input = VIM::Buffer.current.line
293fc1421ebSBram Moolenaar    input.strip!
294fc1421ebSBram Moolenaar  end
295c6249bb2SBram Moolenaar  message = nil
296c6249bb2SBram Moolenaar
297c6249bb2SBram Moolenaar
298c6249bb2SBram Moolenaar  case input
299c6249bb2SBram Moolenaar    when /^(\/[^\/]*\/)\.([^.]*)$/
300c6249bb2SBram Moolenaar      # Regexp
301c6249bb2SBram Moolenaar      receiver = $1
302c6249bb2SBram Moolenaar      message = Regexp.quote($2)
303c6249bb2SBram Moolenaar
304c6249bb2SBram Moolenaar      candidates = Regexp.instance_methods(true)
305c6249bb2SBram Moolenaar      select_message(receiver, message, candidates)
306c6249bb2SBram Moolenaar
307c6249bb2SBram Moolenaar    when /^([^\]]*\])\.([^.]*)$/
308c6249bb2SBram Moolenaar      # Array
309c6249bb2SBram Moolenaar      receiver = $1
310c6249bb2SBram Moolenaar      message = Regexp.quote($2)
311c6249bb2SBram Moolenaar
312c6249bb2SBram Moolenaar      candidates = Array.instance_methods(true)
313c6249bb2SBram Moolenaar      select_message(receiver, message, candidates)
314c6249bb2SBram Moolenaar
315c6249bb2SBram Moolenaar    when /^([^\}]*\})\.([^.]*)$/
316c6249bb2SBram Moolenaar      # Proc or Hash
317c6249bb2SBram Moolenaar      receiver = $1
318c6249bb2SBram Moolenaar      message = Regexp.quote($2)
319c6249bb2SBram Moolenaar
320c6249bb2SBram Moolenaar      candidates = Proc.instance_methods(true) | Hash.instance_methods(true)
321c6249bb2SBram Moolenaar      select_message(receiver, message, candidates)
322c6249bb2SBram Moolenaar
323c6249bb2SBram Moolenaar    when /^(:[^:.]*)$/
324c6249bb2SBram Moolenaar      # Symbol
325c6249bb2SBram Moolenaar      if Symbol.respond_to?(:all_symbols)
326c6249bb2SBram Moolenaar        sym = $1
327c6249bb2SBram Moolenaar        candidates = Symbol.all_symbols.collect{|s| ":" + s.id2name}
328c6249bb2SBram Moolenaar        candidates.grep(/^#{sym}/)
329fc1421ebSBram Moolenaar        candidates.delete_if do |c|
330fc1421ebSBram Moolenaar            c.match( /'/ )
331fc1421ebSBram Moolenaar        end
332fc1421ebSBram Moolenaar        candidates.uniq!
333fc1421ebSBram Moolenaar        candidates.sort!
334c6249bb2SBram Moolenaar      else
335c6249bb2SBram Moolenaar        []
336c6249bb2SBram Moolenaar      end
337c6249bb2SBram Moolenaar
338c6249bb2SBram Moolenaar    when /^::([A-Z][^:\.\(]*)$/
339c6249bb2SBram Moolenaar      # Absolute Constant or class methods
340c6249bb2SBram Moolenaar      receiver = $1
341c6249bb2SBram Moolenaar      candidates = Object.constants
342c6249bb2SBram Moolenaar      candidates.grep(/^#{receiver}/).collect{|e| "::" + e}
343c6249bb2SBram Moolenaar
344c6249bb2SBram Moolenaar    when /^(((::)?[A-Z][^:.\(]*)+)::?([^:.]*)$/
345c6249bb2SBram Moolenaar      # Constant or class methods
346c6249bb2SBram Moolenaar      receiver = $1
347c6249bb2SBram Moolenaar      message = Regexp.quote($4)
348c6249bb2SBram Moolenaar      begin
349c6249bb2SBram Moolenaar        candidates = eval("#{receiver}.constants | #{receiver}.methods")
350c6249bb2SBram Moolenaar      rescue Exception
351c6249bb2SBram Moolenaar        candidates = []
352c6249bb2SBram Moolenaar      end
353c6249bb2SBram Moolenaar      candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e}
354c6249bb2SBram Moolenaar
355c6249bb2SBram Moolenaar    when /^(:[^:.]+)\.([^.]*)$/
356c6249bb2SBram Moolenaar      # Symbol
357c6249bb2SBram Moolenaar      receiver = $1
358c6249bb2SBram Moolenaar      message = Regexp.quote($2)
359c6249bb2SBram Moolenaar
360c6249bb2SBram Moolenaar      candidates = Symbol.instance_methods(true)
361c6249bb2SBram Moolenaar      select_message(receiver, message, candidates)
362c6249bb2SBram Moolenaar
363c6249bb2SBram Moolenaar    when /^([0-9_]+(\.[0-9_]+)?(e[0-9]+)?)\.([^.]*)$/
364c6249bb2SBram Moolenaar      # Numeric
365c6249bb2SBram Moolenaar      receiver = $1
366c6249bb2SBram Moolenaar      message = Regexp.quote($4)
367c6249bb2SBram Moolenaar
368c6249bb2SBram Moolenaar      begin
369c6249bb2SBram Moolenaar        candidates = eval(receiver).methods
370c6249bb2SBram Moolenaar      rescue Exception
371c6249bb2SBram Moolenaar        candidates
372c6249bb2SBram Moolenaar      end
373c6249bb2SBram Moolenaar      select_message(receiver, message, candidates)
374c6249bb2SBram Moolenaar
375c6249bb2SBram Moolenaar    when /^(\$[^.]*)$/
376c6249bb2SBram Moolenaar	  candidates = global_variables.grep(Regexp.new(Regexp.quote($1)))
377c6249bb2SBram Moolenaar
378c6249bb2SBram Moolenaar#   when /^(\$?(\.?[^.]+)+)\.([^.]*)$/
379c6249bb2SBram Moolenaar    when /^((\.?[^.]+)+)\.([^.]*)$/
380c6249bb2SBram Moolenaar      # variable
381c6249bb2SBram Moolenaar      receiver = $1
382c6249bb2SBram Moolenaar      message = Regexp.quote($3)
383fc1421ebSBram Moolenaar      load_buffer_class( receiver )
384c6249bb2SBram Moolenaar
385c6249bb2SBram Moolenaar      cv = eval("self.class.constants")
386c6249bb2SBram Moolenaar
387c6249bb2SBram Moolenaar      vartype = VIM::evaluate("GetRubyVarType('%s')" % receiver)
388c6249bb2SBram Moolenaar      if vartype != ''
389fc1421ebSBram Moolenaar        load_buffer_class( vartype )
390fc1421ebSBram Moolenaar
391fc1421ebSBram Moolenaar        begin
392c6249bb2SBram Moolenaar          candidates = eval("#{vartype}.instance_methods")
393fc1421ebSBram Moolenaar        rescue Exception
394fc1421ebSBram Moolenaar          candidates = []
395fc1421ebSBram Moolenaar        end
396c6249bb2SBram Moolenaar      elsif (cv).include?(receiver)
397c6249bb2SBram Moolenaar        # foo.func and foo is local var.
398c6249bb2SBram Moolenaar        candidates = eval("#{receiver}.methods")
399c6249bb2SBram Moolenaar      elsif /^[A-Z]/ =~ receiver and /\./ !~ receiver
400c6249bb2SBram Moolenaar        # Foo::Bar.func
401c6249bb2SBram Moolenaar        begin
402c6249bb2SBram Moolenaar          candidates = eval("#{receiver}.methods")
403c6249bb2SBram Moolenaar        rescue Exception
404c6249bb2SBram Moolenaar          candidates = []
405c6249bb2SBram Moolenaar        end
406c6249bb2SBram Moolenaar      else
407c6249bb2SBram Moolenaar        # func1.func2
408c6249bb2SBram Moolenaar        candidates = []
409c6249bb2SBram Moolenaar        ObjectSpace.each_object(Module){|m|
410c6249bb2SBram Moolenaar          next if m.name != "IRB::Context" and
411c6249bb2SBram Moolenaar            /^(IRB|SLex|RubyLex|RubyToken)/ =~ m.name
412c6249bb2SBram Moolenaar          candidates.concat m.instance_methods(false)
413c6249bb2SBram Moolenaar        }
414c6249bb2SBram Moolenaar        candidates.sort!
415c6249bb2SBram Moolenaar        candidates.uniq!
416c6249bb2SBram Moolenaar      end
417c6249bb2SBram Moolenaar      #identify_type( receiver )
418c6249bb2SBram Moolenaar      select_message(receiver, message, candidates)
419c6249bb2SBram Moolenaar
420c6249bb2SBram Moolenaar    #when /^((\.?[^.]+)+)\.([^.]*)\(\s*\)*$/
421c6249bb2SBram Moolenaar        #function call
422c6249bb2SBram Moolenaar        #obj = $1
423c6249bb2SBram Moolenaar        #func = $3
424c6249bb2SBram Moolenaar
425c6249bb2SBram Moolenaar    when /^\.([^.]*)$/
426c6249bb2SBram Moolenaar	# unknown(maybe String)
427c6249bb2SBram Moolenaar
428c6249bb2SBram Moolenaar      receiver = ""
429c6249bb2SBram Moolenaar      message = Regexp.quote($1)
430c6249bb2SBram Moolenaar
431c6249bb2SBram Moolenaar      candidates = String.instance_methods(true)
432c6249bb2SBram Moolenaar      select_message(receiver, message, candidates)
433c6249bb2SBram Moolenaar
434c6249bb2SBram Moolenaar  else
435fc1421ebSBram Moolenaar    inclass = eval( VIM::evaluate("IsInClassDef()") )
436c6249bb2SBram Moolenaar
437fc1421ebSBram Moolenaar    if inclass != nil
438fc1421ebSBram Moolenaar      classdef = "%s\n" % VIM::Buffer.current[ inclass.min ]
439fc1421ebSBram Moolenaar      found = /^\s*class\s*([A-Za-z0-9_-]*)(\s*<\s*([A-Za-z0-9_:-]*))?\s*\n$/.match( classdef )
440fc1421ebSBram Moolenaar
441fc1421ebSBram Moolenaar      if found != nil
442fc1421ebSBram Moolenaar        receiver = $1
443fc1421ebSBram Moolenaar        message = input
444fc1421ebSBram Moolenaar        load_buffer_class( receiver )
445*eb3593b3SBram Moolenaar        begin
446fc1421ebSBram Moolenaar          candidates = eval( "#{receiver}.instance_methods" )
447fc1421ebSBram Moolenaar          candidates += get_rails_helpers
448fc1421ebSBram Moolenaar          select_message(receiver, message, candidates)
449*eb3593b3SBram Moolenaar        rescue Exception
450*eb3593b3SBram Moolenaar          found = nil
451*eb3593b3SBram Moolenaar        end
452fc1421ebSBram Moolenaar      end
453fc1421ebSBram Moolenaar    end
454fc1421ebSBram Moolenaar
455fc1421ebSBram Moolenaar    if inclass == nil || found == nil
456fc1421ebSBram Moolenaar      candidates = eval("self.class.constants")
457*eb3593b3SBram Moolenaar      candidates += get_buffer_classes
458*eb3593b3SBram Moolenaar      candidates.uniq!
459*eb3593b3SBram Moolenaar      candidates.sort!
460c6249bb2SBram Moolenaar      (candidates|ReservedWords).grep(/^#{Regexp.quote(input)}/)
461c6249bb2SBram Moolenaar    end
462fc1421ebSBram Moolenaar  end
463c6249bb2SBram Moolenaar
464c6249bb2SBram Moolenaar    #print candidates
465c6249bb2SBram Moolenaar  if message != nil && message.length > 0
466c6249bb2SBram Moolenaar    rexp = '^%s' % message.downcase
467c6249bb2SBram Moolenaar    candidates.delete_if do |c|
468c6249bb2SBram Moolenaar        c.downcase.match( rexp )
469c6249bb2SBram Moolenaar        $~ == nil
470c6249bb2SBram Moolenaar    end
471c6249bb2SBram Moolenaar  end
472c6249bb2SBram Moolenaar
473c6249bb2SBram Moolenaar  outp = ""
474fc1421ebSBram Moolenaar
475c6249bb2SBram Moolenaar  #    tags = VIM::evaluate("taglist('^%s$')" %
476fc1421ebSBram Moolenaar  valid = (candidates-Object.instance_methods)
477fc1421ebSBram Moolenaar
478fc1421ebSBram Moolenaar  rg = 0..valid.length
479fc1421ebSBram Moolenaar  rg.step(150) do |x|
480fc1421ebSBram Moolenaar    stpos = 0+x
481fc1421ebSBram Moolenaar    enpos = 150+x
482fc1421ebSBram Moolenaar    valid[stpos..enpos].each { |c| outp += "{'word':'%s','item':'%s'}," % [ c, c ] }
483c6249bb2SBram Moolenaar    outp.sub!(/,$/, '')
484fc1421ebSBram Moolenaar
485fc1421ebSBram Moolenaar    VIM::command("call extend(g:rubycomplete_completions, [%s])" % outp)
486fc1421ebSBram Moolenaar    outp = ""
487fc1421ebSBram Moolenaar  end
488c6249bb2SBram Moolenaarend
489c6249bb2SBram Moolenaar
490c6249bb2SBram Moolenaar
491c6249bb2SBram Moolenaardef select_message(receiver, message, candidates)
492fc1421ebSBram Moolenaar  #tags = VIM::evaluate("taglist('%s')" % receiver)
493fc1421ebSBram Moolenaar  #print tags
494c6249bb2SBram Moolenaar  candidates.grep(/^#{message}/).collect do |e|
495c6249bb2SBram Moolenaar    case e
496c6249bb2SBram Moolenaar      when /^[a-zA-Z_]/
497c6249bb2SBram Moolenaar        receiver + "." + e
498c6249bb2SBram Moolenaar      when /^[0-9]/
499c6249bb2SBram Moolenaar      when *Operators
500c6249bb2SBram Moolenaar        #receiver + " " + e
501c6249bb2SBram Moolenaar    end
502c6249bb2SBram Moolenaar  end
503c6249bb2SBram Moolenaar  candidates.delete_if { |x| x == nil }
504c6249bb2SBram Moolenaar  candidates.uniq!
505c6249bb2SBram Moolenaar  candidates.sort!
506c6249bb2SBram Moolenaarend
507*eb3593b3SBram Moolenaar
508*eb3593b3SBram Moolenaar# }}} ruby completion
509c6249bb2SBram MoolenaarRUBYEOF
510c6249bb2SBram Moolenaarendfunction
511c6249bb2SBram Moolenaar
512*eb3593b3SBram Moolenaarlet g:rubycomplete_rails_loaded = 0
513fc1421ebSBram Moolenaar
514c6249bb2SBram Moolenaarcall s:DefRuby()
515*eb3593b3SBram Moolenaar" vim:tw=78:sw=4:ts=8:ft=vim:norl:
516