Completed a fully custom formatexpr (#436)
This commit is contained in:
parent
b82a8d3798
commit
0fdaee31ed
@ -44,7 +44,8 @@ function! vimtex#format#formatexpr() " {{{1
|
|||||||
|
|
||||||
let l:top = v:lnum
|
let l:top = v:lnum
|
||||||
let l:bottom = v:lnum + v:count - 1
|
let l:bottom = v:lnum + v:count - 1
|
||||||
let l:mark = l:bottom
|
let l:lines_old = getline(l:top, l:bottom)
|
||||||
|
let l:tries = 5
|
||||||
|
|
||||||
" This is a hack to make undo restore the correct position
|
" This is a hack to make undo restore the correct position
|
||||||
if mode() !=# 'i'
|
if mode() !=# 'i'
|
||||||
@ -52,7 +53,43 @@ function! vimtex#format#formatexpr() " {{{1
|
|||||||
normal! x
|
normal! x
|
||||||
endif
|
endif
|
||||||
|
|
||||||
for l:current in range(l:bottom, l:top, -1)
|
" Main formatting algorithm
|
||||||
|
while l:tries > 0
|
||||||
|
" Format the range of lines
|
||||||
|
let l:bottom = s:format(l:top, l:bottom)
|
||||||
|
|
||||||
|
" Ensure proper indentation
|
||||||
|
silent! execute printf('normal! %sG=%sG', l:top, l:bottom)
|
||||||
|
|
||||||
|
" Check if any lines have changed
|
||||||
|
let l:lines_new = getline(l:top, l:bottom)
|
||||||
|
let l:index = s:compare_lines(l:lines_new, l:lines_old)
|
||||||
|
let l:top += l:index
|
||||||
|
if l:top > l:bottom | break | endif
|
||||||
|
let l:lines_old = l:lines_new[l:index:]
|
||||||
|
let l:tries -= 1
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
" Move cursor to first non-blank of the last formatted line
|
||||||
|
if mode() !=# 'i'
|
||||||
|
execute 'normal!' l:bottom . 'G^'
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Don't change the text if the formatting algorithm failed
|
||||||
|
if l:tries == 0
|
||||||
|
silent! undo
|
||||||
|
call vimtex#echo#warning('Formatting of selected text failed!')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let &l:foldenable = l:foldenable
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" }}}1
|
||||||
|
|
||||||
|
function! s:format(top, bottom) " {{{1
|
||||||
|
let l:bottom = a:bottom
|
||||||
|
let l:mark = a:bottom
|
||||||
|
for l:current in range(a:bottom, a:top, -1)
|
||||||
let l:line = getline(l:current)
|
let l:line = getline(l:current)
|
||||||
|
|
||||||
if vimtex#util#in_mathzone(l:current, 1)
|
if vimtex#util#in_mathzone(l:current, 1)
|
||||||
@ -63,24 +100,79 @@ function! vimtex#format#formatexpr() " {{{1
|
|||||||
|
|
||||||
if l:line =~# s:border_end
|
if l:line =~# s:border_end
|
||||||
if l:current < l:mark
|
if l:current < l:mark
|
||||||
execute 'normal!' (l:current+1) . 'Ggw' . l:mark . 'G'
|
let l:bottom += s:format_build_lines(l:current+1, l:mark)
|
||||||
endif
|
endif
|
||||||
let l:mark = l:current
|
let l:mark = l:current
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if l:line =~# s:border_beginning
|
if l:line =~# s:border_beginning
|
||||||
if l:current < l:mark
|
if l:current < l:mark
|
||||||
execute 'normal!' l:current . 'Ggw' . l:mark . 'G'
|
let l:bottom += s:format_build_lines(l:current, l:mark)
|
||||||
endif
|
endif
|
||||||
let l:mark = l:current-1
|
let l:mark = l:current-1
|
||||||
endif
|
endif
|
||||||
endwhile
|
|
||||||
|
|
||||||
if l:top <= l:mark
|
if l:line =~# '^\s*$'
|
||||||
execute 'normal!' l:top . 'Ggw' . l:mark . 'G'
|
let l:bottom += s:format_build_lines(l:current+1, l:mark)
|
||||||
|
let l:mark = l:current-1
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
if a:top <= l:mark
|
||||||
|
let l:bottom += s:format_build_lines(a:top, l:mark)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let &l:foldenable = l:foldenable
|
return l:bottom
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" }}}1
|
||||||
|
function! s:format_build_lines(start, end) " {{{1
|
||||||
|
"
|
||||||
|
" Get the desired text to format as a list of words
|
||||||
|
"
|
||||||
|
let l:words = split(join(map(getline(a:start, a:end),
|
||||||
|
\ 'substitute(v:val, ''^\s*'', '''', '''')'), ' '), ' ')
|
||||||
|
if empty(l:words) | return 0 | endif
|
||||||
|
|
||||||
|
"
|
||||||
|
" Add the words in properly indented and formatted lines
|
||||||
|
"
|
||||||
|
let l:lnum = a:start-1
|
||||||
|
let l:current = repeat(' ', VimtexIndent(a:start))
|
||||||
|
for l:word in l:words
|
||||||
|
if len(l:word) + len(l:current) > &tw
|
||||||
|
call append(l:lnum, substitute(l:current, '\s$', '', ''))
|
||||||
|
let l:lnum += 1
|
||||||
|
let l:current = repeat(' ', VimtexIndent(a:start))
|
||||||
|
endif
|
||||||
|
let l:current .= l:word . ' '
|
||||||
|
endfor
|
||||||
|
if l:current !~# '^\s*$'
|
||||||
|
call append(l:lnum, substitute(l:current, '\s$', '', ''))
|
||||||
|
let l:lnum += 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
"
|
||||||
|
" Remove old text
|
||||||
|
"
|
||||||
|
silent! execute printf('%s;+%s delete', l:lnum+1, a:end-a:start)
|
||||||
|
|
||||||
|
"
|
||||||
|
" Return the difference between number of lines of old and new text
|
||||||
|
"
|
||||||
|
return l:lnum - a:end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" }}}1
|
||||||
|
|
||||||
|
function! s:compare_lines(new, old) " {{{1
|
||||||
|
let l:min_length = min([len(a:new), len(a:old)])
|
||||||
|
for l:i in range(l:min_length)
|
||||||
|
if a:new[l:i] !=# a:old[l:i]
|
||||||
|
return l:i
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
return l:min_length
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" }}}1
|
" }}}1
|
||||||
|
@ -17,31 +17,31 @@ let s:cpo_save = &cpo
|
|||||||
set cpo&vim
|
set cpo&vim
|
||||||
|
|
||||||
setlocal autoindent
|
setlocal autoindent
|
||||||
setlocal indentexpr=VimtexIndent()
|
setlocal indentexpr=VimtexIndent(v:lnum)
|
||||||
setlocal indentkeys&
|
setlocal indentkeys&
|
||||||
setlocal indentkeys+=[,(,{,),},],\&,=item
|
setlocal indentkeys+=[,(,{,),},],\&,=item
|
||||||
|
|
||||||
function! VimtexIndent() " {{{1
|
function! VimtexIndent(lnum) " {{{1
|
||||||
let l:nprev = s:get_prev_line(prevnonblank(v:lnum - 1))
|
let l:nprev = s:get_prev_line(prevnonblank(a:lnum - 1))
|
||||||
if l:nprev == 0 | return 0 | endif
|
if l:nprev == 0 | return 0 | endif
|
||||||
|
|
||||||
" Get current and previous line and remove comments
|
" Get current and previous line and remove comments
|
||||||
let l:cur = substitute(getline(v:lnum), '\\\@<!%.*', '', '')
|
let l:cur = substitute(getline(a:lnum), '\\\@<!%.*', '', '')
|
||||||
let l:prev = substitute(getline(l:nprev), '\\\@<!%.*', '', '')
|
let l:prev = substitute(getline(l:nprev), '\\\@<!%.*', '', '')
|
||||||
|
|
||||||
" Check for verbatim modes
|
" Check for verbatim modes
|
||||||
if s:is_verbatim(l:cur, v:lnum)
|
if s:is_verbatim(l:cur, a:lnum)
|
||||||
return empty(l:cur) ? indent(l:nprev) : indent(v:lnum)
|
return empty(l:cur) ? indent(l:nprev) : indent(a:lnum)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" Align on ampersands
|
" Align on ampersands
|
||||||
if l:cur =~# '^\s*&' && l:prev =~# '\\\@<!&.*'
|
if l:cur =~# '^\s*&' && l:prev =~# '\\\@<!&.*'
|
||||||
return indent(v:lnum) + match(l:prev, '\\\@<!&') - stridx(l:cur, '&')
|
return indent(a:lnum) + match(l:prev, '\\\@<!&') - stridx(l:cur, '&')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" Use previous indentation for comments
|
" Use previous indentation for comments
|
||||||
if l:cur =~# '^\s*%'
|
if l:cur =~# '^\s*%'
|
||||||
return indent(v:lnum)
|
return indent(a:lnum)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:nprev = s:get_prev_line(l:nprev, 'ignore-ampersands')
|
let l:nprev = s:get_prev_line(l:nprev, 'ignore-ampersands')
|
||||||
@ -50,7 +50,7 @@ function! VimtexIndent() " {{{1
|
|||||||
|
|
||||||
let l:ind = indent(l:nprev)
|
let l:ind = indent(l:nprev)
|
||||||
let l:ind += s:indent_envs(l:cur, l:prev)
|
let l:ind += s:indent_envs(l:cur, l:prev)
|
||||||
let l:ind += s:indent_delims(l:cur, l:prev)
|
let l:ind += s:indent_delims(l:cur, l:prev, a:lnum)
|
||||||
let l:ind += s:indent_tikz(l:nprev, l:prev)
|
let l:ind += s:indent_tikz(l:nprev, l:prev)
|
||||||
return l:ind
|
return l:ind
|
||||||
endfunction
|
endfunction
|
||||||
@ -105,8 +105,8 @@ let s:envs_begitem = s:envs_item . '\|' . s:envs_beglist
|
|||||||
let s:envs_enditem = s:envs_item . '\|' . s:envs_endlist
|
let s:envs_enditem = s:envs_item . '\|' . s:envs_endlist
|
||||||
|
|
||||||
" }}}1
|
" }}}1
|
||||||
function! s:indent_delims(cur, prev) " {{{1
|
function! s:indent_delims(cur, prev, lnum) " {{{1
|
||||||
let [l:open, l:close] = vimtex#delim#get_valid_regexps(v:lnum, col('.'))
|
let [l:open, l:close] = vimtex#delim#get_valid_regexps(a:lnum, col('.'))
|
||||||
return &sw*( max([s:count(a:prev, l:open) - s:count(a:prev, l:close), 0])
|
return &sw*( max([s:count(a:prev, l:open) - s:count(a:prev, l:close), 0])
|
||||||
\ - max([s:count(a:cur, l:close) - s:count(a:cur, l:open), 0]))
|
\ - max([s:count(a:cur, l:close) - s:count(a:cur, l:open), 0]))
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -168,9 +168,8 @@ Expect tex (Verify):
|
|||||||
distribution over $x^u$ when sampled at label $\vec x$ some time later; another
|
distribution over $x^u$ when sampled at label $\vec x$ some time later; another
|
||||||
population started around $\vec x_1$ carries a different history when it, too,
|
population started around $\vec x_1$ carries a different history when it, too,
|
||||||
visits $\vec x$ later. Therefore, for instance the effective drift $\vec v(\vec
|
visits $\vec x$ later. Therefore, for instance the effective drift $\vec v(\vec
|
||||||
x)$ will be different in the two cases. We conclude that, if unobserved
|
x)$ will be different in the two cases. We conclude that, if unobserved degrees
|
||||||
degrees of freedom have dynamics on the time scale of the experiment
|
of freedom have dynamics on the time scale of the experiment eq.~\ref{eq:fpe}
|
||||||
eq.~\ref{eq:fpe} is an approximation whose coefficients become
|
is an approximation whose coefficients become \emph{non-universal} (dependent
|
||||||
\emph{non-universal} (dependent on intial conditions) and
|
on intial conditions) and \emph{time-dependent}.
|
||||||
\emph{time-dependent}.
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user