diff options
author | Adam Stankiewicz <sheerun@sher.pl> | 2020-04-25 21:30:46 +0200 |
---|---|---|
committer | Adam Stankiewicz <sheerun@sher.pl> | 2020-04-25 21:30:46 +0200 |
commit | d757bfd643cc73c2d495355c153ed0257f5d5b47 (patch) | |
tree | ff210950456938a779d98f6a2ba7321aca512897 /indent | |
parent | 8ec73a3a8974a62a613680a6b6222a77a7b99546 (diff) | |
download | vim-polyglot-d757bfd643cc73c2d495355c153ed0257f5d5b47.tar.gz vim-polyglot-d757bfd643cc73c2d495355c153ed0257f5d5b47.zip |
Change latex provider to luatex, closes #476
Diffstat (limited to 'indent')
-rw-r--r-- | indent/bib.vim | 85 | ||||
-rw-r--r-- | indent/tex.vim | 402 |
2 files changed, 385 insertions, 102 deletions
diff --git a/indent/bib.vim b/indent/bib.vim new file mode 100644 index 00000000..fa326f3a --- /dev/null +++ b/indent/bib.vim @@ -0,0 +1,85 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1 + +" vimtex - LaTeX plugin for Vim +" +" Maintainer: Karl Yngve Lervåg +" Email: karl.yngve@gmail.com +" + +if exists('b:did_indent') + finish +endif + +if !get(g:, 'vimtex_indent_bib_enabled', 1) | finish | endif + +let b:did_indent = 1 + +let s:cpo_save = &cpo +set cpo&vim + +setlocal autoindent +setlocal indentexpr=VimtexIndentBib() + +function! VimtexIndentBib() abort " {{{1 + " Find first non-blank line above the current line + let lnum = prevnonblank(v:lnum - 1) + if lnum == 0 + return 0 + endif + + " Get some initial conditions + let ind = indent(lnum) + let line = getline(lnum) + let cline = getline(v:lnum) + let g:test = 1 + + " Zero indent for first line of each entry + if cline =~# '^\s*@' + return 0 + endif + + " Title line of entry + if line =~# '^@' + if cline =~# '^\s*}' + return 0 + else + return &sw + endif + endif + + if line =~# '=' + " Indent continued bib info entries + if s:count('{', line) - s:count('}', line) > 0 + let match = searchpos('.*=\s*{','bcne') + return match[1] + elseif cline =~# '^\s*}' + return 0 + endif + elseif s:count('{', line) - s:count('}', line) < 0 + if s:count('{', cline) - s:count('}', cline) < 0 + return 0 + else + return &sw + endif + endif + + return ind +endfunction + +function! s:count(pattern, line) abort " {{{1 + let sum = 0 + let indx = match(a:line, a:pattern) + while indx >= 0 + let sum += 1 + let indx += 1 + let indx = match(a:line, a:pattern, indx) + endwhile + return sum +endfunction + +" }}}1 + +let &cpo = s:cpo_save +unlet s:cpo_save + +endif diff --git a/indent/tex.vim b/indent/tex.vim index f129157e..d0f44282 100644 --- a/indent/tex.vim +++ b/indent/tex.vim @@ -1,140 +1,338 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1 -" LaTeX indent file (part of LaTeX Box) -" Maintainer: David Munger (mungerd@gmail.com) - -if exists("g:LatexBox_custom_indent") && ! g:LatexBox_custom_indent - finish -endif -if exists("b:did_indent") - finish +" vimtex - LaTeX plugin for Vim +" +" Maintainer: Karl Yngve Lervåg +" Email: karl.yngve@gmail.com +" + +if exists('b:did_indent') + finish endif +if !get(g:, 'vimtex_indent_enabled', 1) | finish | endif + +let b:did_vimtex_indent = 1 let b:did_indent = 1 -setlocal indentexpr=LatexBox_TexIndent() -setlocal indentkeys=0=\\end,0=\\end{enumerate},0=\\end{itemize},0=\\end{description},0=\\right,0=\\item,0=\\),0=\\],0},o,O,0\\ +let s:cpo_save = &cpoptions +set cpoptions&vim -let s:list_envs = ['itemize', 'enumerate', 'description'] -" indent on \left( and on \(, but not on ( -" indent on \left[ and on \[, but not on [ -" indent on \left\{ and on {, but not on \{ -let s:open_pat = '\\\@<!\%(\\begin\|\\left\a\@!\|\\(\|\\\[\|{\)' -let s:close_pat = '\\\@<!\%(\\end\|\\right\a\@!\|\\)\|\\\]\|}\)' -let s:list_open_pat = '\\\@<!\\begin{\%(' . join(s:list_envs, '\|') . '\)}' -let s:list_close_pat = '\\\@<!\\end{\%(' . join(s:list_envs, '\|') . '\)}' +setlocal autoindent +setlocal indentexpr=VimtexIndentExpr() +setlocal indentkeys=!^F,o,O,(,),],},\&,=item,=else,=fi -function! s:CountMatches(str, pat) - return len(substitute(substitute(a:str, a:pat, "\n", 'g'), "[^\n]", '', 'g')) -endfunction +" Add standard closing math delimiters to indentkeys +for s:delim in [ + \ 'rangle', 'rbrace', 'rvert', 'rVert', 'rfloor', 'rceil', 'urcorner'] + let &l:indentkeys .= ',=' . s:delim +endfor -" TexIndent {{{ -function! LatexBox_TexIndent() +function! VimtexIndentExpr() abort " {{{1 + return VimtexIndent(v:lnum) +endfunction - let lnum_curr = v:lnum - let lnum_prev = prevnonblank(lnum_curr - 1) +"}}} +function! VimtexIndent(lnum) abort " {{{1 + let s:sw = exists('*shiftwidth') ? shiftwidth() : &shiftwidth + + let [l:prev_lnum, l:prev_line] = s:get_prev_lnum(prevnonblank(a:lnum - 1)) + if l:prev_lnum == 0 | return indent(a:lnum) | endif + let l:line = s:clean_line(getline(a:lnum)) + + " Check for verbatim modes + if s:is_verbatim(l:line, a:lnum) + return empty(l:line) ? indent(l:prev_lnum) : indent(a:lnum) + endif + + " Use previous indentation for comments + if l:line =~# '^\s*%' + return indent(a:lnum) + endif + + " Align on ampersands + let l:ind = s:indent_amps.check(a:lnum, l:line, l:prev_lnum, l:prev_line) + if s:indent_amps.finished | return l:ind | endif + let l:prev_lnum = s:indent_amps.prev_lnum + let l:prev_line = s:indent_amps.prev_line + + " Indent environments, delimiters, and tikz + let l:ind += s:indent_envs(l:line, l:prev_line) + let l:ind += s:indent_delims(l:line, a:lnum, l:prev_line, l:prev_lnum) + let l:ind += s:indent_conditionals(l:line, a:lnum, l:prev_line, l:prev_lnum) + let l:ind += s:indent_tikz(l:prev_lnum, l:prev_line) + + return l:ind +endfunction - if lnum_prev == 0 - return 0 - endif +"}}} - let line_curr = getline(lnum_curr) - let line_prev = getline(lnum_prev) +function! s:get_prev_lnum(lnum) abort " {{{1 + let l:lnum = a:lnum + let l:line = getline(l:lnum) - " remove \\ - let line_curr = substitute(line_curr, '\\\\', '', 'g') - let line_prev = substitute(line_prev, '\\\\', '', 'g') + while l:lnum != 0 && (l:line =~# '^\s*%' || s:is_verbatim(l:line, l:lnum)) + let l:lnum = prevnonblank(l:lnum - 1) + let l:line = getline(l:lnum) + endwhile - " strip comments - let line_curr = substitute(line_curr, '\\\@<!%.*$', '', 'g') - let line_prev = substitute(line_prev, '\\\@<!%.*$', '', 'g') + return [ + \ l:lnum, + \ l:lnum > 0 ? s:clean_line(l:line) : '', + \] +endfunction - " find unmatched opening patterns on previous line - let n = s:CountMatches(line_prev, s:open_pat)-s:CountMatches(line_prev, s:close_pat) - let n += s:CountMatches(line_prev, s:list_open_pat)-s:CountMatches(line_prev, s:list_close_pat) +" }}}1 +function! s:clean_line(line) abort " {{{1 + return substitute(a:line, '\s*\\\@<!%.*', '', '') +endfunction - " reduce indentation if current line starts with a closing pattern - if line_curr =~ '^\s*\%(' . s:close_pat . '\)' - let n -= 1 - endif +" }}}1 +function! s:is_verbatim(line, lnum) abort " {{{1 + return a:line !~# '\v\\%(begin|end)\{%(verbatim|lstlisting|minted)' + \ && vimtex#env#is_inside('\%(lstlisting\|verbatim\|minted\)')[0] +endfunction - " compensate indentation if previous line starts with a closing pattern - if line_prev =~ '^\s*\%(' . s:close_pat . '\)' - let n += 1 - endif +" }}}1 + +let s:indent_amps = {} +let s:indent_amps.re_amp = g:vimtex#re#not_bslash . '\&' +let s:indent_amps.re_align = '^[ \t\\]*' . s:indent_amps.re_amp +function! s:indent_amps.check(lnum, cline, plnum, pline) abort dict " {{{1 + let self.finished = 0 + let self.amp_ind = -1 + let self.init_ind = -1 + let self.prev_lnum = a:plnum + let self.prev_line = a:pline + let self.prev_ind = a:plnum > 0 ? indent(a:plnum) : 0 + if !get(g:, 'vimtex_indent_on_ampersands', 1) | return self.prev_ind | endif + + if a:cline =~# self.re_align + \ || a:cline =~# self.re_amp + \ || a:cline =~# '^\v\s*\\%(end|])' + call self.parse_context(a:lnum, a:cline) + endif + + if a:cline =~# self.re_align + let self.finished = 1 + let l:ind_diff = + \ strdisplaywidth(strpart(a:cline, 0, match(a:cline, self.re_amp))) + \ - strdisplaywidth(strpart(a:cline, 0, match(a:cline, '\S'))) + return self.amp_ind - l:ind_diff + endif + + if self.amp_ind >= 0 + \ && (a:cline =~# '^\v\s*\\%(end|])' || a:cline =~# self.re_amp) + let self.prev_lnum = self.init_lnum + let self.prev_line = self.init_line + return self.init_ind + endif + + return self.prev_ind +endfunction + +" }}}1 +function! s:indent_amps.parse_context(lnum, line) abort dict " {{{1 + let l:depth = 1 + let l:init_depth = l:depth + let l:lnum = prevnonblank(a:lnum - 1) + + while l:lnum >= 1 + let l:line = getline(l:lnum) + + if l:line =~# '\v^\s*%(}|\\%(end|]))' + let l:depth += 1 + endif + + if l:line =~# '\v\\begin\s*\{|\\[|\\\w+\{\s*$' + let l:depth -= 1 + if l:depth == l:init_depth - 1 + let self.init_lnum = l:lnum + let self.init_line = l:line + let self.init_ind = indent(l:lnum) + break + endif + endif + + if l:depth == 1 && l:line =~# self.re_amp + if self.amp_ind < 0 + let self.amp_ind = strdisplaywidth( + \ strpart(l:line, 0, match(l:line, self.re_amp))) + endif + if l:line !~# self.re_align + let self.init_lnum = l:lnum + let self.init_line = l:line + let self.init_ind = indent(l:lnum) + break + endif + endif + + let l:lnum = prevnonblank(l:lnum - 1) + endwhile +endfunction - " reduce indentation if current line starts with a closing list - if line_curr =~ '^\s*\%(' . s:list_close_pat . '\)' - let n -= 1 - endif +" }}}1 - " compensate indentation if previous line starts with a closing list - if line_prev =~ '^\s*\%(' . s:list_close_pat . '\)' - let n += 1 - endif +function! s:indent_envs(cur, prev) abort " {{{1 + let l:ind = 0 - " reduce indentation if previous line is \begin{document} - if line_prev =~ '\\begin\s*{document}' - let n -= 1 - endif + " First for general environments + let l:ind += s:sw*( + \ a:prev =~# s:envs_begin + \ && a:prev !~# s:envs_end + \ && a:prev !~# s:envs_ignored) + let l:ind -= s:sw*( + \ a:cur !~# s:envs_begin + \ && a:cur =~# s:envs_end + \ && a:cur !~# s:envs_ignored) - " less shift for lines starting with \item - let item_here = line_curr =~ '^\s*\\item' - let item_above = line_prev =~ '^\s*\\item' - if !item_here && item_above - let n += 1 - elseif item_here && !item_above - let n -= 1 - endif + " Indentation for prolonged items in lists + let l:ind += s:sw*((a:prev =~# s:envs_item) && (a:cur !~# s:envs_enditem)) + let l:ind -= s:sw*((a:cur =~# s:envs_item) && (a:prev !~# s:envs_begitem)) + let l:ind -= s:sw*((a:cur =~# s:envs_endlist) && (a:prev !~# s:envs_begitem)) - return indent(lnum_prev) + n * &sw + return l:ind endfunction -" }}} -" Restore cursor position, window position, and last search after running a -" command. -function! Latexbox_CallIndent() - " Save the current cursor position. - let cursor = getpos('.') +let s:envs_begin = '\\begin{.*}\|\\\@<!\\\[' +let s:envs_end = '\\end{.*}\|\\\]' +let s:envs_ignored = '\v' + \ . join(get(g:, 'vimtex_indent_ignored_envs', ['document']), '|') + +let s:envs_lists = join(get(g:, 'vimtex_indent_lists', [ + \ 'itemize', + \ 'description', + \ 'enumerate', + \ 'thebibliography', + \]), '\|') +let s:envs_item = '^\s*\\item' +let s:envs_beglist = '\\begin{\%(' . s:envs_lists . '\)' +let s:envs_endlist = '\\end{\%(' . s:envs_lists . '\)' +let s:envs_begitem = s:envs_item . '\|' . s:envs_beglist +let s:envs_enditem = s:envs_item . '\|' . s:envs_endlist + +" }}}1 +function! s:indent_delims(line, lnum, prev_line, prev_lnum) abort " {{{1 + if s:re_opt.close_indented + return s:sw*(s:count(a:prev_line, s:re_open) + \ - s:count(a:prev_line, s:re_close)) + else + return s:sw*( max([ s:count(a:prev_line, s:re_open) + \ - s:count(a:prev_line, s:re_close), 0]) + \ - max([ s:count(a:line, s:re_close) + \ - s:count(a:line, s:re_open), 0])) + endif +endfunction - " Save the current window position. - normal! H - let window = getpos('.') - call setpos('.', cursor) +let s:re_opt = extend({ + \ 'open' : ['{'], + \ 'close' : ['}'], + \ 'close_indented' : 0, + \ 'include_modified_math' : 1, + \}, get(g:, 'vimtex_indent_delims', {})) +let s:re_open = join(s:re_opt.open, '\|') +let s:re_close = join(s:re_opt.close, '\|') +if s:re_opt.include_modified_math + let s:re_open .= (empty(s:re_open) ? '' : '\|') . g:vimtex#delim#re.delim_mod_math.open + let s:re_close .= (empty(s:re_close) ? '' : '\|') . g:vimtex#delim#re.delim_mod_math.close +endif - " Get first non-whitespace character of current line. - let line_start_char = matchstr(getline('.'), '\S') +" }}}1 +function! s:indent_conditionals(line, lnum, prev_line, prev_lnum) abort " {{{1 + if !exists('s:re_cond') + let l:cfg = {} + + if exists('g:vimtex_indent_conditionals') + let l:cfg = g:vimtex_indent_conditionals + if empty(l:cfg) + let s:re_cond = {} + return 0 + endif + endif + + let s:re_cond = extend({ + \ 'open': '\v(\\newif\s*)@<!\\if(f|field|name|numequal|thenelse)@!', + \ 'else': '\\else\>', + \ 'close': '\\fi\>', + \}, l:cfg) + endif + + if empty(s:re_cond) | return 0 | endif + + if get(s:, 'conditional_opened') + if a:line =~# s:re_cond.close + silent! unlet s:conditional_opened + return a:prev_line =~# s:re_cond.open ? 0 : -s:sw + elseif a:line =~# s:re_cond.else + return -s:sw + elseif a:prev_line =~# s:re_cond.else + return s:sw + elseif a:prev_line =~# s:re_cond.open + return s:sw + endif + endif + + if a:line =~# s:re_cond.open + \ && a:line !~# s:re_cond.close + let s:conditional_opened = 1 + endif + + return 0 +endfunction - " Get initial tab position. - let initial_tab = stridx(getline('.'), line_start_char) +" }}}1 +function! s:indent_tikz(lnum, prev) abort " {{{1 + if !has_key(b:vimtex.packages, 'tikz') | return 0 | endif - " Execute the command. - execute 'normal! ==' + let l:env_pos = vimtex#env#is_inside('tikzpicture') + if l:env_pos[0] > 0 && l:env_pos[0] < a:lnum + let l:prev_starts = a:prev =~# s:tikz_commands + let l:prev_stops = a:prev =~# ';\s*$' - " Get tab position difference. - let difference = stridx(getline('.'), line_start_char) - initial_tab + " Increase indent on tikz command start + if l:prev_starts && ! l:prev_stops + return s:sw + endif - " Set new cursor Y position based on calculated difference. - let cursor[2] = cursor[2] + difference + " Decrease indent on tikz command end, i.e. on semicolon + if ! l:prev_starts && l:prev_stops + let l:context = join(getline(l:env_pos[0], a:lnum-1), '') + return -s:sw*(l:context =~# s:tikz_commands) + endif + endif - " Restore the previous window position. - call setpos('.', window) - normal! zt + return 0 +endfunction - " Restore the previous cursor position. - call setpos('.', cursor) +let s:tikz_commands = '\v\\%(' . join([ + \ 'draw', + \ 'fill', + \ 'path', + \ 'node', + \ 'coordinate', + \ 'add%(legendentry|plot)', + \ ], '|') . ')' + +" }}}1 + +function! s:count(line, pattern) abort " {{{1 + if empty(a:pattern) | return 0 | endif + + let l:sum = 0 + let l:indx = match(a:line, a:pattern) + while l:indx >= 0 + let l:sum += 1 + let l:match = matchstr(a:line, a:pattern, l:indx) + let l:indx += len(l:match) + let l:indx = match(a:line, a:pattern, l:indx) + endwhile + return l:sum endfunction -" autocmd to call indent after completion -" 7.3.598 -if v:version > 703 || (v:version == 703 && has('patch598')) - augroup LatexBox_Completion - autocmd! - autocmd CompleteDone <buffer> call Latexbox_CallIndent() - augroup END -endif +" }}}1 -" vim:fdm=marker:ff=unix:noet:ts=4:sw=4 +let &cpoptions = s:cpo_save +unlet s:cpo_save endif |