blob: 5d144e426b5266caf4edafb8892e8bbc7d237908 [file] [log] [blame]
Bram Moolenaar5e3dae82010-03-02 16:19:40 +01001" Vim indent file
2" Language: Cucumber
3" Maintainer: Tim Pope <vimNOSPAM@tpope.org>
Tim Pope715a8052023-12-28 13:03:39 -05004" Last Change: 2023 Dec 28
Bram Moolenaar5e3dae82010-03-02 16:19:40 +01005
6if exists("b:did_indent")
7 finish
8endif
9let b:did_indent = 1
10
11setlocal autoindent
12setlocal indentexpr=GetCucumberIndent()
13setlocal indentkeys=o,O,*<Return>,<:>,0<Bar>,0#,=,!^F
14
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020015let b:undo_indent = 'setl ai< inde< indk<'
16
Bram Moolenaar5e3dae82010-03-02 16:19:40 +010017" Only define the function once.
18if exists("*GetCucumberIndent")
19 finish
20endif
21
Tim Pope715a8052023-12-28 13:03:39 -050022let 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
31function! 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 \ }
Bram Moolenaar5e3dae82010-03-02 16:19:40 +010049endfunction
50
Tim Pope715a8052023-12-28 13:03:39 -050051function! 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'
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020058 " feature heading
Bram Moolenaar5e3dae82010-03-02 16:19:40 +010059 return 0
Tim Pope715a8052023-12-28 13:03:39 -050060 elseif curr.heading ==# 'examples'
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020061 " examples heading
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020062 return 2 * sw
Tim Pope715a8052023-12-28 13:03:39 -050063 elseif curr.heading ==# 'bg_or_scenario'
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020064 " background, scenario or outline heading
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020065 return sw
Tim Pope715a8052023-12-28 13:03:39 -050066 elseif prev.heading ==# 'feature'
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020067 " line after feature heading
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020068 return sw
Tim Pope715a8052023-12-28 13:03:39 -050069 elseif prev.heading ==# 'examples'
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020070 " line after examples heading
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020071 return 3 * sw
Tim Pope715a8052023-12-28 13:03:39 -050072 elseif prev.heading ==# 'bg_or_scenario'
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020073 " line after background, scenario or outline heading
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020074 return 2 * sw
Tim Pope715a8052023-12-28 13:03:39 -050075 elseif (curr.tag || curr.comment) && (next.heading ==# 'feature' || prev.indent <= 0)
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020076 " tag or comment before a feature heading
Bram Moolenaar5e3dae82010-03-02 16:19:40 +010077 return 0
Tim Pope715a8052023-12-28 13:03:39 -050078 elseif curr.tag
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020079 " other tags
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020080 return sw
Tim Pope715a8052023-12-28 13:03:39 -050081 elseif (curr.table || curr.comment) && prev.table
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020082 " mid-table
83 " preserve indent
Tim Pope715a8052023-12-28 13:03:39 -050084 return prev.indent
85 elseif curr.table && !prev.table
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020086 " first line of a table, relative indent
Tim Pope715a8052023-12-28 13:03:39 -050087 return prev.indent + sw
88 elseif !curr.table && prev.table
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020089 " line after a table, relative unindent
Tim Pope715a8052023-12-28 13:03:39 -050090 return prev.indent - sw
91 elseif curr.comment && getline(v:lnum-1) =~# '^\s*$' && next.heading ==# 'bg_or_scenario'
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020092 " comments on scenarios
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020093 return sw
Bram Moolenaar5e3dae82010-03-02 16:19:40 +010094 endif
Tim Pope715a8052023-12-28 13:03:39 -050095 return prev.indent < 0 ? 0 : prev.indent
Bram Moolenaar5e3dae82010-03-02 16:19:40 +010096endfunction
97
98" vim:set sts=2 sw=2: