summaryrefslogtreecommitdiffstats
path: root/runtime/autoload/rubycomplete.vim
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/autoload/rubycomplete.vim')
-rw-r--r--runtime/autoload/rubycomplete.vim308
1 files changed, 308 insertions, 0 deletions
diff --git a/runtime/autoload/rubycomplete.vim b/runtime/autoload/rubycomplete.vim
new file mode 100644
index 0000000000..8def228edc
--- /dev/null
+++ b/runtime/autoload/rubycomplete.vim
@@ -0,0 +1,308 @@
+" Vim completion script
+" Language: Ruby
+" Maintainer: Mark Guzman ( segfault AT hasno DOT info )
+" Info: $Id$
+" URL: http://vim-ruby.rubyforge.org
+" Anon CVS: See above site
+" Release Coordinator: Doug Kearns <dougkearns@gmail.com>
+" ----------------------------------------------------------------------------
+"
+" Ruby IRB/Complete author: Keiju ISHITSUKA(keiju@ishitsuka.com)
+" ----------------------------------------------------------------------------
+
+if !has('ruby')
+ echo "Error: Required vim compiled with +ruby"
+ finish
+endif
+
+if version < 700
+ echo "Error: Required vim >= 7.0"
+ finish
+endif
+
+func! GetRubyVarType(v)
+ let stopline = 1
+ let vtp = ''
+ let pos = getpos('.')
+ let [lnum,lcol] = searchpos('^\s*#\s*@var\s*'.a:v.'\>\s\+[^ \t]\+\s*$','nb',stopline)
+ if lnum != 0 && lcol != 0
+ call setpos('.',pos)
+ let str = getline(lnum)
+ let vtp = substitute(str,'^\s*#\s*@var\s*'.a:v.'\>\s\+\([^ \t]\+\)\s*$','\1','')
+ return vtp
+ endif
+ call setpos('.',pos)
+ let [lnum,lcol] = searchpos(''.a:v.'\>\s*[+\-*/]*=\s*\([^ \t]\+.\(now\|new\|open\|get_instance\)\>\|[\[{"'']\)','nb',stopline)
+ if lnum != 0 && lcol != 0
+ let str = matchstr(getline(lnum),'=\s*\([^ \t]\+.\(now\|new\|open\|get_instance\)\>\|[\[{"'']\)',lcol)
+ let str = substitute(str,'^=\s*','','')
+ call setpos('.',pos)
+ if str == '"' || str == ''''
+ return 'String'
+ elseif str == '['
+ return 'Array'
+ elseif str == '{'
+ return 'Hash'
+ elseif strlen(str) > 4
+ let l = stridx(str,'.')
+ return str[0:l-1]
+ end
+ return ''
+ endif
+ call setpos('.',pos)
+ return ''
+endf
+
+function! rubycomplete#Complete(findstart, base)
+ "findstart = 1 when we need to get the text length
+ if a:findstart
+ let line = getline('.')
+ let idx = col('.')
+ while idx > 0
+ let idx -= 1
+ let c = line[idx-1]
+ if c =~ '\w'
+ continue
+ elseif ! c =~ '\.'
+ idx = -1
+ break
+ else
+ break
+ endif
+ endwhile
+
+ return idx
+ "findstart = 0 when we need to return the list of completions
+ else
+ execute "ruby get_completions('" . a:base . "')"
+ return g:rbcomplete_completions
+ endif
+endfunction
+
+
+function! s:DefRuby()
+ruby << RUBYEOF
+ReservedWords = [
+ "BEGIN", "END",
+ "alias", "and",
+ "begin", "break",
+ "case", "class",
+ "def", "defined", "do",
+ "else", "elsif", "end", "ensure",
+ "false", "for",
+ "if", "in",
+ "module",
+ "next", "nil", "not",
+ "or",
+ "redo", "rescue", "retry", "return",
+ "self", "super",
+ "then", "true",
+ "undef", "unless", "until",
+ "when", "while",
+ "yield",
+ ]
+
+Operators = [ "%", "&", "*", "**", "+", "-", "/",
+ "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>",
+ "[]", "[]=", "^", ]
+
+def identify_type(var)
+ @buf = VIM::Buffer.current
+ enum = @buf.line_number
+ snum = (enum-10).abs
+ nums = Range.new( snum, enum )
+ regxs = '/.*(%s)\s*=(.*)/' % var
+ regx = Regexp.new( regxs )
+ nums.each do |x|
+ ln = @buf[x]
+ #print $~ if regx.match( ln )
+ end
+end
+
+def load_requires
+ @buf = VIM::Buffer.current
+ enum = @buf.line_number
+ nums = Range.new( 1, enum )
+ nums.each do |x|
+ ln = @buf[x]
+ begin
+ eval( "require %s" % $1 ) if /.*require\s*(.*)$/.match( ln )
+ rescue Exception
+ #ignore?
+ end
+ end
+end
+
+def get_completions(base)
+ load_requires
+ input = VIM::evaluate('expand("<cWORD>")')
+ input += base
+ message = nil
+
+
+ case input
+ when /^(\/[^\/]*\/)\.([^.]*)$/
+ # Regexp
+ receiver = $1
+ message = Regexp.quote($2)
+
+ candidates = Regexp.instance_methods(true)
+ select_message(receiver, message, candidates)
+
+ when /^([^\]]*\])\.([^.]*)$/
+ # Array
+ receiver = $1
+ message = Regexp.quote($2)
+
+ candidates = Array.instance_methods(true)
+ select_message(receiver, message, candidates)
+
+ when /^([^\}]*\})\.([^.]*)$/
+ # Proc or Hash
+ receiver = $1
+ message = Regexp.quote($2)
+
+ candidates = Proc.instance_methods(true) | Hash.instance_methods(true)
+ select_message(receiver, message, candidates)
+
+ when /^(:[^:.]*)$/
+ # Symbol
+ if Symbol.respond_to?(:all_symbols)
+ sym = $1
+ candidates = Symbol.all_symbols.collect{|s| ":" + s.id2name}
+ candidates.grep(/^#{sym}/)
+ else
+ []
+ end
+
+ when /^::([A-Z][^:\.\(]*)$/
+ # Absolute Constant or class methods
+ receiver = $1
+ candidates = Object.constants
+ candidates.grep(/^#{receiver}/).collect{|e| "::" + e}
+
+ when /^(((::)?[A-Z][^:.\(]*)+)::?([^:.]*)$/
+ # Constant or class methods
+ receiver = $1
+ message = Regexp.quote($4)
+ begin
+ candidates = eval("#{receiver}.constants | #{receiver}.methods")
+ rescue Exception
+ candidates = []
+ end
+ candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e}
+
+ when /^(:[^:.]+)\.([^.]*)$/
+ # Symbol
+ receiver = $1
+ message = Regexp.quote($2)
+
+ candidates = Symbol.instance_methods(true)
+ select_message(receiver, message, candidates)
+
+ when /^([0-9_]+(\.[0-9_]+)?(e[0-9]+)?)\.([^.]*)$/
+ # Numeric
+ receiver = $1
+ message = Regexp.quote($4)
+
+ begin
+ candidates = eval(receiver).methods
+ rescue Exception
+ candidates
+ end
+ select_message(receiver, message, candidates)
+
+ when /^(\$[^.]*)$/
+ candidates = global_variables.grep(Regexp.new(Regexp.quote($1)))
+
+# when /^(\$?(\.?[^.]+)+)\.([^.]*)$/
+ when /^((\.?[^.]+)+)\.([^.]*)$/
+ # variable
+ receiver = $1
+ message = Regexp.quote($3)
+
+ cv = eval("self.class.constants")
+
+ vartype = VIM::evaluate("GetRubyVarType('%s')" % receiver)
+ if vartype != ''
+ candidates = eval("#{vartype}.instance_methods")
+ elsif (cv).include?(receiver)
+ # foo.func and foo is local var.
+ candidates = eval("#{receiver}.methods")
+ elsif /^[A-Z]/ =~ receiver and /\./ !~ receiver
+ # Foo::Bar.func
+ begin
+ candidates = eval("#{receiver}.methods")
+ rescue Exception
+ candidates = []
+ end
+ else
+ # func1.func2
+ candidates = []
+ ObjectSpace.each_object(Module){|m|
+ next if m.name != "IRB::Context" and
+ /^(IRB|SLex|RubyLex|RubyToken)/ =~ m.name
+ candidates.concat m.instance_methods(false)
+ }
+ candidates.sort!
+ candidates.uniq!
+ end
+ #identify_type( receiver )
+ select_message(receiver, message, candidates)
+
+ #when /^((\.?[^.]+)+)\.([^.]*)\(\s*\)*$/
+ #function call
+ #obj = $1
+ #func = $3
+
+ when /^\.([^.]*)$/
+ # unknown(maybe String)
+
+ receiver = ""
+ message = Regexp.quote($1)
+
+ candidates = String.instance_methods(true)
+ select_message(receiver, message, candidates)
+
+ else
+ candidates = eval("self.class.constants")
+
+ (candidates|ReservedWords).grep(/^#{Regexp.quote(input)}/)
+ end
+
+ #print candidates
+ if message != nil && message.length > 0
+ rexp = '^%s' % message.downcase
+ candidates.delete_if do |c|
+ c.downcase.match( rexp )
+ $~ == nil
+ end
+ end
+
+ outp = ""
+ # tags = VIM::evaluate("taglist('^%s$')" %
+ (candidates-Object.instance_methods).each { |c| outp += "{'word':'%s','item':'%s'}," % [ c, c ] }
+ outp.sub!(/,$/, '')
+ VIM::command("let g:rbcomplete_completions = [%s]" % outp)
+end
+
+
+def select_message(receiver, message, candidates)
+ candidates.grep(/^#{message}/).collect do |e|
+ case e
+ when /^[a-zA-Z_]/
+ receiver + "." + e
+ when /^[0-9]/
+ when *Operators
+ #receiver + " " + e
+ end
+ end
+ candidates.delete_if { |x| x == nil }
+ candidates.uniq!
+ candidates.sort!
+end
+RUBYEOF
+endfunction
+
+call s:DefRuby()
+" vim: set et ts=4: