xref: /vim-8.2.3635/runtime/ftplugin/ruby.vim (revision ec7944aa)
1071d4279SBram Moolenaar" Vim filetype plugin
2071d4279SBram Moolenaar" Language:		Ruby
3*ec7944aaSBram Moolenaar" Maintainer:		Tim Pope <[email protected]>
4*ec7944aaSBram Moolenaar" URL:			https://github.com/vim-ruby/vim-ruby
5c6249bb2SBram Moolenaar" Release Coordinator:  Doug Kearns <[email protected]>
660a795aaSBram Moolenaar" ----------------------------------------------------------------------------
7071d4279SBram Moolenaar
8071d4279SBram Moolenaarif (exists("b:did_ftplugin"))
9071d4279SBram Moolenaar  finish
10071d4279SBram Moolenaarendif
11071d4279SBram Moolenaarlet b:did_ftplugin = 1
12071d4279SBram Moolenaar
1360a795aaSBram Moolenaarlet s:cpo_save = &cpo
1460a795aaSBram Moolenaarset cpo&vim
1560a795aaSBram Moolenaar
16756ec0f3SBram Moolenaarif has("gui_running") && !has("gui_win32")
17*ec7944aaSBram Moolenaar  setlocal keywordprg=ri\ -T\ -f\ bs
18756ec0f3SBram Moolenaarelse
19756ec0f3SBram Moolenaar  setlocal keywordprg=ri
20756ec0f3SBram Moolenaarendif
21756ec0f3SBram Moolenaar
2260a795aaSBram Moolenaar" Matchit support
2360a795aaSBram Moolenaarif exists("loaded_matchit") && !exists("b:match_words")
2460a795aaSBram Moolenaar  let b:match_ignorecase = 0
2560a795aaSBram Moolenaar
2660a795aaSBram Moolenaar  let b:match_words =
2779166c43SBram Moolenaar	\ '\<\%(if\|unless\|case\|while\|until\|for\|do\|class\|module\|def\|begin\)\>=\@!' .
2860a795aaSBram Moolenaar	\ ':' .
2979166c43SBram Moolenaar	\ '\<\%(else\|elsif\|ensure\|when\|rescue\|break\|redo\|next\|retry\)\>' .
3060a795aaSBram Moolenaar	\ ':' .
3179166c43SBram Moolenaar	\ '\<end\>' .
3291170f8aSBram Moolenaar	\ ',{:},\[:\],(:)'
3360a795aaSBram Moolenaar
3460a795aaSBram Moolenaar  let b:match_skip =
3560a795aaSBram Moolenaar	\ "synIDattr(synID(line('.'),col('.'),0),'name') =~ '" .
3679166c43SBram Moolenaar	\ "\\<ruby\\%(String\\|StringDelimiter\\|ASCIICode\\|Escape\\|" .
3779166c43SBram Moolenaar	\ "Interpolation\\|NoInterpolation\\|Comment\\|Documentation\\|" .
3879166c43SBram Moolenaar	\ "ConditionalModifier\\|RepeatModifier\\|OptionalDo\\|" .
3979166c43SBram Moolenaar	\ "Function\\|BlockArgument\\|KeywordAsMethod\\|ClassVariable\\|" .
4079166c43SBram Moolenaar	\ "InstanceVariable\\|GlobalVariable\\|Symbol\\)\\>'"
4160a795aaSBram Moolenaarendif
4260a795aaSBram Moolenaar
4360a795aaSBram Moolenaarsetlocal formatoptions-=t formatoptions+=croql
4460a795aaSBram Moolenaar
45*ec7944aaSBram Moolenaarsetlocal include=^\\s*\\<\\(load\\>\\\|require\\>\\\|autoload\\s*:\\=[\"']\\=\\h\\w*[\"']\\=,\\)
4660a795aaSBram Moolenaarsetlocal includeexpr=substitute(substitute(v:fname,'::','/','g'),'$','.rb','')
4760a795aaSBram Moolenaarsetlocal suffixesadd=.rb
48c6249bb2SBram Moolenaar
49756ec0f3SBram Moolenaarif exists("&ofu") && has("ruby")
509e54a0e7SBram Moolenaar  setlocal omnifunc=rubycomplete#Complete
51c6249bb2SBram Moolenaarendif
5260a795aaSBram Moolenaar
53756ec0f3SBram Moolenaar" To activate, :set ballooneval
54756ec0f3SBram Moolenaarif has('balloon_eval') && exists('+balloonexpr')
55756ec0f3SBram Moolenaar  setlocal balloonexpr=RubyBalloonexpr()
56756ec0f3SBram Moolenaarendif
57756ec0f3SBram Moolenaar
58756ec0f3SBram Moolenaar
5960a795aaSBram Moolenaar" TODO:
6060a795aaSBram Moolenaar"setlocal define=^\\s*def
6160a795aaSBram Moolenaar
6260a795aaSBram Moolenaarsetlocal comments=:#
6360a795aaSBram Moolenaarsetlocal commentstring=#\ %s
6460a795aaSBram Moolenaar
65*ec7944aaSBram Moolenaarif !exists('g:ruby_version_paths')
66*ec7944aaSBram Moolenaar  let g:ruby_version_paths = {}
6760a795aaSBram Moolenaarendif
68*ec7944aaSBram Moolenaar
69*ec7944aaSBram Moolenaarfunction! s:query_path(root)
70*ec7944aaSBram Moolenaar  let code = "print $:.join %q{,}"
71*ec7944aaSBram Moolenaar  if &shell =~# 'sh' && $PATH !~# '\s'
72*ec7944aaSBram Moolenaar    let prefix = 'env PATH='.$PATH.' '
7360a795aaSBram Moolenaar  else
74*ec7944aaSBram Moolenaar    let prefix = ''
75*ec7944aaSBram Moolenaar  endif
76*ec7944aaSBram Moolenaar  if &shellxquote == "'"
77*ec7944aaSBram Moolenaar    let path_check = prefix.'ruby -e "' . code . '"'
78*ec7944aaSBram Moolenaar  else
79*ec7944aaSBram Moolenaar    let path_check = prefix."ruby -e '" . code . "'"
80*ec7944aaSBram Moolenaar  endif
81*ec7944aaSBram Moolenaar
82*ec7944aaSBram Moolenaar  let cd = haslocaldir() ? 'lcd' : 'cd'
83*ec7944aaSBram Moolenaar  let cwd = getcwd()
84*ec7944aaSBram Moolenaar  try
85*ec7944aaSBram Moolenaar    exe cd fnameescape(a:root)
86*ec7944aaSBram Moolenaar    let path = split(system(path_check),',')
87*ec7944aaSBram Moolenaar    exe cd fnameescape(cwd)
88*ec7944aaSBram Moolenaar    return path
89*ec7944aaSBram Moolenaar  finally
90*ec7944aaSBram Moolenaar    exe cd fnameescape(cwd)
91*ec7944aaSBram Moolenaar  endtry
92*ec7944aaSBram Moolenaarendfunction
93*ec7944aaSBram Moolenaar
94*ec7944aaSBram Moolenaarfunction! s:build_path(path)
95*ec7944aaSBram Moolenaar  let path = join(map(copy(a:path), 'v:val ==# "." ? "" : v:val'), ',')
96*ec7944aaSBram Moolenaar  if &g:path !~# '\v^\.%(,/%(usr|emx)/include)=,,$'
97*ec7944aaSBram Moolenaar    let path = substitute(&g:path,',,$',',','') . ',' . path
98*ec7944aaSBram Moolenaar  endif
99*ec7944aaSBram Moolenaar  return path
100*ec7944aaSBram Moolenaarendfunction
101*ec7944aaSBram Moolenaar
102*ec7944aaSBram Moolenaarif !exists('b:ruby_version') && !exists('g:ruby_path') && isdirectory(expand('%:p:h'))
103*ec7944aaSBram Moolenaar  let s:version_file = findfile('.ruby-version', '.;')
104*ec7944aaSBram Moolenaar  if !empty(s:version_file)
105*ec7944aaSBram Moolenaar    let b:ruby_version = get(readfile(s:version_file, '', 1), '')
106*ec7944aaSBram Moolenaar    if !has_key(g:ruby_version_paths, b:ruby_version)
107*ec7944aaSBram Moolenaar      let g:ruby_version_paths[b:ruby_version] = s:query_path(fnamemodify(s:version_file, ':p:h'))
108*ec7944aaSBram Moolenaar    endif
10960a795aaSBram Moolenaar  endif
11060a795aaSBram Moolenaarendif
11160a795aaSBram Moolenaar
112*ec7944aaSBram Moolenaarif exists("g:ruby_path")
113*ec7944aaSBram Moolenaar  let s:ruby_path = type(g:ruby_path) == type([]) ? join(g:ruby_path, ',') : g:ruby_path
114*ec7944aaSBram Moolenaarelseif has_key(g:ruby_version_paths, get(b:, 'ruby_version', ''))
115*ec7944aaSBram Moolenaar  let s:ruby_paths = g:ruby_version_paths[b:ruby_version]
116*ec7944aaSBram Moolenaar  let s:ruby_path = s:build_path(s:ruby_paths)
117*ec7944aaSBram Moolenaarelse
118*ec7944aaSBram Moolenaar  if !exists('g:ruby_default_path')
119*ec7944aaSBram Moolenaar    if has("ruby") && has("win32")
120*ec7944aaSBram Moolenaar      ruby ::VIM::command( 'let g:ruby_default_path = split("%s",",")' % $:.join(%q{,}) )
121*ec7944aaSBram Moolenaar    elseif executable('ruby')
122*ec7944aaSBram Moolenaar      let g:ruby_default_path = s:query_path($HOME)
123*ec7944aaSBram Moolenaar    else
124*ec7944aaSBram Moolenaar      let g:ruby_default_path = map(split($RUBYLIB,':'), 'v:val ==# "." ? "" : v:val')
125*ec7944aaSBram Moolenaar    endif
126*ec7944aaSBram Moolenaar  endif
127*ec7944aaSBram Moolenaar  let s:ruby_paths = g:ruby_default_path
128*ec7944aaSBram Moolenaar  let s:ruby_path = s:build_path(s:ruby_paths)
129*ec7944aaSBram Moolenaarendif
130*ec7944aaSBram Moolenaar
131*ec7944aaSBram Moolenaarif stridx(&l:path, s:ruby_path) == -1
1321d68952aSBram Moolenaar  let &l:path = s:ruby_path
133*ec7944aaSBram Moolenaarendif
134*ec7944aaSBram Moolenaarif exists('s:ruby_paths') && stridx(&l:tags, join(map(copy(s:ruby_paths),'v:val."/tags"'),',')) == -1
135*ec7944aaSBram Moolenaar  let &l:tags = &tags . ',' . join(map(copy(s:ruby_paths),'v:val."/tags"'),',')
136*ec7944aaSBram Moolenaarendif
13760a795aaSBram Moolenaar
13860a795aaSBram Moolenaarif has("gui_win32") && !exists("b:browsefilter")
13960a795aaSBram Moolenaar  let b:browsefilter = "Ruby Source Files (*.rb)\t*.rb\n" .
14060a795aaSBram Moolenaar                     \ "All Files (*.*)\t*.*\n"
14160a795aaSBram Moolenaarendif
14260a795aaSBram Moolenaar
143*ec7944aaSBram Moolenaarlet b:undo_ftplugin = "setl fo< inc< inex< sua< def< com< cms< path< tags< kp<"
14479166c43SBram Moolenaar      \."| unlet! b:browsefilter b:match_ignorecase b:match_words b:match_skip"
14579166c43SBram Moolenaar      \."| if exists('&ofu') && has('ruby') | setl ofu< | endif"
14679166c43SBram Moolenaar      \."| if has('balloon_eval') && exists('+bexpr') | setl bexpr< | endif"
14779166c43SBram Moolenaar
14879166c43SBram Moolenaarif !exists("g:no_plugin_maps") && !exists("g:no_ruby_maps")
1491d68952aSBram Moolenaar  nnoremap <silent> <buffer> [m :<C-U>call <SID>searchsyn('\<def\>','rubyDefine','b','n')<CR>
1501d68952aSBram Moolenaar  nnoremap <silent> <buffer> ]m :<C-U>call <SID>searchsyn('\<def\>','rubyDefine','','n')<CR>
1511d68952aSBram Moolenaar  nnoremap <silent> <buffer> [M :<C-U>call <SID>searchsyn('\<end\>','rubyDefine','b','n')<CR>
1521d68952aSBram Moolenaar  nnoremap <silent> <buffer> ]M :<C-U>call <SID>searchsyn('\<end\>','rubyDefine','','n')<CR>
1531d68952aSBram Moolenaar  xnoremap <silent> <buffer> [m :<C-U>call <SID>searchsyn('\<def\>','rubyDefine','b','v')<CR>
1541d68952aSBram Moolenaar  xnoremap <silent> <buffer> ]m :<C-U>call <SID>searchsyn('\<def\>','rubyDefine','','v')<CR>
1551d68952aSBram Moolenaar  xnoremap <silent> <buffer> [M :<C-U>call <SID>searchsyn('\<end\>','rubyDefine','b','v')<CR>
1561d68952aSBram Moolenaar  xnoremap <silent> <buffer> ]M :<C-U>call <SID>searchsyn('\<end\>','rubyDefine','','v')<CR>
15779166c43SBram Moolenaar
1581d68952aSBram Moolenaar  nnoremap <silent> <buffer> [[ :<C-U>call <SID>searchsyn('\<\%(class\<Bar>module\)\>','rubyModule\<Bar>rubyClass','b','n')<CR>
1591d68952aSBram Moolenaar  nnoremap <silent> <buffer> ]] :<C-U>call <SID>searchsyn('\<\%(class\<Bar>module\)\>','rubyModule\<Bar>rubyClass','','n')<CR>
1601d68952aSBram Moolenaar  nnoremap <silent> <buffer> [] :<C-U>call <SID>searchsyn('\<end\>','rubyModule\<Bar>rubyClass','b','n')<CR>
1611d68952aSBram Moolenaar  nnoremap <silent> <buffer> ][ :<C-U>call <SID>searchsyn('\<end\>','rubyModule\<Bar>rubyClass','','n')<CR>
1621d68952aSBram Moolenaar  xnoremap <silent> <buffer> [[ :<C-U>call <SID>searchsyn('\<\%(class\<Bar>module\)\>','rubyModule\<Bar>rubyClass','b','v')<CR>
1631d68952aSBram Moolenaar  xnoremap <silent> <buffer> ]] :<C-U>call <SID>searchsyn('\<\%(class\<Bar>module\)\>','rubyModule\<Bar>rubyClass','','v')<CR>
1641d68952aSBram Moolenaar  xnoremap <silent> <buffer> [] :<C-U>call <SID>searchsyn('\<end\>','rubyModule\<Bar>rubyClass','b','v')<CR>
1651d68952aSBram Moolenaar  xnoremap <silent> <buffer> ][ :<C-U>call <SID>searchsyn('\<end\>','rubyModule\<Bar>rubyClass','','v')<CR>
16679166c43SBram Moolenaar
16779166c43SBram Moolenaar  let b:undo_ftplugin = b:undo_ftplugin
16879166c43SBram Moolenaar        \."| sil! exe 'unmap <buffer> [[' | sil! exe 'unmap <buffer> ]]' | sil! exe 'unmap <buffer> []' | sil! exe 'unmap <buffer> ]['"
16979166c43SBram Moolenaar        \."| sil! exe 'unmap <buffer> [m' | sil! exe 'unmap <buffer> ]m' | sil! exe 'unmap <buffer> [M' | sil! exe 'unmap <buffer> ]M'"
1701d68952aSBram Moolenaar
171*ec7944aaSBram Moolenaar  if maparg('im','n') == ''
172*ec7944aaSBram Moolenaar    onoremap <silent> <buffer> im :<C-U>call <SID>wrap_i('[m',']M')<CR>
173*ec7944aaSBram Moolenaar    onoremap <silent> <buffer> am :<C-U>call <SID>wrap_a('[m',']M')<CR>
174*ec7944aaSBram Moolenaar    xnoremap <silent> <buffer> im :<C-U>call <SID>wrap_i('[m',']M')<CR>
175*ec7944aaSBram Moolenaar    xnoremap <silent> <buffer> am :<C-U>call <SID>wrap_a('[m',']M')<CR>
176*ec7944aaSBram Moolenaar    let b:undo_ftplugin = b:undo_ftplugin
177*ec7944aaSBram Moolenaar          \."| sil! exe 'ounmap <buffer> im' | sil! exe 'ounmap <buffer> am'"
178*ec7944aaSBram Moolenaar          \."| sil! exe 'xunmap <buffer> im' | sil! exe 'xunmap <buffer> am'"
179*ec7944aaSBram Moolenaar  endif
180*ec7944aaSBram Moolenaar
181*ec7944aaSBram Moolenaar  if maparg('iM','n') == ''
182*ec7944aaSBram Moolenaar    onoremap <silent> <buffer> iM :<C-U>call <SID>wrap_i('[[','][')<CR>
183*ec7944aaSBram Moolenaar    onoremap <silent> <buffer> aM :<C-U>call <SID>wrap_a('[[','][')<CR>
184*ec7944aaSBram Moolenaar    xnoremap <silent> <buffer> iM :<C-U>call <SID>wrap_i('[[','][')<CR>
185*ec7944aaSBram Moolenaar    xnoremap <silent> <buffer> aM :<C-U>call <SID>wrap_a('[[','][')<CR>
186*ec7944aaSBram Moolenaar    let b:undo_ftplugin = b:undo_ftplugin
187*ec7944aaSBram Moolenaar          \."| sil! exe 'ounmap <buffer> iM' | sil! exe 'ounmap <buffer> aM'"
188*ec7944aaSBram Moolenaar          \."| sil! exe 'xunmap <buffer> iM' | sil! exe 'xunmap <buffer> aM'"
189*ec7944aaSBram Moolenaar  endif
190*ec7944aaSBram Moolenaar
1911d68952aSBram Moolenaar  if maparg("\<C-]>",'n') == ''
1921d68952aSBram Moolenaar    nnoremap <silent> <buffer> <C-]>       :<C-U>exe  v:count1."tag <C-R>=RubyCursorIdentifier()<CR>"<CR>
1931d68952aSBram Moolenaar    nnoremap <silent> <buffer> g<C-]>      :<C-U>exe         "tjump <C-R>=RubyCursorIdentifier()<CR>"<CR>
1941d68952aSBram Moolenaar    nnoremap <silent> <buffer> g]          :<C-U>exe       "tselect <C-R>=RubyCursorIdentifier()<CR>"<CR>
1951d68952aSBram Moolenaar    nnoremap <silent> <buffer> <C-W>]      :<C-U>exe v:count1."stag <C-R>=RubyCursorIdentifier()<CR>"<CR>
1961d68952aSBram Moolenaar    nnoremap <silent> <buffer> <C-W><C-]>  :<C-U>exe v:count1."stag <C-R>=RubyCursorIdentifier()<CR>"<CR>
1971d68952aSBram Moolenaar    nnoremap <silent> <buffer> <C-W>g<C-]> :<C-U>exe        "stjump <C-R>=RubyCursorIdentifier()<CR>"<CR>
1981d68952aSBram Moolenaar    nnoremap <silent> <buffer> <C-W>g]     :<C-U>exe      "stselect <C-R>=RubyCursorIdentifier()<CR>"<CR>
1991d68952aSBram Moolenaar    nnoremap <silent> <buffer> <C-W>}      :<C-U>exe          "ptag <C-R>=RubyCursorIdentifier()<CR>"<CR>
2001d68952aSBram Moolenaar    nnoremap <silent> <buffer> <C-W>g}     :<C-U>exe        "ptjump <C-R>=RubyCursorIdentifier()<CR>"<CR>
2011d68952aSBram Moolenaar    let b:undo_ftplugin = b:undo_ftplugin
2021d68952aSBram Moolenaar          \."| sil! exe 'nunmap <buffer> <C-]>'| sil! exe 'nunmap <buffer> g<C-]>'| sil! exe 'nunmap <buffer> g]'"
2031d68952aSBram Moolenaar          \."| sil! exe 'nunmap <buffer> <C-W>]'| sil! exe 'nunmap <buffer> <C-W><C-]>'"
2041d68952aSBram Moolenaar          \."| sil! exe 'nunmap <buffer> <C-W>g<C-]>'| sil! exe 'nunmap <buffer> <C-W>g]'"
2051d68952aSBram Moolenaar          \."| sil! exe 'nunmap <buffer> <C-W>}'| sil! exe 'nunmap <buffer> <C-W>g}'"
2061d68952aSBram Moolenaar  endif
207*ec7944aaSBram Moolenaar
208*ec7944aaSBram Moolenaar  if maparg("gf",'n') == ''
209*ec7944aaSBram Moolenaar    " By using findfile() rather than gf's normal behavior, we prevent
210*ec7944aaSBram Moolenaar    " erroneously editing a directory.
211*ec7944aaSBram Moolenaar    nnoremap <silent> <buffer> gf         :<C-U>exe <SID>gf(v:count1,"gf",'edit')<CR>
212*ec7944aaSBram Moolenaar    nnoremap <silent> <buffer> <C-W>f     :<C-U>exe <SID>gf(v:count1,"\<Lt>C-W>f",'split')<CR>
213*ec7944aaSBram Moolenaar    nnoremap <silent> <buffer> <C-W><C-F> :<C-U>exe <SID>gf(v:count1,"\<Lt>C-W>\<Lt>C-F>",'split')<CR>
214*ec7944aaSBram Moolenaar    nnoremap <silent> <buffer> <C-W>gf    :<C-U>exe <SID>gf(v:count1,"\<Lt>C-W>gf",'tabedit')<CR>
215*ec7944aaSBram Moolenaar    let b:undo_ftplugin = b:undo_ftplugin
216*ec7944aaSBram Moolenaar          \."| sil! exe 'nunmap <buffer> gf' | sil! exe 'nunmap <buffer> <C-W>f' | sil! exe 'nunmap <buffer> <C-W><C-F>' | sil! exe 'nunmap <buffer> <C-W>gf'"
217*ec7944aaSBram Moolenaar  endif
21879166c43SBram Moolenaarendif
21960a795aaSBram Moolenaar
22060a795aaSBram Moolenaarlet &cpo = s:cpo_save
22160a795aaSBram Moolenaarunlet s:cpo_save
22260a795aaSBram Moolenaar
223756ec0f3SBram Moolenaarif exists("g:did_ruby_ftplugin_functions")
224756ec0f3SBram Moolenaar  finish
225756ec0f3SBram Moolenaarendif
226756ec0f3SBram Moolenaarlet g:did_ruby_ftplugin_functions = 1
227756ec0f3SBram Moolenaar
228756ec0f3SBram Moolenaarfunction! RubyBalloonexpr()
229756ec0f3SBram Moolenaar  if !exists('s:ri_found')
230756ec0f3SBram Moolenaar    let s:ri_found = executable('ri')
231756ec0f3SBram Moolenaar  endif
232756ec0f3SBram Moolenaar  if s:ri_found
233756ec0f3SBram Moolenaar    let line = getline(v:beval_lnum)
234756ec0f3SBram Moolenaar    let b = matchstr(strpart(line,0,v:beval_col),'\%(\w\|[:.]\)*$')
235756ec0f3SBram Moolenaar    let a = substitute(matchstr(strpart(line,v:beval_col),'^\w*\%([?!]\|\s*=\)\?'),'\s\+','','g')
236756ec0f3SBram Moolenaar    let str = b.a
237756ec0f3SBram Moolenaar    let before = strpart(line,0,v:beval_col-strlen(b))
238756ec0f3SBram Moolenaar    let after  = strpart(line,v:beval_col+strlen(a))
239756ec0f3SBram Moolenaar    if str =~ '^\.'
240756ec0f3SBram Moolenaar      let str = substitute(str,'^\.','#','g')
241756ec0f3SBram Moolenaar      if before =~ '\]\s*$'
242756ec0f3SBram Moolenaar        let str = 'Array'.str
243756ec0f3SBram Moolenaar      elseif before =~ '}\s*$'
244756ec0f3SBram Moolenaar        " False positives from blocks here
245756ec0f3SBram Moolenaar        let str = 'Hash'.str
246756ec0f3SBram Moolenaar      elseif before =~ "[\"'`]\\s*$" || before =~ '\$\d\+\s*$'
247756ec0f3SBram Moolenaar        let str = 'String'.str
248756ec0f3SBram Moolenaar      elseif before =~ '\$\d\+\.\d\+\s*$'
249756ec0f3SBram Moolenaar        let str = 'Float'.str
250756ec0f3SBram Moolenaar      elseif before =~ '\$\d\+\s*$'
251756ec0f3SBram Moolenaar        let str = 'Integer'.str
252756ec0f3SBram Moolenaar      elseif before =~ '/\s*$'
253756ec0f3SBram Moolenaar        let str = 'Regexp'.str
254756ec0f3SBram Moolenaar      else
255756ec0f3SBram Moolenaar        let str = substitute(str,'^#','.','')
256756ec0f3SBram Moolenaar      endif
257756ec0f3SBram Moolenaar    endif
258756ec0f3SBram Moolenaar    let str = substitute(str,'.*\.\s*to_f\s*\.\s*','Float#','')
259756ec0f3SBram Moolenaar    let str = substitute(str,'.*\.\s*to_i\%(nt\)\=\s*\.\s*','Integer#','')
260756ec0f3SBram Moolenaar    let str = substitute(str,'.*\.\s*to_s\%(tr\)\=\s*\.\s*','String#','')
261756ec0f3SBram Moolenaar    let str = substitute(str,'.*\.\s*to_sym\s*\.\s*','Symbol#','')
262756ec0f3SBram Moolenaar    let str = substitute(str,'.*\.\s*to_a\%(ry\)\=\s*\.\s*','Array#','')
263756ec0f3SBram Moolenaar    let str = substitute(str,'.*\.\s*to_proc\s*\.\s*','Proc#','')
264756ec0f3SBram Moolenaar    if str !~ '^\w'
265756ec0f3SBram Moolenaar      return ''
266756ec0f3SBram Moolenaar    endif
267*ec7944aaSBram Moolenaar    silent! let res = substitute(system("ri -f rdoc -T \"".str.'"'),'\n$','','')
26879166c43SBram Moolenaar    if res =~ '^Nothing known about' || res =~ '^Bad argument:' || res =~ '^More than one method'
269756ec0f3SBram Moolenaar      return ''
270756ec0f3SBram Moolenaar    endif
271756ec0f3SBram Moolenaar    return res
272756ec0f3SBram Moolenaar  else
273756ec0f3SBram Moolenaar    return ""
274756ec0f3SBram Moolenaar  endif
275756ec0f3SBram Moolenaarendfunction
276756ec0f3SBram Moolenaar
2771d68952aSBram Moolenaarfunction! s:searchsyn(pattern,syn,flags,mode)
27879166c43SBram Moolenaar  norm! m'
2791d68952aSBram Moolenaar  if a:mode ==# 'v'
2801d68952aSBram Moolenaar    norm! gv
2811d68952aSBram Moolenaar  endif
28279166c43SBram Moolenaar  let i = 0
28379166c43SBram Moolenaar  let cnt = v:count ? v:count : 1
28479166c43SBram Moolenaar  while i < cnt
28579166c43SBram Moolenaar    let i = i + 1
28679166c43SBram Moolenaar    let line = line('.')
28779166c43SBram Moolenaar    let col  = col('.')
28879166c43SBram Moolenaar    let pos = search(a:pattern,'W'.a:flags)
28979166c43SBram Moolenaar    while pos != 0 && s:synname() !~# a:syn
29079166c43SBram Moolenaar      let pos = search(a:pattern,'W'.a:flags)
29179166c43SBram Moolenaar    endwhile
29279166c43SBram Moolenaar    if pos == 0
29379166c43SBram Moolenaar      call cursor(line,col)
29479166c43SBram Moolenaar      return
29579166c43SBram Moolenaar    endif
29679166c43SBram Moolenaar  endwhile
29779166c43SBram Moolenaarendfunction
29879166c43SBram Moolenaar
29979166c43SBram Moolenaarfunction! s:synname()
30079166c43SBram Moolenaar  return synIDattr(synID(line('.'),col('.'),0),'name')
30179166c43SBram Moolenaarendfunction
302756ec0f3SBram Moolenaar
303*ec7944aaSBram Moolenaarfunction! s:wrap_i(back,forward)
304*ec7944aaSBram Moolenaar  execute 'norm k'.a:forward
305*ec7944aaSBram Moolenaar  let line = line('.')
306*ec7944aaSBram Moolenaar  execute 'norm '.a:back
307*ec7944aaSBram Moolenaar  if line('.') == line - 1
308*ec7944aaSBram Moolenaar    return s:wrap_a(a:back,a:forward)
309*ec7944aaSBram Moolenaar  endif
310*ec7944aaSBram Moolenaar  execute 'norm jV'.a:forward.'k'
311*ec7944aaSBram Moolenaarendfunction
312*ec7944aaSBram Moolenaar
313*ec7944aaSBram Moolenaarfunction! s:wrap_a(back,forward)
314*ec7944aaSBram Moolenaar  execute 'norm '.a:forward
315*ec7944aaSBram Moolenaar  if line('.') < line('$') && getline(line('.')+1) ==# ''
316*ec7944aaSBram Moolenaar    let after = 1
317*ec7944aaSBram Moolenaar  endif
318*ec7944aaSBram Moolenaar  execute 'norm '.a:back
319*ec7944aaSBram Moolenaar  while getline(line('.')-1) =~# '^\s*#' && line('.')
320*ec7944aaSBram Moolenaar    -
321*ec7944aaSBram Moolenaar  endwhile
322*ec7944aaSBram Moolenaar  if exists('after')
323*ec7944aaSBram Moolenaar    execute 'norm V'.a:forward.'j'
324*ec7944aaSBram Moolenaar  elseif line('.') > 1 && getline(line('.')-1) =~# '^\s*$'
325*ec7944aaSBram Moolenaar    execute 'norm kV'.a:forward
326*ec7944aaSBram Moolenaar  else
327*ec7944aaSBram Moolenaar    execute 'norm V'.a:forward
328*ec7944aaSBram Moolenaar  endif
329*ec7944aaSBram Moolenaarendfunction
330*ec7944aaSBram Moolenaar
3311d68952aSBram Moolenaarfunction! RubyCursorIdentifier()
3321d68952aSBram Moolenaar  let asciicode    = '\%(\w\|[]})\"'."'".']\)\@<!\%(?\%(\\M-\\C-\|\\C-\\M-\|\\M-\\c\|\\c\\M-\|\\c\|\\C-\|\\M-\)\=\%(\\\o\{1,3}\|\\x\x\{1,2}\|\\\=\S\)\)'
3331d68952aSBram Moolenaar  let number       = '\%(\%(\w\|[]})\"'."'".']\s*\)\@<!-\)\=\%(\<[[:digit:]_]\+\%(\.[[:digit:]_]\+\)\=\%([Ee][[:digit:]_]\+\)\=\>\|\<0[xXbBoOdD][[:xdigit:]_]\+\>\)\|'.asciicode
3341d68952aSBram Moolenaar  let operator     = '\%(\[\]\|<<\|<=>\|[!<>]=\=\|===\=\|[!=]\~\|>>\|\*\*\|\.\.\.\=\|=>\|[~^&|*/%+-]\)'
3351d68952aSBram Moolenaar  let method       = '\%(\<[_a-zA-Z]\w*\>\%([?!]\|\s*=>\@!\)\=\)'
3361d68952aSBram Moolenaar  let global       = '$\%([!$&"'."'".'*+,./:;<=>?@\`~]\|-\=\w\+\>\)'
3371d68952aSBram Moolenaar  let symbolizable = '\%(\%(@@\=\)\w\+\>\|'.global.'\|'.method.'\|'.operator.'\)'
3381d68952aSBram Moolenaar  let pattern      = '\C\s*\%('.number.'\|\%(:\@<!:\)\='.symbolizable.'\)'
3391d68952aSBram Moolenaar  let [lnum, col]  = searchpos(pattern,'bcn',line('.'))
3401d68952aSBram Moolenaar  let raw          = matchstr(getline('.')[col-1 : ],pattern)
3411d68952aSBram Moolenaar  let stripped     = substitute(substitute(raw,'\s\+=$','=',''),'^\s*:\=','','')
3421d68952aSBram Moolenaar  return stripped == '' ? expand("<cword>") : stripped
3431d68952aSBram Moolenaarendfunction
3441d68952aSBram Moolenaar
345*ec7944aaSBram Moolenaarfunction! s:gf(count,map,edit) abort
346*ec7944aaSBram Moolenaar  if getline('.') =~# '^\s*require_relative\s*\(["'']\).*\1\s*$'
347*ec7944aaSBram Moolenaar    let target = matchstr(getline('.'),'\(["'']\)\zs.\{-\}\ze\1')
348*ec7944aaSBram Moolenaar    return a:edit.' %:h/'.target.'.rb'
349*ec7944aaSBram Moolenaar  elseif getline('.') =~# '^\s*\%(require[( ]\|load[( ]\|autoload[( ]:\w\+,\)\s*\s*\%(::\)\=File\.expand_path(\(["'']\)\.\./.*\1,\s*__FILE__)\s*$'
350*ec7944aaSBram Moolenaar    let target = matchstr(getline('.'),'\(["'']\)\.\./\zs.\{-\}\ze\1')
351*ec7944aaSBram Moolenaar    return a:edit.' %:h/'.target.'.rb'
352*ec7944aaSBram Moolenaar  elseif getline('.') =~# '^\s*\%(require \|load \|autoload :\w\+,\)\s*\(["'']\).*\1\s*$'
353*ec7944aaSBram Moolenaar    let target = matchstr(getline('.'),'\(["'']\)\zs.\{-\}\ze\1')
354*ec7944aaSBram Moolenaar  else
355*ec7944aaSBram Moolenaar    let target = expand('<cfile>')
356*ec7944aaSBram Moolenaar  endif
357*ec7944aaSBram Moolenaar  let found = findfile(target, &path, a:count)
358*ec7944aaSBram Moolenaar  if found ==# ''
359*ec7944aaSBram Moolenaar    return 'norm! '.a:count.a:map
360*ec7944aaSBram Moolenaar  else
361*ec7944aaSBram Moolenaar    return a:edit.' '.fnameescape(found)
362*ec7944aaSBram Moolenaar  endif
363*ec7944aaSBram Moolenaarendfunction
364*ec7944aaSBram Moolenaar
36560a795aaSBram Moolenaar"
36660a795aaSBram Moolenaar" Instructions for enabling "matchit" support:
36760a795aaSBram Moolenaar"
36860a795aaSBram Moolenaar" 1. Look for the latest "matchit" plugin at
36960a795aaSBram Moolenaar"
37060a795aaSBram Moolenaar"         http://www.vim.org/scripts/script.php?script_id=39
37160a795aaSBram Moolenaar"
37260a795aaSBram Moolenaar"    It is also packaged with Vim, in the $VIMRUNTIME/macros directory.
37360a795aaSBram Moolenaar"
37460a795aaSBram Moolenaar" 2. Copy "matchit.txt" into a "doc" directory (e.g. $HOME/.vim/doc).
37560a795aaSBram Moolenaar"
37660a795aaSBram Moolenaar" 3. Copy "matchit.vim" into a "plugin" directory (e.g. $HOME/.vim/plugin).
37760a795aaSBram Moolenaar"
37860a795aaSBram Moolenaar" 4. Ensure this file (ftplugin/ruby.vim) is installed.
37960a795aaSBram Moolenaar"
38060a795aaSBram Moolenaar" 5. Ensure you have this line in your $HOME/.vimrc:
38160a795aaSBram Moolenaar"         filetype plugin on
38260a795aaSBram Moolenaar"
38360a795aaSBram Moolenaar" 6. Restart Vim and create the matchit documentation:
38460a795aaSBram Moolenaar"
38560a795aaSBram Moolenaar"         :helptags ~/.vim/doc
38660a795aaSBram Moolenaar"
38760a795aaSBram Moolenaar"    Now you can do ":help matchit", and you should be able to use "%" on Ruby
38860a795aaSBram Moolenaar"    keywords.  Try ":echo b:match_words" to be sure.
38960a795aaSBram Moolenaar"
39060a795aaSBram Moolenaar" Thanks to Mark J. Reed for the instructions.  See ":help vimrc" for the
39160a795aaSBram Moolenaar" locations of plugin directories, etc., as there are several options, and it
39260a795aaSBram Moolenaar" differs on Windows.  Email [email protected] if you need help.
39360a795aaSBram Moolenaar"
39460a795aaSBram Moolenaar
395446cb837SBram Moolenaar" vim: nowrap sw=2 sts=2 ts=8:
396