home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / runtime / ftplugin / ruby.vim < prev    next >
Encoding:
Text File  |  2010-08-15  |  11.3 KB  |  275 lines

  1. " Vim filetype plugin
  2. " Language:        Ruby
  3. " Maintainer:        Gavin Sinclair <gsinclair at gmail.com>
  4. " Last Change:        2010 Mar 15
  5. " URL:            http://vim-ruby.rubyforge.org
  6. " Anon CVS:        See above site
  7. " Release Coordinator:  Doug Kearns <dougkearns@gmail.com>
  8. " ----------------------------------------------------------------------------
  9. "
  10. " Original matchit support thanks to Ned Konz.  See his ftplugin/ruby.vim at
  11. "   http://bike-nomad.com/vim/ruby.vim.
  12. " ----------------------------------------------------------------------------
  13.  
  14. " Only do this when not done yet for this buffer
  15. if (exists("b:did_ftplugin"))
  16.   finish
  17. endif
  18. let b:did_ftplugin = 1
  19.  
  20. let s:cpo_save = &cpo
  21. set cpo&vim
  22.  
  23. if has("gui_running") && !has("gui_win32")
  24.   setlocal keywordprg=ri\ -T
  25. else
  26.   setlocal keywordprg=ri
  27. endif
  28.  
  29. " Matchit support
  30. if exists("loaded_matchit") && !exists("b:match_words")
  31.   let b:match_ignorecase = 0
  32.  
  33.   let b:match_words =
  34.     \ '\<\%(if\|unless\|case\|while\|until\|for\|do\|class\|module\|def\|begin\)\>=\@!' .
  35.     \ ':' .
  36.     \ '\<\%(else\|elsif\|ensure\|when\|rescue\|break\|redo\|next\|retry\)\>' .
  37.     \ ':' .
  38.     \ '\<end\>' .
  39.     \ ',{:},\[:\],(:)'
  40.  
  41.   let b:match_skip =
  42.     \ "synIDattr(synID(line('.'),col('.'),0),'name') =~ '" .
  43.     \ "\\<ruby\\%(String\\|StringDelimiter\\|ASCIICode\\|Escape\\|" .
  44.     \ "Interpolation\\|NoInterpolation\\|Comment\\|Documentation\\|" .
  45.     \ "ConditionalModifier\\|RepeatModifier\\|OptionalDo\\|" .
  46.     \ "Function\\|BlockArgument\\|KeywordAsMethod\\|ClassVariable\\|" .
  47.     \ "InstanceVariable\\|GlobalVariable\\|Symbol\\)\\>'"
  48. endif
  49.  
  50. setlocal formatoptions-=t formatoptions+=croql
  51.  
  52. setlocal include=^\\s*\\<\\(load\\\|\w*require\\)\\>
  53. setlocal includeexpr=substitute(substitute(v:fname,'::','/','g'),'$','.rb','')
  54. setlocal suffixesadd=.rb
  55.  
  56. if exists("&ofu") && has("ruby")
  57.   setlocal omnifunc=rubycomplete#Complete
  58. endif
  59.  
  60. " To activate, :set ballooneval
  61. if has('balloon_eval') && exists('+balloonexpr')
  62.   setlocal balloonexpr=RubyBalloonexpr()
  63. endif
  64.  
  65.  
  66. " TODO:
  67. "setlocal define=^\\s*def
  68.  
  69. setlocal comments=:#
  70. setlocal commentstring=#\ %s
  71.  
  72. if !exists("s:ruby_path")
  73.   if exists("g:ruby_path")
  74.     let s:ruby_path = g:ruby_path
  75.   elseif has("ruby") && has("win32")
  76.     ruby VIM::command( 'let s:ruby_path = "%s"' % ($: + begin; require %q{rubygems}; Gem.all_load_paths.sort.uniq; rescue LoadError; []; end).join(%q{,}) )
  77.     let s:ruby_path = '.,' . substitute(s:ruby_path, '\%(^\|,\)\.\%(,\|$\)', ',,', '')
  78.   elseif executable("ruby")
  79.     let s:code = "print ($: + begin; require %q{rubygems}; Gem.all_load_paths.sort.uniq; rescue LoadError; []; end).join(%q{,})"
  80.     if &shellxquote == "'"
  81.       let s:ruby_path = system('ruby -e "' . s:code . '"')
  82.     else
  83.       let s:ruby_path = system("ruby -e '" . s:code . "'")
  84.     endif
  85.     let s:ruby_path = '.,' . substitute(s:ruby_path, '\%(^\|,\)\.\%(,\|$\)', ',,', '')
  86.   else
  87.     " If we can't call ruby to get its path, just default to using the
  88.     " current directory and the directory of the current file.
  89.     let s:ruby_path = ".,,"
  90.   endif
  91. endif
  92.  
  93. let &l:path = s:ruby_path
  94.  
  95. if has("gui_win32") && !exists("b:browsefilter")
  96.   let b:browsefilter = "Ruby Source Files (*.rb)\t*.rb\n" .
  97.                      \ "All Files (*.*)\t*.*\n"
  98. endif
  99.  
  100. let b:undo_ftplugin = "setl fo< inc< inex< sua< def< com< cms< path< kp<"
  101.       \."| unlet! b:browsefilter b:match_ignorecase b:match_words b:match_skip"
  102.       \."| if exists('&ofu') && has('ruby') | setl ofu< | endif"
  103.       \."| if has('balloon_eval') && exists('+bexpr') | setl bexpr< | endif"
  104.  
  105. if !exists("g:no_plugin_maps") && !exists("g:no_ruby_maps")
  106.  
  107.   nnoremap <silent> <buffer> [m :<C-U>call <SID>searchsyn('\<def\>','rubyDefine','b','n')<CR>
  108.   nnoremap <silent> <buffer> ]m :<C-U>call <SID>searchsyn('\<def\>','rubyDefine','','n')<CR>
  109.   nnoremap <silent> <buffer> [M :<C-U>call <SID>searchsyn('\<end\>','rubyDefine','b','n')<CR>
  110.   nnoremap <silent> <buffer> ]M :<C-U>call <SID>searchsyn('\<end\>','rubyDefine','','n')<CR>
  111.   xnoremap <silent> <buffer> [m :<C-U>call <SID>searchsyn('\<def\>','rubyDefine','b','v')<CR>
  112.   xnoremap <silent> <buffer> ]m :<C-U>call <SID>searchsyn('\<def\>','rubyDefine','','v')<CR>
  113.   xnoremap <silent> <buffer> [M :<C-U>call <SID>searchsyn('\<end\>','rubyDefine','b','v')<CR>
  114.   xnoremap <silent> <buffer> ]M :<C-U>call <SID>searchsyn('\<end\>','rubyDefine','','v')<CR>
  115.  
  116.   nnoremap <silent> <buffer> [[ :<C-U>call <SID>searchsyn('\<\%(class\<Bar>module\)\>','rubyModule\<Bar>rubyClass','b','n')<CR>
  117.   nnoremap <silent> <buffer> ]] :<C-U>call <SID>searchsyn('\<\%(class\<Bar>module\)\>','rubyModule\<Bar>rubyClass','','n')<CR>
  118.   nnoremap <silent> <buffer> [] :<C-U>call <SID>searchsyn('\<end\>','rubyModule\<Bar>rubyClass','b','n')<CR>
  119.   nnoremap <silent> <buffer> ][ :<C-U>call <SID>searchsyn('\<end\>','rubyModule\<Bar>rubyClass','','n')<CR>
  120.   xnoremap <silent> <buffer> [[ :<C-U>call <SID>searchsyn('\<\%(class\<Bar>module\)\>','rubyModule\<Bar>rubyClass','b','v')<CR>
  121.   xnoremap <silent> <buffer> ]] :<C-U>call <SID>searchsyn('\<\%(class\<Bar>module\)\>','rubyModule\<Bar>rubyClass','','v')<CR>
  122.   xnoremap <silent> <buffer> [] :<C-U>call <SID>searchsyn('\<end\>','rubyModule\<Bar>rubyClass','b','v')<CR>
  123.   xnoremap <silent> <buffer> ][ :<C-U>call <SID>searchsyn('\<end\>','rubyModule\<Bar>rubyClass','','v')<CR>
  124.  
  125.   let b:undo_ftplugin = b:undo_ftplugin
  126.         \."| sil! exe 'unmap <buffer> [[' | sil! exe 'unmap <buffer> ]]' | sil! exe 'unmap <buffer> []' | sil! exe 'unmap <buffer> ]['"
  127.         \."| sil! exe 'unmap <buffer> [m' | sil! exe 'unmap <buffer> ]m' | sil! exe 'unmap <buffer> [M' | sil! exe 'unmap <buffer> ]M'"
  128.  
  129.   if maparg("\<C-]>",'n') == ''
  130.     nnoremap <silent> <buffer> <C-]>       :<C-U>exe  v:count1."tag <C-R>=RubyCursorIdentifier()<CR>"<CR>
  131.     nnoremap <silent> <buffer> g<C-]>      :<C-U>exe         "tjump <C-R>=RubyCursorIdentifier()<CR>"<CR>
  132.     nnoremap <silent> <buffer> g]          :<C-U>exe       "tselect <C-R>=RubyCursorIdentifier()<CR>"<CR>
  133.     nnoremap <silent> <buffer> <C-W>]      :<C-U>exe v:count1."stag <C-R>=RubyCursorIdentifier()<CR>"<CR>
  134.     nnoremap <silent> <buffer> <C-W><C-]>  :<C-U>exe v:count1."stag <C-R>=RubyCursorIdentifier()<CR>"<CR>
  135.     nnoremap <silent> <buffer> <C-W>g<C-]> :<C-U>exe        "stjump <C-R>=RubyCursorIdentifier()<CR>"<CR>
  136.     nnoremap <silent> <buffer> <C-W>g]     :<C-U>exe      "stselect <C-R>=RubyCursorIdentifier()<CR>"<CR>
  137.     nnoremap <silent> <buffer> <C-W>}      :<C-U>exe          "ptag <C-R>=RubyCursorIdentifier()<CR>"<CR>
  138.     nnoremap <silent> <buffer> <C-W>g}     :<C-U>exe        "ptjump <C-R>=RubyCursorIdentifier()<CR>"<CR>
  139.     let b:undo_ftplugin = b:undo_ftplugin
  140.           \."| sil! exe 'nunmap <buffer> <C-]>'| sil! exe 'nunmap <buffer> g<C-]>'| sil! exe 'nunmap <buffer> g]'"
  141.           \."| sil! exe 'nunmap <buffer> <C-W>]'| sil! exe 'nunmap <buffer> <C-W><C-]>'"
  142.           \."| sil! exe 'nunmap <buffer> <C-W>g<C-]>'| sil! exe 'nunmap <buffer> <C-W>g]'"
  143.           \."| sil! exe 'nunmap <buffer> <C-W>}'| sil! exe 'nunmap <buffer> <C-W>g}'"
  144.   endif
  145. endif
  146.  
  147. let &cpo = s:cpo_save
  148. unlet s:cpo_save
  149.  
  150. if exists("g:did_ruby_ftplugin_functions")
  151.   finish
  152. endif
  153. let g:did_ruby_ftplugin_functions = 1
  154.  
  155. function! RubyBalloonexpr()
  156.   if !exists('s:ri_found')
  157.     let s:ri_found = executable('ri')
  158.   endif
  159.   if s:ri_found
  160.     let line = getline(v:beval_lnum)
  161.     let b = matchstr(strpart(line,0,v:beval_col),'\%(\w\|[:.]\)*$')
  162.     let a = substitute(matchstr(strpart(line,v:beval_col),'^\w*\%([?!]\|\s*=\)\?'),'\s\+','','g')
  163.     let str = b.a
  164.     let before = strpart(line,0,v:beval_col-strlen(b))
  165.     let after  = strpart(line,v:beval_col+strlen(a))
  166.     if str =~ '^\.'
  167.       let str = substitute(str,'^\.','#','g')
  168.       if before =~ '\]\s*$'
  169.         let str = 'Array'.str
  170.       elseif before =~ '}\s*$'
  171.         " False positives from blocks here
  172.         let str = 'Hash'.str
  173.       elseif before =~ "[\"'`]\\s*$" || before =~ '\$\d\+\s*$'
  174.         let str = 'String'.str
  175.       elseif before =~ '\$\d\+\.\d\+\s*$'
  176.         let str = 'Float'.str
  177.       elseif before =~ '\$\d\+\s*$'
  178.         let str = 'Integer'.str
  179.       elseif before =~ '/\s*$'
  180.         let str = 'Regexp'.str
  181.       else
  182.         let str = substitute(str,'^#','.','')
  183.       endif
  184.     endif
  185.     let str = substitute(str,'.*\.\s*to_f\s*\.\s*','Float#','')
  186.     let str = substitute(str,'.*\.\s*to_i\%(nt\)\=\s*\.\s*','Integer#','')
  187.     let str = substitute(str,'.*\.\s*to_s\%(tr\)\=\s*\.\s*','String#','')
  188.     let str = substitute(str,'.*\.\s*to_sym\s*\.\s*','Symbol#','')
  189.     let str = substitute(str,'.*\.\s*to_a\%(ry\)\=\s*\.\s*','Array#','')
  190.     let str = substitute(str,'.*\.\s*to_proc\s*\.\s*','Proc#','')
  191.     if str !~ '^\w'
  192.       return ''
  193.     endif
  194.     silent! let res = substitute(system("ri -f simple -T \"".str.'"'),'\n$','','')
  195.     if res =~ '^Nothing known about' || res =~ '^Bad argument:' || res =~ '^More than one method'
  196.       return ''
  197.     endif
  198.     return res
  199.   else
  200.     return ""
  201.   endif
  202. endfunction
  203.  
  204. function! s:searchsyn(pattern,syn,flags,mode)
  205.     norm! m'
  206.     if a:mode ==# 'v'
  207.       norm! gv
  208.     endif
  209.     let i = 0
  210.     let cnt = v:count ? v:count : 1
  211.     while i < cnt
  212.         let i = i + 1
  213.         let line = line('.')
  214.         let col  = col('.')
  215.         let pos = search(a:pattern,'W'.a:flags)
  216.         while pos != 0 && s:synname() !~# a:syn
  217.             let pos = search(a:pattern,'W'.a:flags)
  218.         endwhile
  219.         if pos == 0
  220.             call cursor(line,col)
  221.             return
  222.         endif
  223.     endwhile
  224. endfunction
  225.  
  226. function! s:synname()
  227.     return synIDattr(synID(line('.'),col('.'),0),'name')
  228. endfunction
  229.  
  230. function! RubyCursorIdentifier()
  231.   let asciicode    = '\%(\w\|[]})\"'."'".']\)\@<!\%(?\%(\\M-\\C-\|\\C-\\M-\|\\M-\\c\|\\c\\M-\|\\c\|\\C-\|\\M-\)\=\%(\\\o\{1,3}\|\\x\x\{1,2}\|\\\=\S\)\)'
  232.   let number       = '\%(\%(\w\|[]})\"'."'".']\s*\)\@<!-\)\=\%(\<[[:digit:]_]\+\%(\.[[:digit:]_]\+\)\=\%([Ee][[:digit:]_]\+\)\=\>\|\<0[xXbBoOdD][[:xdigit:]_]\+\>\)\|'.asciicode
  233.   let operator     = '\%(\[\]\|<<\|<=>\|[!<>]=\=\|===\=\|[!=]\~\|>>\|\*\*\|\.\.\.\=\|=>\|[~^&|*/%+-]\)'
  234.   let method       = '\%(\<[_a-zA-Z]\w*\>\%([?!]\|\s*=>\@!\)\=\)'
  235.   let global       = '$\%([!$&"'."'".'*+,./:;<=>?@\`~]\|-\=\w\+\>\)'
  236.   let symbolizable = '\%(\%(@@\=\)\w\+\>\|'.global.'\|'.method.'\|'.operator.'\)'
  237.   let pattern      = '\C\s*\%('.number.'\|\%(:\@<!:\)\='.symbolizable.'\)'
  238.   let [lnum, col]  = searchpos(pattern,'bcn',line('.'))
  239.   let raw          = matchstr(getline('.')[col-1 : ],pattern)
  240.   let stripped     = substitute(substitute(raw,'\s\+=$','=',''),'^\s*:\=','','')
  241.   return stripped == '' ? expand("<cword>") : stripped
  242. endfunction
  243.  
  244. "
  245. " Instructions for enabling "matchit" support:
  246. "
  247. " 1. Look for the latest "matchit" plugin at
  248. "
  249. "         http://www.vim.org/scripts/script.php?script_id=39
  250. "
  251. "    It is also packaged with Vim, in the $VIMRUNTIME/macros directory.
  252. "
  253. " 2. Copy "matchit.txt" into a "doc" directory (e.g. $HOME/.vim/doc).
  254. "
  255. " 3. Copy "matchit.vim" into a "plugin" directory (e.g. $HOME/.vim/plugin).
  256. "
  257. " 4. Ensure this file (ftplugin/ruby.vim) is installed.
  258. "
  259. " 5. Ensure you have this line in your $HOME/.vimrc:
  260. "         filetype plugin on
  261. "
  262. " 6. Restart Vim and create the matchit documentation:
  263. "
  264. "         :helptags ~/.vim/doc
  265. "
  266. "    Now you can do ":help matchit", and you should be able to use "%" on Ruby
  267. "    keywords.  Try ":echo b:match_words" to be sure.
  268. "
  269. " Thanks to Mark J. Reed for the instructions.  See ":help vimrc" for the
  270. " locations of plugin directories, etc., as there are several options, and it
  271. " differs on Windows.  Email gsinclair@soyabean.com.au if you need help.
  272. "
  273.  
  274. " vim: nowrap sw=2 sts=2 ts=8:
  275.