1c6249bb2SBram Moolenaar" Vim completion script 2c6249bb2SBram Moolenaar" Language: Ruby 3fc1421ebSBram Moolenaar" Maintainer: Mark Guzman <[email protected]> 4ec7944aaSBram Moolenaar" URL: https://github.com/vim-ruby/vim-ruby 5c6249bb2SBram Moolenaar" Release Coordinator: Doug Kearns <[email protected]> 6*d09091d4SBram Moolenaar" Last Change: 2019 Jan 06 7c6249bb2SBram Moolenaar" ---------------------------------------------------------------------------- 8c6249bb2SBram Moolenaar" 9c6249bb2SBram Moolenaar" Ruby IRB/Complete author: Keiju ISHITSUKA([email protected]) 10c6249bb2SBram Moolenaar" ---------------------------------------------------------------------------- 11c6249bb2SBram Moolenaar 12eb3593b3SBram Moolenaar" {{{ requirement checks 13ec7944aaSBram Moolenaar 14ec7944aaSBram Moolenaarfunction! s:ErrMsg(msg) 15ec7944aaSBram Moolenaar echohl ErrorMsg 16ec7944aaSBram Moolenaar echo a:msg 17ec7944aaSBram Moolenaar echohl None 18ec7944aaSBram Moolenaarendfunction 19ec7944aaSBram Moolenaar 20c6249bb2SBram Moolenaarif !has('ruby') 21ec7944aaSBram Moolenaar call s:ErrMsg( "Error: Rubycomplete requires vim compiled with +ruby" ) 22ec7944aaSBram Moolenaar call s:ErrMsg( "Error: falling back to syntax completion" ) 239964e468SBram Moolenaar " lets fall back to syntax completion 249964e468SBram Moolenaar setlocal omnifunc=syntaxcomplete#Complete 25c6249bb2SBram Moolenaar finish 26c6249bb2SBram Moolenaarendif 27c6249bb2SBram Moolenaar 28c6249bb2SBram Moolenaarif version < 700 29ec7944aaSBram Moolenaar call s:ErrMsg( "Error: Required vim >= 7.0" ) 30c6249bb2SBram Moolenaar finish 31c6249bb2SBram Moolenaarendif 32eb3593b3SBram Moolenaar" }}} requirement checks 33c6249bb2SBram Moolenaar 349964e468SBram Moolenaar" {{{ configuration failsafe initialization 35eb3593b3SBram Moolenaarif !exists("g:rubycomplete_rails") 36eb3593b3SBram Moolenaar let g:rubycomplete_rails = 0 37eb3593b3SBram Moolenaarendif 38fc1421ebSBram Moolenaar 39eb3593b3SBram Moolenaarif !exists("g:rubycomplete_classes_in_global") 40eb3593b3SBram Moolenaar let g:rubycomplete_classes_in_global = 0 41eb3593b3SBram Moolenaarendif 42eb3593b3SBram Moolenaar 439964e468SBram Moolenaarif !exists("g:rubycomplete_buffer_loading") 44a7241f5fSBram Moolenaar let g:rubycomplete_buffer_loading = 0 459964e468SBram Moolenaarendif 469964e468SBram Moolenaar 479964e468SBram Moolenaarif !exists("g:rubycomplete_include_object") 489964e468SBram Moolenaar let g:rubycomplete_include_object = 0 499964e468SBram Moolenaarendif 509964e468SBram Moolenaar 519964e468SBram Moolenaarif !exists("g:rubycomplete_include_objectspace") 529964e468SBram Moolenaar let g:rubycomplete_include_objectspace = 0 539964e468SBram Moolenaarendif 549964e468SBram Moolenaar" }}} configuration failsafe initialization 559964e468SBram Moolenaar 56eb3593b3SBram Moolenaar" {{{ vim-side support functions 579964e468SBram Moolenaarlet s:rubycomplete_debug = 0 589964e468SBram Moolenaar 599964e468SBram Moolenaarfunction! s:dprint(msg) 609964e468SBram Moolenaar if s:rubycomplete_debug == 1 619964e468SBram Moolenaar echom a:msg 629964e468SBram Moolenaar endif 639964e468SBram Moolenaarendfunction 649964e468SBram Moolenaar 659964e468SBram Moolenaarfunction! s:GetBufferRubyModule(name, ...) 669964e468SBram Moolenaar if a:0 == 1 679964e468SBram Moolenaar let [snum,enum] = s:GetBufferRubyEntity(a:name, "module", a:1) 689964e468SBram Moolenaar else 699964e468SBram Moolenaar let [snum,enum] = s:GetBufferRubyEntity(a:name, "module") 709964e468SBram Moolenaar endif 71fc1421ebSBram Moolenaar return snum . '..' . enum 72fc1421ebSBram Moolenaarendfunction 73fc1421ebSBram Moolenaar 749964e468SBram Moolenaarfunction! s:GetBufferRubyClass(name, ...) 759964e468SBram Moolenaar if a:0 >= 1 769964e468SBram Moolenaar let [snum,enum] = s:GetBufferRubyEntity(a:name, "class", a:1) 779964e468SBram Moolenaar else 789964e468SBram Moolenaar let [snum,enum] = s:GetBufferRubyEntity(a:name, "class") 799964e468SBram Moolenaar endif 80fc1421ebSBram Moolenaar return snum . '..' . enum 81fc1421ebSBram Moolenaarendfunction 82fc1421ebSBram Moolenaar 839964e468SBram Moolenaarfunction! s:GetBufferRubySingletonMethods(name) 84fc1421ebSBram Moolenaarendfunction 85fc1421ebSBram Moolenaar 869964e468SBram Moolenaarfunction! s:GetBufferRubyEntity( name, type, ... ) 879964e468SBram Moolenaar let lastpos = getpos(".") 889964e468SBram Moolenaar let lastline = lastpos 899964e468SBram Moolenaar if (a:0 >= 1) 909964e468SBram Moolenaar let lastline = [ 0, a:1, 0, 0 ] 919964e468SBram Moolenaar call cursor( a:1, 0 ) 929964e468SBram Moolenaar endif 939964e468SBram Moolenaar 94fc1421ebSBram Moolenaar let stopline = 1 959964e468SBram Moolenaar 9689bcfda6SBram Moolenaar let crex = '^\s*\<' . a:type . '\>\s*\<' . escape(a:name, '*') . '\>\s*\(<\s*.*\s*\)\?' 979964e468SBram Moolenaar let [lnum,lcol] = searchpos( crex, 'w' ) 989964e468SBram Moolenaar "let [lnum,lcol] = searchpairpos( crex . '\zs', '', '\(end\|}\)', 'w' ) 999964e468SBram Moolenaar 100fc1421ebSBram Moolenaar if lnum == 0 && lcol == 0 1019964e468SBram Moolenaar call cursor(lastpos[1], lastpos[2]) 102fc1421ebSBram Moolenaar return [0,0] 103fc1421ebSBram Moolenaar endif 104fc1421ebSBram Moolenaar 1059964e468SBram Moolenaar let curpos = getpos(".") 106*d09091d4SBram Moolenaar let [enum,ecol] = searchpairpos( crex, '', '\(end\|}\)', 'W' ) 1079964e468SBram Moolenaar call cursor(lastpos[1], lastpos[2]) 1089964e468SBram Moolenaar 109fc1421ebSBram Moolenaar if lnum > enum 1109964e468SBram Moolenaar return [0,0] 111fc1421ebSBram Moolenaar endif 112fc1421ebSBram Moolenaar " we found a the class def 113fc1421ebSBram Moolenaar return [lnum,enum] 114fc1421ebSBram Moolenaarendfunction 115fc1421ebSBram Moolenaar 1169964e468SBram Moolenaarfunction! s:IsInClassDef() 1179964e468SBram Moolenaar return s:IsPosInClassDef( line('.') ) 1189964e468SBram Moolenaarendfunction 119fc1421ebSBram Moolenaar 1209964e468SBram Moolenaarfunction! s:IsPosInClassDef(pos) 1219964e468SBram Moolenaar let [snum,enum] = s:GetBufferRubyEntity( '.*', "class" ) 1229964e468SBram Moolenaar let ret = 'nil' 1239964e468SBram Moolenaar 1249964e468SBram Moolenaar if snum < a:pos && a:pos < enum 125fc1421ebSBram Moolenaar let ret = snum . '..' . enum 126fc1421ebSBram Moolenaar endif 127fc1421ebSBram Moolenaar 128fc1421ebSBram Moolenaar return ret 129fc1421ebSBram Moolenaarendfunction 130fc1421ebSBram Moolenaar 1319964e468SBram Moolenaarfunction! s:GetRubyVarType(v) 132c6249bb2SBram Moolenaar let stopline = 1 133c6249bb2SBram Moolenaar let vtp = '' 134c6249bb2SBram Moolenaar let pos = getpos('.') 135ec7944aaSBram Moolenaar let sstr = '^\s*#\s*@var\s*'.escape(a:v, '*').'\>\s\+[^ \t]\+\s*$' 1369964e468SBram Moolenaar let [lnum,lcol] = searchpos(sstr,'nb',stopline) 137c6249bb2SBram Moolenaar if lnum != 0 && lcol != 0 138c6249bb2SBram Moolenaar call setpos('.',pos) 139c6249bb2SBram Moolenaar let str = getline(lnum) 1409964e468SBram Moolenaar let vtp = substitute(str,sstr,'\1','') 141c6249bb2SBram Moolenaar return vtp 142c6249bb2SBram Moolenaar endif 143c6249bb2SBram Moolenaar call setpos('.',pos) 1449964e468SBram Moolenaar let ctors = '\(now\|new\|open\|get_instance' 1459964e468SBram Moolenaar if exists('g:rubycomplete_rails') && g:rubycomplete_rails == 1 && s:rubycomplete_rails_loaded == 1 1469964e468SBram Moolenaar let ctors = ctors.'\|find\|create' 147551dbcc9SBram Moolenaar else 148551dbcc9SBram Moolenaar endif 1499964e468SBram Moolenaar let ctors = ctors.'\)' 150551dbcc9SBram Moolenaar 1519964e468SBram Moolenaar let fstr = '=\s*\([^ \t]\+.' . ctors .'\>\|[\[{"''/]\|%[xwQqr][(\[{@]\|[A-Za-z0-9@:\-()\.]\+...\?\|lambda\|&\)' 15289bcfda6SBram Moolenaar let sstr = ''.escape(a:v, '*').'\>\s*[+\-*/]*'.fstr 1539964e468SBram Moolenaar let [lnum,lcol] = searchpos(sstr,'nb',stopline) 154c6249bb2SBram Moolenaar if lnum != 0 && lcol != 0 1559964e468SBram Moolenaar let str = matchstr(getline(lnum),fstr,lcol) 156c6249bb2SBram Moolenaar let str = substitute(str,'^=\s*','','') 1579964e468SBram Moolenaar 158c6249bb2SBram Moolenaar call setpos('.',pos) 1599964e468SBram Moolenaar if str == '"' || str == '''' || stridx(tolower(str), '%q[') != -1 160c6249bb2SBram Moolenaar return 'String' 1619964e468SBram Moolenaar elseif str == '[' || stridx(str, '%w[') != -1 162c6249bb2SBram Moolenaar return 'Array' 163c6249bb2SBram Moolenaar elseif str == '{' 164c6249bb2SBram Moolenaar return 'Hash' 165fc1421ebSBram Moolenaar elseif str == '/' || str == '%r{' 166fc1421ebSBram Moolenaar return 'Regexp' 167d8fc5c0bSBram Moolenaar elseif strlen(str) >= 4 && stridx(str,'..') != -1 168d8fc5c0bSBram Moolenaar return 'Range' 1699964e468SBram Moolenaar elseif stridx(str, 'lambda') != -1 || str == '&' 1709964e468SBram Moolenaar return 'Proc' 171c6249bb2SBram Moolenaar elseif strlen(str) > 4 172c6249bb2SBram Moolenaar let l = stridx(str,'.') 173c6249bb2SBram Moolenaar return str[0:l-1] 174c6249bb2SBram Moolenaar end 175c6249bb2SBram Moolenaar return '' 176c6249bb2SBram Moolenaar endif 177c6249bb2SBram Moolenaar call setpos('.',pos) 178c6249bb2SBram Moolenaar return '' 179fc1421ebSBram Moolenaarendfunction 180c6249bb2SBram Moolenaar 181eb3593b3SBram Moolenaar"}}} vim-side support functions 182eb3593b3SBram Moolenaar 1839964e468SBram Moolenaar"{{{ vim-side completion function 1849964e468SBram Moolenaarfunction! rubycomplete#Init() 1859964e468SBram Moolenaar execute "ruby VimRubyCompletion.preload_rails" 1869964e468SBram Moolenaarendfunction 1879964e468SBram Moolenaar 188c6249bb2SBram Moolenaarfunction! rubycomplete#Complete(findstart, base) 189c6249bb2SBram Moolenaar "findstart = 1 when we need to get the text length 190c6249bb2SBram Moolenaar if a:findstart 191c6249bb2SBram Moolenaar let line = getline('.') 192c6249bb2SBram Moolenaar let idx = col('.') 193c6249bb2SBram Moolenaar while idx > 0 194c6249bb2SBram Moolenaar let idx -= 1 195c6249bb2SBram Moolenaar let c = line[idx-1] 196c6249bb2SBram Moolenaar if c =~ '\w' 197c6249bb2SBram Moolenaar continue 198c6249bb2SBram Moolenaar elseif ! c =~ '\.' 1994575876dSBram Moolenaar let idx = -1 200c6249bb2SBram Moolenaar break 201c6249bb2SBram Moolenaar else 202c6249bb2SBram Moolenaar break 203c6249bb2SBram Moolenaar endif 204c6249bb2SBram Moolenaar endwhile 205c6249bb2SBram Moolenaar 206c6249bb2SBram Moolenaar return idx 207c6249bb2SBram Moolenaar "findstart = 0 when we need to return the list of completions 208c6249bb2SBram Moolenaar else 209fc1421ebSBram Moolenaar let g:rubycomplete_completions = [] 2109964e468SBram Moolenaar execute "ruby VimRubyCompletion.get_completions('" . a:base . "')" 211fc1421ebSBram Moolenaar return g:rubycomplete_completions 212c6249bb2SBram Moolenaar endif 213c6249bb2SBram Moolenaarendfunction 2149964e468SBram Moolenaar"}}} vim-side completion function 215c6249bb2SBram Moolenaar 2169964e468SBram Moolenaar"{{{ ruby-side code 217c6249bb2SBram Moolenaarfunction! s:DefRuby() 218c6249bb2SBram Moolenaarruby << RUBYEOF 219eb3593b3SBram Moolenaar# {{{ ruby completion 220fc1421ebSBram Moolenaar 2219964e468SBram Moolenaarbegin 2229964e468SBram Moolenaar require 'rubygems' # let's assume this is safe...? 2239964e468SBram Moolenaarrescue Exception 2249964e468SBram Moolenaar #ignore? 2259964e468SBram Moolenaarend 2269964e468SBram Moolenaarclass VimRubyCompletion 2279964e468SBram Moolenaar# {{{ constants 2289964e468SBram Moolenaar @@debug = false 2299964e468SBram Moolenaar @@ReservedWords = [ 230c6249bb2SBram Moolenaar "BEGIN", "END", 231c6249bb2SBram Moolenaar "alias", "and", 232c6249bb2SBram Moolenaar "begin", "break", 233c6249bb2SBram Moolenaar "case", "class", 234c6249bb2SBram Moolenaar "def", "defined", "do", 235c6249bb2SBram Moolenaar "else", "elsif", "end", "ensure", 236c6249bb2SBram Moolenaar "false", "for", 237c6249bb2SBram Moolenaar "if", "in", 238c6249bb2SBram Moolenaar "module", 239c6249bb2SBram Moolenaar "next", "nil", "not", 240c6249bb2SBram Moolenaar "or", 241c6249bb2SBram Moolenaar "redo", "rescue", "retry", "return", 242c6249bb2SBram Moolenaar "self", "super", 243c6249bb2SBram Moolenaar "then", "true", 244c6249bb2SBram Moolenaar "undef", "unless", "until", 245c6249bb2SBram Moolenaar "when", "while", 246c6249bb2SBram Moolenaar "yield", 247c6249bb2SBram Moolenaar ] 248c6249bb2SBram Moolenaar 2499964e468SBram Moolenaar @@Operators = [ "%", "&", "*", "**", "+", "-", "/", 250c6249bb2SBram Moolenaar "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>", 251c6249bb2SBram Moolenaar "[]", "[]=", "^", ] 2529964e468SBram Moolenaar# }}} constants 253c6249bb2SBram Moolenaar 2549964e468SBram Moolenaar# {{{ buffer analysis magic 255c6249bb2SBram Moolenaar def load_requires 256*d09091d4SBram Moolenaar 257*d09091d4SBram Moolenaar custom_paths = VIM::evaluate("get(g:, 'rubycomplete_load_paths', [])") 258*d09091d4SBram Moolenaar 259*d09091d4SBram Moolenaar if !custom_paths.empty? 260*d09091d4SBram Moolenaar $LOAD_PATH.concat(custom_paths).uniq! 261*d09091d4SBram Moolenaar end 262*d09091d4SBram Moolenaar 263eb3593b3SBram Moolenaar buf = VIM::Buffer.current 264eb3593b3SBram Moolenaar enum = buf.line_number 265c6249bb2SBram Moolenaar nums = Range.new( 1, enum ) 266c6249bb2SBram Moolenaar nums.each do |x| 267*d09091d4SBram Moolenaar 268eb3593b3SBram Moolenaar ln = buf[x] 269c6249bb2SBram Moolenaar begin 270*d09091d4SBram Moolenaar if /.*require_relative\s*(.*)$/.match( ln ) 271*d09091d4SBram Moolenaar eval( "require %s" % File.expand_path($1) ) 272*d09091d4SBram Moolenaar elsif /.*require\s*(["'].*?["'])/.match( ln ) 273*d09091d4SBram Moolenaar eval( "require %s" % $1 ) 274*d09091d4SBram Moolenaar end 275*d09091d4SBram Moolenaar rescue Exception => e 276*d09091d4SBram Moolenaar dprint e.inspect 277c6249bb2SBram Moolenaar end 278c6249bb2SBram Moolenaar end 279c6249bb2SBram Moolenaar end 280c6249bb2SBram Moolenaar 28189bcfda6SBram Moolenaar def load_gems 28289bcfda6SBram Moolenaar fpath = VIM::evaluate("get(g:, 'rubycomplete_gemfile_path', 'Gemfile')") 28389bcfda6SBram Moolenaar return unless File.file?(fpath) && File.readable?(fpath) 28489bcfda6SBram Moolenaar want_bundler = VIM::evaluate("get(g:, 'rubycomplete_use_bundler')") 28589bcfda6SBram Moolenaar parse_file = !want_bundler 28689bcfda6SBram Moolenaar begin 28789bcfda6SBram Moolenaar require 'bundler' 28889bcfda6SBram Moolenaar Bundler.setup 28989bcfda6SBram Moolenaar Bundler.require 29089bcfda6SBram Moolenaar rescue Exception 29189bcfda6SBram Moolenaar parse_file = true 29289bcfda6SBram Moolenaar end 29389bcfda6SBram Moolenaar if parse_file 29489bcfda6SBram Moolenaar File.new(fpath).each_line do |line| 29589bcfda6SBram Moolenaar begin 29689bcfda6SBram Moolenaar require $1 if /\s*gem\s*['"]([^'"]+)/.match(line) 29789bcfda6SBram Moolenaar rescue Exception 29889bcfda6SBram Moolenaar end 29989bcfda6SBram Moolenaar end 30089bcfda6SBram Moolenaar end 30189bcfda6SBram Moolenaar end 30289bcfda6SBram Moolenaar 303fc1421ebSBram Moolenaar def load_buffer_class(name) 3049964e468SBram Moolenaar dprint "load_buffer_class(%s) START" % name 3059964e468SBram Moolenaar classdef = get_buffer_entity(name, 's:GetBufferRubyClass("%s")') 306fc1421ebSBram Moolenaar return if classdef == nil 307fc1421ebSBram Moolenaar 308fc1421ebSBram Moolenaar pare = /^\s*class\s*(.*)\s*<\s*(.*)\s*\n/.match( classdef ) 3099964e468SBram Moolenaar load_buffer_class( $2 ) if pare != nil && $2 != name # load parent class if needed 310fc1421ebSBram Moolenaar 311ec7944aaSBram Moolenaar mixre = /.*\n\s*(include|prepend)\s*(.*)\s*\n/.match( classdef ) 3129964e468SBram Moolenaar load_buffer_module( $2 ) if mixre != nil && $2 != name # load mixins if needed 313fc1421ebSBram Moolenaar 3149964e468SBram Moolenaar begin 315fc1421ebSBram Moolenaar eval classdef 3169964e468SBram Moolenaar rescue Exception 3179964e468SBram Moolenaar VIM::evaluate( "s:ErrMsg( 'Problem loading class \"%s\", was it already completed?' )" % name ) 3189964e468SBram Moolenaar end 3199964e468SBram Moolenaar dprint "load_buffer_class(%s) END" % name 320fc1421ebSBram Moolenaar end 321fc1421ebSBram Moolenaar 322fc1421ebSBram Moolenaar def load_buffer_module(name) 3239964e468SBram Moolenaar dprint "load_buffer_module(%s) START" % name 3249964e468SBram Moolenaar classdef = get_buffer_entity(name, 's:GetBufferRubyModule("%s")') 325fc1421ebSBram Moolenaar return if classdef == nil 326fc1421ebSBram Moolenaar 3279964e468SBram Moolenaar begin 328fc1421ebSBram Moolenaar eval classdef 3299964e468SBram Moolenaar rescue Exception 3309964e468SBram Moolenaar VIM::evaluate( "s:ErrMsg( 'Problem loading module \"%s\", was it already completed?' )" % name ) 3319964e468SBram Moolenaar end 3329964e468SBram Moolenaar dprint "load_buffer_module(%s) END" % name 333fc1421ebSBram Moolenaar end 334fc1421ebSBram Moolenaar 335fc1421ebSBram Moolenaar def get_buffer_entity(name, vimfun) 3369964e468SBram Moolenaar loading_allowed = VIM::evaluate("exists('g:rubycomplete_buffer_loading') && g:rubycomplete_buffer_loading") 337c236c16dSBram Moolenaar return nil if loading_allowed.to_i.zero? 338d8fc5c0bSBram Moolenaar return nil if /(\"|\')+/.match( name ) 339eb3593b3SBram Moolenaar buf = VIM::Buffer.current 340fc1421ebSBram Moolenaar nums = eval( VIM::evaluate( vimfun % name ) ) 341fc1421ebSBram Moolenaar return nil if nums == nil 342fc1421ebSBram Moolenaar return nil if nums.min == nums.max && nums.min == 0 343fc1421ebSBram Moolenaar 3449964e468SBram Moolenaar dprint "get_buffer_entity START" 3459964e468SBram Moolenaar visited = [] 3469964e468SBram Moolenaar clscnt = 0 3479964e468SBram Moolenaar bufname = VIM::Buffer.current.name 348fc1421ebSBram Moolenaar classdef = "" 3499964e468SBram Moolenaar cur_line = VIM::Buffer.current.line_number 3509964e468SBram Moolenaar while (nums != nil && !(nums.min == 0 && nums.max == 0) ) 3519964e468SBram Moolenaar dprint "visited: %s" % visited.to_s 3529964e468SBram Moolenaar break if visited.index( nums ) 3539964e468SBram Moolenaar visited << nums 3549964e468SBram Moolenaar 355fc1421ebSBram Moolenaar nums.each do |x| 356fc1421ebSBram Moolenaar if x != cur_line 3579964e468SBram Moolenaar next if x == 0 358eb3593b3SBram Moolenaar ln = buf[x] 359*d09091d4SBram Moolenaar is_const = false 360*d09091d4SBram Moolenaar if /^\s*(module|class|def|include)\s+/.match(ln) || is_const = /^\s*?[A-Z]([A-z]|[1-9])*\s*?[|]{0,2}=\s*?.+\s*?/.match(ln) 361*d09091d4SBram Moolenaar clscnt += 1 if /class|module/.match($1) 362*d09091d4SBram Moolenaar # We must make sure to load each constant only once to avoid errors 363*d09091d4SBram Moolenaar if is_const 364*d09091d4SBram Moolenaar ln.gsub!(/\s*?[|]{0,2}=\s*?/, '||=') 365*d09091d4SBram Moolenaar end 3661d68952aSBram Moolenaar #dprint "\$1$1 367fc1421ebSBram Moolenaar classdef += "%s\n" % ln 3689964e468SBram Moolenaar classdef += "end\n" if /def\s+/.match(ln) 3699964e468SBram Moolenaar dprint ln 3709964e468SBram Moolenaar end 371fc1421ebSBram Moolenaar end 372fc1421ebSBram Moolenaar end 373fc1421ebSBram Moolenaar 3749964e468SBram Moolenaar nm = "%s(::.*)*\", %s, \"" % [ name, nums.last ] 3759964e468SBram Moolenaar nums = eval( VIM::evaluate( vimfun % nm ) ) 3769964e468SBram Moolenaar dprint "nm: \"%s\"" % nm 3779964e468SBram Moolenaar dprint "vimfun: %s" % (vimfun % nm) 3789964e468SBram Moolenaar dprint "got nums: %s" % nums.to_s 3799964e468SBram Moolenaar end 3809964e468SBram Moolenaar if classdef.length > 1 3819964e468SBram Moolenaar classdef += "end\n"*clscnt 3829964e468SBram Moolenaar # classdef = "class %s\n%s\nend\n" % [ bufname.gsub( /\/|\\/, "_" ), classdef ] 3839964e468SBram Moolenaar end 3849964e468SBram Moolenaar 3859964e468SBram Moolenaar dprint "get_buffer_entity END" 3869964e468SBram Moolenaar dprint "classdef====start" 3879964e468SBram Moolenaar lns = classdef.split( "\n" ) 3889964e468SBram Moolenaar lns.each { |x| dprint x } 3899964e468SBram Moolenaar dprint "classdef====end" 390fc1421ebSBram Moolenaar return classdef 391fc1421ebSBram Moolenaar end 392fc1421ebSBram Moolenaar 393d8fc5c0bSBram Moolenaar def get_var_type( receiver ) 394d8fc5c0bSBram Moolenaar if /(\"|\')+/.match( receiver ) 395d8fc5c0bSBram Moolenaar "String" 396d8fc5c0bSBram Moolenaar else 3979964e468SBram Moolenaar VIM::evaluate("s:GetRubyVarType('%s')" % receiver) 398d8fc5c0bSBram Moolenaar end 399d8fc5c0bSBram Moolenaar end 400d8fc5c0bSBram Moolenaar 4019964e468SBram Moolenaar def dprint( txt ) 4029964e468SBram Moolenaar print txt if @@debug 4039964e468SBram Moolenaar end 4049964e468SBram Moolenaar 405ec7944aaSBram Moolenaar def escape_vim_singlequote_string(str) 406ec7944aaSBram Moolenaar str.to_s.gsub(/'/,"\\'") 407ec7944aaSBram Moolenaar end 408ec7944aaSBram Moolenaar 4099964e468SBram Moolenaar def get_buffer_entity_list( type ) 410eb3593b3SBram Moolenaar # this will be a little expensive. 4119964e468SBram Moolenaar loading_allowed = VIM::evaluate("exists('g:rubycomplete_buffer_loading') && g:rubycomplete_buffer_loading") 4129964e468SBram Moolenaar allow_aggressive_load = VIM::evaluate("exists('g:rubycomplete_classes_in_global') && g:rubycomplete_classes_in_global") 413c236c16dSBram Moolenaar return [] if allow_aggressive_load.to_i.zero? || loading_allowed.to_i.zero? 414eb3593b3SBram Moolenaar 415eb3593b3SBram Moolenaar buf = VIM::Buffer.current 416eb3593b3SBram Moolenaar eob = buf.length 417eb3593b3SBram Moolenaar ret = [] 418eb3593b3SBram Moolenaar rg = 1..eob 4199964e468SBram Moolenaar re = eval( "/^\s*%s\s*([A-Za-z0-9_:-]*)(\s*<\s*([A-Za-z0-9_:-]*))?\s*/" % type ) 420eb3593b3SBram Moolenaar 421eb3593b3SBram Moolenaar rg.each do |x| 4229964e468SBram Moolenaar if re.match( buf[x] ) 4239964e468SBram Moolenaar next if type == "def" && eval( VIM::evaluate("s:IsPosInClassDef(%s)" % x) ) != nil 424eb3593b3SBram Moolenaar ret.push $1 425eb3593b3SBram Moolenaar end 426eb3593b3SBram Moolenaar end 427eb3593b3SBram Moolenaar 428eb3593b3SBram Moolenaar return ret 429eb3593b3SBram Moolenaar end 430eb3593b3SBram Moolenaar 4319964e468SBram Moolenaar def get_buffer_modules 4329964e468SBram Moolenaar return get_buffer_entity_list( "modules" ) 4339964e468SBram Moolenaar end 4349964e468SBram Moolenaar 4359964e468SBram Moolenaar def get_buffer_methods 4369964e468SBram Moolenaar return get_buffer_entity_list( "def" ) 4379964e468SBram Moolenaar end 4389964e468SBram Moolenaar 4399964e468SBram Moolenaar def get_buffer_classes 4409964e468SBram Moolenaar return get_buffer_entity_list( "class" ) 4419964e468SBram Moolenaar end 4429964e468SBram Moolenaar 4439964e468SBram Moolenaar def load_rails 4449964e468SBram Moolenaar allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails") 445c236c16dSBram Moolenaar return if allow_rails.to_i.zero? 446fc1421ebSBram Moolenaar 447fc1421ebSBram Moolenaar buf_path = VIM::evaluate('expand("%:p")') 448fc1421ebSBram Moolenaar file_name = VIM::evaluate('expand("%:t")') 4499964e468SBram Moolenaar vim_dir = VIM::evaluate('getcwd()') 4509964e468SBram Moolenaar file_dir = buf_path.gsub( file_name, '' ) 4519964e468SBram Moolenaar file_dir.gsub!( /\\/, "/" ) 4529964e468SBram Moolenaar vim_dir.gsub!( /\\/, "/" ) 4539964e468SBram Moolenaar vim_dir << "/" 4549964e468SBram Moolenaar dirs = [ vim_dir, file_dir ] 4559964e468SBram Moolenaar sdirs = [ "", "./", "../", "../../", "../../../", "../../../../" ] 4569964e468SBram Moolenaar rails_base = nil 457fc1421ebSBram Moolenaar 4589964e468SBram Moolenaar dirs.each do |dir| 4599964e468SBram Moolenaar sdirs.each do |sub| 4609964e468SBram Moolenaar trail = "%s%s" % [ dir, sub ] 4619964e468SBram Moolenaar tcfg = "%sconfig" % trail 4629964e468SBram Moolenaar 4639964e468SBram Moolenaar if File.exists?( tcfg ) 4649964e468SBram Moolenaar rails_base = trail 465fc1421ebSBram Moolenaar break 466fc1421ebSBram Moolenaar end 467fc1421ebSBram Moolenaar end 4689964e468SBram Moolenaar break if rails_base 4699964e468SBram Moolenaar end 470eb3593b3SBram Moolenaar 4719964e468SBram Moolenaar return if rails_base == nil 4729964e468SBram Moolenaar $:.push rails_base unless $:.index( rails_base ) 473551dbcc9SBram Moolenaar 4749964e468SBram Moolenaar rails_config = rails_base + "config/" 4759964e468SBram Moolenaar rails_lib = rails_base + "lib/" 4769964e468SBram Moolenaar $:.push rails_config unless $:.index( rails_config ) 4779964e468SBram Moolenaar $:.push rails_lib unless $:.index( rails_lib ) 4789964e468SBram Moolenaar 4799964e468SBram Moolenaar bootfile = rails_config + "boot.rb" 4809964e468SBram Moolenaar envfile = rails_config + "environment.rb" 481551dbcc9SBram Moolenaar if File.exists?( bootfile ) && File.exists?( envfile ) 482551dbcc9SBram Moolenaar begin 483eb3593b3SBram Moolenaar require bootfile 484551dbcc9SBram Moolenaar require envfile 4859964e468SBram Moolenaar begin 486551dbcc9SBram Moolenaar require 'console_app' 487551dbcc9SBram Moolenaar require 'console_with_helpers' 4889964e468SBram Moolenaar rescue Exception 4899964e468SBram Moolenaar dprint "Rails 1.1+ Error %s" % $! 4909964e468SBram Moolenaar # assume 1.0 4919964e468SBram Moolenaar end 4929964e468SBram Moolenaar #eval( "Rails::Initializer.run" ) #not necessary? 4939964e468SBram Moolenaar VIM::command('let s:rubycomplete_rails_loaded = 1') 4949964e468SBram Moolenaar dprint "rails loaded" 4959964e468SBram Moolenaar rescue Exception 4969964e468SBram Moolenaar dprint "Rails Error %s" % $! 4979964e468SBram Moolenaar VIM::evaluate( "s:ErrMsg('Error loading rails environment')" ) 498551dbcc9SBram Moolenaar end 499eb3593b3SBram Moolenaar end 500fc1421ebSBram Moolenaar end 501fc1421ebSBram Moolenaar 502fc1421ebSBram Moolenaar def get_rails_helpers 5039964e468SBram Moolenaar allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails") 5049964e468SBram Moolenaar rails_loaded = VIM::evaluate('s:rubycomplete_rails_loaded') 505c236c16dSBram Moolenaar return [] if allow_rails.to_i.zero? || rails_loaded.to_i.zero? 5069964e468SBram Moolenaar 5079964e468SBram Moolenaar buf_path = VIM::evaluate('expand("%:p")') 5089964e468SBram Moolenaar buf_path.gsub!( /\\/, "/" ) 5099964e468SBram Moolenaar path_elm = buf_path.split( "/" ) 5109964e468SBram Moolenaar dprint "buf_path: %s" % buf_path 5119964e468SBram Moolenaar types = [ "app", "db", "lib", "test", "components", "script" ] 5129964e468SBram Moolenaar 5139964e468SBram Moolenaar i = nil 5149964e468SBram Moolenaar ret = [] 5159964e468SBram Moolenaar type = nil 5169964e468SBram Moolenaar types.each do |t| 5179964e468SBram Moolenaar i = path_elm.index( t ) 5189964e468SBram Moolenaar break if i 5199964e468SBram Moolenaar end 5209964e468SBram Moolenaar type = path_elm[i] 5219964e468SBram Moolenaar type.downcase! 5229964e468SBram Moolenaar 5239964e468SBram Moolenaar dprint "type: %s" % type 5249964e468SBram Moolenaar case type 5259964e468SBram Moolenaar when "app" 5269964e468SBram Moolenaar i += 1 5279964e468SBram Moolenaar subtype = path_elm[i] 5289964e468SBram Moolenaar subtype.downcase! 5299964e468SBram Moolenaar 5309964e468SBram Moolenaar dprint "subtype: %s" % subtype 5319964e468SBram Moolenaar case subtype 5329964e468SBram Moolenaar when "views" 5339964e468SBram Moolenaar ret += ActionView::Base.instance_methods 5349964e468SBram Moolenaar ret += ActionView::Base.methods 5359964e468SBram Moolenaar when "controllers" 5369964e468SBram Moolenaar ret += ActionController::Base.instance_methods 5379964e468SBram Moolenaar ret += ActionController::Base.methods 5389964e468SBram Moolenaar when "models" 5399964e468SBram Moolenaar ret += ActiveRecord::Base.instance_methods 5409964e468SBram Moolenaar ret += ActiveRecord::Base.methods 5419964e468SBram Moolenaar end 5429964e468SBram Moolenaar 5439964e468SBram Moolenaar when "db" 5449964e468SBram Moolenaar ret += ActiveRecord::ConnectionAdapters::SchemaStatements.instance_methods 5459964e468SBram Moolenaar ret += ActiveRecord::ConnectionAdapters::SchemaStatements.methods 5469964e468SBram Moolenaar end 5479964e468SBram Moolenaar 5489964e468SBram Moolenaar return ret 5499964e468SBram Moolenaar end 5509964e468SBram Moolenaar 5519964e468SBram Moolenaar def add_rails_columns( cls ) 5529964e468SBram Moolenaar allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails") 5539964e468SBram Moolenaar rails_loaded = VIM::evaluate('s:rubycomplete_rails_loaded') 554c236c16dSBram Moolenaar return [] if allow_rails.to_i.zero? || rails_loaded.to_i.zero? 5559964e468SBram Moolenaar 5569964e468SBram Moolenaar begin 5579964e468SBram Moolenaar eval( "#{cls}.establish_connection" ) 5589964e468SBram Moolenaar return [] unless eval( "#{cls}.ancestors.include?(ActiveRecord::Base).to_s" ) 5599964e468SBram Moolenaar col = eval( "#{cls}.column_names" ) 5609964e468SBram Moolenaar return col if col 5619964e468SBram Moolenaar rescue 5629964e468SBram Moolenaar dprint "add_rails_columns err: (cls: %s) %s" % [ cls, $! ] 5639964e468SBram Moolenaar return [] 5649964e468SBram Moolenaar end 5659964e468SBram Moolenaar return [] 5669964e468SBram Moolenaar end 5679964e468SBram Moolenaar 5689964e468SBram Moolenaar def clean_sel(sel, msg) 569ec7944aaSBram Moolenaar ret = sel.reject{|x|x.nil?}.uniq 570ec7944aaSBram Moolenaar ret = ret.grep(/^#{Regexp.quote(msg)}/) if msg != nil 571ec7944aaSBram Moolenaar ret 5729964e468SBram Moolenaar end 5739964e468SBram Moolenaar 5749964e468SBram Moolenaar def get_rails_view_methods 5759964e468SBram Moolenaar allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails") 5769964e468SBram Moolenaar rails_loaded = VIM::evaluate('s:rubycomplete_rails_loaded') 577c236c16dSBram Moolenaar return [] if allow_rails.to_i.zero? || rails_loaded.to_i.zero? 5789964e468SBram Moolenaar 5799964e468SBram Moolenaar buf_path = VIM::evaluate('expand("%:p")') 5809964e468SBram Moolenaar buf_path.gsub!( /\\/, "/" ) 5819964e468SBram Moolenaar pelm = buf_path.split( "/" ) 5829964e468SBram Moolenaar idx = pelm.index( "views" ) 5839964e468SBram Moolenaar 5849964e468SBram Moolenaar return [] unless idx 5859964e468SBram Moolenaar idx += 1 5869964e468SBram Moolenaar 5879964e468SBram Moolenaar clspl = pelm[idx].camelize.pluralize 5889964e468SBram Moolenaar cls = clspl.singularize 5899964e468SBram Moolenaar 5909964e468SBram Moolenaar ret = [] 5919964e468SBram Moolenaar begin 5929964e468SBram Moolenaar ret += eval( "#{cls}.instance_methods" ) 5939964e468SBram Moolenaar ret += eval( "#{clspl}Helper.instance_methods" ) 5949964e468SBram Moolenaar rescue Exception 5959964e468SBram Moolenaar dprint "Error: Unable to load rails view helpers for %s: %s" % [ cls, $! ] 5969964e468SBram Moolenaar end 5979964e468SBram Moolenaar 5989964e468SBram Moolenaar return ret 5999964e468SBram Moolenaar end 6009964e468SBram Moolenaar# }}} buffer analysis magic 6019964e468SBram Moolenaar 6029964e468SBram Moolenaar# {{{ main completion code 6039964e468SBram Moolenaar def self.preload_rails 6049964e468SBram Moolenaar a = VimRubyCompletion.new 605*d09091d4SBram Moolenaar if VIM::evaluate("has('nvim')") == 0 606*d09091d4SBram Moolenaar require 'thread' 6079964e468SBram Moolenaar Thread.new(a) do |b| 6089964e468SBram Moolenaar begin 6099964e468SBram Moolenaar b.load_rails 6109964e468SBram Moolenaar rescue 6119964e468SBram Moolenaar end 6129964e468SBram Moolenaar end 613*d09091d4SBram Moolenaar end 6149964e468SBram Moolenaar a.load_rails 6159964e468SBram Moolenaar rescue 6169964e468SBram Moolenaar end 6179964e468SBram Moolenaar 6189964e468SBram Moolenaar def self.get_completions(base) 6199964e468SBram Moolenaar b = VimRubyCompletion.new 6209964e468SBram Moolenaar b.get_completions base 621fc1421ebSBram Moolenaar end 622fc1421ebSBram Moolenaar 623c6249bb2SBram Moolenaar def get_completions(base) 6249964e468SBram Moolenaar loading_allowed = VIM::evaluate("exists('g:rubycomplete_buffer_loading') && g:rubycomplete_buffer_loading") 625c236c16dSBram Moolenaar if loading_allowed.to_i == 1 626c6249bb2SBram Moolenaar load_requires 627fc1421ebSBram Moolenaar load_rails 6289964e468SBram Moolenaar end 629fc1421ebSBram Moolenaar 63089bcfda6SBram Moolenaar want_gems = VIM::evaluate("get(g:, 'rubycomplete_load_gemfile')") 63189bcfda6SBram Moolenaar load_gems unless want_gems.to_i.zero? 63289bcfda6SBram Moolenaar 633fc1421ebSBram Moolenaar input = VIM::Buffer.current.line 634d8fc5c0bSBram Moolenaar cpos = VIM::Window.current.cursor[1] - 1 6359964e468SBram Moolenaar input = input[0..cpos] 636d8fc5c0bSBram Moolenaar input += base 6379964e468SBram Moolenaar input.sub!(/.*[ \t\n\"\\'`><=;|&{(]/, '') # Readline.basic_word_break_characters 6389964e468SBram Moolenaar input.sub!(/self\./, '') 6399964e468SBram Moolenaar input.sub!(/.*((\.\.[\[(]?)|([\[(]))/, '') 640c6249bb2SBram Moolenaar 6419964e468SBram Moolenaar dprint 'input %s' % input 642d8fc5c0bSBram Moolenaar message = nil 643d8fc5c0bSBram Moolenaar receiver = nil 6449964e468SBram Moolenaar methods = [] 6459964e468SBram Moolenaar variables = [] 6469964e468SBram Moolenaar classes = [] 6479964e468SBram Moolenaar constants = [] 648c6249bb2SBram Moolenaar 649c6249bb2SBram Moolenaar case input 650d8fc5c0bSBram Moolenaar when /^(\/[^\/]*\/)\.([^.]*)$/ # Regexp 651c6249bb2SBram Moolenaar receiver = $1 652c6249bb2SBram Moolenaar message = Regexp.quote($2) 6539964e468SBram Moolenaar methods = Regexp.instance_methods(true) 654c6249bb2SBram Moolenaar 655d8fc5c0bSBram Moolenaar when /^([^\]]*\])\.([^.]*)$/ # Array 656c6249bb2SBram Moolenaar receiver = $1 657c6249bb2SBram Moolenaar message = Regexp.quote($2) 6589964e468SBram Moolenaar methods = Array.instance_methods(true) 659c6249bb2SBram Moolenaar 660d8fc5c0bSBram Moolenaar when /^([^\}]*\})\.([^.]*)$/ # Proc or Hash 661c6249bb2SBram Moolenaar receiver = $1 662c6249bb2SBram Moolenaar message = Regexp.quote($2) 6639964e468SBram Moolenaar methods = Proc.instance_methods(true) | Hash.instance_methods(true) 664c6249bb2SBram Moolenaar 665d8fc5c0bSBram Moolenaar when /^(:[^:.]*)$/ # Symbol 6669964e468SBram Moolenaar dprint "symbol" 667c6249bb2SBram Moolenaar if Symbol.respond_to?(:all_symbols) 668d8fc5c0bSBram Moolenaar receiver = $1 6699964e468SBram Moolenaar message = $1.sub( /:/, '' ) 6709964e468SBram Moolenaar methods = Symbol.all_symbols.collect{|s| s.id2name} 6719964e468SBram Moolenaar methods.delete_if { |c| c.match( /'/ ) } 672c6249bb2SBram Moolenaar end 673c6249bb2SBram Moolenaar 674d8fc5c0bSBram Moolenaar when /^::([A-Z][^:\.\(]*)$/ # Absolute Constant or class methods 6759964e468SBram Moolenaar dprint "const or cls" 676c6249bb2SBram Moolenaar receiver = $1 6779964e468SBram Moolenaar methods = Object.constants 6789964e468SBram Moolenaar methods.grep(/^#{receiver}/).collect{|e| "::" + e} 679c6249bb2SBram Moolenaar 6801d68952aSBram Moolenaar when /^(((::)?[A-Z][^:.\(]*)+?)::?([^:.]*)$/ # Constant or class methods 681c6249bb2SBram Moolenaar receiver = $1 682c6249bb2SBram Moolenaar message = Regexp.quote($4) 6839964e468SBram Moolenaar dprint "const or cls 2 [recv: \'%s\', msg: \'%s\']" % [ receiver, message ] 6849964e468SBram Moolenaar load_buffer_class( receiver ) 685*d09091d4SBram Moolenaar load_buffer_module( receiver ) 686c6249bb2SBram Moolenaar begin 6879964e468SBram Moolenaar classes = eval("#{receiver}.constants") 6889964e468SBram Moolenaar #methods = eval("#{receiver}.methods") 689c6249bb2SBram Moolenaar rescue Exception 6909964e468SBram Moolenaar dprint "exception: %s" % $! 6919964e468SBram Moolenaar methods = [] 692c6249bb2SBram Moolenaar end 6939964e468SBram Moolenaar methods.grep(/^#{message}/).collect{|e| receiver + "::" + e} 694c6249bb2SBram Moolenaar 695d8fc5c0bSBram Moolenaar when /^(:[^:.]+)\.([^.]*)$/ # Symbol 6969964e468SBram Moolenaar dprint "symbol" 697c6249bb2SBram Moolenaar receiver = $1 698c6249bb2SBram Moolenaar message = Regexp.quote($2) 6999964e468SBram Moolenaar methods = Symbol.instance_methods(true) 700c6249bb2SBram Moolenaar 701d8fc5c0bSBram Moolenaar when /^([0-9_]+(\.[0-9_]+)?(e[0-9]+)?)\.([^.]*)$/ # Numeric 7029964e468SBram Moolenaar dprint "numeric" 703c6249bb2SBram Moolenaar receiver = $1 704c6249bb2SBram Moolenaar message = Regexp.quote($4) 705c6249bb2SBram Moolenaar begin 7069964e468SBram Moolenaar methods = eval(receiver).methods 707c6249bb2SBram Moolenaar rescue Exception 7089964e468SBram Moolenaar methods = [] 709c6249bb2SBram Moolenaar end 710c6249bb2SBram Moolenaar 711d8fc5c0bSBram Moolenaar when /^(\$[^.]*)$/ #global 7129964e468SBram Moolenaar dprint "global" 7139964e468SBram Moolenaar methods = global_variables.grep(Regexp.new(Regexp.quote($1))) 714c6249bb2SBram Moolenaar 7151d68952aSBram Moolenaar when /^((\.?[^.]+)+?)\.([^.]*)$/ # variable 7169964e468SBram Moolenaar dprint "variable" 717c6249bb2SBram Moolenaar receiver = $1 718c6249bb2SBram Moolenaar message = Regexp.quote($3) 719fc1421ebSBram Moolenaar load_buffer_class( receiver ) 720c6249bb2SBram Moolenaar 721c6249bb2SBram Moolenaar cv = eval("self.class.constants") 722d8fc5c0bSBram Moolenaar vartype = get_var_type( receiver ) 7239964e468SBram Moolenaar dprint "vartype: %s" % vartype 72489bcfda6SBram Moolenaar 72589bcfda6SBram Moolenaar invalid_vartype = ['', "gets"] 72689bcfda6SBram Moolenaar if !invalid_vartype.include?(vartype) 727fc1421ebSBram Moolenaar load_buffer_class( vartype ) 728fc1421ebSBram Moolenaar 729fc1421ebSBram Moolenaar begin 7309964e468SBram Moolenaar methods = eval("#{vartype}.instance_methods") 7319964e468SBram Moolenaar variables = eval("#{vartype}.instance_variables") 732fc1421ebSBram Moolenaar rescue Exception 7339964e468SBram Moolenaar dprint "load_buffer_class err: %s" % $! 734fc1421ebSBram Moolenaar end 735c6249bb2SBram Moolenaar elsif (cv).include?(receiver) 736c6249bb2SBram Moolenaar # foo.func and foo is local var. 7379964e468SBram Moolenaar methods = eval("#{receiver}.methods") 7389964e468SBram Moolenaar vartype = receiver 739c6249bb2SBram Moolenaar elsif /^[A-Z]/ =~ receiver and /\./ !~ receiver 7409964e468SBram Moolenaar vartype = receiver 741c6249bb2SBram Moolenaar # Foo::Bar.func 742c6249bb2SBram Moolenaar begin 7439964e468SBram Moolenaar methods = eval("#{receiver}.methods") 744c6249bb2SBram Moolenaar rescue Exception 745c6249bb2SBram Moolenaar end 746c6249bb2SBram Moolenaar else 747c6249bb2SBram Moolenaar # func1.func2 748c6249bb2SBram Moolenaar ObjectSpace.each_object(Module){|m| 749c6249bb2SBram Moolenaar next if m.name != "IRB::Context" and 750c6249bb2SBram Moolenaar /^(IRB|SLex|RubyLex|RubyToken)/ =~ m.name 7519964e468SBram Moolenaar methods.concat m.instance_methods(false) 752c6249bb2SBram Moolenaar } 753c6249bb2SBram Moolenaar end 75489bcfda6SBram Moolenaar variables += add_rails_columns( "#{vartype}" ) if vartype && !invalid_vartype.include?(vartype) 755c6249bb2SBram Moolenaar 756d8fc5c0bSBram Moolenaar when /^\(?\s*[A-Za-z0-9:^@.%\/+*\(\)]+\.\.\.?[A-Za-z0-9:^@.%\/+*\(\)]+\s*\)?\.([^.]*)/ 757d8fc5c0bSBram Moolenaar message = $1 7589964e468SBram Moolenaar methods = Range.instance_methods(true) 759c6249bb2SBram Moolenaar 760d8fc5c0bSBram Moolenaar when /^\.([^.]*)$/ # unknown(maybe String) 761c6249bb2SBram Moolenaar message = Regexp.quote($1) 7629964e468SBram Moolenaar methods = String.instance_methods(true) 763c6249bb2SBram Moolenaar 764c6249bb2SBram Moolenaar else 7659964e468SBram Moolenaar dprint "default/other" 7669964e468SBram Moolenaar inclass = eval( VIM::evaluate("s:IsInClassDef()") ) 767c6249bb2SBram Moolenaar 768fc1421ebSBram Moolenaar if inclass != nil 7699964e468SBram Moolenaar dprint "inclass" 770fc1421ebSBram Moolenaar classdef = "%s\n" % VIM::Buffer.current[ inclass.min ] 771fc1421ebSBram Moolenaar found = /^\s*class\s*([A-Za-z0-9_-]*)(\s*<\s*([A-Za-z0-9_:-]*))?\s*\n$/.match( classdef ) 772fc1421ebSBram Moolenaar 773fc1421ebSBram Moolenaar if found != nil 774fc1421ebSBram Moolenaar receiver = $1 775fc1421ebSBram Moolenaar message = input 776fc1421ebSBram Moolenaar load_buffer_class( receiver ) 777eb3593b3SBram Moolenaar begin 7789964e468SBram Moolenaar methods = eval( "#{receiver}.instance_methods" ) 7799964e468SBram Moolenaar variables += add_rails_columns( "#{receiver}" ) 780eb3593b3SBram Moolenaar rescue Exception 781eb3593b3SBram Moolenaar found = nil 782eb3593b3SBram Moolenaar end 783fc1421ebSBram Moolenaar end 784fc1421ebSBram Moolenaar end 785fc1421ebSBram Moolenaar 786fc1421ebSBram Moolenaar if inclass == nil || found == nil 7879964e468SBram Moolenaar dprint "inclass == nil" 7889964e468SBram Moolenaar methods = get_buffer_methods 7899964e468SBram Moolenaar methods += get_rails_view_methods 7909964e468SBram Moolenaar 7919964e468SBram Moolenaar cls_const = Class.constants 7929964e468SBram Moolenaar constants = cls_const.select { |c| /^[A-Z_-]+$/.match( c ) } 7939964e468SBram Moolenaar classes = eval("self.class.constants") - constants 7949964e468SBram Moolenaar classes += get_buffer_classes 7959964e468SBram Moolenaar classes += get_buffer_modules 7969964e468SBram Moolenaar 7979964e468SBram Moolenaar include_objectspace = VIM::evaluate("exists('g:rubycomplete_include_objectspace') && g:rubycomplete_include_objectspace") 7989964e468SBram Moolenaar ObjectSpace.each_object(Class) { |cls| classes << cls.to_s } if include_objectspace == "1" 799d8fc5c0bSBram Moolenaar message = receiver = input 800d8fc5c0bSBram Moolenaar end 8019964e468SBram Moolenaar 8029964e468SBram Moolenaar methods += get_rails_helpers 8039964e468SBram Moolenaar methods += Kernel.public_methods 804d8fc5c0bSBram Moolenaar end 805d8fc5c0bSBram Moolenaar 8069964e468SBram Moolenaar include_object = VIM::evaluate("exists('g:rubycomplete_include_object') && g:rubycomplete_include_object") 8079964e468SBram Moolenaar methods = clean_sel( methods, message ) 8089964e468SBram Moolenaar methods = (methods-Object.instance_methods) if include_object == "0" 8099964e468SBram Moolenaar rbcmeth = (VimRubyCompletion.instance_methods-Object.instance_methods) # lets remove those rubycomplete methods 8109964e468SBram Moolenaar methods = (methods-rbcmeth) 8119964e468SBram Moolenaar 8129964e468SBram Moolenaar variables = clean_sel( variables, message ) 8139964e468SBram Moolenaar classes = clean_sel( classes, message ) - ["VimRubyCompletion"] 8149964e468SBram Moolenaar constants = clean_sel( constants, message ) 8159964e468SBram Moolenaar 8169964e468SBram Moolenaar valid = [] 817ec7944aaSBram Moolenaar valid += methods.collect { |m| { :name => m.to_s, :type => 'm' } } 818ec7944aaSBram Moolenaar valid += variables.collect { |v| { :name => v.to_s, :type => 'v' } } 819ec7944aaSBram Moolenaar valid += classes.collect { |c| { :name => c.to_s, :type => 't' } } 820ec7944aaSBram Moolenaar valid += constants.collect { |d| { :name => d.to_s, :type => 'd' } } 8219964e468SBram Moolenaar valid.sort! { |x,y| x[:name] <=> y[:name] } 822c6249bb2SBram Moolenaar 823c6249bb2SBram Moolenaar outp = "" 824fc1421ebSBram Moolenaar 825fc1421ebSBram Moolenaar rg = 0..valid.length 826fc1421ebSBram Moolenaar rg.step(150) do |x| 827fc1421ebSBram Moolenaar stpos = 0+x 828fc1421ebSBram Moolenaar enpos = 150+x 829ec7944aaSBram Moolenaar valid[stpos..enpos].each { |c| outp += "{'word':'%s','item':'%s','kind':'%s'}," % [ c[:name], c[:name], c[:type] ].map{|x|escape_vim_singlequote_string(x)} } 830c6249bb2SBram Moolenaar outp.sub!(/,$/, '') 831fc1421ebSBram Moolenaar 832fc1421ebSBram Moolenaar VIM::command("call extend(g:rubycomplete_completions, [%s])" % outp) 833fc1421ebSBram Moolenaar outp = "" 834fc1421ebSBram Moolenaar end 835c6249bb2SBram Moolenaar end 8369964e468SBram Moolenaar# }}} main completion code 837c6249bb2SBram Moolenaar 8389964e468SBram Moolenaarend # VimRubyCompletion 839eb3593b3SBram Moolenaar# }}} ruby completion 840c6249bb2SBram MoolenaarRUBYEOF 841c6249bb2SBram Moolenaarendfunction 842c6249bb2SBram Moolenaar 8439964e468SBram Moolenaarlet s:rubycomplete_rails_loaded = 0 844fc1421ebSBram Moolenaar 845c6249bb2SBram Moolenaarcall s:DefRuby() 8469964e468SBram Moolenaar"}}} ruby-side code 8479964e468SBram Moolenaar 8489964e468SBram Moolenaar" vim:tw=78:sw=4:ts=8:et:fdm=marker:ft=vim:norl: 849