blob: 3dd8d711a8342d83763a7630a08c7d43e6a945df [file] [log] [blame]
Bram Moolenaarc81e5e72007-05-05 18:24:42 +00001" Vim indent file
2" Language: bst
3" Author: Tim Pope <vimNOSPAM@tpope.info>
Bram Moolenaar47c532e2022-03-19 15:18:53 +00004" Last Change: 2022 Mar 15
Bram Moolenaarc81e5e72007-05-05 18:24:42 +00005
6if exists("b:did_indent")
7 finish
8endif
9let b:did_indent = 1
10
Bram Moolenaarc81e5e72007-05-05 18:24:42 +000011setlocal indentexpr=GetBstIndent(v:lnum)
Bram Moolenaarc81e5e72007-05-05 18:24:42 +000012setlocal cinkeys&
13setlocal cinkeys-=0#
14setlocal indentkeys&
Bram Moolenaar47c532e2022-03-19 15:18:53 +000015let b:undo_indent = 'setlocal indentexpr< cinkeys< indentkeys<'
Bram Moolenaarc81e5e72007-05-05 18:24:42 +000016
17" Only define the function once.
18if exists("*GetBstIndent")
19 finish
20endif
21
22function! s:prevgood(lnum)
23 " Find a non-blank line above the current line.
24 " Skip over comments.
25 let lnum = a:lnum
26 while lnum > 0
27 let lnum = prevnonblank(lnum - 1)
28 if getline(lnum) !~ '^\s*%.*$'
29 break
30 endif
31 endwhile
32 return lnum
33endfunction
34
35function! s:strip(lnum)
36 let line = getline(a:lnum)
37 let line = substitute(line,'"[^"]*"','""','g')
38 let line = substitute(line,'%.*','','')
39 let line = substitute(line,'^\s\+','','')
40 return line
41endfunction
42
43function! s:count(string,char)
44 let str = substitute(a:string,'[^'.a:char.']','','g')
45 return strlen(str)
46endfunction
47
48function! GetBstIndent(lnum) abort
49 if a:lnum == 1
50 return 0
51 endif
52 let lnum = s:prevgood(a:lnum)
53 if lnum <= 0
54 return indent(a:lnum - 1)
55 endif
56 let line = s:strip(lnum)
57 let cline = s:strip(a:lnum)
58 if cline =~ '^}' && exists("b:current_syntax")
59 call cursor(a:lnum,indent(a:lnum))
60 if searchpair('{','','}','bW',"synIDattr(synID(line('.'),col('.'),1),'name') =~? 'comment\\|string'")
61 if col('.')+1 == col('$')
62 return indent('.')
63 else
64 return virtcol('.')-1
65 endif
66 endif
67 endif
68 let fakeline = substitute(line,'^}','','').matchstr(cline,'^}')
69 let ind = indent(lnum)
Bram Moolenaar3ec574f2017-06-13 18:12:01 +020070 let ind = ind + shiftwidth() * s:count(line,'{')
71 let ind = ind - shiftwidth() * s:count(fakeline,'}')
Bram Moolenaarc81e5e72007-05-05 18:24:42 +000072 return ind
73endfunction