blob: 33d4cc73177eecd5a65ce0818d67927577589312 [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
Eisuke Kawashimafbbaa6e2025-04-16 18:20:59 +02005" 2025 Apr 16 by Vim Project (set 'cpoptions' for line continuation, #17121)
Bram Moolenaar5e3dae82010-03-02 16:19:40 +01006
7if exists("b:did_indent")
8 finish
9endif
10let b:did_indent = 1
Eisuke Kawashimafbbaa6e2025-04-16 18:20:59 +020011let s:cpo_save = &cpo
12set cpo&vim
Bram Moolenaar5e3dae82010-03-02 16:19:40 +010013
14setlocal autoindent
15setlocal indentexpr=GetCucumberIndent()
16setlocal indentkeys=o,O,*<Return>,<:>,0<Bar>,0#,=,!^F
17
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020018let b:undo_indent = 'setl ai< inde< indk<'
19
Bram Moolenaar5e3dae82010-03-02 16:19:40 +010020" Only define the function once.
21if exists("*GetCucumberIndent")
22 finish
23endif
24
Tim Pope715a8052023-12-28 13:03:39 -050025let s:headings = {
26 \ 'Feature': 'feature',
27 \ 'Rule': 'rule',
28 \ 'Background': 'bg_or_scenario',
29 \ 'Scenario': 'bg_or_scenario',
30 \ 'ScenarioOutline': 'bg_or_scenario',
31 \ 'Examples': 'examples',
32 \ 'Scenarios': 'examples'}
33
34function! s:Line(lnum) abort
35 if getline(a:lnum) =~# ':'
36 let group = matchstr(synIDattr(synID(a:lnum,1+indent(a:lnum), 1), 'name'), '^cucumber\zs.*')
37 if !has_key(s:headings, group)
38 let group = substitute(matchstr(getline(a:lnum), '^\s*\zs\%([^:]\+\)\ze:\S\@!'), '\s\+', '', 'g')
39 endif
40 else
41 let group = ''
42 endif
43 let char = matchstr(getline(a:lnum), '^\s*\zs[[:punct:]]')
44 return {
45 \ 'lnum': a:lnum,
46 \ 'indent': indent(a:lnum),
47 \ 'heading': get(s:headings, group, ''),
48 \ 'tag': char ==# '@',
49 \ 'table': char ==# '|',
50 \ 'comment': char ==# '#',
51 \ }
Bram Moolenaar5e3dae82010-03-02 16:19:40 +010052endfunction
53
Tim Pope715a8052023-12-28 13:03:39 -050054function! GetCucumberIndent(...) abort
55 let lnum = a:0 ? a:1 : v:lnum
56 let sw = shiftwidth()
57 let prev = s:Line(prevnonblank(lnum-1))
58 let curr = s:Line(lnum)
59 let next = s:Line(nextnonblank(lnum+1))
60 if curr.heading ==# 'feature'
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020061 " feature heading
Bram Moolenaar5e3dae82010-03-02 16:19:40 +010062 return 0
Tim Pope715a8052023-12-28 13:03:39 -050063 elseif curr.heading ==# 'examples'
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020064 " examples heading
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020065 return 2 * sw
Tim Pope715a8052023-12-28 13:03:39 -050066 elseif curr.heading ==# 'bg_or_scenario'
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020067 " background, scenario or outline heading
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020068 return sw
Tim Pope715a8052023-12-28 13:03:39 -050069 elseif prev.heading ==# 'feature'
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020070 " line after feature heading
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020071 return sw
Tim Pope715a8052023-12-28 13:03:39 -050072 elseif prev.heading ==# 'examples'
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020073 " line after examples heading
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020074 return 3 * sw
Tim Pope715a8052023-12-28 13:03:39 -050075 elseif prev.heading ==# 'bg_or_scenario'
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020076 " line after background, scenario or outline heading
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020077 return 2 * sw
Tim Pope715a8052023-12-28 13:03:39 -050078 elseif (curr.tag || curr.comment) && (next.heading ==# 'feature' || prev.indent <= 0)
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020079 " tag or comment before a feature heading
Bram Moolenaar5e3dae82010-03-02 16:19:40 +010080 return 0
Tim Pope715a8052023-12-28 13:03:39 -050081 elseif curr.tag
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020082 " other tags
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020083 return sw
Tim Pope715a8052023-12-28 13:03:39 -050084 elseif (curr.table || curr.comment) && prev.table
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020085 " mid-table
86 " preserve indent
Tim Pope715a8052023-12-28 13:03:39 -050087 return prev.indent
88 elseif curr.table && !prev.table
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020089 " first line of a table, relative indent
Tim Pope715a8052023-12-28 13:03:39 -050090 return prev.indent + sw
91 elseif !curr.table && prev.table
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020092 " line after a table, relative unindent
Tim Pope715a8052023-12-28 13:03:39 -050093 return prev.indent - sw
94 elseif curr.comment && getline(v:lnum-1) =~# '^\s*$' && next.heading ==# 'bg_or_scenario'
Bram Moolenaar543b7ef2013-06-01 14:50:56 +020095 " comments on scenarios
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020096 return sw
Bram Moolenaar5e3dae82010-03-02 16:19:40 +010097 endif
Tim Pope715a8052023-12-28 13:03:39 -050098 return prev.indent < 0 ? 0 : prev.indent
Bram Moolenaar5e3dae82010-03-02 16:19:40 +010099endfunction
100
Eisuke Kawashimafbbaa6e2025-04-16 18:20:59 +0200101let &cpo = s:cpo_save
102unlet s:cpo_save
103
Bram Moolenaar5e3dae82010-03-02 16:19:40 +0100104" vim:set sts=2 sw=2: