xref: /vim-8.2.3635/runtime/indent/tcl.vim (revision 94688b8a)
1" Vim indent file
2" Language:	    	Tcl
3" Previous Maintainer:	Nikolai Weibull <[email protected]>
4" Latest Update:  	Chris Heithoff <[email protected]>
5" Latest Revision:  	2018-12-05
6
7if exists("b:did_indent")
8  finish
9endif
10let b:did_indent = 1
11
12setlocal indentexpr=GetTclIndent()
13setlocal indentkeys=0{,0},!^F,o,O,0]
14setlocal nosmartindent
15
16if exists("*GetTclIndent")
17  finish
18endif
19
20function s:prevnonblanknoncomment(lnum)
21  let lnum = prevnonblank(a:lnum)
22  while lnum > 0
23    let line = getline(lnum)
24    if line !~ '^\s*\(#\|$\)'
25      break
26    endif
27    let lnum = prevnonblank(lnum - 1)
28  endwhile
29  return lnum
30endfunction
31
32function s:ends_with_backslash(lnum)
33  let line = getline(a:lnum)
34  if line =~ '\\\s*$'
35    return 1
36  else
37    return 0
38  endif
39endfunction
40
41function s:count_braces(lnum, count_open)
42  let n_open = 0
43  let n_close = 0
44  let line = getline(a:lnum)
45  let pattern = '[{}]'
46  let i = match(line, pattern)
47  while i != -1
48    if synIDattr(synID(a:lnum, i + 1, 0), 'name') !~ 'tcl\%(Comment\|String\)'
49      if line[i] == '{'
50        let n_open += 1
51      elseif line[i] == '}'
52        if n_open > 0
53          let n_open -= 1
54        else
55          let n_close += 1
56        endif
57      endif
58    endif
59    let i = match(line, pattern, i + 1)
60  endwhile
61  return a:count_open ? n_open : n_close
62endfunction
63
64function GetTclIndent()
65  let line = getline(v:lnum)
66
67  " Get the line number of the previous non-blank or non-comment line.
68  let pnum = s:prevnonblanknoncomment(v:lnum - 1)
69  if pnum == 0
70    return 0
71  endif
72
73  " ..and the previous line before the previous line.
74  let pnum2 = s:prevnonblanknoncomment(pnum-1)
75
76  " Default indentation is to preserve the previous indentation.
77  let ind = indent(pnum)
78
79  " ...but if previous line introduces an open brace, then increase current line's indentation
80  if s:count_braces(pnum, 1) > 0
81    let ind += shiftwidth()
82  else
83    " Look for backslash line continuation on the previous two lines.
84    let slash1 = s:ends_with_backslash(pnum)
85    let slash2 = s:ends_with_backslash(pnum2)
86    if slash1 && !slash2
87      " If the previous line begins a line continuation.
88      let ind += shiftwidth()
89    elseif !slash1 && slash2
90      " If two lines ago was the end of a line continuation group of lines.
91      let ind -= shiftwidth()
92    endif
93  endif
94
95  " If the current line begins with a closed brace, then decrease the indentation by one.
96  if line =~ '^\s*}'
97    let ind -= shiftwidth()
98  endif
99
100  return ind
101endfunction
102