Skip to content

Commit f37c891

Browse files
committed
Refactor indentation to reduce repetition
References: #51
1 parent 4d43c1b commit f37c891

File tree

1 file changed

+48
-25
lines changed

1 file changed

+48
-25
lines changed

indent/cucumber.vim

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,57 +19,80 @@ if exists("*GetCucumberIndent")
1919
finish
2020
endif
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+
\ }
2449
endfunction
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))
51+
function! GetCucumberIndent(...) abort
52+
let lnum = a:0 ? a:1 : v:lnum
3053
let sw = 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:'
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
7396
endfunction
7497

7598
" vim:set sts=2 sw=2:

0 commit comments

Comments
 (0)