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