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*4d8f4761SBram Moolenaar" Last Change: 2020 Apr 12 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 562ed639abSBram Moolenaar" {{{ regex patterns 572ed639abSBram Moolenaar 582ed639abSBram Moolenaar" Regex that defines the start-match for the 'end' keyword. 592ed639abSBram Moolenaarlet s:end_start_regex = 602ed639abSBram Moolenaar \ '\C\%(^\s*\|[=,*/%+\-|;{]\|<<\|>>\|:\s\)\s*\zs' . 612ed639abSBram Moolenaar \ '\<\%(module\|class\|if\|for\|while\|until\|case\|unless\|begin' . 622ed639abSBram Moolenaar \ '\|\%(\K\k*[!?]\?\s\+\)\=def\):\@!\>' . 632ed639abSBram Moolenaar \ '\|\%(^\|[^.:@$]\)\@<=\<do:\@!\>' 642ed639abSBram Moolenaar 652ed639abSBram Moolenaar" Regex that defines the middle-match for the 'end' keyword. 662ed639abSBram Moolenaarlet s:end_middle_regex = '\<\%(ensure\|else\|\%(\%(^\|;\)\s*\)\@<=\<rescue:\@!\>\|when\|elsif\):\@!\>' 672ed639abSBram Moolenaar 682ed639abSBram Moolenaar" Regex that defines the end-match for the 'end' keyword. 692ed639abSBram Moolenaarlet s:end_end_regex = '\%(^\|[^.:@$]\)\@<=\<end:\@!\>' 702ed639abSBram Moolenaar 712ed639abSBram Moolenaar" }}} regex patterns 722ed639abSBram Moolenaar 73eb3593b3SBram Moolenaar" {{{ vim-side support functions 749964e468SBram Moolenaarlet s:rubycomplete_debug = 0 759964e468SBram Moolenaar 769964e468SBram Moolenaarfunction! s:dprint(msg) 779964e468SBram Moolenaar if s:rubycomplete_debug == 1 789964e468SBram Moolenaar echom a:msg 799964e468SBram Moolenaar endif 809964e468SBram Moolenaarendfunction 819964e468SBram Moolenaar 829964e468SBram Moolenaarfunction! s:GetBufferRubyModule(name, ...) 839964e468SBram Moolenaar if a:0 == 1 849964e468SBram Moolenaar let [snum,enum] = s:GetBufferRubyEntity(a:name, "module", a:1) 859964e468SBram Moolenaar else 869964e468SBram Moolenaar let [snum,enum] = s:GetBufferRubyEntity(a:name, "module") 879964e468SBram Moolenaar endif 88fc1421ebSBram Moolenaar return snum . '..' . enum 89fc1421ebSBram Moolenaarendfunction 90fc1421ebSBram Moolenaar 919964e468SBram Moolenaarfunction! s:GetBufferRubyClass(name, ...) 929964e468SBram Moolenaar if a:0 >= 1 939964e468SBram Moolenaar let [snum,enum] = s:GetBufferRubyEntity(a:name, "class", a:1) 949964e468SBram Moolenaar else 959964e468SBram Moolenaar let [snum,enum] = s:GetBufferRubyEntity(a:name, "class") 969964e468SBram Moolenaar endif 97fc1421ebSBram Moolenaar return snum . '..' . enum 98fc1421ebSBram Moolenaarendfunction 99fc1421ebSBram Moolenaar 1009964e468SBram Moolenaarfunction! s:GetBufferRubySingletonMethods(name) 101fc1421ebSBram Moolenaarendfunction 102fc1421ebSBram Moolenaar 1039964e468SBram Moolenaarfunction! s:GetBufferRubyEntity( name, type, ... ) 1049964e468SBram Moolenaar let lastpos = getpos(".") 1059964e468SBram Moolenaar let lastline = lastpos 1069964e468SBram Moolenaar if (a:0 >= 1) 1079964e468SBram Moolenaar let lastline = [ 0, a:1, 0, 0 ] 1089964e468SBram Moolenaar call cursor( a:1, 0 ) 1099964e468SBram Moolenaar endif 1109964e468SBram Moolenaar 111fc1421ebSBram Moolenaar let stopline = 1 1129964e468SBram Moolenaar 11389bcfda6SBram Moolenaar let crex = '^\s*\<' . a:type . '\>\s*\<' . escape(a:name, '*') . '\>\s*\(<\s*.*\s*\)\?' 1149964e468SBram Moolenaar let [lnum,lcol] = searchpos( crex, 'w' ) 1159964e468SBram Moolenaar "let [lnum,lcol] = searchpairpos( crex . '\zs', '', '\(end\|}\)', 'w' ) 1169964e468SBram Moolenaar 117fc1421ebSBram Moolenaar if lnum == 0 && lcol == 0 1189964e468SBram Moolenaar call cursor(lastpos[1], lastpos[2]) 119fc1421ebSBram Moolenaar return [0,0] 120fc1421ebSBram Moolenaar endif 121fc1421ebSBram Moolenaar 1229964e468SBram Moolenaar let curpos = getpos(".") 1232ed639abSBram Moolenaar let [enum,ecol] = searchpairpos( s:end_start_regex, s:end_middle_regex, s:end_end_regex, 'W' ) 1249964e468SBram Moolenaar call cursor(lastpos[1], lastpos[2]) 1259964e468SBram Moolenaar 126fc1421ebSBram Moolenaar if lnum > enum 1279964e468SBram Moolenaar return [0,0] 128fc1421ebSBram Moolenaar endif 129fc1421ebSBram Moolenaar " we found a the class def 130fc1421ebSBram Moolenaar return [lnum,enum] 131fc1421ebSBram Moolenaarendfunction 132fc1421ebSBram Moolenaar 1339964e468SBram Moolenaarfunction! s:IsInClassDef() 1349964e468SBram Moolenaar return s:IsPosInClassDef( line('.') ) 1359964e468SBram Moolenaarendfunction 136fc1421ebSBram Moolenaar 1379964e468SBram Moolenaarfunction! s:IsPosInClassDef(pos) 1389964e468SBram Moolenaar let [snum,enum] = s:GetBufferRubyEntity( '.*', "class" ) 1399964e468SBram Moolenaar let ret = 'nil' 1409964e468SBram Moolenaar 1419964e468SBram Moolenaar if snum < a:pos && a:pos < enum 142fc1421ebSBram Moolenaar let ret = snum . '..' . enum 143fc1421ebSBram Moolenaar endif 144fc1421ebSBram Moolenaar 145fc1421ebSBram Moolenaar return ret 146fc1421ebSBram Moolenaarendfunction 147fc1421ebSBram Moolenaar 1482ed639abSBram Moolenaarfunction! s:IsInComment(pos) 1492ed639abSBram Moolenaar let stack = synstack(a:pos[0], a:pos[1]) 1502ed639abSBram Moolenaar if !empty(stack) 1512ed639abSBram Moolenaar return synIDattr(stack[0], 'name') =~ 'ruby\%(.*Comment\|Documentation\)' 1522ed639abSBram Moolenaar else 1532ed639abSBram Moolenaar return 0 1542ed639abSBram Moolenaar endif 1552ed639abSBram Moolenaarendfunction 1562ed639abSBram Moolenaar 1579964e468SBram Moolenaarfunction! s:GetRubyVarType(v) 158c6249bb2SBram Moolenaar let stopline = 1 159c6249bb2SBram Moolenaar let vtp = '' 1602ed639abSBram Moolenaar let curpos = getpos('.') 161ec7944aaSBram Moolenaar let sstr = '^\s*#\s*@var\s*'.escape(a:v, '*').'\>\s\+[^ \t]\+\s*$' 1629964e468SBram Moolenaar let [lnum,lcol] = searchpos(sstr,'nb',stopline) 163c6249bb2SBram Moolenaar if lnum != 0 && lcol != 0 1642ed639abSBram Moolenaar call setpos('.',curpos) 165c6249bb2SBram Moolenaar let str = getline(lnum) 1669964e468SBram Moolenaar let vtp = substitute(str,sstr,'\1','') 167c6249bb2SBram Moolenaar return vtp 168c6249bb2SBram Moolenaar endif 1692ed639abSBram Moolenaar call setpos('.',curpos) 1709964e468SBram Moolenaar let ctors = '\(now\|new\|open\|get_instance' 1719964e468SBram Moolenaar if exists('g:rubycomplete_rails') && g:rubycomplete_rails == 1 && s:rubycomplete_rails_loaded == 1 1729964e468SBram Moolenaar let ctors = ctors.'\|find\|create' 173551dbcc9SBram Moolenaar else 174551dbcc9SBram Moolenaar endif 1759964e468SBram Moolenaar let ctors = ctors.'\)' 176551dbcc9SBram Moolenaar 1779964e468SBram Moolenaar let fstr = '=\s*\([^ \t]\+.' . ctors .'\>\|[\[{"''/]\|%[xwQqr][(\[{@]\|[A-Za-z0-9@:\-()\.]\+...\?\|lambda\|&\)' 17889bcfda6SBram Moolenaar let sstr = ''.escape(a:v, '*').'\>\s*[+\-*/]*'.fstr 1792ed639abSBram Moolenaar let pos = searchpos(sstr,'bW') 1802ed639abSBram Moolenaar while pos != [0,0] && s:IsInComment(pos) 1812ed639abSBram Moolenaar let pos = searchpos(sstr,'bW') 1822ed639abSBram Moolenaar endwhile 1832ed639abSBram Moolenaar if pos != [0,0] 1842ed639abSBram Moolenaar let [lnum, col] = pos 1852ed639abSBram Moolenaar let str = matchstr(getline(lnum),fstr,col) 186c6249bb2SBram Moolenaar let str = substitute(str,'^=\s*','','') 1879964e468SBram Moolenaar 188c6249bb2SBram Moolenaar call setpos('.',pos) 1899964e468SBram Moolenaar if str == '"' || str == '''' || stridx(tolower(str), '%q[') != -1 190c6249bb2SBram Moolenaar return 'String' 1919964e468SBram Moolenaar elseif str == '[' || stridx(str, '%w[') != -1 192c6249bb2SBram Moolenaar return 'Array' 193c6249bb2SBram Moolenaar elseif str == '{' 194c6249bb2SBram Moolenaar return 'Hash' 195fc1421ebSBram Moolenaar elseif str == '/' || str == '%r{' 196fc1421ebSBram Moolenaar return 'Regexp' 197d8fc5c0bSBram Moolenaar elseif strlen(str) >= 4 && stridx(str,'..') != -1 198d8fc5c0bSBram Moolenaar return 'Range' 1999964e468SBram Moolenaar elseif stridx(str, 'lambda') != -1 || str == '&' 2009964e468SBram Moolenaar return 'Proc' 201c6249bb2SBram Moolenaar elseif strlen(str) > 4 202c6249bb2SBram Moolenaar let l = stridx(str,'.') 203c6249bb2SBram Moolenaar return str[0:l-1] 204c6249bb2SBram Moolenaar end 205c6249bb2SBram Moolenaar return '' 206c6249bb2SBram Moolenaar endif 2072ed639abSBram Moolenaar call setpos('.',curpos) 208c6249bb2SBram Moolenaar return '' 209fc1421ebSBram Moolenaarendfunction 210c6249bb2SBram Moolenaar 211eb3593b3SBram Moolenaar"}}} vim-side support functions 212eb3593b3SBram Moolenaar 2139964e468SBram Moolenaar"{{{ vim-side completion function 2149964e468SBram Moolenaarfunction! rubycomplete#Init() 2159964e468SBram Moolenaar execute "ruby VimRubyCompletion.preload_rails" 2169964e468SBram Moolenaarendfunction 2179964e468SBram Moolenaar 218c6249bb2SBram Moolenaarfunction! rubycomplete#Complete(findstart, base) 219c6249bb2SBram Moolenaar "findstart = 1 when we need to get the text length 220c6249bb2SBram Moolenaar if a:findstart 221c6249bb2SBram Moolenaar let line = getline('.') 222c6249bb2SBram Moolenaar let idx = col('.') 223c6249bb2SBram Moolenaar while idx > 0 224c6249bb2SBram Moolenaar let idx -= 1 225c6249bb2SBram Moolenaar let c = line[idx-1] 226c6249bb2SBram Moolenaar if c =~ '\w' 227c6249bb2SBram Moolenaar continue 228c6249bb2SBram Moolenaar elseif ! c =~ '\.' 2294575876dSBram Moolenaar let idx = -1 230c6249bb2SBram Moolenaar break 231c6249bb2SBram Moolenaar else 232c6249bb2SBram Moolenaar break 233c6249bb2SBram Moolenaar endif 234c6249bb2SBram Moolenaar endwhile 235c6249bb2SBram Moolenaar 236c6249bb2SBram Moolenaar return idx 237c6249bb2SBram Moolenaar "findstart = 0 when we need to return the list of completions 238c6249bb2SBram Moolenaar else 239fc1421ebSBram Moolenaar let g:rubycomplete_completions = [] 2409964e468SBram Moolenaar execute "ruby VimRubyCompletion.get_completions('" . a:base . "')" 241fc1421ebSBram Moolenaar return g:rubycomplete_completions 242c6249bb2SBram Moolenaar endif 243c6249bb2SBram Moolenaarendfunction 2449964e468SBram Moolenaar"}}} vim-side completion function 245c6249bb2SBram Moolenaar 2469964e468SBram Moolenaar"{{{ ruby-side code 247c6249bb2SBram Moolenaarfunction! s:DefRuby() 248c6249bb2SBram Moolenaarruby << RUBYEOF 249eb3593b3SBram Moolenaar# {{{ ruby completion 250fc1421ebSBram Moolenaar 2519964e468SBram Moolenaarbegin 2529964e468SBram Moolenaar require 'rubygems' # let's assume this is safe...? 2539964e468SBram Moolenaarrescue Exception 2549964e468SBram Moolenaar #ignore? 2559964e468SBram Moolenaarend 2569964e468SBram Moolenaarclass VimRubyCompletion 2579964e468SBram Moolenaar# {{{ constants 2589964e468SBram Moolenaar @@debug = false 2599964e468SBram Moolenaar @@ReservedWords = [ 260c6249bb2SBram Moolenaar "BEGIN", "END", 261c6249bb2SBram Moolenaar "alias", "and", 262c6249bb2SBram Moolenaar "begin", "break", 263c6249bb2SBram Moolenaar "case", "class", 264c6249bb2SBram Moolenaar "def", "defined", "do", 265c6249bb2SBram Moolenaar "else", "elsif", "end", "ensure", 266c6249bb2SBram Moolenaar "false", "for", 267c6249bb2SBram Moolenaar "if", "in", 268c6249bb2SBram Moolenaar "module", 269c6249bb2SBram Moolenaar "next", "nil", "not", 270c6249bb2SBram Moolenaar "or", 271c6249bb2SBram Moolenaar "redo", "rescue", "retry", "return", 272c6249bb2SBram Moolenaar "self", "super", 273c6249bb2SBram Moolenaar "then", "true", 274c6249bb2SBram Moolenaar "undef", "unless", "until", 275c6249bb2SBram Moolenaar "when", "while", 276c6249bb2SBram Moolenaar "yield", 277c6249bb2SBram Moolenaar ] 278c6249bb2SBram Moolenaar 2799964e468SBram Moolenaar @@Operators = [ "%", "&", "*", "**", "+", "-", "/", 280c6249bb2SBram Moolenaar "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>", 281c6249bb2SBram Moolenaar "[]", "[]=", "^", ] 2829964e468SBram Moolenaar# }}} constants 283c6249bb2SBram Moolenaar 2849964e468SBram Moolenaar# {{{ buffer analysis magic 285c6249bb2SBram Moolenaar def load_requires 286d09091d4SBram Moolenaar 287d09091d4SBram Moolenaar custom_paths = VIM::evaluate("get(g:, 'rubycomplete_load_paths', [])") 288d09091d4SBram Moolenaar 289d09091d4SBram Moolenaar if !custom_paths.empty? 290d09091d4SBram Moolenaar $LOAD_PATH.concat(custom_paths).uniq! 291d09091d4SBram Moolenaar end 292d09091d4SBram Moolenaar 293eb3593b3SBram Moolenaar buf = VIM::Buffer.current 294eb3593b3SBram Moolenaar enum = buf.line_number 295c6249bb2SBram Moolenaar nums = Range.new( 1, enum ) 296c6249bb2SBram Moolenaar nums.each do |x| 297d09091d4SBram Moolenaar 298eb3593b3SBram Moolenaar ln = buf[x] 299c6249bb2SBram Moolenaar begin 300d09091d4SBram Moolenaar if /.*require_relative\s*(.*)$/.match( ln ) 301d09091d4SBram Moolenaar eval( "require %s" % File.expand_path($1) ) 302d09091d4SBram Moolenaar elsif /.*require\s*(["'].*?["'])/.match( ln ) 303d09091d4SBram Moolenaar eval( "require %s" % $1 ) 304d09091d4SBram Moolenaar end 305d09091d4SBram Moolenaar rescue Exception => e 306d09091d4SBram Moolenaar dprint e.inspect 307c6249bb2SBram Moolenaar end 308c6249bb2SBram Moolenaar end 309c6249bb2SBram Moolenaar end 310c6249bb2SBram Moolenaar 31189bcfda6SBram Moolenaar def load_gems 31289bcfda6SBram Moolenaar fpath = VIM::evaluate("get(g:, 'rubycomplete_gemfile_path', 'Gemfile')") 31389bcfda6SBram Moolenaar return unless File.file?(fpath) && File.readable?(fpath) 31489bcfda6SBram Moolenaar want_bundler = VIM::evaluate("get(g:, 'rubycomplete_use_bundler')") 31589bcfda6SBram Moolenaar parse_file = !want_bundler 31689bcfda6SBram Moolenaar begin 31789bcfda6SBram Moolenaar require 'bundler' 31889bcfda6SBram Moolenaar Bundler.setup 31989bcfda6SBram Moolenaar Bundler.require 32089bcfda6SBram Moolenaar rescue Exception 32189bcfda6SBram Moolenaar parse_file = true 32289bcfda6SBram Moolenaar end 32389bcfda6SBram Moolenaar if parse_file 32489bcfda6SBram Moolenaar File.new(fpath).each_line do |line| 32589bcfda6SBram Moolenaar begin 32689bcfda6SBram Moolenaar require $1 if /\s*gem\s*['"]([^'"]+)/.match(line) 32789bcfda6SBram Moolenaar rescue Exception 32889bcfda6SBram Moolenaar end 32989bcfda6SBram Moolenaar end 33089bcfda6SBram Moolenaar end 33189bcfda6SBram Moolenaar end 33289bcfda6SBram Moolenaar 333fc1421ebSBram Moolenaar def load_buffer_class(name) 3349964e468SBram Moolenaar dprint "load_buffer_class(%s) START" % name 3359964e468SBram Moolenaar classdef = get_buffer_entity(name, 's:GetBufferRubyClass("%s")') 336fc1421ebSBram Moolenaar return if classdef == nil 337fc1421ebSBram Moolenaar 338fc1421ebSBram Moolenaar pare = /^\s*class\s*(.*)\s*<\s*(.*)\s*\n/.match( classdef ) 3399964e468SBram Moolenaar load_buffer_class( $2 ) if pare != nil && $2 != name # load parent class if needed 340fc1421ebSBram Moolenaar 341ec7944aaSBram Moolenaar mixre = /.*\n\s*(include|prepend)\s*(.*)\s*\n/.match( classdef ) 3429964e468SBram Moolenaar load_buffer_module( $2 ) if mixre != nil && $2 != name # load mixins if needed 343fc1421ebSBram Moolenaar 3449964e468SBram Moolenaar begin 345fc1421ebSBram Moolenaar eval classdef 3469964e468SBram Moolenaar rescue Exception 3479964e468SBram Moolenaar VIM::evaluate( "s:ErrMsg( 'Problem loading class \"%s\", was it already completed?' )" % name ) 3489964e468SBram Moolenaar end 3499964e468SBram Moolenaar dprint "load_buffer_class(%s) END" % name 350fc1421ebSBram Moolenaar end 351fc1421ebSBram Moolenaar 352fc1421ebSBram Moolenaar def load_buffer_module(name) 3539964e468SBram Moolenaar dprint "load_buffer_module(%s) START" % name 3549964e468SBram Moolenaar classdef = get_buffer_entity(name, 's:GetBufferRubyModule("%s")') 355fc1421ebSBram Moolenaar return if classdef == nil 356fc1421ebSBram Moolenaar 3579964e468SBram Moolenaar begin 358fc1421ebSBram Moolenaar eval classdef 3599964e468SBram Moolenaar rescue Exception 3609964e468SBram Moolenaar VIM::evaluate( "s:ErrMsg( 'Problem loading module \"%s\", was it already completed?' )" % name ) 3619964e468SBram Moolenaar end 3629964e468SBram Moolenaar dprint "load_buffer_module(%s) END" % name 363fc1421ebSBram Moolenaar end 364fc1421ebSBram Moolenaar 365fc1421ebSBram Moolenaar def get_buffer_entity(name, vimfun) 3669964e468SBram Moolenaar loading_allowed = VIM::evaluate("exists('g:rubycomplete_buffer_loading') && g:rubycomplete_buffer_loading") 367c236c16dSBram Moolenaar return nil if loading_allowed.to_i.zero? 368d8fc5c0bSBram Moolenaar return nil if /(\"|\')+/.match( name ) 369eb3593b3SBram Moolenaar buf = VIM::Buffer.current 370fc1421ebSBram Moolenaar nums = eval( VIM::evaluate( vimfun % name ) ) 371fc1421ebSBram Moolenaar return nil if nums == nil 372fc1421ebSBram Moolenaar return nil if nums.min == nums.max && nums.min == 0 373fc1421ebSBram Moolenaar 3749964e468SBram Moolenaar dprint "get_buffer_entity START" 3759964e468SBram Moolenaar visited = [] 3769964e468SBram Moolenaar clscnt = 0 3779964e468SBram Moolenaar bufname = VIM::Buffer.current.name 378fc1421ebSBram Moolenaar classdef = "" 3799964e468SBram Moolenaar cur_line = VIM::Buffer.current.line_number 3809964e468SBram Moolenaar while (nums != nil && !(nums.min == 0 && nums.max == 0) ) 3819964e468SBram Moolenaar dprint "visited: %s" % visited.to_s 3829964e468SBram Moolenaar break if visited.index( nums ) 3839964e468SBram Moolenaar visited << nums 3849964e468SBram Moolenaar 385fc1421ebSBram Moolenaar nums.each do |x| 386fc1421ebSBram Moolenaar if x != cur_line 3879964e468SBram Moolenaar next if x == 0 388eb3593b3SBram Moolenaar ln = buf[x] 389d09091d4SBram Moolenaar is_const = false 390d09091d4SBram 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) 391d09091d4SBram Moolenaar clscnt += 1 if /class|module/.match($1) 392d09091d4SBram Moolenaar # We must make sure to load each constant only once to avoid errors 393d09091d4SBram Moolenaar if is_const 394d09091d4SBram Moolenaar ln.gsub!(/\s*?[|]{0,2}=\s*?/, '||=') 395d09091d4SBram Moolenaar end 3961d68952aSBram Moolenaar #dprint "\$1$1 397fc1421ebSBram Moolenaar classdef += "%s\n" % ln 3989964e468SBram Moolenaar classdef += "end\n" if /def\s+/.match(ln) 3999964e468SBram Moolenaar dprint ln 4009964e468SBram Moolenaar end 401fc1421ebSBram Moolenaar end 402fc1421ebSBram Moolenaar end 403fc1421ebSBram Moolenaar 4049964e468SBram Moolenaar nm = "%s(::.*)*\", %s, \"" % [ name, nums.last ] 4059964e468SBram Moolenaar nums = eval( VIM::evaluate( vimfun % nm ) ) 4069964e468SBram Moolenaar dprint "nm: \"%s\"" % nm 4079964e468SBram Moolenaar dprint "vimfun: %s" % (vimfun % nm) 4089964e468SBram Moolenaar dprint "got nums: %s" % nums.to_s 4099964e468SBram Moolenaar end 4109964e468SBram Moolenaar if classdef.length > 1 4119964e468SBram Moolenaar classdef += "end\n"*clscnt 4129964e468SBram Moolenaar # classdef = "class %s\n%s\nend\n" % [ bufname.gsub( /\/|\\/, "_" ), classdef ] 4139964e468SBram Moolenaar end 4149964e468SBram Moolenaar 4159964e468SBram Moolenaar dprint "get_buffer_entity END" 4169964e468SBram Moolenaar dprint "classdef====start" 4179964e468SBram Moolenaar lns = classdef.split( "\n" ) 4189964e468SBram Moolenaar lns.each { |x| dprint x } 4199964e468SBram Moolenaar dprint "classdef====end" 420fc1421ebSBram Moolenaar return classdef 421fc1421ebSBram Moolenaar end 422fc1421ebSBram Moolenaar 423d8fc5c0bSBram Moolenaar def get_var_type( receiver ) 424d8fc5c0bSBram Moolenaar if /(\"|\')+/.match( receiver ) 425d8fc5c0bSBram Moolenaar "String" 426d8fc5c0bSBram Moolenaar else 4279964e468SBram Moolenaar VIM::evaluate("s:GetRubyVarType('%s')" % receiver) 428d8fc5c0bSBram Moolenaar end 429d8fc5c0bSBram Moolenaar end 430d8fc5c0bSBram Moolenaar 4319964e468SBram Moolenaar def dprint( txt ) 4329964e468SBram Moolenaar print txt if @@debug 4339964e468SBram Moolenaar end 4349964e468SBram Moolenaar 435ec7944aaSBram Moolenaar def escape_vim_singlequote_string(str) 436ec7944aaSBram Moolenaar str.to_s.gsub(/'/,"\\'") 437ec7944aaSBram Moolenaar end 438ec7944aaSBram Moolenaar 4399964e468SBram Moolenaar def get_buffer_entity_list( type ) 440eb3593b3SBram Moolenaar # this will be a little expensive. 4419964e468SBram Moolenaar loading_allowed = VIM::evaluate("exists('g:rubycomplete_buffer_loading') && g:rubycomplete_buffer_loading") 4429964e468SBram Moolenaar allow_aggressive_load = VIM::evaluate("exists('g:rubycomplete_classes_in_global') && g:rubycomplete_classes_in_global") 443c236c16dSBram Moolenaar return [] if allow_aggressive_load.to_i.zero? || loading_allowed.to_i.zero? 444eb3593b3SBram Moolenaar 445eb3593b3SBram Moolenaar buf = VIM::Buffer.current 446eb3593b3SBram Moolenaar eob = buf.length 447eb3593b3SBram Moolenaar ret = [] 448eb3593b3SBram Moolenaar rg = 1..eob 4499964e468SBram Moolenaar re = eval( "/^\s*%s\s*([A-Za-z0-9_:-]*)(\s*<\s*([A-Za-z0-9_:-]*))?\s*/" % type ) 450eb3593b3SBram Moolenaar 451eb3593b3SBram Moolenaar rg.each do |x| 4529964e468SBram Moolenaar if re.match( buf[x] ) 4539964e468SBram Moolenaar next if type == "def" && eval( VIM::evaluate("s:IsPosInClassDef(%s)" % x) ) != nil 454eb3593b3SBram Moolenaar ret.push $1 455eb3593b3SBram Moolenaar end 456eb3593b3SBram Moolenaar end 457eb3593b3SBram Moolenaar 458eb3593b3SBram Moolenaar return ret 459eb3593b3SBram Moolenaar end 460eb3593b3SBram Moolenaar 4619964e468SBram Moolenaar def get_buffer_modules 4629964e468SBram Moolenaar return get_buffer_entity_list( "modules" ) 4639964e468SBram Moolenaar end 4649964e468SBram Moolenaar 4659964e468SBram Moolenaar def get_buffer_methods 4669964e468SBram Moolenaar return get_buffer_entity_list( "def" ) 4679964e468SBram Moolenaar end 4689964e468SBram Moolenaar 4699964e468SBram Moolenaar def get_buffer_classes 4709964e468SBram Moolenaar return get_buffer_entity_list( "class" ) 4719964e468SBram Moolenaar end 4729964e468SBram Moolenaar 4739964e468SBram Moolenaar def load_rails 4749964e468SBram Moolenaar allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails") 475c236c16dSBram Moolenaar return if allow_rails.to_i.zero? 476fc1421ebSBram Moolenaar 477fc1421ebSBram Moolenaar buf_path = VIM::evaluate('expand("%:p")') 478fc1421ebSBram Moolenaar file_name = VIM::evaluate('expand("%:t")') 4799964e468SBram Moolenaar vim_dir = VIM::evaluate('getcwd()') 4809964e468SBram Moolenaar file_dir = buf_path.gsub( file_name, '' ) 4819964e468SBram Moolenaar file_dir.gsub!( /\\/, "/" ) 4829964e468SBram Moolenaar vim_dir.gsub!( /\\/, "/" ) 4839964e468SBram Moolenaar vim_dir << "/" 4849964e468SBram Moolenaar dirs = [ vim_dir, file_dir ] 4859964e468SBram Moolenaar sdirs = [ "", "./", "../", "../../", "../../../", "../../../../" ] 4869964e468SBram Moolenaar rails_base = nil 487fc1421ebSBram Moolenaar 4889964e468SBram Moolenaar dirs.each do |dir| 4899964e468SBram Moolenaar sdirs.each do |sub| 4909964e468SBram Moolenaar trail = "%s%s" % [ dir, sub ] 4919964e468SBram Moolenaar tcfg = "%sconfig" % trail 4929964e468SBram Moolenaar 4939964e468SBram Moolenaar if File.exists?( tcfg ) 4949964e468SBram Moolenaar rails_base = trail 495fc1421ebSBram Moolenaar break 496fc1421ebSBram Moolenaar end 497fc1421ebSBram Moolenaar end 4989964e468SBram Moolenaar break if rails_base 4999964e468SBram Moolenaar end 500eb3593b3SBram Moolenaar 5019964e468SBram Moolenaar return if rails_base == nil 5029964e468SBram Moolenaar $:.push rails_base unless $:.index( rails_base ) 503551dbcc9SBram Moolenaar 504*4d8f4761SBram Moolenaar bootfile = rails_base + "config/boot.rb" 505*4d8f4761SBram Moolenaar envfile = rails_base + "config/environment.rb" 506551dbcc9SBram Moolenaar if File.exists?( bootfile ) && File.exists?( envfile ) 507551dbcc9SBram Moolenaar begin 508eb3593b3SBram Moolenaar require bootfile 509551dbcc9SBram Moolenaar require envfile 5109964e468SBram Moolenaar begin 511551dbcc9SBram Moolenaar require 'console_app' 512551dbcc9SBram Moolenaar require 'console_with_helpers' 5139964e468SBram Moolenaar rescue Exception 5149964e468SBram Moolenaar dprint "Rails 1.1+ Error %s" % $! 5159964e468SBram Moolenaar # assume 1.0 5169964e468SBram Moolenaar end 5179964e468SBram Moolenaar #eval( "Rails::Initializer.run" ) #not necessary? 5189964e468SBram Moolenaar VIM::command('let s:rubycomplete_rails_loaded = 1') 5199964e468SBram Moolenaar dprint "rails loaded" 5209964e468SBram Moolenaar rescue Exception 5219964e468SBram Moolenaar dprint "Rails Error %s" % $! 5229964e468SBram Moolenaar VIM::evaluate( "s:ErrMsg('Error loading rails environment')" ) 523551dbcc9SBram Moolenaar end 524eb3593b3SBram Moolenaar end 525fc1421ebSBram Moolenaar end 526fc1421ebSBram Moolenaar 527fc1421ebSBram Moolenaar def get_rails_helpers 5289964e468SBram Moolenaar allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails") 5299964e468SBram Moolenaar rails_loaded = VIM::evaluate('s:rubycomplete_rails_loaded') 530c236c16dSBram Moolenaar return [] if allow_rails.to_i.zero? || rails_loaded.to_i.zero? 5319964e468SBram Moolenaar 5329964e468SBram Moolenaar buf_path = VIM::evaluate('expand("%:p")') 5339964e468SBram Moolenaar buf_path.gsub!( /\\/, "/" ) 5349964e468SBram Moolenaar path_elm = buf_path.split( "/" ) 5359964e468SBram Moolenaar dprint "buf_path: %s" % buf_path 5369964e468SBram Moolenaar types = [ "app", "db", "lib", "test", "components", "script" ] 5379964e468SBram Moolenaar 5389964e468SBram Moolenaar i = nil 5399964e468SBram Moolenaar ret = [] 5409964e468SBram Moolenaar type = nil 5419964e468SBram Moolenaar types.each do |t| 5429964e468SBram Moolenaar i = path_elm.index( t ) 5439964e468SBram Moolenaar break if i 5449964e468SBram Moolenaar end 5459964e468SBram Moolenaar type = path_elm[i] 5469964e468SBram Moolenaar type.downcase! 5479964e468SBram Moolenaar 5489964e468SBram Moolenaar dprint "type: %s" % type 5499964e468SBram Moolenaar case type 5509964e468SBram Moolenaar when "app" 5519964e468SBram Moolenaar i += 1 5529964e468SBram Moolenaar subtype = path_elm[i] 5539964e468SBram Moolenaar subtype.downcase! 5549964e468SBram Moolenaar 5559964e468SBram Moolenaar dprint "subtype: %s" % subtype 5569964e468SBram Moolenaar case subtype 5579964e468SBram Moolenaar when "views" 5589964e468SBram Moolenaar ret += ActionView::Base.instance_methods 5599964e468SBram Moolenaar ret += ActionView::Base.methods 5609964e468SBram Moolenaar when "controllers" 5619964e468SBram Moolenaar ret += ActionController::Base.instance_methods 5629964e468SBram Moolenaar ret += ActionController::Base.methods 5639964e468SBram Moolenaar when "models" 5649964e468SBram Moolenaar ret += ActiveRecord::Base.instance_methods 5659964e468SBram Moolenaar ret += ActiveRecord::Base.methods 5669964e468SBram Moolenaar end 5679964e468SBram Moolenaar 5689964e468SBram Moolenaar when "db" 5699964e468SBram Moolenaar ret += ActiveRecord::ConnectionAdapters::SchemaStatements.instance_methods 5709964e468SBram Moolenaar ret += ActiveRecord::ConnectionAdapters::SchemaStatements.methods 5719964e468SBram Moolenaar end 5729964e468SBram Moolenaar 5739964e468SBram Moolenaar return ret 5749964e468SBram Moolenaar end 5759964e468SBram Moolenaar 5769964e468SBram Moolenaar def add_rails_columns( cls ) 5779964e468SBram Moolenaar allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails") 5789964e468SBram Moolenaar rails_loaded = VIM::evaluate('s:rubycomplete_rails_loaded') 579c236c16dSBram Moolenaar return [] if allow_rails.to_i.zero? || rails_loaded.to_i.zero? 5809964e468SBram Moolenaar 5819964e468SBram Moolenaar begin 5829964e468SBram Moolenaar eval( "#{cls}.establish_connection" ) 5839964e468SBram Moolenaar return [] unless eval( "#{cls}.ancestors.include?(ActiveRecord::Base).to_s" ) 5849964e468SBram Moolenaar col = eval( "#{cls}.column_names" ) 5859964e468SBram Moolenaar return col if col 5869964e468SBram Moolenaar rescue 5879964e468SBram Moolenaar dprint "add_rails_columns err: (cls: %s) %s" % [ cls, $! ] 5889964e468SBram Moolenaar return [] 5899964e468SBram Moolenaar end 5909964e468SBram Moolenaar return [] 5919964e468SBram Moolenaar end 5929964e468SBram Moolenaar 5939964e468SBram Moolenaar def clean_sel(sel, msg) 594ec7944aaSBram Moolenaar ret = sel.reject{|x|x.nil?}.uniq 595ec7944aaSBram Moolenaar ret = ret.grep(/^#{Regexp.quote(msg)}/) if msg != nil 596ec7944aaSBram Moolenaar ret 5979964e468SBram Moolenaar end 5989964e468SBram Moolenaar 5999964e468SBram Moolenaar def get_rails_view_methods 6009964e468SBram Moolenaar allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails") 6019964e468SBram Moolenaar rails_loaded = VIM::evaluate('s:rubycomplete_rails_loaded') 602c236c16dSBram Moolenaar return [] if allow_rails.to_i.zero? || rails_loaded.to_i.zero? 6039964e468SBram Moolenaar 6049964e468SBram Moolenaar buf_path = VIM::evaluate('expand("%:p")') 6059964e468SBram Moolenaar buf_path.gsub!( /\\/, "/" ) 6069964e468SBram Moolenaar pelm = buf_path.split( "/" ) 6079964e468SBram Moolenaar idx = pelm.index( "views" ) 6089964e468SBram Moolenaar 6099964e468SBram Moolenaar return [] unless idx 6109964e468SBram Moolenaar idx += 1 6119964e468SBram Moolenaar 6129964e468SBram Moolenaar clspl = pelm[idx].camelize.pluralize 6139964e468SBram Moolenaar cls = clspl.singularize 6149964e468SBram Moolenaar 6159964e468SBram Moolenaar ret = [] 6169964e468SBram Moolenaar begin 6179964e468SBram Moolenaar ret += eval( "#{cls}.instance_methods" ) 6189964e468SBram Moolenaar ret += eval( "#{clspl}Helper.instance_methods" ) 6199964e468SBram Moolenaar rescue Exception 6209964e468SBram Moolenaar dprint "Error: Unable to load rails view helpers for %s: %s" % [ cls, $! ] 6219964e468SBram Moolenaar end 6229964e468SBram Moolenaar 6239964e468SBram Moolenaar return ret 6249964e468SBram Moolenaar end 6259964e468SBram Moolenaar# }}} buffer analysis magic 6269964e468SBram Moolenaar 6279964e468SBram Moolenaar# {{{ main completion code 6289964e468SBram Moolenaar def self.preload_rails 6299964e468SBram Moolenaar a = VimRubyCompletion.new 630d09091d4SBram Moolenaar if VIM::evaluate("has('nvim')") == 0 631d09091d4SBram Moolenaar require 'thread' 6329964e468SBram Moolenaar Thread.new(a) do |b| 6339964e468SBram Moolenaar begin 6349964e468SBram Moolenaar b.load_rails 6359964e468SBram Moolenaar rescue 6369964e468SBram Moolenaar end 6379964e468SBram Moolenaar end 638d09091d4SBram Moolenaar end 6399964e468SBram Moolenaar a.load_rails 6409964e468SBram Moolenaar rescue 6419964e468SBram Moolenaar end 6429964e468SBram Moolenaar 6439964e468SBram Moolenaar def self.get_completions(base) 6449964e468SBram Moolenaar b = VimRubyCompletion.new 6459964e468SBram Moolenaar b.get_completions base 646fc1421ebSBram Moolenaar end 647fc1421ebSBram Moolenaar 648c6249bb2SBram Moolenaar def get_completions(base) 6499964e468SBram Moolenaar loading_allowed = VIM::evaluate("exists('g:rubycomplete_buffer_loading') && g:rubycomplete_buffer_loading") 650c236c16dSBram Moolenaar if loading_allowed.to_i == 1 651c6249bb2SBram Moolenaar load_requires 652fc1421ebSBram Moolenaar load_rails 6539964e468SBram Moolenaar end 654fc1421ebSBram Moolenaar 65589bcfda6SBram Moolenaar want_gems = VIM::evaluate("get(g:, 'rubycomplete_load_gemfile')") 65689bcfda6SBram Moolenaar load_gems unless want_gems.to_i.zero? 65789bcfda6SBram Moolenaar 658fc1421ebSBram Moolenaar input = VIM::Buffer.current.line 659d8fc5c0bSBram Moolenaar cpos = VIM::Window.current.cursor[1] - 1 6609964e468SBram Moolenaar input = input[0..cpos] 661d8fc5c0bSBram Moolenaar input += base 6629964e468SBram Moolenaar input.sub!(/.*[ \t\n\"\\'`><=;|&{(]/, '') # Readline.basic_word_break_characters 6639964e468SBram Moolenaar input.sub!(/self\./, '') 6649964e468SBram Moolenaar input.sub!(/.*((\.\.[\[(]?)|([\[(]))/, '') 665c6249bb2SBram Moolenaar 6669964e468SBram Moolenaar dprint 'input %s' % input 667d8fc5c0bSBram Moolenaar message = nil 668d8fc5c0bSBram Moolenaar receiver = nil 6699964e468SBram Moolenaar methods = [] 6709964e468SBram Moolenaar variables = [] 6719964e468SBram Moolenaar classes = [] 6729964e468SBram Moolenaar constants = [] 673c6249bb2SBram Moolenaar 674c6249bb2SBram Moolenaar case input 675d8fc5c0bSBram Moolenaar when /^(\/[^\/]*\/)\.([^.]*)$/ # Regexp 676c6249bb2SBram Moolenaar receiver = $1 677c6249bb2SBram Moolenaar message = Regexp.quote($2) 6789964e468SBram Moolenaar methods = Regexp.instance_methods(true) 679c6249bb2SBram Moolenaar 680d8fc5c0bSBram Moolenaar when /^([^\]]*\])\.([^.]*)$/ # Array 681c6249bb2SBram Moolenaar receiver = $1 682c6249bb2SBram Moolenaar message = Regexp.quote($2) 6839964e468SBram Moolenaar methods = Array.instance_methods(true) 684c6249bb2SBram Moolenaar 685d8fc5c0bSBram Moolenaar when /^([^\}]*\})\.([^.]*)$/ # Proc or Hash 686c6249bb2SBram Moolenaar receiver = $1 687c6249bb2SBram Moolenaar message = Regexp.quote($2) 6889964e468SBram Moolenaar methods = Proc.instance_methods(true) | Hash.instance_methods(true) 689c6249bb2SBram Moolenaar 690d8fc5c0bSBram Moolenaar when /^(:[^:.]*)$/ # Symbol 6919964e468SBram Moolenaar dprint "symbol" 692c6249bb2SBram Moolenaar if Symbol.respond_to?(:all_symbols) 693d8fc5c0bSBram Moolenaar receiver = $1 6949964e468SBram Moolenaar message = $1.sub( /:/, '' ) 6959964e468SBram Moolenaar methods = Symbol.all_symbols.collect{|s| s.id2name} 6969964e468SBram Moolenaar methods.delete_if { |c| c.match( /'/ ) } 697c6249bb2SBram Moolenaar end 698c6249bb2SBram Moolenaar 6992ed639abSBram Moolenaar when /^::([A-Z][^:\.\(]*)?$/ # Absolute Constant or class methods 7009964e468SBram Moolenaar dprint "const or cls" 701c6249bb2SBram Moolenaar receiver = $1 7022ed639abSBram Moolenaar methods = Object.constants.collect{ |c| c.to_s }.grep(/^#{receiver}/) 703c6249bb2SBram Moolenaar 7041d68952aSBram Moolenaar when /^(((::)?[A-Z][^:.\(]*)+?)::?([^:.]*)$/ # Constant or class methods 705c6249bb2SBram Moolenaar receiver = $1 706c6249bb2SBram Moolenaar message = Regexp.quote($4) 7079964e468SBram Moolenaar dprint "const or cls 2 [recv: \'%s\', msg: \'%s\']" % [ receiver, message ] 7089964e468SBram Moolenaar load_buffer_class( receiver ) 709d09091d4SBram Moolenaar load_buffer_module( receiver ) 710c6249bb2SBram Moolenaar begin 7112ed639abSBram Moolenaar constants = eval("#{receiver}.constants").collect{ |c| c.to_s }.grep(/^#{message}/) 7122ed639abSBram Moolenaar methods = eval("#{receiver}.methods").collect{ |m| m.to_s }.grep(/^#{message}/) 713c6249bb2SBram Moolenaar rescue Exception 7149964e468SBram Moolenaar dprint "exception: %s" % $! 7152ed639abSBram Moolenaar constants = [] 7169964e468SBram Moolenaar methods = [] 717c6249bb2SBram Moolenaar end 718c6249bb2SBram Moolenaar 719d8fc5c0bSBram Moolenaar when /^(:[^:.]+)\.([^.]*)$/ # Symbol 7209964e468SBram Moolenaar dprint "symbol" 721c6249bb2SBram Moolenaar receiver = $1 722c6249bb2SBram Moolenaar message = Regexp.quote($2) 7239964e468SBram Moolenaar methods = Symbol.instance_methods(true) 724c6249bb2SBram Moolenaar 725d8fc5c0bSBram Moolenaar when /^([0-9_]+(\.[0-9_]+)?(e[0-9]+)?)\.([^.]*)$/ # Numeric 7269964e468SBram Moolenaar dprint "numeric" 727c6249bb2SBram Moolenaar receiver = $1 728c6249bb2SBram Moolenaar message = Regexp.quote($4) 729c6249bb2SBram Moolenaar begin 7309964e468SBram Moolenaar methods = eval(receiver).methods 731c6249bb2SBram Moolenaar rescue Exception 7329964e468SBram Moolenaar methods = [] 733c6249bb2SBram Moolenaar end 734c6249bb2SBram Moolenaar 735d8fc5c0bSBram Moolenaar when /^(\$[^.]*)$/ #global 7369964e468SBram Moolenaar dprint "global" 7379964e468SBram Moolenaar methods = global_variables.grep(Regexp.new(Regexp.quote($1))) 738c6249bb2SBram Moolenaar 7391d68952aSBram Moolenaar when /^((\.?[^.]+)+?)\.([^.]*)$/ # variable 7409964e468SBram Moolenaar dprint "variable" 741c6249bb2SBram Moolenaar receiver = $1 742c6249bb2SBram Moolenaar message = Regexp.quote($3) 743fc1421ebSBram Moolenaar load_buffer_class( receiver ) 744c6249bb2SBram Moolenaar 745c6249bb2SBram Moolenaar cv = eval("self.class.constants") 746d8fc5c0bSBram Moolenaar vartype = get_var_type( receiver ) 7479964e468SBram Moolenaar dprint "vartype: %s" % vartype 74889bcfda6SBram Moolenaar 74989bcfda6SBram Moolenaar invalid_vartype = ['', "gets"] 75089bcfda6SBram Moolenaar if !invalid_vartype.include?(vartype) 751fc1421ebSBram Moolenaar load_buffer_class( vartype ) 752fc1421ebSBram Moolenaar 753fc1421ebSBram Moolenaar begin 7549964e468SBram Moolenaar methods = eval("#{vartype}.instance_methods") 7559964e468SBram Moolenaar variables = eval("#{vartype}.instance_variables") 756fc1421ebSBram Moolenaar rescue Exception 7579964e468SBram Moolenaar dprint "load_buffer_class err: %s" % $! 758fc1421ebSBram Moolenaar end 759c6249bb2SBram Moolenaar elsif (cv).include?(receiver) 760c6249bb2SBram Moolenaar # foo.func and foo is local var. 7619964e468SBram Moolenaar methods = eval("#{receiver}.methods") 7629964e468SBram Moolenaar vartype = receiver 763c6249bb2SBram Moolenaar elsif /^[A-Z]/ =~ receiver and /\./ !~ receiver 7649964e468SBram Moolenaar vartype = receiver 765c6249bb2SBram Moolenaar # Foo::Bar.func 766c6249bb2SBram Moolenaar begin 7679964e468SBram Moolenaar methods = eval("#{receiver}.methods") 768c6249bb2SBram Moolenaar rescue Exception 769c6249bb2SBram Moolenaar end 770c6249bb2SBram Moolenaar else 771c6249bb2SBram Moolenaar # func1.func2 772c6249bb2SBram Moolenaar ObjectSpace.each_object(Module){|m| 773c6249bb2SBram Moolenaar next if m.name != "IRB::Context" and 774c6249bb2SBram Moolenaar /^(IRB|SLex|RubyLex|RubyToken)/ =~ m.name 7759964e468SBram Moolenaar methods.concat m.instance_methods(false) 776c6249bb2SBram Moolenaar } 777c6249bb2SBram Moolenaar end 77889bcfda6SBram Moolenaar variables += add_rails_columns( "#{vartype}" ) if vartype && !invalid_vartype.include?(vartype) 779c6249bb2SBram Moolenaar 780d8fc5c0bSBram Moolenaar when /^\(?\s*[A-Za-z0-9:^@.%\/+*\(\)]+\.\.\.?[A-Za-z0-9:^@.%\/+*\(\)]+\s*\)?\.([^.]*)/ 781d8fc5c0bSBram Moolenaar message = $1 7829964e468SBram Moolenaar methods = Range.instance_methods(true) 783c6249bb2SBram Moolenaar 784d8fc5c0bSBram Moolenaar when /^\.([^.]*)$/ # unknown(maybe String) 785c6249bb2SBram Moolenaar message = Regexp.quote($1) 7869964e468SBram Moolenaar methods = String.instance_methods(true) 787c6249bb2SBram Moolenaar 788c6249bb2SBram Moolenaar else 7899964e468SBram Moolenaar dprint "default/other" 7909964e468SBram Moolenaar inclass = eval( VIM::evaluate("s:IsInClassDef()") ) 791c6249bb2SBram Moolenaar 792fc1421ebSBram Moolenaar if inclass != nil 7939964e468SBram Moolenaar dprint "inclass" 794fc1421ebSBram Moolenaar classdef = "%s\n" % VIM::Buffer.current[ inclass.min ] 795fc1421ebSBram Moolenaar found = /^\s*class\s*([A-Za-z0-9_-]*)(\s*<\s*([A-Za-z0-9_:-]*))?\s*\n$/.match( classdef ) 796fc1421ebSBram Moolenaar 797fc1421ebSBram Moolenaar if found != nil 798fc1421ebSBram Moolenaar receiver = $1 799fc1421ebSBram Moolenaar message = input 800fc1421ebSBram Moolenaar load_buffer_class( receiver ) 801eb3593b3SBram Moolenaar begin 8029964e468SBram Moolenaar methods = eval( "#{receiver}.instance_methods" ) 8039964e468SBram Moolenaar variables += add_rails_columns( "#{receiver}" ) 804eb3593b3SBram Moolenaar rescue Exception 805eb3593b3SBram Moolenaar found = nil 806eb3593b3SBram Moolenaar end 807fc1421ebSBram Moolenaar end 808fc1421ebSBram Moolenaar end 809fc1421ebSBram Moolenaar 810fc1421ebSBram Moolenaar if inclass == nil || found == nil 8119964e468SBram Moolenaar dprint "inclass == nil" 8129964e468SBram Moolenaar methods = get_buffer_methods 8139964e468SBram Moolenaar methods += get_rails_view_methods 8149964e468SBram Moolenaar 8159964e468SBram Moolenaar cls_const = Class.constants 8169964e468SBram Moolenaar constants = cls_const.select { |c| /^[A-Z_-]+$/.match( c ) } 8179964e468SBram Moolenaar classes = eval("self.class.constants") - constants 8189964e468SBram Moolenaar classes += get_buffer_classes 8199964e468SBram Moolenaar classes += get_buffer_modules 8209964e468SBram Moolenaar 8219964e468SBram Moolenaar include_objectspace = VIM::evaluate("exists('g:rubycomplete_include_objectspace') && g:rubycomplete_include_objectspace") 8229964e468SBram Moolenaar ObjectSpace.each_object(Class) { |cls| classes << cls.to_s } if include_objectspace == "1" 823d8fc5c0bSBram Moolenaar message = receiver = input 824d8fc5c0bSBram Moolenaar end 8259964e468SBram Moolenaar 8269964e468SBram Moolenaar methods += get_rails_helpers 8279964e468SBram Moolenaar methods += Kernel.public_methods 828d8fc5c0bSBram Moolenaar end 829d8fc5c0bSBram Moolenaar 8309964e468SBram Moolenaar include_object = VIM::evaluate("exists('g:rubycomplete_include_object') && g:rubycomplete_include_object") 8319964e468SBram Moolenaar methods = clean_sel( methods, message ) 8329964e468SBram Moolenaar methods = (methods-Object.instance_methods) if include_object == "0" 8339964e468SBram Moolenaar rbcmeth = (VimRubyCompletion.instance_methods-Object.instance_methods) # lets remove those rubycomplete methods 8349964e468SBram Moolenaar methods = (methods-rbcmeth) 8359964e468SBram Moolenaar 8369964e468SBram Moolenaar variables = clean_sel( variables, message ) 8379964e468SBram Moolenaar classes = clean_sel( classes, message ) - ["VimRubyCompletion"] 8389964e468SBram Moolenaar constants = clean_sel( constants, message ) 8399964e468SBram Moolenaar 8409964e468SBram Moolenaar valid = [] 841ec7944aaSBram Moolenaar valid += methods.collect { |m| { :name => m.to_s, :type => 'm' } } 842ec7944aaSBram Moolenaar valid += variables.collect { |v| { :name => v.to_s, :type => 'v' } } 843ec7944aaSBram Moolenaar valid += classes.collect { |c| { :name => c.to_s, :type => 't' } } 844ec7944aaSBram Moolenaar valid += constants.collect { |d| { :name => d.to_s, :type => 'd' } } 8459964e468SBram Moolenaar valid.sort! { |x,y| x[:name] <=> y[:name] } 846c6249bb2SBram Moolenaar 847c6249bb2SBram Moolenaar outp = "" 848fc1421ebSBram Moolenaar 849fc1421ebSBram Moolenaar rg = 0..valid.length 850fc1421ebSBram Moolenaar rg.step(150) do |x| 851fc1421ebSBram Moolenaar stpos = 0+x 852fc1421ebSBram Moolenaar enpos = 150+x 853ec7944aaSBram 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)} } 854c6249bb2SBram Moolenaar outp.sub!(/,$/, '') 855fc1421ebSBram Moolenaar 856fc1421ebSBram Moolenaar VIM::command("call extend(g:rubycomplete_completions, [%s])" % outp) 857fc1421ebSBram Moolenaar outp = "" 858fc1421ebSBram Moolenaar end 859c6249bb2SBram Moolenaar end 8609964e468SBram Moolenaar# }}} main completion code 861c6249bb2SBram Moolenaar 8629964e468SBram Moolenaarend # VimRubyCompletion 863eb3593b3SBram Moolenaar# }}} ruby completion 864c6249bb2SBram MoolenaarRUBYEOF 865c6249bb2SBram Moolenaarendfunction 866c6249bb2SBram Moolenaar 8679964e468SBram Moolenaarlet s:rubycomplete_rails_loaded = 0 868fc1421ebSBram Moolenaar 869c6249bb2SBram Moolenaarcall s:DefRuby() 8709964e468SBram Moolenaar"}}} ruby-side code 8719964e468SBram Moolenaar 8729964e468SBram Moolenaar" vim:tw=78:sw=4:ts=8:et:fdm=marker:ft=vim:norl: 873