codekingpro/portable-devtools
114k
1" Vim filetype plugin2" Language: Cucumber3" Maintainer: Tim Pope <vimNOSPAM@tpope.org>4" Last Change: 2016 Aug 295 6" Only do this when not done yet for this buffer7if (exists("b:did_ftplugin"))8 finish9endif10let b:did_ftplugin = 111 12let s:keepcpo= &cpo13set cpo&vim14 15setlocal formatoptions-=t formatoptions+=croql16setlocal comments=:# commentstring=#\ %s17setlocal omnifunc=CucumberComplete18 19let b:undo_ftplugin = "setl fo< com< cms< ofu<"20 21let b:cucumber_root = expand('%:p:h:s?.*[\/]\%(features\|stories\)\zs[\/].*??')22if !exists("b:cucumber_steps_glob")23 let b:cucumber_steps_glob = b:cucumber_root.'/**/*.rb'24endif25 26if !exists("g:no_plugin_maps") && !exists("g:no_cucumber_maps")27 cnoremap <SID>foldopen <Bar>if &foldopen =~# 'tag'<Bar>exe 'norm! zv'<Bar>endif28 nnoremap <silent> <script> <buffer> [<C-D> :<C-U>exe <SID>jump('edit',v:count)<SID>foldopen<CR>29 nnoremap <silent> <script> <buffer> ]<C-D> :<C-U>exe <SID>jump('edit',v:count)<SID>foldopen<CR>30 nnoremap <silent> <script> <buffer> <C-W>d :<C-U>exe <SID>jump('split',v:count)<SID>foldopen<CR>31 nnoremap <silent> <script> <buffer> <C-W><C-D> :<C-U>exe <SID>jump('split',v:count)<SID>foldopen<CR>32 nnoremap <silent> <script> <buffer> [d :<C-U>exe <SID>jump('pedit',v:count)<CR>33 nnoremap <silent> <script> <buffer> ]d :<C-U>exe <SID>jump('pedit',v:count)<CR>34 let b:undo_ftplugin .=35 \ "|sil! nunmap <buffer> [<C-D>" .36 \ "|sil! nunmap <buffer> ]<C-D>" .37 \ "|sil! nunmap <buffer> <C-W>d" .38 \ "|sil! nunmap <buffer> <C-W><C-D>" .39 \ "|sil! nunmap <buffer> [d" .40 \ "|sil! nunmap <buffer> ]d"41endif42 43function! s:jump(command,count)44 let steps = s:steps('.')45 if len(steps) == 0 || len(steps) < a:count46 return 'echoerr "No matching step found"'47 elseif len(steps) > 1 && !a:count48 return 'echoerr "Multiple matching steps found"'49 else50 let c = a:count ? a:count-1 : 051 return a:command.' +'.steps[c][1].' '.escape(steps[c][0],' %#')52 endif53endfunction54 55function! s:allsteps()56 let step_pattern = '\C^\s*\K\k*\>\s*(\=\s*\zs\S.\{-\}\ze\s*)\=\s*\%(do\|{\)\s*\%(|[^|]*|\s*\)\=\%($\|#\)'57 let steps = []58 for file in split(glob(b:cucumber_steps_glob),"\n")59 let lines = readfile(file)60 let num = 061 for line in lines62 let num += 163 if line =~ step_pattern64 let type = matchstr(line,'\w\+')65 let steps += [[file,num,type,matchstr(line,step_pattern)]]66 endif67 endfor68 endfor69 return steps70endfunction71 72function! s:steps(lnum)73 let c = match(getline(a:lnum), '\S') + 174 while synIDattr(synID(a:lnum,c,1),'name') !~# '^$\|Region$'75 let c = c + 176 endwhile77 let step = matchstr(getline(a:lnum)[c-1 : -1],'^\s*\zs.\{-\}\ze\s*$')78 return filter(s:allsteps(),'s:stepmatch(v:val[3],step)')79endfunction80 81function! s:stepmatch(receiver,target)82 if a:receiver =~ '^[''"].*[''"]$'83 let pattern = '^'.escape(substitute(a:receiver[1:-2],'$\w\+','(.*)','g'),'/').'$'84 elseif a:receiver =~ '^/.*/$'85 let pattern = a:receiver[1:-2]86 elseif a:receiver =~ '^%r..*.$'87 let pattern = escape(a:receiver[3:-2],'/')88 else89 return 090 endif91 try92 let vimpattern = substitute(substitute(pattern,'\\\@<!(?:','%(','g'),'\\\@<!\*?','{-}','g')93 if a:target =~# '\v'.vimpattern94 return 195 endif96 catch97 endtry98 if has("ruby") && pattern !~ '\\\@<!#{'99 ruby VIM.command("return #{if (begin; Kernel.eval('/'+VIM.evaluate('pattern')+'/'); rescue SyntaxError; end) === VIM.evaluate('a:target') then 1 else 0 end}")100 else101 return 0102 endif103endfunction104 105function! s:bsub(target,pattern,replacement)106 return substitute(a:target,'\C\\\@<!'.a:pattern,a:replacement,'g')107endfunction108 109function! CucumberComplete(findstart,base) abort110 let indent = indent('.')111 let group = synIDattr(synID(line('.'),indent+1,1),'name')112 let type = matchstr(group,'\Ccucumber\zs\%(Given\|When\|Then\)')113 let e = matchend(getline('.'),'^\s*\S\+\s')114 if type == '' || col('.') < col('$') || e < 0115 return -1116 endif117 if a:findstart118 return e119 endif120 let steps = []121 for step in s:allsteps()122 if step[2] ==# type123 if step[3] =~ '^[''"]'124 let steps += [step[3][1:-2]]125 elseif step[3] =~ '^/\^.*\$/$'126 let pattern = step[3][2:-3]127 let pattern = substitute(pattern,'\C^(?:|I )','I ','')128 let pattern = s:bsub(pattern,'\\[Sw]','w')129 let pattern = s:bsub(pattern,'\\d','1')130 let pattern = s:bsub(pattern,'\\[sWD]',' ')131 let pattern = s:bsub(pattern,'\[\^\\\="\]','_')132 let pattern = s:bsub(pattern,'[[:alnum:]. _-][?*]?\=','')133 let pattern = s:bsub(pattern,'\[\([^^]\).\{-\}\]','\1')134 let pattern = s:bsub(pattern,'+?\=','')135 let pattern = s:bsub(pattern,'(\([[:alnum:]. -]\{-\}\))','\1')136 let pattern = s:bsub(pattern,'\\\([[:punct:]]\)','\1')137 if pattern !~ '[\\()*?]'138 let steps += [pattern]139 endif140 endif141 endif142 endfor143 call filter(steps,'strpart(v:val,0,strlen(a:base)) ==# a:base')144 return sort(steps)145endfunction146 147let &cpo = s:keepcpo148unlet s:keepcpo149 150" vim:set sts=2 sw=2:151 