vimtex/indent/tex.vim

181 lines
4.5 KiB
VimL
Raw Normal View History

2015-03-07 17:02:15 -05:00
" vimtex - LaTeX plugin for Vim
2014-07-22 18:08:57 -04:00
"
" Maintainer: Karl Yngve Lervåg
" Email: karl.yngve@gmail.com
"
2015-03-19 10:12:12 -04:00
if exists('b:did_indent')
2013-10-10 08:47:08 -04:00
finish
endif
let b:did_indent = 1
2015-01-26 09:41:40 -05:00
2015-03-07 17:02:15 -05:00
call vimtex#util#set_default('g:vimtex_indent_enabled', 1)
if !g:vimtex_indent_enabled | finish | endif
2015-01-26 09:41:40 -05:00
2013-10-10 08:47:08 -04:00
let s:cpo_save = &cpo
set cpo&vim
setlocal autoindent
setlocal indentexpr=VimtexIndent()
2013-10-10 08:47:08 -04:00
setlocal indentkeys&
2015-10-26 17:43:36 -04:00
setlocal indentkeys+=[,(,{,),},],\&,=item
2013-10-10 08:47:08 -04:00
function! VimtexIndent() " {{{1
2013-10-10 08:47:08 -04:00
" Find a non-blank non-comment line above the current line
let lnum = prevnonblank(v:lnum - 1)
2015-03-19 10:12:12 -04:00
while lnum != 0 && getline(lnum) =~# '^\s*%'
2013-10-10 08:47:08 -04:00
let lnum = prevnonblank(lnum - 1)
endwhile
" Zero indent for top of file
if lnum == 0
return 0
endif
" Get current and previous line, remove comments
let cline = substitute(getline(v:lnum), '\\\@<!%.*', '', '')
let pline = substitute(getline(lnum), '\\\@<!%.*', '', '')
" Check for verbatim modes
2015-03-19 10:12:12 -04:00
if synIDattr(synID(v:lnum, indent(v:lnum), 1), 'name') ==# 'texZone'
2013-10-10 08:47:08 -04:00
if empty(cline)
return indent(lnum)
else
return indent(v:lnum)
end
endif
" Align on ampersands
2015-03-19 10:12:12 -04:00
if cline =~# '^\s*&' && pline =~# '\\\@<!&.*'
return indent(v:lnum) + match(pline, '\\\@<!&') - stridx(cline, '&')
2013-10-10 08:47:08 -04:00
endif
" Find previous non-empty non-comment non-ampersand line
2015-03-19 10:12:12 -04:00
while lnum != 0 && (match(pline, '\\\@<!&') != -1 || pline =~# '^\s*%')
2013-10-10 08:47:08 -04:00
let lnum = prevnonblank(lnum - 1)
let pline = getline(lnum)
endwhile
" Zero indent for top of file
if lnum == 0
return 0
endif
" Use previous indentation for comments
2015-03-19 10:12:12 -04:00
if cline =~# '^\s*%'
2013-10-10 08:47:08 -04:00
return indent(v:lnum)
endif
let ind = indent(lnum)
" Add indent on begin environment
2015-03-19 10:12:12 -04:00
if pline =~# '\\begin{.*}' && pline !~ s:envs_noindent
2013-10-10 08:47:08 -04:00
let ind = ind + &sw
" Add extra indent for list environments
if pline =~ s:envs_lists
let ind = ind + &sw
endif
endif
" Subtract indent on end environment
2015-03-19 10:12:12 -04:00
if cline =~# '\\end{.*}' && cline !~ s:envs_noindent
2013-10-10 08:47:08 -04:00
let ind = ind - &sw
" Subtract extra indent for list environments
if cline =~ s:envs_lists
let ind = ind - &sw
endif
endif
" Indent opening and closing delimiters
let l:delimiters = match(map(synstack(v:lnum, max([col('.') - 1, 1])),
\ 'synIDattr(v:val, ''name'')'), '^texMathZone') >= 0
\ ? [s:delimiters_open_math, s:delimiters_close_math]
\ : [s:delimiters_open_tex, s:delimiters_close_tex]
let popen = s:count_delimiters(pline, l:delimiters[0])
let copen = s:count_delimiters(cline, l:delimiters[0])
let pclose = s:count_delimiters(pline, l:delimiters[1])
let cclose = s:count_delimiters(cline, l:delimiters[1])
let ind += &sw*(max([popen - pclose, 0]) - max([cclose - copen, 0]))
2013-10-10 08:47:08 -04:00
" Indent list items
2015-03-19 10:12:12 -04:00
if pline =~# '^\s*\\\(bib\)\?item'
2013-10-10 08:47:08 -04:00
let ind += &sw
endif
2015-03-19 10:12:12 -04:00
if cline =~# '^\s*\\\(bib\)\?item'
2013-10-10 08:47:08 -04:00
let ind -= &sw
endif
" Indent tikz elements
if pline =~ s:tikz_commands
let ind += &sw
let s:tikz_indented += 1
endif
2015-11-10 14:06:26 -05:00
if s:tikz_indented > 0 && pline =~# ';'
let ind -= &sw
let s:tikz_indented -= 1
endif
2013-10-10 08:47:08 -04:00
return ind
endfunction
"}}}
2015-03-07 17:02:15 -05:00
function! s:count_delimiters(line, pattern) " {{{1
2013-10-10 08:47:08 -04:00
let sum = 0
let indx = match(a:line, a:pattern)
while indx >= 0
let sum += 1
let match = matchstr(a:line, a:pattern, indx)
let indx += len(match)
let indx = match(a:line, a:pattern, indx)
endwhile
return sum
endfunction
2015-03-07 17:02:15 -05:00
" }}}1
" {{{1 Script variables
let s:tikz_indented = 0
" Define some common patterns
let s:envs_lists = 'itemize\|description\|enumerate\|thebibliography'
let s:envs_noindent = 'document\|verbatim\|lstlisting'
let s:delimiters_open_tex = '\(' . join([
2015-03-07 17:02:15 -05:00
\ '{',
\ '\[',
\ '\\(',
\ '\\\[',
\ '\\\Cbegin\s*{.\{-}}',
\ ], '\|') . '\)'
let s:delimiters_close_tex = '\(' . join([
2015-03-07 17:02:15 -05:00
\ '}',
\ '\]',
\ '\\)',
\ '\\\]',
\ '\\\Cend\s*{.\{-}}',
\ ], '\|') . '\)'
let s:delimiters_open_math = '\(' . join([
\ '\\{',
\ '\\\Cleft\s*\%([^\\]\|\\.\|\\\a*\)',
\ '\\\cbigg\?\((\|\[\|\\{\)',
\ ], '\|') . '\)'
let s:delimiters_close_math = '\(' . join([
\ '\\}',
2015-03-07 17:02:15 -05:00
\ '\\\Cright\s*\%([^\\]\|\\.\|\\\a*\)',
\ '\\\cbigg\?\()\|\]\|\\}\)',
\ ], '\|') . '\)'
let s:tikz_commands = '\\\(' . join([
\ 'draw',
\ 'fill',
\ 'path',
\ 'node',
\ 'add\(legendentry\|plot\)',
\ ], '\|') . '\)'
2013-10-10 08:47:08 -04:00
" }}}1
let &cpo = s:cpo_save
unlet s:cpo_save
2014-12-08 14:44:17 -05:00
" vim: fdm=marker sw=2