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