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 | 
