The attached patches update rubycomplete to match the vim-ruby version.
This adds a few features and no longer defaults to loading code from the
current buffer.
One patch handles the rubycomplete changes, the other updates the
documentation to match the changed functionality.
--mark
--
sic transit gloria et adulescentia
blog | http://blog.hasno.info/blog
wiki | http://wiki.hasno.info
--- vim7\runtime\autoload\rubycomplete.vim Tue May 16 22:09:00 2006
+++ vim-ruby\autoload\rubycomplete.vim Mon Jun 19 13:10:24 2006
@@ -1,7 +1,7 @@
" Vim completion script
" Language: Ruby
" Maintainer: Mark Guzman <[EMAIL PROTECTED]>
-" Info: $Id: rubycomplete.vim,v 1.5 2006/04/29 21:54:43
vimboss Exp $
+" Info: $Id: rubycomplete.vim,v 1.33 2006/06/19 17:10:24 segy
Exp $
" URL: http://vim-ruby.rubyforge.org
" Anon CVS: See above site
" Release Coordinator: Doug Kearns <[EMAIL PROTECTED]>
@@ -12,16 +12,12 @@
" {{{ requirement checks
if !has('ruby')
- echohl ErrorMsg
- echo "Error: Required vim compiled with +ruby"
- echohl None
+ s:ErrMsg( "Error: Required vim compiled with +ruby" )
finish
endif
if version < 700
- echohl ErrorMsg
- echo "Error: Required vim >= 7.0"
- echohl None
+ s:ErrMsg( "Error: Required vim >= 7.0" )
finish
endif
" }}} requirement checks
@@ -34,21 +30,32 @@
let g:rubycomplete_classes_in_global = 0
endif
+if !exists("g:rubycomplete_buffer_loading")
+ let g:rubycomplete_classes_in_global = 0
+endif
+
+
" {{{ vim-side support functions
-function! GetBufferRubyModule(name)
- let [snum,enum] = GetBufferRubyEntity(a:name, "module")
+function! s:ErrMsg(msg)
+ echohl ErrorMsg
+ echo a:msg
+ echohl None
+endfunction
+
+function! s:GetBufferRubyModule(name)
+ let [snum,enum] = s:GetBufferRubyEntity(a:name, "module")
return snum . '..' . enum
endfunction
-function! GetBufferRubyClass(name)
- let [snum,enum] = GetBufferRubyEntity(a:name, "class")
+function! s:GetBufferRubyClass(name)
+ let [snum,enum] = s:GetBufferRubyEntity(a:name, "class")
return snum . '..' . enum
endfunction
-function! GetBufferRubySingletonMethods(name)
+function! s:GetBufferRubySingletonMethods(name)
endfunction
-function! GetBufferRubyEntity( name, type )
+function! s:GetBufferRubyEntity( name, type )
let stopline = 1
let crex = '^\s*' . a:type . '\s*' . a:name .
'\s*\(<\s*.*\s*\)\?\n*\(\(\s\|#\).*\n*\)*\n*\s*end$'
let [lnum,lcol] = searchpos( crex, 'nbw')
@@ -66,8 +73,8 @@
return [lnum,enum]
endfunction
-function! IsInClassDef()
- let [snum,enum] = GetBufferRubyEntity( '.*', "class" )
+function! s:IsInClassDef()
+ let [snum,enum] = s:GetBufferRubyEntity( '.*', "class" )
let ret = 'nil'
let pos = line('.')
@@ -78,7 +85,7 @@
return ret
endfunction
-function! GetRubyVarType(v)
+function! s:GetRubyVarType(v)
let stopline = 1
let vtp = ''
let pos = getpos('.')
@@ -90,7 +97,7 @@
return vtp
endif
call setpos('.',pos)
- if g:rubycomplete_rails == 1 && g:rubycomplete_rails_loaded == 1
+ if exists('g:rubycomplete_rails') && g:rubycomplete_rails == 1 &&
s:rubycomplete_rails_loaded == 1
let ctors = '\(now\|new\|open\|get_instance\|find\|create\)'
else
let ctors = '\(now\|new\|open\|get_instance\)'
@@ -199,7 +206,7 @@
end
def load_buffer_class(name)
- classdef = get_buffer_entity(name, 'GetBufferRubyClass("%s")')
+ classdef = get_buffer_entity(name, 's:GetBufferRubyClass("%s")')
return if classdef == nil
pare = /^\s*class\s*(.*)\s*<\s*(.*)\s*\n/.match( classdef )
@@ -208,17 +215,27 @@
mixre = /.*\n\s*include\s*(.*)\s*\n/.match( classdef )
load_buffer_module( $2 ) if mixre != nil
- eval classdef
+ begin
+ eval classdef
+ rescue
+ VIM::evaluate( "s:ErrMsg( 'Problem loading class \"%s\", was it already
completed?' )" % name )
+ end
end
def load_buffer_module(name)
- classdef = get_buffer_entity(name, 'GetBufferRubyModule("%s")')
+ classdef = get_buffer_entity(name, 's:GetBufferRubyModule("%s")')
return if classdef == nil
- eval classdef
+ begin
+ eval classdef
+ rescue
+ VIM::evaluate( "s:ErrMsg( 'Problem loading module \"%s\", was it already
completed?' )" % name )
+ end
end
def get_buffer_entity(name, vimfun)
+ loading_allowed = VIM::evaluate("exists('g:rubycomplete_buffer_loading') &&
g:rubycomplete_buffer_loading")
+ return nil if loading_allowed != '1'
return nil if /(\"|\')+/.match( name )
buf = VIM::Buffer.current
nums = eval( VIM::evaluate( vimfun % name ) )
@@ -241,14 +258,15 @@
if /(\"|\')+/.match( receiver )
"String"
else
- VIM::evaluate("GetRubyVarType('%s')" % receiver)
+ VIM::evaluate("s:GetRubyVarType('%s')" % receiver)
end
end
def get_buffer_classes()
# this will be a little expensive.
- allow_aggressive_load = VIM::evaluate('g:rubycomplete_classes_in_global')
- return [] if allow_aggressive_load != '1'
+ loading_allowed = VIM::evaluate("exists('g:rubycomplete_buffer_loading') &&
g:rubycomplete_buffer_loading")
+ allow_aggressive_load =
VIM::evaluate("exists('g:rubycomplete_classes_in_global') &&
g:rubycomplete_classes_in_global")
+ return [] if allow_aggressive_load != '1' || loading_allowed != '1'
buf = VIM::Buffer.current
eob = buf.length
@@ -265,7 +283,7 @@
end
def load_rails()
- allow_rails = VIM::evaluate('g:rubycomplete_rails')
+ allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') &&
g:rubycomplete_rails")
return if allow_rails != '1'
buf_path = VIM::evaluate('expand("%:p")')
@@ -291,100 +309,119 @@
begin
require bootfile
require envfile
- require 'console_app'
- require 'console_with_helpers'
- VIM::command('let g:rubycomplete_rails_loaded = 1')
+ begin
+ require 'console_app'
+ require 'console_with_helpers'
+ rescue
+ # 1.0
+ end
+ Rails::Initializer.run
+ VIM::command('let s:rubycomplete_rails_loaded = 1')
rescue
- print "Error loading rails environment"
+ VIM::evaluate( "s:ErrMsg('Error loading rails environment')" )
end
end
end
def get_rails_helpers
- allow_rails = VIM::evaluate('g:rubycomplete_rails')
- rails_loaded = VIM::evaluate('g:rubycomplete_rails_loaded')
+ allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') &&
g:rubycomplete_rails")
+ rails_loaded = VIM::evaluate('s:rubycomplete_rails_loaded')
return [] if allow_rails != '1' || rails_loaded != '1'
return RailsWords
end
+def add_rails_columns( cls )
+ allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') &&
g:rubycomplete_rails")
+ rails_loaded = VIM::evaluate('s:rubycomplete_rails_loaded')
+ return [] if allow_rails != '1' || rails_loaded != '1'
+ eval( "#{cls}.establish_connection" )
+ return [] unless eval( "#{cls}.ancestors.include?(ActiveRecord::Base).to_s" )
+ col = eval( "#{cls}.column_names" )
+ return col if col
+ return []
+end
+
+def clean_sel(sel, msg)
+ sel.delete_if { |x| x == nil }
+ sel.uniq!
+ sel.grep(/^#{Regexp.quote(msg)}/) if msg != nil
+end
+
def get_completions(base)
- load_requires
- load_rails
+ loading_allowed = VIM::evaluate("exists('g:rubycomplete_buffer_loading') &&
g:rubycomplete_buffer_loading")
+ if loading_allowed == '1'
+ load_requires
+ load_rails
+ end
input = VIM::Buffer.current.line
cpos = VIM::Window.current.cursor[1] - 1
- input = input[0..cpos] if cpos != 0
+ input = input[0..cpos]
input += base
+ input.sub!(/.*[ \t\n\"\\'`><=;|&{(]/, '') #
Readline.basic_word_break_characters
+ input.sub!(/self\./, '')
- rip = input.rindex(/\s/,cpos)
- if rip
- input = input[rip..input.length]
- end
-
- asn =
/^.*(\+|\-|\*|=|\(|\[)=?(\s*[A-Za-z0-9_:@.-]*)(\s*(\{|\+|\-|\*|\%|\/)?\s*).*/
- if asn.match(input)
- input = $2
- end
-
- input.strip!
message = nil
receiver = nil
- candidates = []
+ methods = []
+ variables = []
+ classes = []
case input
when /^(\/[^\/]*\/)\.([^.]*)$/ # Regexp
receiver = $1
message = Regexp.quote($2)
- candidates = Regexp.instance_methods(true)
+ methods = Regexp.instance_methods(true)
when /^([^\]]*\])\.([^.]*)$/ # Array
receiver = $1
message = Regexp.quote($2)
- candidates = Array.instance_methods(true)
+ methods = Array.instance_methods(true)
when /^([^\}]*\})\.([^.]*)$/ # Proc or Hash
receiver = $1
message = Regexp.quote($2)
- candidates = Proc.instance_methods(true) | Hash.instance_methods(true)
+ methods = Proc.instance_methods(true) | Hash.instance_methods(true)
when /^(:[^:.]*)$/ # Symbol
if Symbol.respond_to?(:all_symbols)
receiver = $1
- candidates = Symbol.all_symbols.collect{|s| s.id2name}
- candidates.delete_if { |c| c.match( /'/ ) }
+ message = $1.sub( /:/, '' )
+ methods = Symbol.all_symbols.collect{|s| s.id2name}
+ methods.delete_if { |c| c.match( /'/ ) }
end
when /^::([A-Z][^:\.\(]*)$/ # Absolute Constant or class methods
receiver = $1
- candidates = Object.constants
- candidates.grep(/^#{receiver}/).collect{|e| "::" + e}
+ methods = Object.constants
+ methods.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")
+ methods = eval("#{receiver}.constants | #{receiver}.methods")
rescue Exception
- candidates = []
+ methods = []
end
- candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e}
+ methods.grep(/^#{message}/).collect{|e| receiver + "::" + e}
when /^(:[^:.]+)\.([^.]*)$/ # Symbol
receiver = $1
message = Regexp.quote($2)
- candidates = Symbol.instance_methods(true)
+ methods = Symbol.instance_methods(true)
when /^([0-9_]+(\.[0-9_]+)?(e[0-9]+)?)\.([^.]*)$/ # Numeric
receiver = $1
message = Regexp.quote($4)
begin
- candidates = eval(receiver).methods
+ methods = eval(receiver).methods
rescue Exception
- candidates
+ methods = []
end
when /^(\$[^.]*)$/ #global
- candidates = global_variables.grep(Regexp.new(Regexp.quote($1)))
+ methods = global_variables.grep(Regexp.new(Regexp.quote($1)))
when /^((\.?[^.]+)+)\.([^.]*)$/ # variable
receiver = $1
@@ -397,44 +434,41 @@
load_buffer_class( vartype )
begin
- candidates = eval("#{vartype}.instance_methods")
+ methods = eval("#{vartype}.instance_methods")
+ variables = eval("#{vartype}.instance_variables")
rescue Exception
- candidates = []
end
elsif (cv).include?(receiver)
# foo.func and foo is local var.
- candidates = eval("#{receiver}.methods")
+ methods = eval("#{receiver}.methods")
+ vartype = receiver
elsif /^[A-Z]/ =~ receiver and /\./ !~ receiver
+ vartype = receiver
# Foo::Bar.func
begin
- candidates = eval("#{receiver}.methods")
+ methods = 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)
+ methods.concat m.instance_methods(false)
}
end
+ variables += add_rails_columns( "#{vartype}" ) if vartype &&
vartype.length > 0
when /^\(?\s*[A-Za-z0-9:[EMAIL PROTECTED]/+*\(\)]+\.\.\.?[A-Za-z0-9:[EMAIL
PROTECTED]/+*\(\)]+\s*\)?\.([^.]*)/
message = $1
- candidates = Range.instance_methods(true)
-
- when /^\[(\s*[A-Za-z0-9:[EMAIL
PROTECTED]/+*\(\)\[\]\{\}.\'\"],?)*\].([^.]*)/
- message = $2
- candidates = Array.instance_methods(true)
+ methods = Range.instance_methods(true)
when /^\.([^.]*)$/ # unknown(maybe String)
message = Regexp.quote($1)
- candidates = String.instance_methods(true)
+ methods = String.instance_methods(true)
else
- inclass = eval( VIM::evaluate("IsInClassDef()") )
+ inclass = eval( VIM::evaluate("s:IsInClassDef()") )
if inclass != nil
classdef = "%s\n" % VIM::Buffer.current[ inclass.min ]
@@ -445,8 +479,9 @@
message = input
load_buffer_class( receiver )
begin
- candidates = eval( "#{receiver}.instance_methods" )
- candidates += get_rails_helpers
+ methods = eval( "#{receiver}.instance_methods" )
+ methods += get_rails_helpers
+ variables += add_rails_columns( "#{receiver}" )
rescue Exception
found = nil
end
@@ -454,25 +489,29 @@
end
if inclass == nil || found == nil
- candidates = eval("self.class.constants")
- candidates += get_buffer_classes
+ classes = eval("self.class.constants")
+ classes += get_buffer_classes
message = receiver = input
end
end
- candidates.delete_if { |x| x == nil }
- candidates.uniq!
- candidates.sort!
- candidates = candidates.grep(/^#{Regexp.quote(message)}/) if message != nil
+ methods = clean_sel( methods, message )
+ methods = (methods-Object.instance_methods)
+ variables = clean_sel( variables, message )
+ classes = clean_sel( classes, message )
+ valid = []
+ valid += methods.collect { |m| { :name => m, :type => 'f' } }
+ valid += variables.collect { |v| { :name => v, :type => 'v' } }
+ valid += classes.collect { |c| { :name => c, :type => 't' } }
+ valid.sort! { |x,y| x[:name] <=> y[:name] }
outp = ""
- valid = (candidates-Object.instance_methods)
rg = 0..valid.length
rg.step(150) do |x|
stpos = 0+x
enpos = 150+x
- valid[stpos..enpos].each { |c| outp += "{'word':'%s','item':'%s'}," % [ c,
c ] }
+ valid[stpos..enpos].each { |c| outp +=
"{'word':'%s','item':'%s','kind':'%s'}," % [ c[:name], c[:name], c[:type] ] }
outp.sub!(/,$/, '')
VIM::command("call extend(g:rubycomplete_completions, [%s])" % outp)
@@ -484,7 +523,7 @@
RUBYEOF
endfunction
-let g:rubycomplete_rails_loaded = 0
+let s:rubycomplete_rails_loaded = 0
call s:DefRuby()
-" vim:tw=78:sw=4:ts=8:et:ft=vim:norl:
+" vim:tw=78:sw=4:ts=8:et:fdm=marker:ft=vim:norl:
--- vim7\runtime\doc\insert.txt.old Mon Jun 19 22:02:34 2006
+++ vim7\runtime\doc\insert.txt Mon Jun 19 22:03:44 2006
@@ -1390,8 +1390,10 @@
Notes:
- Vim will load/evaluate code in order to provide completions. This may
- cause some code execution, which may be a concern.
- - In context 1 above, Vim can parse the entire buffer to add a list of
+ cause some code execution, which may be a concern. This is no longer
+ enabled by default, to enable this feature add >
+ let g:rubycomplete_buffer_loading = 1
+<- In context 1 above, Vim can parse the entire buffer to add a list of
classes to the completion results. This feature is turned off by default,
to enable it add >
let g:rubycomplete_classes_in_global = 1