comparison runtime/autoload/rubycomplete.vim @ 838:8e5830943bff v7.0e04

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