1" Vim completion script 2" Language: Ruby 3" Maintainer: Mark Guzman <[email protected]> 4" URL: https://github.com/vim-ruby/vim-ruby 5" Release Coordinator: Doug Kearns <[email protected]> 6" Maintainer Version: 0.8.1 7" ---------------------------------------------------------------------------- 8" 9" Ruby IRB/Complete author: Keiju ISHITSUKA([email protected]) 10" ---------------------------------------------------------------------------- 11 12" {{{ requirement checks 13 14function! s:ErrMsg(msg) 15 echohl ErrorMsg 16 echo a:msg 17 echohl None 18endfunction 19 20if !has('ruby') 21 call s:ErrMsg( "Error: Rubycomplete requires vim compiled with +ruby" ) 22 call s:ErrMsg( "Error: falling back to syntax completion" ) 23 " lets fall back to syntax completion 24 setlocal omnifunc=syntaxcomplete#Complete 25 finish 26endif 27 28if version < 700 29 call s:ErrMsg( "Error: Required vim >= 7.0" ) 30 finish 31endif 32" }}} requirement checks 33 34" {{{ configuration failsafe initialization 35if !exists("g:rubycomplete_rails") 36 let g:rubycomplete_rails = 0 37endif 38 39if !exists("g:rubycomplete_classes_in_global") 40 let g:rubycomplete_classes_in_global = 0 41endif 42 43if !exists("g:rubycomplete_buffer_loading") 44 let g:rubycomplete_buffer_loading = 0 45endif 46 47if !exists("g:rubycomplete_include_object") 48 let g:rubycomplete_include_object = 0 49endif 50 51if !exists("g:rubycomplete_include_objectspace") 52 let g:rubycomplete_include_objectspace = 0 53endif 54" }}} configuration failsafe initialization 55 56" {{{ vim-side support functions 57let s:rubycomplete_debug = 0 58 59function! s:dprint(msg) 60 if s:rubycomplete_debug == 1 61 echom a:msg 62 endif 63endfunction 64 65function! s:GetBufferRubyModule(name, ...) 66 if a:0 == 1 67 let [snum,enum] = s:GetBufferRubyEntity(a:name, "module", a:1) 68 else 69 let [snum,enum] = s:GetBufferRubyEntity(a:name, "module") 70 endif 71 return snum . '..' . enum 72endfunction 73 74function! s:GetBufferRubyClass(name, ...) 75 if a:0 >= 1 76 let [snum,enum] = s:GetBufferRubyEntity(a:name, "class", a:1) 77 else 78 let [snum,enum] = s:GetBufferRubyEntity(a:name, "class") 79 endif 80 return snum . '..' . enum 81endfunction 82 83function! s:GetBufferRubySingletonMethods(name) 84endfunction 85 86function! s:GetBufferRubyEntity( name, type, ... ) 87 let lastpos = getpos(".") 88 let lastline = lastpos 89 if (a:0 >= 1) 90 let lastline = [ 0, a:1, 0, 0 ] 91 call cursor( a:1, 0 ) 92 endif 93 94 let stopline = 1 95 96 let crex = '^\s*\<' . a:type . '\>\s*\<' . escape(a:name, '*') . '\>\s*\(<\s*.*\s*\)\?' 97 let [lnum,lcol] = searchpos( crex, 'w' ) 98 "let [lnum,lcol] = searchpairpos( crex . '\zs', '', '\(end\|}\)', 'w' ) 99 100 if lnum == 0 && lcol == 0 101 call cursor(lastpos[1], lastpos[2]) 102 return [0,0] 103 endif 104 105 let curpos = getpos(".") 106 let [enum,ecol] = searchpairpos( crex, '', '\(end\|}\)', 'wr' ) 107 call cursor(lastpos[1], lastpos[2]) 108 109 if lnum > enum 110 return [0,0] 111 endif 112 " we found a the class def 113 return [lnum,enum] 114endfunction 115 116function! s:IsInClassDef() 117 return s:IsPosInClassDef( line('.') ) 118endfunction 119 120function! s:IsPosInClassDef(pos) 121 let [snum,enum] = s:GetBufferRubyEntity( '.*', "class" ) 122 let ret = 'nil' 123 124 if snum < a:pos && a:pos < enum 125 let ret = snum . '..' . enum 126 endif 127 128 return ret 129endfunction 130 131function! s:GetRubyVarType(v) 132 let stopline = 1 133 let vtp = '' 134 let pos = getpos('.') 135 let sstr = '^\s*#\s*@var\s*'.escape(a:v, '*').'\>\s\+[^ \t]\+\s*$' 136 let [lnum,lcol] = searchpos(sstr,'nb',stopline) 137 if lnum != 0 && lcol != 0 138 call setpos('.',pos) 139 let str = getline(lnum) 140 let vtp = substitute(str,sstr,'\1','') 141 return vtp 142 endif 143 call setpos('.',pos) 144 let ctors = '\(now\|new\|open\|get_instance' 145 if exists('g:rubycomplete_rails') && g:rubycomplete_rails == 1 && s:rubycomplete_rails_loaded == 1 146 let ctors = ctors.'\|find\|create' 147 else 148 endif 149 let ctors = ctors.'\)' 150 151 let fstr = '=\s*\([^ \t]\+.' . ctors .'\>\|[\[{"''/]\|%[xwQqr][(\[{@]\|[A-Za-z0-9@:\-()\.]\+...\?\|lambda\|&\)' 152 let sstr = ''.escape(a:v, '*').'\>\s*[+\-*/]*'.fstr 153 let [lnum,lcol] = searchpos(sstr,'nb',stopline) 154 if lnum != 0 && lcol != 0 155 let str = matchstr(getline(lnum),fstr,lcol) 156 let str = substitute(str,'^=\s*','','') 157 158 call setpos('.',pos) 159 if str == '"' || str == '''' || stridx(tolower(str), '%q[') != -1 160 return 'String' 161 elseif str == '[' || stridx(str, '%w[') != -1 162 return 'Array' 163 elseif str == '{' 164 return 'Hash' 165 elseif str == '/' || str == '%r{' 166 return 'Regexp' 167 elseif strlen(str) >= 4 && stridx(str,'..') != -1 168 return 'Range' 169 elseif stridx(str, 'lambda') != -1 || str == '&' 170 return 'Proc' 171 elseif strlen(str) > 4 172 let l = stridx(str,'.') 173 return str[0:l-1] 174 end 175 return '' 176 endif 177 call setpos('.',pos) 178 return '' 179endfunction 180 181"}}} vim-side support functions 182 183"{{{ vim-side completion function 184function! rubycomplete#Init() 185 execute "ruby VimRubyCompletion.preload_rails" 186endfunction 187 188function! rubycomplete#Complete(findstart, base) 189 "findstart = 1 when we need to get the text length 190 if a:findstart 191 let line = getline('.') 192 let idx = col('.') 193 while idx > 0 194 let idx -= 1 195 let c = line[idx-1] 196 if c =~ '\w' 197 continue 198 elseif ! c =~ '\.' 199 let idx = -1 200 break 201 else 202 break 203 endif 204 endwhile 205 206 return idx 207 "findstart = 0 when we need to return the list of completions 208 else 209 let g:rubycomplete_completions = [] 210 execute "ruby VimRubyCompletion.get_completions('" . a:base . "')" 211 return g:rubycomplete_completions 212 endif 213endfunction 214"}}} vim-side completion function 215 216"{{{ ruby-side code 217function! s:DefRuby() 218ruby << RUBYEOF 219# {{{ ruby completion 220 221begin 222 require 'rubygems' # let's assume this is safe...? 223rescue Exception 224 #ignore? 225end 226class VimRubyCompletion 227# {{{ constants 228 @@debug = false 229 @@ReservedWords = [ 230 "BEGIN", "END", 231 "alias", "and", 232 "begin", "break", 233 "case", "class", 234 "def", "defined", "do", 235 "else", "elsif", "end", "ensure", 236 "false", "for", 237 "if", "in", 238 "module", 239 "next", "nil", "not", 240 "or", 241 "redo", "rescue", "retry", "return", 242 "self", "super", 243 "then", "true", 244 "undef", "unless", "until", 245 "when", "while", 246 "yield", 247 ] 248 249 @@Operators = [ "%", "&", "*", "**", "+", "-", "/", 250 "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>", 251 "[]", "[]=", "^", ] 252# }}} constants 253 254# {{{ buffer analysis magic 255 def load_requires 256 buf = VIM::Buffer.current 257 enum = buf.line_number 258 nums = Range.new( 1, enum ) 259 nums.each do |x| 260 ln = buf[x] 261 begin 262 eval( "require %s" % $1 ) if /.*require\s*(.*)$/.match( ln ) 263 rescue Exception 264 #ignore? 265 end 266 end 267 end 268 269 def load_gems 270 fpath = VIM::evaluate("get(g:, 'rubycomplete_gemfile_path', 'Gemfile')") 271 return unless File.file?(fpath) && File.readable?(fpath) 272 want_bundler = VIM::evaluate("get(g:, 'rubycomplete_use_bundler')") 273 parse_file = !want_bundler 274 begin 275 require 'bundler' 276 Bundler.setup 277 Bundler.require 278 rescue Exception 279 parse_file = true 280 end 281 if parse_file 282 File.new(fpath).each_line do |line| 283 begin 284 require $1 if /\s*gem\s*['"]([^'"]+)/.match(line) 285 rescue Exception 286 end 287 end 288 end 289 end 290 291 def load_buffer_class(name) 292 dprint "load_buffer_class(%s) START" % name 293 classdef = get_buffer_entity(name, 's:GetBufferRubyClass("%s")') 294 return if classdef == nil 295 296 pare = /^\s*class\s*(.*)\s*<\s*(.*)\s*\n/.match( classdef ) 297 load_buffer_class( $2 ) if pare != nil && $2 != name # load parent class if needed 298 299 mixre = /.*\n\s*(include|prepend)\s*(.*)\s*\n/.match( classdef ) 300 load_buffer_module( $2 ) if mixre != nil && $2 != name # load mixins if needed 301 302 begin 303 eval classdef 304 rescue Exception 305 VIM::evaluate( "s:ErrMsg( 'Problem loading class \"%s\", was it already completed?' )" % name ) 306 end 307 dprint "load_buffer_class(%s) END" % name 308 end 309 310 def load_buffer_module(name) 311 dprint "load_buffer_module(%s) START" % name 312 classdef = get_buffer_entity(name, 's:GetBufferRubyModule("%s")') 313 return if classdef == nil 314 315 begin 316 eval classdef 317 rescue Exception 318 VIM::evaluate( "s:ErrMsg( 'Problem loading module \"%s\", was it already completed?' )" % name ) 319 end 320 dprint "load_buffer_module(%s) END" % name 321 end 322 323 def get_buffer_entity(name, vimfun) 324 loading_allowed = VIM::evaluate("exists('g:rubycomplete_buffer_loading') && g:rubycomplete_buffer_loading") 325 return nil if loading_allowed.to_i.zero? 326 return nil if /(\"|\')+/.match( name ) 327 buf = VIM::Buffer.current 328 nums = eval( VIM::evaluate( vimfun % name ) ) 329 return nil if nums == nil 330 return nil if nums.min == nums.max && nums.min == 0 331 332 dprint "get_buffer_entity START" 333 visited = [] 334 clscnt = 0 335 bufname = VIM::Buffer.current.name 336 classdef = "" 337 cur_line = VIM::Buffer.current.line_number 338 while (nums != nil && !(nums.min == 0 && nums.max == 0) ) 339 dprint "visited: %s" % visited.to_s 340 break if visited.index( nums ) 341 visited << nums 342 343 nums.each do |x| 344 if x != cur_line 345 next if x == 0 346 ln = buf[x] 347 if /^\s*(module|class|def|include)\s+/.match(ln) 348 clscnt += 1 if $1 == "class" 349 #dprint "\$1$1 350 classdef += "%s\n" % ln 351 classdef += "end\n" if /def\s+/.match(ln) 352 dprint ln 353 end 354 end 355 end 356 357 nm = "%s(::.*)*\", %s, \"" % [ name, nums.last ] 358 nums = eval( VIM::evaluate( vimfun % nm ) ) 359 dprint "nm: \"%s\"" % nm 360 dprint "vimfun: %s" % (vimfun % nm) 361 dprint "got nums: %s" % nums.to_s 362 end 363 if classdef.length > 1 364 classdef += "end\n"*clscnt 365 # classdef = "class %s\n%s\nend\n" % [ bufname.gsub( /\/|\\/, "_" ), classdef ] 366 end 367 368 dprint "get_buffer_entity END" 369 dprint "classdef====start" 370 lns = classdef.split( "\n" ) 371 lns.each { |x| dprint x } 372 dprint "classdef====end" 373 return classdef 374 end 375 376 def get_var_type( receiver ) 377 if /(\"|\')+/.match( receiver ) 378 "String" 379 else 380 VIM::evaluate("s:GetRubyVarType('%s')" % receiver) 381 end 382 end 383 384 def dprint( txt ) 385 print txt if @@debug 386 end 387 388 def escape_vim_singlequote_string(str) 389 str.to_s.gsub(/'/,"\\'") 390 end 391 392 def get_buffer_entity_list( type ) 393 # this will be a little expensive. 394 loading_allowed = VIM::evaluate("exists('g:rubycomplete_buffer_loading') && g:rubycomplete_buffer_loading") 395 allow_aggressive_load = VIM::evaluate("exists('g:rubycomplete_classes_in_global') && g:rubycomplete_classes_in_global") 396 return [] if allow_aggressive_load.to_i.zero? || loading_allowed.to_i.zero? 397 398 buf = VIM::Buffer.current 399 eob = buf.length 400 ret = [] 401 rg = 1..eob 402 re = eval( "/^\s*%s\s*([A-Za-z0-9_:-]*)(\s*<\s*([A-Za-z0-9_:-]*))?\s*/" % type ) 403 404 rg.each do |x| 405 if re.match( buf[x] ) 406 next if type == "def" && eval( VIM::evaluate("s:IsPosInClassDef(%s)" % x) ) != nil 407 ret.push $1 408 end 409 end 410 411 return ret 412 end 413 414 def get_buffer_modules 415 return get_buffer_entity_list( "modules" ) 416 end 417 418 def get_buffer_methods 419 return get_buffer_entity_list( "def" ) 420 end 421 422 def get_buffer_classes 423 return get_buffer_entity_list( "class" ) 424 end 425 426 427 def load_rails 428 allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails") 429 return if allow_rails.to_i.zero? 430 431 buf_path = VIM::evaluate('expand("%:p")') 432 file_name = VIM::evaluate('expand("%:t")') 433 vim_dir = VIM::evaluate('getcwd()') 434 file_dir = buf_path.gsub( file_name, '' ) 435 file_dir.gsub!( /\\/, "/" ) 436 vim_dir.gsub!( /\\/, "/" ) 437 vim_dir << "/" 438 dirs = [ vim_dir, file_dir ] 439 sdirs = [ "", "./", "../", "../../", "../../../", "../../../../" ] 440 rails_base = nil 441 442 dirs.each do |dir| 443 sdirs.each do |sub| 444 trail = "%s%s" % [ dir, sub ] 445 tcfg = "%sconfig" % trail 446 447 if File.exists?( tcfg ) 448 rails_base = trail 449 break 450 end 451 end 452 break if rails_base 453 end 454 455 return if rails_base == nil 456 $:.push rails_base unless $:.index( rails_base ) 457 458 rails_config = rails_base + "config/" 459 rails_lib = rails_base + "lib/" 460 $:.push rails_config unless $:.index( rails_config ) 461 $:.push rails_lib unless $:.index( rails_lib ) 462 463 bootfile = rails_config + "boot.rb" 464 envfile = rails_config + "environment.rb" 465 if File.exists?( bootfile ) && File.exists?( envfile ) 466 begin 467 require bootfile 468 require envfile 469 begin 470 require 'console_app' 471 require 'console_with_helpers' 472 rescue Exception 473 dprint "Rails 1.1+ Error %s" % $! 474 # assume 1.0 475 end 476 #eval( "Rails::Initializer.run" ) #not necessary? 477 VIM::command('let s:rubycomplete_rails_loaded = 1') 478 dprint "rails loaded" 479 rescue Exception 480 dprint "Rails Error %s" % $! 481 VIM::evaluate( "s:ErrMsg('Error loading rails environment')" ) 482 end 483 end 484 end 485 486 def get_rails_helpers 487 allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails") 488 rails_loaded = VIM::evaluate('s:rubycomplete_rails_loaded') 489 return [] if allow_rails.to_i.zero? || rails_loaded.to_i.zero? 490 491 buf_path = VIM::evaluate('expand("%:p")') 492 buf_path.gsub!( /\\/, "/" ) 493 path_elm = buf_path.split( "/" ) 494 dprint "buf_path: %s" % buf_path 495 types = [ "app", "db", "lib", "test", "components", "script" ] 496 497 i = nil 498 ret = [] 499 type = nil 500 types.each do |t| 501 i = path_elm.index( t ) 502 break if i 503 end 504 type = path_elm[i] 505 type.downcase! 506 507 dprint "type: %s" % type 508 case type 509 when "app" 510 i += 1 511 subtype = path_elm[i] 512 subtype.downcase! 513 514 dprint "subtype: %s" % subtype 515 case subtype 516 when "views" 517 ret += ActionView::Base.instance_methods 518 ret += ActionView::Base.methods 519 when "controllers" 520 ret += ActionController::Base.instance_methods 521 ret += ActionController::Base.methods 522 when "models" 523 ret += ActiveRecord::Base.instance_methods 524 ret += ActiveRecord::Base.methods 525 end 526 527 when "db" 528 ret += ActiveRecord::ConnectionAdapters::SchemaStatements.instance_methods 529 ret += ActiveRecord::ConnectionAdapters::SchemaStatements.methods 530 end 531 532 533 return ret 534 end 535 536 def add_rails_columns( cls ) 537 allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails") 538 rails_loaded = VIM::evaluate('s:rubycomplete_rails_loaded') 539 return [] if allow_rails.to_i.zero? || rails_loaded.to_i.zero? 540 541 begin 542 eval( "#{cls}.establish_connection" ) 543 return [] unless eval( "#{cls}.ancestors.include?(ActiveRecord::Base).to_s" ) 544 col = eval( "#{cls}.column_names" ) 545 return col if col 546 rescue 547 dprint "add_rails_columns err: (cls: %s) %s" % [ cls, $! ] 548 return [] 549 end 550 return [] 551 end 552 553 def clean_sel(sel, msg) 554 ret = sel.reject{|x|x.nil?}.uniq 555 ret = ret.grep(/^#{Regexp.quote(msg)}/) if msg != nil 556 ret 557 end 558 559 def get_rails_view_methods 560 allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails") 561 rails_loaded = VIM::evaluate('s:rubycomplete_rails_loaded') 562 return [] if allow_rails.to_i.zero? || rails_loaded.to_i.zero? 563 564 buf_path = VIM::evaluate('expand("%:p")') 565 buf_path.gsub!( /\\/, "/" ) 566 pelm = buf_path.split( "/" ) 567 idx = pelm.index( "views" ) 568 569 return [] unless idx 570 idx += 1 571 572 clspl = pelm[idx].camelize.pluralize 573 cls = clspl.singularize 574 575 ret = [] 576 begin 577 ret += eval( "#{cls}.instance_methods" ) 578 ret += eval( "#{clspl}Helper.instance_methods" ) 579 rescue Exception 580 dprint "Error: Unable to load rails view helpers for %s: %s" % [ cls, $! ] 581 end 582 583 return ret 584 end 585# }}} buffer analysis magic 586 587# {{{ main completion code 588 def self.preload_rails 589 a = VimRubyCompletion.new 590 require 'Thread' 591 Thread.new(a) do |b| 592 begin 593 b.load_rails 594 rescue 595 end 596 end 597 a.load_rails 598 rescue 599 end 600 601 def self.get_completions(base) 602 b = VimRubyCompletion.new 603 b.get_completions base 604 end 605 606 def get_completions(base) 607 loading_allowed = VIM::evaluate("exists('g:rubycomplete_buffer_loading') && g:rubycomplete_buffer_loading") 608 if loading_allowed.to_i == 1 609 load_requires 610 load_rails 611 end 612 613 want_gems = VIM::evaluate("get(g:, 'rubycomplete_load_gemfile')") 614 load_gems unless want_gems.to_i.zero? 615 616 617 input = VIM::Buffer.current.line 618 cpos = VIM::Window.current.cursor[1] - 1 619 input = input[0..cpos] 620 input += base 621 input.sub!(/.*[ \t\n\"\\'`><=;|&{(]/, '') # Readline.basic_word_break_characters 622 input.sub!(/self\./, '') 623 input.sub!(/.*((\.\.[\[(]?)|([\[(]))/, '') 624 625 dprint 'input %s' % input 626 message = nil 627 receiver = nil 628 methods = [] 629 variables = [] 630 classes = [] 631 constants = [] 632 633 case input 634 when /^(\/[^\/]*\/)\.([^.]*)$/ # Regexp 635 receiver = $1 636 message = Regexp.quote($2) 637 methods = Regexp.instance_methods(true) 638 639 when /^([^\]]*\])\.([^.]*)$/ # Array 640 receiver = $1 641 message = Regexp.quote($2) 642 methods = Array.instance_methods(true) 643 644 when /^([^\}]*\})\.([^.]*)$/ # Proc or Hash 645 receiver = $1 646 message = Regexp.quote($2) 647 methods = Proc.instance_methods(true) | Hash.instance_methods(true) 648 649 when /^(:[^:.]*)$/ # Symbol 650 dprint "symbol" 651 if Symbol.respond_to?(:all_symbols) 652 receiver = $1 653 message = $1.sub( /:/, '' ) 654 methods = Symbol.all_symbols.collect{|s| s.id2name} 655 methods.delete_if { |c| c.match( /'/ ) } 656 end 657 658 when /^::([A-Z][^:\.\(]*)$/ # Absolute Constant or class methods 659 dprint "const or cls" 660 receiver = $1 661 methods = Object.constants 662 methods.grep(/^#{receiver}/).collect{|e| "::" + e} 663 664 when /^(((::)?[A-Z][^:.\(]*)+?)::?([^:.]*)$/ # Constant or class methods 665 receiver = $1 666 message = Regexp.quote($4) 667 dprint "const or cls 2 [recv: \'%s\', msg: \'%s\']" % [ receiver, message ] 668 load_buffer_class( receiver ) 669 begin 670 classes = eval("#{receiver}.constants") 671 #methods = eval("#{receiver}.methods") 672 rescue Exception 673 dprint "exception: %s" % $! 674 methods = [] 675 end 676 methods.grep(/^#{message}/).collect{|e| receiver + "::" + e} 677 678 when /^(:[^:.]+)\.([^.]*)$/ # Symbol 679 dprint "symbol" 680 receiver = $1 681 message = Regexp.quote($2) 682 methods = Symbol.instance_methods(true) 683 684 when /^([0-9_]+(\.[0-9_]+)?(e[0-9]+)?)\.([^.]*)$/ # Numeric 685 dprint "numeric" 686 receiver = $1 687 message = Regexp.quote($4) 688 begin 689 methods = eval(receiver).methods 690 rescue Exception 691 methods = [] 692 end 693 694 when /^(\$[^.]*)$/ #global 695 dprint "global" 696 methods = global_variables.grep(Regexp.new(Regexp.quote($1))) 697 698 when /^((\.?[^.]+)+?)\.([^.]*)$/ # variable 699 dprint "variable" 700 receiver = $1 701 message = Regexp.quote($3) 702 load_buffer_class( receiver ) 703 704 cv = eval("self.class.constants") 705 vartype = get_var_type( receiver ) 706 dprint "vartype: %s" % vartype 707 708 invalid_vartype = ['', "gets"] 709 if !invalid_vartype.include?(vartype) 710 load_buffer_class( vartype ) 711 712 begin 713 methods = eval("#{vartype}.instance_methods") 714 variables = eval("#{vartype}.instance_variables") 715 rescue Exception 716 dprint "load_buffer_class err: %s" % $! 717 end 718 elsif (cv).include?(receiver) 719 # foo.func and foo is local var. 720 methods = eval("#{receiver}.methods") 721 vartype = receiver 722 elsif /^[A-Z]/ =~ receiver and /\./ !~ receiver 723 vartype = receiver 724 # Foo::Bar.func 725 begin 726 methods = eval("#{receiver}.methods") 727 rescue Exception 728 end 729 else 730 # func1.func2 731 ObjectSpace.each_object(Module){|m| 732 next if m.name != "IRB::Context" and 733 /^(IRB|SLex|RubyLex|RubyToken)/ =~ m.name 734 methods.concat m.instance_methods(false) 735 } 736 end 737 variables += add_rails_columns( "#{vartype}" ) if vartype && !invalid_vartype.include?(vartype) 738 739 when /^\(?\s*[A-Za-z0-9:^@.%\/+*\(\)]+\.\.\.?[A-Za-z0-9:^@.%\/+*\(\)]+\s*\)?\.([^.]*)/ 740 message = $1 741 methods = Range.instance_methods(true) 742 743 when /^\.([^.]*)$/ # unknown(maybe String) 744 message = Regexp.quote($1) 745 methods = String.instance_methods(true) 746 747 else 748 dprint "default/other" 749 inclass = eval( VIM::evaluate("s:IsInClassDef()") ) 750 751 if inclass != nil 752 dprint "inclass" 753 classdef = "%s\n" % VIM::Buffer.current[ inclass.min ] 754 found = /^\s*class\s*([A-Za-z0-9_-]*)(\s*<\s*([A-Za-z0-9_:-]*))?\s*\n$/.match( classdef ) 755 756 if found != nil 757 receiver = $1 758 message = input 759 load_buffer_class( receiver ) 760 begin 761 methods = eval( "#{receiver}.instance_methods" ) 762 variables += add_rails_columns( "#{receiver}" ) 763 rescue Exception 764 found = nil 765 end 766 end 767 end 768 769 if inclass == nil || found == nil 770 dprint "inclass == nil" 771 methods = get_buffer_methods 772 methods += get_rails_view_methods 773 774 cls_const = Class.constants 775 constants = cls_const.select { |c| /^[A-Z_-]+$/.match( c ) } 776 classes = eval("self.class.constants") - constants 777 classes += get_buffer_classes 778 classes += get_buffer_modules 779 780 include_objectspace = VIM::evaluate("exists('g:rubycomplete_include_objectspace') && g:rubycomplete_include_objectspace") 781 ObjectSpace.each_object(Class) { |cls| classes << cls.to_s } if include_objectspace == "1" 782 message = receiver = input 783 end 784 785 methods += get_rails_helpers 786 methods += Kernel.public_methods 787 end 788 789 790 include_object = VIM::evaluate("exists('g:rubycomplete_include_object') && g:rubycomplete_include_object") 791 methods = clean_sel( methods, message ) 792 methods = (methods-Object.instance_methods) if include_object == "0" 793 rbcmeth = (VimRubyCompletion.instance_methods-Object.instance_methods) # lets remove those rubycomplete methods 794 methods = (methods-rbcmeth) 795 796 variables = clean_sel( variables, message ) 797 classes = clean_sel( classes, message ) - ["VimRubyCompletion"] 798 constants = clean_sel( constants, message ) 799 800 valid = [] 801 valid += methods.collect { |m| { :name => m.to_s, :type => 'm' } } 802 valid += variables.collect { |v| { :name => v.to_s, :type => 'v' } } 803 valid += classes.collect { |c| { :name => c.to_s, :type => 't' } } 804 valid += constants.collect { |d| { :name => d.to_s, :type => 'd' } } 805 valid.sort! { |x,y| x[:name] <=> y[:name] } 806 807 outp = "" 808 809 rg = 0..valid.length 810 rg.step(150) do |x| 811 stpos = 0+x 812 enpos = 150+x 813 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)} } 814 outp.sub!(/,$/, '') 815 816 VIM::command("call extend(g:rubycomplete_completions, [%s])" % outp) 817 outp = "" 818 end 819 end 820# }}} main completion code 821 822end # VimRubyCompletion 823# }}} ruby completion 824RUBYEOF 825endfunction 826 827let s:rubycomplete_rails_loaded = 0 828 829call s:DefRuby() 830"}}} ruby-side code 831 832 833" vim:tw=78:sw=4:ts=8:et:fdm=marker:ft=vim:norl: 834