neovim

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

tcl.vim (2542B)


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