Bram Moolenaar | 5e3dae8 | 2010-03-02 16:19:40 +0100 | [diff] [blame] | 1 | " Vim indent file |
| 2 | " Language: Cucumber |
| 3 | " Maintainer: Tim Pope <vimNOSPAM@tpope.org> |
Tim Pope | 715a805 | 2023-12-28 13:03:39 -0500 | [diff] [blame] | 4 | " Last Change: 2023 Dec 28 |
Eisuke Kawashima | fbbaa6e | 2025-04-16 18:20:59 +0200 | [diff] [blame] | 5 | " 2025 Apr 16 by Vim Project (set 'cpoptions' for line continuation, #17121) |
Bram Moolenaar | 5e3dae8 | 2010-03-02 16:19:40 +0100 | [diff] [blame] | 6 | |
| 7 | if exists("b:did_indent") |
| 8 | finish |
| 9 | endif |
| 10 | let b:did_indent = 1 |
Eisuke Kawashima | fbbaa6e | 2025-04-16 18:20:59 +0200 | [diff] [blame] | 11 | let s:cpo_save = &cpo |
| 12 | set cpo&vim |
Bram Moolenaar | 5e3dae8 | 2010-03-02 16:19:40 +0100 | [diff] [blame] | 13 | |
| 14 | setlocal autoindent |
| 15 | setlocal indentexpr=GetCucumberIndent() |
| 16 | setlocal indentkeys=o,O,*<Return>,<:>,0<Bar>,0#,=,!^F |
| 17 | |
Bram Moolenaar | 543b7ef | 2013-06-01 14:50:56 +0200 | [diff] [blame] | 18 | let b:undo_indent = 'setl ai< inde< indk<' |
| 19 | |
Bram Moolenaar | 5e3dae8 | 2010-03-02 16:19:40 +0100 | [diff] [blame] | 20 | " Only define the function once. |
| 21 | if exists("*GetCucumberIndent") |
| 22 | finish |
| 23 | endif |
| 24 | |
Tim Pope | 715a805 | 2023-12-28 13:03:39 -0500 | [diff] [blame] | 25 | let 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 | |
| 34 | function! 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 Moolenaar | 5e3dae8 | 2010-03-02 16:19:40 +0100 | [diff] [blame] | 52 | endfunction |
| 53 | |
Tim Pope | 715a805 | 2023-12-28 13:03:39 -0500 | [diff] [blame] | 54 | function! 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 Moolenaar | 543b7ef | 2013-06-01 14:50:56 +0200 | [diff] [blame] | 61 | " feature heading |
Bram Moolenaar | 5e3dae8 | 2010-03-02 16:19:40 +0100 | [diff] [blame] | 62 | return 0 |
Tim Pope | 715a805 | 2023-12-28 13:03:39 -0500 | [diff] [blame] | 63 | elseif curr.heading ==# 'examples' |
Bram Moolenaar | 543b7ef | 2013-06-01 14:50:56 +0200 | [diff] [blame] | 64 | " examples heading |
Bram Moolenaar | 89bcfda | 2016-08-30 23:26:57 +0200 | [diff] [blame] | 65 | return 2 * sw |
Tim Pope | 715a805 | 2023-12-28 13:03:39 -0500 | [diff] [blame] | 66 | elseif curr.heading ==# 'bg_or_scenario' |
Bram Moolenaar | 543b7ef | 2013-06-01 14:50:56 +0200 | [diff] [blame] | 67 | " background, scenario or outline heading |
Bram Moolenaar | 89bcfda | 2016-08-30 23:26:57 +0200 | [diff] [blame] | 68 | return sw |
Tim Pope | 715a805 | 2023-12-28 13:03:39 -0500 | [diff] [blame] | 69 | elseif prev.heading ==# 'feature' |
Bram Moolenaar | 543b7ef | 2013-06-01 14:50:56 +0200 | [diff] [blame] | 70 | " line after feature heading |
Bram Moolenaar | 89bcfda | 2016-08-30 23:26:57 +0200 | [diff] [blame] | 71 | return sw |
Tim Pope | 715a805 | 2023-12-28 13:03:39 -0500 | [diff] [blame] | 72 | elseif prev.heading ==# 'examples' |
Bram Moolenaar | 543b7ef | 2013-06-01 14:50:56 +0200 | [diff] [blame] | 73 | " line after examples heading |
Bram Moolenaar | 89bcfda | 2016-08-30 23:26:57 +0200 | [diff] [blame] | 74 | return 3 * sw |
Tim Pope | 715a805 | 2023-12-28 13:03:39 -0500 | [diff] [blame] | 75 | elseif prev.heading ==# 'bg_or_scenario' |
Bram Moolenaar | 543b7ef | 2013-06-01 14:50:56 +0200 | [diff] [blame] | 76 | " line after background, scenario or outline heading |
Bram Moolenaar | 89bcfda | 2016-08-30 23:26:57 +0200 | [diff] [blame] | 77 | return 2 * sw |
Tim Pope | 715a805 | 2023-12-28 13:03:39 -0500 | [diff] [blame] | 78 | elseif (curr.tag || curr.comment) && (next.heading ==# 'feature' || prev.indent <= 0) |
Bram Moolenaar | 543b7ef | 2013-06-01 14:50:56 +0200 | [diff] [blame] | 79 | " tag or comment before a feature heading |
Bram Moolenaar | 5e3dae8 | 2010-03-02 16:19:40 +0100 | [diff] [blame] | 80 | return 0 |
Tim Pope | 715a805 | 2023-12-28 13:03:39 -0500 | [diff] [blame] | 81 | elseif curr.tag |
Bram Moolenaar | 543b7ef | 2013-06-01 14:50:56 +0200 | [diff] [blame] | 82 | " other tags |
Bram Moolenaar | 89bcfda | 2016-08-30 23:26:57 +0200 | [diff] [blame] | 83 | return sw |
Tim Pope | 715a805 | 2023-12-28 13:03:39 -0500 | [diff] [blame] | 84 | elseif (curr.table || curr.comment) && prev.table |
Bram Moolenaar | 543b7ef | 2013-06-01 14:50:56 +0200 | [diff] [blame] | 85 | " mid-table |
| 86 | " preserve indent |
Tim Pope | 715a805 | 2023-12-28 13:03:39 -0500 | [diff] [blame] | 87 | return prev.indent |
| 88 | elseif curr.table && !prev.table |
Bram Moolenaar | 543b7ef | 2013-06-01 14:50:56 +0200 | [diff] [blame] | 89 | " first line of a table, relative indent |
Tim Pope | 715a805 | 2023-12-28 13:03:39 -0500 | [diff] [blame] | 90 | return prev.indent + sw |
| 91 | elseif !curr.table && prev.table |
Bram Moolenaar | 543b7ef | 2013-06-01 14:50:56 +0200 | [diff] [blame] | 92 | " line after a table, relative unindent |
Tim Pope | 715a805 | 2023-12-28 13:03:39 -0500 | [diff] [blame] | 93 | return prev.indent - sw |
| 94 | elseif curr.comment && getline(v:lnum-1) =~# '^\s*$' && next.heading ==# 'bg_or_scenario' |
Bram Moolenaar | 543b7ef | 2013-06-01 14:50:56 +0200 | [diff] [blame] | 95 | " comments on scenarios |
Bram Moolenaar | 89bcfda | 2016-08-30 23:26:57 +0200 | [diff] [blame] | 96 | return sw |
Bram Moolenaar | 5e3dae8 | 2010-03-02 16:19:40 +0100 | [diff] [blame] | 97 | endif |
Tim Pope | 715a805 | 2023-12-28 13:03:39 -0500 | [diff] [blame] | 98 | return prev.indent < 0 ? 0 : prev.indent |
Bram Moolenaar | 5e3dae8 | 2010-03-02 16:19:40 +0100 | [diff] [blame] | 99 | endfunction |
| 100 | |
Eisuke Kawashima | fbbaa6e | 2025-04-16 18:20:59 +0200 | [diff] [blame] | 101 | let &cpo = s:cpo_save |
| 102 | unlet s:cpo_save |
| 103 | |
Bram Moolenaar | 5e3dae8 | 2010-03-02 16:19:40 +0100 | [diff] [blame] | 104 | " vim:set sts=2 sw=2: |