1*c6249bb2SBram Moolenaar" Vim completion script 2*c6249bb2SBram Moolenaar" Language: Ruby 3*c6249bb2SBram Moolenaar" Maintainer: Mark Guzman ( segfault AT hasno DOT info ) 4*c6249bb2SBram Moolenaar" Info: $Id$ 5*c6249bb2SBram Moolenaar" URL: http://vim-ruby.rubyforge.org 6*c6249bb2SBram Moolenaar" Anon CVS: See above site 7*c6249bb2SBram Moolenaar" Release Coordinator: Doug Kearns <[email protected]> 8*c6249bb2SBram Moolenaar" ---------------------------------------------------------------------------- 9*c6249bb2SBram Moolenaar" 10*c6249bb2SBram Moolenaar" Ruby IRB/Complete author: Keiju ISHITSUKA([email protected]) 11*c6249bb2SBram Moolenaar" ---------------------------------------------------------------------------- 12*c6249bb2SBram Moolenaar 13*c6249bb2SBram Moolenaarif !has('ruby') 14*c6249bb2SBram Moolenaar echo "Error: Required vim compiled with +ruby" 15*c6249bb2SBram Moolenaar finish 16*c6249bb2SBram Moolenaarendif 17*c6249bb2SBram Moolenaar 18*c6249bb2SBram Moolenaarif version < 700 19*c6249bb2SBram Moolenaar echo "Error: Required vim >= 7.0" 20*c6249bb2SBram Moolenaar finish 21*c6249bb2SBram Moolenaarendif 22*c6249bb2SBram Moolenaar 23*c6249bb2SBram Moolenaarfunc! GetRubyVarType(v) 24*c6249bb2SBram Moolenaar let stopline = 1 25*c6249bb2SBram Moolenaar let vtp = '' 26*c6249bb2SBram Moolenaar let pos = getpos('.') 27*c6249bb2SBram Moolenaar let [lnum,lcol] = searchpos('^\s*#\s*@var\s*'.a:v.'\>\s\+[^ \t]\+\s*$','nb',stopline) 28*c6249bb2SBram Moolenaar if lnum != 0 && lcol != 0 29*c6249bb2SBram Moolenaar call setpos('.',pos) 30*c6249bb2SBram Moolenaar let str = getline(lnum) 31*c6249bb2SBram Moolenaar let vtp = substitute(str,'^\s*#\s*@var\s*'.a:v.'\>\s\+\([^ \t]\+\)\s*$','\1','') 32*c6249bb2SBram Moolenaar return vtp 33*c6249bb2SBram Moolenaar endif 34*c6249bb2SBram Moolenaar call setpos('.',pos) 35*c6249bb2SBram Moolenaar let [lnum,lcol] = searchpos(''.a:v.'\>\s*[+\-*/]*=\s*\([^ \t]\+.\(now\|new\|open\|get_instance\)\>\|[\[{"'']\)','nb',stopline) 36*c6249bb2SBram Moolenaar if lnum != 0 && lcol != 0 37*c6249bb2SBram Moolenaar let str = matchstr(getline(lnum),'=\s*\([^ \t]\+.\(now\|new\|open\|get_instance\)\>\|[\[{"'']\)',lcol) 38*c6249bb2SBram Moolenaar let str = substitute(str,'^=\s*','','') 39*c6249bb2SBram Moolenaar call setpos('.',pos) 40*c6249bb2SBram Moolenaar if str == '"' || str == '''' 41*c6249bb2SBram Moolenaar return 'String' 42*c6249bb2SBram Moolenaar elseif str == '[' 43*c6249bb2SBram Moolenaar return 'Array' 44*c6249bb2SBram Moolenaar elseif str == '{' 45*c6249bb2SBram Moolenaar return 'Hash' 46*c6249bb2SBram Moolenaar elseif strlen(str) > 4 47*c6249bb2SBram Moolenaar let l = stridx(str,'.') 48*c6249bb2SBram Moolenaar return str[0:l-1] 49*c6249bb2SBram Moolenaar end 50*c6249bb2SBram Moolenaar return '' 51*c6249bb2SBram Moolenaar endif 52*c6249bb2SBram Moolenaar call setpos('.',pos) 53*c6249bb2SBram Moolenaar return '' 54*c6249bb2SBram Moolenaarendf 55*c6249bb2SBram Moolenaar 56*c6249bb2SBram Moolenaarfunction! rubycomplete#Complete(findstart, base) 57*c6249bb2SBram Moolenaar "findstart = 1 when we need to get the text length 58*c6249bb2SBram Moolenaar if a:findstart 59*c6249bb2SBram Moolenaar let line = getline('.') 60*c6249bb2SBram Moolenaar let idx = col('.') 61*c6249bb2SBram Moolenaar while idx > 0 62*c6249bb2SBram Moolenaar let idx -= 1 63*c6249bb2SBram Moolenaar let c = line[idx-1] 64*c6249bb2SBram Moolenaar if c =~ '\w' 65*c6249bb2SBram Moolenaar continue 66*c6249bb2SBram Moolenaar elseif ! c =~ '\.' 67*c6249bb2SBram Moolenaar idx = -1 68*c6249bb2SBram Moolenaar break 69*c6249bb2SBram Moolenaar else 70*c6249bb2SBram Moolenaar break 71*c6249bb2SBram Moolenaar endif 72*c6249bb2SBram Moolenaar endwhile 73*c6249bb2SBram Moolenaar 74*c6249bb2SBram Moolenaar return idx 75*c6249bb2SBram Moolenaar "findstart = 0 when we need to return the list of completions 76*c6249bb2SBram Moolenaar else 77*c6249bb2SBram Moolenaar execute "ruby get_completions('" . a:base . "')" 78*c6249bb2SBram Moolenaar return g:rbcomplete_completions 79*c6249bb2SBram Moolenaar endif 80*c6249bb2SBram Moolenaarendfunction 81*c6249bb2SBram Moolenaar 82*c6249bb2SBram Moolenaar 83*c6249bb2SBram Moolenaarfunction! s:DefRuby() 84*c6249bb2SBram Moolenaarruby << RUBYEOF 85*c6249bb2SBram MoolenaarReservedWords = [ 86*c6249bb2SBram Moolenaar "BEGIN", "END", 87*c6249bb2SBram Moolenaar "alias", "and", 88*c6249bb2SBram Moolenaar "begin", "break", 89*c6249bb2SBram Moolenaar "case", "class", 90*c6249bb2SBram Moolenaar "def", "defined", "do", 91*c6249bb2SBram Moolenaar "else", "elsif", "end", "ensure", 92*c6249bb2SBram Moolenaar "false", "for", 93*c6249bb2SBram Moolenaar "if", "in", 94*c6249bb2SBram Moolenaar "module", 95*c6249bb2SBram Moolenaar "next", "nil", "not", 96*c6249bb2SBram Moolenaar "or", 97*c6249bb2SBram Moolenaar "redo", "rescue", "retry", "return", 98*c6249bb2SBram Moolenaar "self", "super", 99*c6249bb2SBram Moolenaar "then", "true", 100*c6249bb2SBram Moolenaar "undef", "unless", "until", 101*c6249bb2SBram Moolenaar "when", "while", 102*c6249bb2SBram Moolenaar "yield", 103*c6249bb2SBram Moolenaar ] 104*c6249bb2SBram Moolenaar 105*c6249bb2SBram MoolenaarOperators = [ "%", "&", "*", "**", "+", "-", "/", 106*c6249bb2SBram Moolenaar "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>", 107*c6249bb2SBram Moolenaar "[]", "[]=", "^", ] 108*c6249bb2SBram Moolenaar 109*c6249bb2SBram Moolenaardef identify_type(var) 110*c6249bb2SBram Moolenaar @buf = VIM::Buffer.current 111*c6249bb2SBram Moolenaar enum = @buf.line_number 112*c6249bb2SBram Moolenaar snum = (enum-10).abs 113*c6249bb2SBram Moolenaar nums = Range.new( snum, enum ) 114*c6249bb2SBram Moolenaar regxs = '/.*(%s)\s*=(.*)/' % var 115*c6249bb2SBram Moolenaar regx = Regexp.new( regxs ) 116*c6249bb2SBram Moolenaar nums.each do |x| 117*c6249bb2SBram Moolenaar ln = @buf[x] 118*c6249bb2SBram Moolenaar #print $~ if regx.match( ln ) 119*c6249bb2SBram Moolenaar end 120*c6249bb2SBram Moolenaarend 121*c6249bb2SBram Moolenaar 122*c6249bb2SBram Moolenaardef load_requires 123*c6249bb2SBram Moolenaar @buf = VIM::Buffer.current 124*c6249bb2SBram Moolenaar enum = @buf.line_number 125*c6249bb2SBram Moolenaar nums = Range.new( 1, enum ) 126*c6249bb2SBram Moolenaar nums.each do |x| 127*c6249bb2SBram Moolenaar ln = @buf[x] 128*c6249bb2SBram Moolenaar begin 129*c6249bb2SBram Moolenaar eval( "require %s" % $1 ) if /.*require\s*(.*)$/.match( ln ) 130*c6249bb2SBram Moolenaar rescue Exception 131*c6249bb2SBram Moolenaar #ignore? 132*c6249bb2SBram Moolenaar end 133*c6249bb2SBram Moolenaar end 134*c6249bb2SBram Moolenaarend 135*c6249bb2SBram Moolenaar 136*c6249bb2SBram Moolenaardef get_completions(base) 137*c6249bb2SBram Moolenaar load_requires 138*c6249bb2SBram Moolenaar input = VIM::evaluate('expand("<cWORD>")') 139*c6249bb2SBram Moolenaar input += base 140*c6249bb2SBram Moolenaar message = nil 141*c6249bb2SBram Moolenaar 142*c6249bb2SBram Moolenaar 143*c6249bb2SBram Moolenaar case input 144*c6249bb2SBram Moolenaar when /^(\/[^\/]*\/)\.([^.]*)$/ 145*c6249bb2SBram Moolenaar # Regexp 146*c6249bb2SBram Moolenaar receiver = $1 147*c6249bb2SBram Moolenaar message = Regexp.quote($2) 148*c6249bb2SBram Moolenaar 149*c6249bb2SBram Moolenaar candidates = Regexp.instance_methods(true) 150*c6249bb2SBram Moolenaar select_message(receiver, message, candidates) 151*c6249bb2SBram Moolenaar 152*c6249bb2SBram Moolenaar when /^([^\]]*\])\.([^.]*)$/ 153*c6249bb2SBram Moolenaar # Array 154*c6249bb2SBram Moolenaar receiver = $1 155*c6249bb2SBram Moolenaar message = Regexp.quote($2) 156*c6249bb2SBram Moolenaar 157*c6249bb2SBram Moolenaar candidates = Array.instance_methods(true) 158*c6249bb2SBram Moolenaar select_message(receiver, message, candidates) 159*c6249bb2SBram Moolenaar 160*c6249bb2SBram Moolenaar when /^([^\}]*\})\.([^.]*)$/ 161*c6249bb2SBram Moolenaar # Proc or Hash 162*c6249bb2SBram Moolenaar receiver = $1 163*c6249bb2SBram Moolenaar message = Regexp.quote($2) 164*c6249bb2SBram Moolenaar 165*c6249bb2SBram Moolenaar candidates = Proc.instance_methods(true) | Hash.instance_methods(true) 166*c6249bb2SBram Moolenaar select_message(receiver, message, candidates) 167*c6249bb2SBram Moolenaar 168*c6249bb2SBram Moolenaar when /^(:[^:.]*)$/ 169*c6249bb2SBram Moolenaar # Symbol 170*c6249bb2SBram Moolenaar if Symbol.respond_to?(:all_symbols) 171*c6249bb2SBram Moolenaar sym = $1 172*c6249bb2SBram Moolenaar candidates = Symbol.all_symbols.collect{|s| ":" + s.id2name} 173*c6249bb2SBram Moolenaar candidates.grep(/^#{sym}/) 174*c6249bb2SBram Moolenaar else 175*c6249bb2SBram Moolenaar [] 176*c6249bb2SBram Moolenaar end 177*c6249bb2SBram Moolenaar 178*c6249bb2SBram Moolenaar when /^::([A-Z][^:\.\(]*)$/ 179*c6249bb2SBram Moolenaar # Absolute Constant or class methods 180*c6249bb2SBram Moolenaar receiver = $1 181*c6249bb2SBram Moolenaar candidates = Object.constants 182*c6249bb2SBram Moolenaar candidates.grep(/^#{receiver}/).collect{|e| "::" + e} 183*c6249bb2SBram Moolenaar 184*c6249bb2SBram Moolenaar when /^(((::)?[A-Z][^:.\(]*)+)::?([^:.]*)$/ 185*c6249bb2SBram Moolenaar # Constant or class methods 186*c6249bb2SBram Moolenaar receiver = $1 187*c6249bb2SBram Moolenaar message = Regexp.quote($4) 188*c6249bb2SBram Moolenaar begin 189*c6249bb2SBram Moolenaar candidates = eval("#{receiver}.constants | #{receiver}.methods") 190*c6249bb2SBram Moolenaar rescue Exception 191*c6249bb2SBram Moolenaar candidates = [] 192*c6249bb2SBram Moolenaar end 193*c6249bb2SBram Moolenaar candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e} 194*c6249bb2SBram Moolenaar 195*c6249bb2SBram Moolenaar when /^(:[^:.]+)\.([^.]*)$/ 196*c6249bb2SBram Moolenaar # Symbol 197*c6249bb2SBram Moolenaar receiver = $1 198*c6249bb2SBram Moolenaar message = Regexp.quote($2) 199*c6249bb2SBram Moolenaar 200*c6249bb2SBram Moolenaar candidates = Symbol.instance_methods(true) 201*c6249bb2SBram Moolenaar select_message(receiver, message, candidates) 202*c6249bb2SBram Moolenaar 203*c6249bb2SBram Moolenaar when /^([0-9_]+(\.[0-9_]+)?(e[0-9]+)?)\.([^.]*)$/ 204*c6249bb2SBram Moolenaar # Numeric 205*c6249bb2SBram Moolenaar receiver = $1 206*c6249bb2SBram Moolenaar message = Regexp.quote($4) 207*c6249bb2SBram Moolenaar 208*c6249bb2SBram Moolenaar begin 209*c6249bb2SBram Moolenaar candidates = eval(receiver).methods 210*c6249bb2SBram Moolenaar rescue Exception 211*c6249bb2SBram Moolenaar candidates 212*c6249bb2SBram Moolenaar end 213*c6249bb2SBram Moolenaar select_message(receiver, message, candidates) 214*c6249bb2SBram Moolenaar 215*c6249bb2SBram Moolenaar when /^(\$[^.]*)$/ 216*c6249bb2SBram Moolenaar candidates = global_variables.grep(Regexp.new(Regexp.quote($1))) 217*c6249bb2SBram Moolenaar 218*c6249bb2SBram Moolenaar# when /^(\$?(\.?[^.]+)+)\.([^.]*)$/ 219*c6249bb2SBram Moolenaar when /^((\.?[^.]+)+)\.([^.]*)$/ 220*c6249bb2SBram Moolenaar # variable 221*c6249bb2SBram Moolenaar receiver = $1 222*c6249bb2SBram Moolenaar message = Regexp.quote($3) 223*c6249bb2SBram Moolenaar 224*c6249bb2SBram Moolenaar cv = eval("self.class.constants") 225*c6249bb2SBram Moolenaar 226*c6249bb2SBram Moolenaar vartype = VIM::evaluate("GetRubyVarType('%s')" % receiver) 227*c6249bb2SBram Moolenaar if vartype != '' 228*c6249bb2SBram Moolenaar candidates = eval("#{vartype}.instance_methods") 229*c6249bb2SBram Moolenaar elsif (cv).include?(receiver) 230*c6249bb2SBram Moolenaar # foo.func and foo is local var. 231*c6249bb2SBram Moolenaar candidates = eval("#{receiver}.methods") 232*c6249bb2SBram Moolenaar elsif /^[A-Z]/ =~ receiver and /\./ !~ receiver 233*c6249bb2SBram Moolenaar # Foo::Bar.func 234*c6249bb2SBram Moolenaar begin 235*c6249bb2SBram Moolenaar candidates = eval("#{receiver}.methods") 236*c6249bb2SBram Moolenaar rescue Exception 237*c6249bb2SBram Moolenaar candidates = [] 238*c6249bb2SBram Moolenaar end 239*c6249bb2SBram Moolenaar else 240*c6249bb2SBram Moolenaar # func1.func2 241*c6249bb2SBram Moolenaar candidates = [] 242*c6249bb2SBram Moolenaar ObjectSpace.each_object(Module){|m| 243*c6249bb2SBram Moolenaar next if m.name != "IRB::Context" and 244*c6249bb2SBram Moolenaar /^(IRB|SLex|RubyLex|RubyToken)/ =~ m.name 245*c6249bb2SBram Moolenaar candidates.concat m.instance_methods(false) 246*c6249bb2SBram Moolenaar } 247*c6249bb2SBram Moolenaar candidates.sort! 248*c6249bb2SBram Moolenaar candidates.uniq! 249*c6249bb2SBram Moolenaar end 250*c6249bb2SBram Moolenaar #identify_type( receiver ) 251*c6249bb2SBram Moolenaar select_message(receiver, message, candidates) 252*c6249bb2SBram Moolenaar 253*c6249bb2SBram Moolenaar #when /^((\.?[^.]+)+)\.([^.]*)\(\s*\)*$/ 254*c6249bb2SBram Moolenaar #function call 255*c6249bb2SBram Moolenaar #obj = $1 256*c6249bb2SBram Moolenaar #func = $3 257*c6249bb2SBram Moolenaar 258*c6249bb2SBram Moolenaar when /^\.([^.]*)$/ 259*c6249bb2SBram Moolenaar # unknown(maybe String) 260*c6249bb2SBram Moolenaar 261*c6249bb2SBram Moolenaar receiver = "" 262*c6249bb2SBram Moolenaar message = Regexp.quote($1) 263*c6249bb2SBram Moolenaar 264*c6249bb2SBram Moolenaar candidates = String.instance_methods(true) 265*c6249bb2SBram Moolenaar select_message(receiver, message, candidates) 266*c6249bb2SBram Moolenaar 267*c6249bb2SBram Moolenaar else 268*c6249bb2SBram Moolenaar candidates = eval("self.class.constants") 269*c6249bb2SBram Moolenaar 270*c6249bb2SBram Moolenaar (candidates|ReservedWords).grep(/^#{Regexp.quote(input)}/) 271*c6249bb2SBram Moolenaar end 272*c6249bb2SBram Moolenaar 273*c6249bb2SBram Moolenaar #print candidates 274*c6249bb2SBram Moolenaar if message != nil && message.length > 0 275*c6249bb2SBram Moolenaar rexp = '^%s' % message.downcase 276*c6249bb2SBram Moolenaar candidates.delete_if do |c| 277*c6249bb2SBram Moolenaar c.downcase.match( rexp ) 278*c6249bb2SBram Moolenaar $~ == nil 279*c6249bb2SBram Moolenaar end 280*c6249bb2SBram Moolenaar end 281*c6249bb2SBram Moolenaar 282*c6249bb2SBram Moolenaar outp = "" 283*c6249bb2SBram Moolenaar # tags = VIM::evaluate("taglist('^%s$')" % 284*c6249bb2SBram Moolenaar (candidates-Object.instance_methods).each { |c| outp += "{'word':'%s','item':'%s'}," % [ c, c ] } 285*c6249bb2SBram Moolenaar outp.sub!(/,$/, '') 286*c6249bb2SBram Moolenaar VIM::command("let g:rbcomplete_completions = [%s]" % outp) 287*c6249bb2SBram Moolenaarend 288*c6249bb2SBram Moolenaar 289*c6249bb2SBram Moolenaar 290*c6249bb2SBram Moolenaardef select_message(receiver, message, candidates) 291*c6249bb2SBram Moolenaar candidates.grep(/^#{message}/).collect do |e| 292*c6249bb2SBram Moolenaar case e 293*c6249bb2SBram Moolenaar when /^[a-zA-Z_]/ 294*c6249bb2SBram Moolenaar receiver + "." + e 295*c6249bb2SBram Moolenaar when /^[0-9]/ 296*c6249bb2SBram Moolenaar when *Operators 297*c6249bb2SBram Moolenaar #receiver + " " + e 298*c6249bb2SBram Moolenaar end 299*c6249bb2SBram Moolenaar end 300*c6249bb2SBram Moolenaar candidates.delete_if { |x| x == nil } 301*c6249bb2SBram Moolenaar candidates.uniq! 302*c6249bb2SBram Moolenaar candidates.sort! 303*c6249bb2SBram Moolenaarend 304*c6249bb2SBram MoolenaarRUBYEOF 305*c6249bb2SBram Moolenaarendfunction 306*c6249bb2SBram Moolenaar 307*c6249bb2SBram Moolenaarcall s:DefRuby() 308*c6249bb2SBram Moolenaar" vim: set et ts=4: 309