neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

cucumber.vim (2960B)


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