11" Vim indent file
22" Language: Cucumber
33" Maintainer: Tim Pope <[email protected] >4- " Last Change: 2017 Jun 13
4+ " Last Change: 2023 Dec 28
55
66if exists (" b:did_indent" )
77 finish
@@ -19,57 +19,80 @@ if exists("*GetCucumberIndent")
1919 finish
2020endif
2121
22- function ! s: syn (lnum)
23- return synIDattr (synID (a: lnum ,1 + indent (a: lnum ),1 ),' name' )
22+ let s: headings = {
23+ \ ' Feature' : ' feature' ,
24+ \ ' Rule' : ' rule' ,
25+ \ ' Background' : ' bg_or_scenario' ,
26+ \ ' Scenario' : ' bg_or_scenario' ,
27+ \ ' ScenarioOutline' : ' bg_or_scenario' ,
28+ \ ' Examples' : ' examples' ,
29+ \ ' Scenarios' : ' examples' }
30+
31+ function ! s: Line (lnum) abort
32+ if getline (a: lnum ) = ~# ' :'
33+ let group = matchstr (synIDattr (synID (a: lnum ,1 + indent (a: lnum ), 1 ), ' name' ), ' ^cucumber\zs.*' )
34+ if ! has_key (s: headings , group)
35+ let group = substitute (matchstr (getline (a: lnum ), ' ^\s*\zs\%([^:]\+\)\ze:\S\@!' ), ' \s\+' , ' ' , ' g' )
36+ endif
37+ else
38+ let group = ' '
39+ endif
40+ let char = matchstr (getline (a: lnum ), ' ^\s*\zs[[:punct:]]' )
41+ return {
42+ \ ' lnum' : a: lnum ,
43+ \ ' indent' : indent (a: lnum ),
44+ \ ' heading' : get (s: headings , group, ' ' ),
45+ \ ' tag' : char == # ' @' ,
46+ \ ' table' : char == # ' |' ,
47+ \ ' comment' : char == # ' #' ,
48+ \ }
2449endfunction
2550
26- function ! GetCucumberIndent ()
27- let line = getline (prevnonblank (v: lnum- 1 ))
28- let cline = getline (v: lnum )
29- let nline = getline (nextnonblank (v: lnum+ 1 ))
30- let sw = exists (' *shiftwidth' ) ? shiftwidth () : shiftwidth ()
31- let syn = s: syn (prevnonblank (v: lnum- 1 ))
32- let csyn = s: syn (v: lnum )
33- let nsyn = s: syn (nextnonblank (v: lnum+ 1 ))
34- if csyn == # ' cucumberFeature' || cline = ~# ' ^\s*Feature:'
51+ function ! GetCucumberIndent (... ) abort
52+ let lnum = a: 0 ? a: 1 : v: lnum
53+ let sw = shiftwidth ()
54+ let prev = s: Line (prevnonblank (lnum- 1 ))
55+ let curr = s: Line (lnum)
56+ let next = s: Line (nextnonblank (lnum+ 1 ))
57+ if curr.heading == # ' feature'
3558 " feature heading
3659 return 0
37- elseif csyn == # ' cucumberExamples ' || cline = ~# ' ^\s*\%(Examples\|Scenarios\): '
60+ elseif curr.heading == # ' examples '
3861 " examples heading
3962 return 2 * sw
40- elseif csyn = ~# ' ^cucumber\%(Background\|Scenario\|ScenarioOutline\)$ ' || cline = ~ # ' ^\s*\%(Background\|Scenario\|Scenario Outline\): '
63+ elseif curr.heading == # ' bg_or_scenario '
4164 " background, scenario or outline heading
4265 return sw
43- elseif syn == # ' cucumberFeature ' || line = ~# ' ^\s*Feature: '
66+ elseif prev .heading == # ' feature '
4467 " line after feature heading
4568 return sw
46- elseif syn == # ' cucumberExamples ' || line = ~# ' ^\s*\%(Examples\|Scenarios\): '
69+ elseif prev .heading == # ' examples '
4770 " line after examples heading
4871 return 3 * sw
49- elseif syn = ~# ' ^cucumber\%(Background\|Scenario\|ScenarioOutline\)$ ' || line = ~ # ' ^\s*\%(Background\|Scenario\|Scenario Outline\): '
72+ elseif prev .heading == # ' bg_or_scenario '
5073 " line after background, scenario or outline heading
5174 return 2 * sw
52- elseif cline = ~# ' ^\s*[@#] ' && (nsyn == ' cucumberFeature ' || nline = ~ # ' ^\s*Feature: ' || indent ( prevnonblank ( v: lnum - 1 )) <= 0 )
75+ elseif (curr. tag || curr. comment ) && (next .heading == # ' feature ' || prev . indent <= 0 )
5376 " tag or comment before a feature heading
5477 return 0
55- elseif cline = ~# ' ^\s*@ '
78+ elseif curr. tag
5679 " other tags
5780 return sw
58- elseif cline = ~# ' ^\s*[#|] ' && line = ~# ' ^\s*| '
81+ elseif (curr.table || curr. comment ) && prev .table
5982 " mid-table
6083 " preserve indent
61- return indent ( prevnonblank ( v: lnum - 1 ))
62- elseif cline = ~# ' ^\s*| ' && line = ~# ' ^\s*[^|] '
84+ return prev . indent
85+ elseif curr.table && ! prev .table
6386 " first line of a table, relative indent
64- return indent ( prevnonblank ( v: lnum - 1 )) + sw
65- elseif cline = ~# ' ^\s*[^|] ' && line = ~# ' ^\s*| '
87+ return prev . indent + sw
88+ elseif ! curr.table && prev .table
6689 " line after a table, relative unindent
67- return indent ( prevnonblank ( v: lnum - 1 )) - sw
68- elseif cline = ~# ' ^\s*# ' && getline (v: lnum- 1 ) = ~ ' ^\s*$' && (nsyn = ~# ' ^cucumber\%(Background\|Scenario\|ScenarioOutline\)$ ' || nline = ~ # ' ^\s*\%(Background\|Scenario\|Scenario Outline\): ' )
90+ return prev . indent - sw
91+ elseif curr. comment && getline (v: lnum- 1 ) = ~# ' ^\s*$' && next .heading == # ' bg_or_scenario '
6992 " comments on scenarios
7093 return sw
7194 endif
72- return indent ( prevnonblank ( v: lnum - 1 ))
95+ return prev . indent < 0 ? 0 : prev . indent
7396endfunction
7497
7598" vim:set sts = 2 sw = 2 :
0 commit comments