15e3dae8bSBram Moolenaar" Vim filetype plugin 25e3dae8bSBram Moolenaar" Language: Cucumber 35e3dae8bSBram Moolenaar" Maintainer: Tim Pope <[email protected]> 4*89bcfda6SBram Moolenaar" Last Change: 2016 Aug 29 55e3dae8bSBram Moolenaar 65e3dae8bSBram Moolenaar" Only do this when not done yet for this buffer 75e3dae8bSBram Moolenaarif (exists("b:did_ftplugin")) 85e3dae8bSBram Moolenaar finish 95e3dae8bSBram Moolenaarendif 105e3dae8bSBram Moolenaarlet b:did_ftplugin = 1 115e3dae8bSBram Moolenaar 12543b7ef7SBram Moolenaarlet s:keepcpo= &cpo 13543b7ef7SBram Moolenaarset cpo&vim 14543b7ef7SBram Moolenaar 155e3dae8bSBram Moolenaarsetlocal formatoptions-=t formatoptions+=croql 165e3dae8bSBram Moolenaarsetlocal comments=:# commentstring=#\ %s 175e3dae8bSBram Moolenaarsetlocal omnifunc=CucumberComplete 185e3dae8bSBram Moolenaar 195e3dae8bSBram Moolenaarlet b:undo_ftplugin = "setl fo< com< cms< ofu<" 205e3dae8bSBram Moolenaar 215e3dae8bSBram Moolenaarlet b:cucumber_root = expand('%:p:h:s?.*[\/]\%(features\|stories\)\zs[\/].*??') 22*89bcfda6SBram Moolenaarif !exists("b:cucumber_steps_glob") 23*89bcfda6SBram Moolenaar let b:cucumber_steps_glob = b:cucumber_root.'/**/*.rb' 24*89bcfda6SBram Moolenaarendif 255e3dae8bSBram Moolenaar 265e3dae8bSBram Moolenaarif !exists("g:no_plugin_maps") && !exists("g:no_cucumber_maps") 27*89bcfda6SBram Moolenaar cnoremap <SID>foldopen <Bar>if &foldopen =~# 'tag'<Bar>exe 'norm! zv'<Bar>endif 28*89bcfda6SBram Moolenaar nnoremap <silent> <script> <buffer> [<C-D> :<C-U>exe <SID>jump('edit',v:count)<SID>foldopen<CR> 29*89bcfda6SBram Moolenaar nnoremap <silent> <script> <buffer> ]<C-D> :<C-U>exe <SID>jump('edit',v:count)<SID>foldopen<CR> 30*89bcfda6SBram Moolenaar nnoremap <silent> <script> <buffer> <C-W>d :<C-U>exe <SID>jump('split',v:count)<SID>foldopen<CR> 31*89bcfda6SBram Moolenaar nnoremap <silent> <script> <buffer> <C-W><C-D> :<C-U>exe <SID>jump('split',v:count)<SID>foldopen<CR> 32*89bcfda6SBram Moolenaar nnoremap <silent> <script> <buffer> [d :<C-U>exe <SID>jump('pedit',v:count)<CR> 33*89bcfda6SBram Moolenaar nnoremap <silent> <script> <buffer> ]d :<C-U>exe <SID>jump('pedit',v:count)<CR> 34543b7ef7SBram Moolenaar let b:undo_ftplugin .= 35543b7ef7SBram Moolenaar \ "|sil! nunmap <buffer> [<C-D>" . 36543b7ef7SBram Moolenaar \ "|sil! nunmap <buffer> ]<C-D>" . 37543b7ef7SBram Moolenaar \ "|sil! nunmap <buffer> <C-W>d" . 38543b7ef7SBram Moolenaar \ "|sil! nunmap <buffer> <C-W><C-D>" . 39543b7ef7SBram Moolenaar \ "|sil! nunmap <buffer> [d" . 40543b7ef7SBram Moolenaar \ "|sil! nunmap <buffer> ]d" 415e3dae8bSBram Moolenaarendif 425e3dae8bSBram Moolenaar 435e3dae8bSBram Moolenaarfunction! s:jump(command,count) 445e3dae8bSBram Moolenaar let steps = s:steps('.') 455e3dae8bSBram Moolenaar if len(steps) == 0 || len(steps) < a:count 465e3dae8bSBram Moolenaar return 'echoerr "No matching step found"' 475e3dae8bSBram Moolenaar elseif len(steps) > 1 && !a:count 485e3dae8bSBram Moolenaar return 'echoerr "Multiple matching steps found"' 495e3dae8bSBram Moolenaar else 505e3dae8bSBram Moolenaar let c = a:count ? a:count-1 : 0 515e3dae8bSBram Moolenaar return a:command.' +'.steps[c][1].' '.escape(steps[c][0],' %#') 525e3dae8bSBram Moolenaar endif 535e3dae8bSBram Moolenaarendfunction 545e3dae8bSBram Moolenaar 555e3dae8bSBram Moolenaarfunction! s:allsteps() 56543b7ef7SBram Moolenaar let step_pattern = '\C^\s*\K\k*\>\s*(\=\s*\zs\S.\{-\}\ze\s*)\=\s*\%(do\|{\)\s*\%(|[^|]*|\s*\)\=\%($\|#\)' 575e3dae8bSBram Moolenaar let steps = [] 58*89bcfda6SBram Moolenaar for file in split(glob(b:cucumber_steps_glob),"\n") 595e3dae8bSBram Moolenaar let lines = readfile(file) 605e3dae8bSBram Moolenaar let num = 0 615e3dae8bSBram Moolenaar for line in lines 625e3dae8bSBram Moolenaar let num += 1 635e3dae8bSBram Moolenaar if line =~ step_pattern 645e3dae8bSBram Moolenaar let type = matchstr(line,'\w\+') 655e3dae8bSBram Moolenaar let steps += [[file,num,type,matchstr(line,step_pattern)]] 665e3dae8bSBram Moolenaar endif 675e3dae8bSBram Moolenaar endfor 685e3dae8bSBram Moolenaar endfor 695e3dae8bSBram Moolenaar return steps 705e3dae8bSBram Moolenaarendfunction 715e3dae8bSBram Moolenaar 725e3dae8bSBram Moolenaarfunction! s:steps(lnum) 73543b7ef7SBram Moolenaar let c = match(getline(a:lnum), '\S') + 1 745e3dae8bSBram Moolenaar while synIDattr(synID(a:lnum,c,1),'name') !~# '^$\|Region$' 755e3dae8bSBram Moolenaar let c = c + 1 765e3dae8bSBram Moolenaar endwhile 775e3dae8bSBram Moolenaar let step = matchstr(getline(a:lnum)[c-1 : -1],'^\s*\zs.\{-\}\ze\s*$') 785e3dae8bSBram Moolenaar return filter(s:allsteps(),'s:stepmatch(v:val[3],step)') 795e3dae8bSBram Moolenaarendfunction 805e3dae8bSBram Moolenaar 815e3dae8bSBram Moolenaarfunction! s:stepmatch(receiver,target) 825e3dae8bSBram Moolenaar if a:receiver =~ '^[''"].*[''"]$' 835e3dae8bSBram Moolenaar let pattern = '^'.escape(substitute(a:receiver[1:-2],'$\w\+','(.*)','g'),'/').'$' 845e3dae8bSBram Moolenaar elseif a:receiver =~ '^/.*/$' 855e3dae8bSBram Moolenaar let pattern = a:receiver[1:-2] 865e3dae8bSBram Moolenaar elseif a:receiver =~ '^%r..*.$' 875e3dae8bSBram Moolenaar let pattern = escape(a:receiver[3:-2],'/') 885e3dae8bSBram Moolenaar else 895e3dae8bSBram Moolenaar return 0 905e3dae8bSBram Moolenaar endif 915e3dae8bSBram Moolenaar try 925e3dae8bSBram Moolenaar let vimpattern = substitute(substitute(pattern,'\\\@<!(?:','%(','g'),'\\\@<!\*?','{-}','g') 935e3dae8bSBram Moolenaar if a:target =~# '\v'.vimpattern 945e3dae8bSBram Moolenaar return 1 955e3dae8bSBram Moolenaar endif 965e3dae8bSBram Moolenaar catch 975e3dae8bSBram Moolenaar endtry 986af737fdSBram Moolenaar if has("ruby") && pattern !~ '\\\@<!#{' 995e3dae8bSBram Moolenaar ruby VIM.command("return #{if (begin; Kernel.eval('/'+VIM.evaluate('pattern')+'/'); rescue SyntaxError; end) === VIM.evaluate('a:target') then 1 else 0 end}") 1005e3dae8bSBram Moolenaar else 1015e3dae8bSBram Moolenaar return 0 1025e3dae8bSBram Moolenaar endif 1035e3dae8bSBram Moolenaarendfunction 1045e3dae8bSBram Moolenaar 1055e3dae8bSBram Moolenaarfunction! s:bsub(target,pattern,replacement) 1065e3dae8bSBram Moolenaar return substitute(a:target,'\C\\\@<!'.a:pattern,a:replacement,'g') 1075e3dae8bSBram Moolenaarendfunction 1085e3dae8bSBram Moolenaar 1095e3dae8bSBram Moolenaarfunction! CucumberComplete(findstart,base) abort 1105e3dae8bSBram Moolenaar let indent = indent('.') 1115e3dae8bSBram Moolenaar let group = synIDattr(synID(line('.'),indent+1,1),'name') 1125e3dae8bSBram Moolenaar let type = matchstr(group,'\Ccucumber\zs\%(Given\|When\|Then\)') 1135e3dae8bSBram Moolenaar let e = matchend(getline('.'),'^\s*\S\+\s') 1145e3dae8bSBram Moolenaar if type == '' || col('.') < col('$') || e < 0 1155e3dae8bSBram Moolenaar return -1 1165e3dae8bSBram Moolenaar endif 1175e3dae8bSBram Moolenaar if a:findstart 1185e3dae8bSBram Moolenaar return e 1195e3dae8bSBram Moolenaar endif 1205e3dae8bSBram Moolenaar let steps = [] 1215e3dae8bSBram Moolenaar for step in s:allsteps() 1225e3dae8bSBram Moolenaar if step[2] ==# type 1235e3dae8bSBram Moolenaar if step[3] =~ '^[''"]' 1245e3dae8bSBram Moolenaar let steps += [step[3][1:-2]] 1255e3dae8bSBram Moolenaar elseif step[3] =~ '^/\^.*\$/$' 1265e3dae8bSBram Moolenaar let pattern = step[3][2:-3] 1275e3dae8bSBram Moolenaar let pattern = substitute(pattern,'\C^(?:|I )','I ','') 1285e3dae8bSBram Moolenaar let pattern = s:bsub(pattern,'\\[Sw]','w') 1295e3dae8bSBram Moolenaar let pattern = s:bsub(pattern,'\\d','1') 1305e3dae8bSBram Moolenaar let pattern = s:bsub(pattern,'\\[sWD]',' ') 1315e3dae8bSBram Moolenaar let pattern = s:bsub(pattern,'\[\^\\\="\]','_') 1325e3dae8bSBram Moolenaar let pattern = s:bsub(pattern,'[[:alnum:]. _-][?*]?\=','') 1335e3dae8bSBram Moolenaar let pattern = s:bsub(pattern,'\[\([^^]\).\{-\}\]','\1') 1345e3dae8bSBram Moolenaar let pattern = s:bsub(pattern,'+?\=','') 1355e3dae8bSBram Moolenaar let pattern = s:bsub(pattern,'(\([[:alnum:]. -]\{-\}\))','\1') 1365e3dae8bSBram Moolenaar let pattern = s:bsub(pattern,'\\\([[:punct:]]\)','\1') 1375e3dae8bSBram Moolenaar if pattern !~ '[\\()*?]' 1385e3dae8bSBram Moolenaar let steps += [pattern] 1395e3dae8bSBram Moolenaar endif 1405e3dae8bSBram Moolenaar endif 1415e3dae8bSBram Moolenaar endif 1425e3dae8bSBram Moolenaar endfor 1435e3dae8bSBram Moolenaar call filter(steps,'strpart(v:val,0,strlen(a:base)) ==# a:base') 1445e3dae8bSBram Moolenaar return sort(steps) 1455e3dae8bSBram Moolenaarendfunction 1465e3dae8bSBram Moolenaar 147543b7ef7SBram Moolenaarlet &cpo = s:keepcpo 148543b7ef7SBram Moolenaarunlet s:keepcpo 149543b7ef7SBram Moolenaar 1505e3dae8bSBram Moolenaar" vim:set sts=2 sw=2: 151