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