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: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
|
||||
if mode() !=# 'i'
|
||||
@ -52,7 +53,43 @@ function! vimtex#format#formatexpr() " {{{1
|
||||
normal! x
|
||||
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)
|
||||
|
||||
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: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
|
||||
let l:mark = l:current
|
||||
endif
|
||||
|
||||
if l:line =~# s:border_beginning
|
||||
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
|
||||
let l:mark = l:current-1
|
||||
endif
|
||||
endwhile
|
||||
|
||||
if l:top <= l:mark
|
||||
execute 'normal!' l:top . 'Ggw' . l:mark . 'G'
|
||||
if l:line =~# '^\s*$'
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
" }}}1
|
||||
|
@ -17,31 +17,31 @@ let s:cpo_save = &cpo
|
||||
set cpo&vim
|
||||
|
||||
setlocal autoindent
|
||||
setlocal indentexpr=VimtexIndent()
|
||||
setlocal indentexpr=VimtexIndent(v:lnum)
|
||||
setlocal indentkeys&
|
||||
setlocal indentkeys+=[,(,{,),},],\&,=item
|
||||
|
||||
function! VimtexIndent() " {{{1
|
||||
let l:nprev = s:get_prev_line(prevnonblank(v:lnum - 1))
|
||||
function! VimtexIndent(lnum) " {{{1
|
||||
let l:nprev = s:get_prev_line(prevnonblank(a:lnum - 1))
|
||||
if l:nprev == 0 | return 0 | endif
|
||||
|
||||
" 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), '\\\@<!%.*', '', '')
|
||||
|
||||
" Check for verbatim modes
|
||||
if s:is_verbatim(l:cur, v:lnum)
|
||||
return empty(l:cur) ? indent(l:nprev) : indent(v:lnum)
|
||||
if s:is_verbatim(l:cur, a:lnum)
|
||||
return empty(l:cur) ? indent(l:nprev) : indent(a:lnum)
|
||||
endif
|
||||
|
||||
" Align on ampersands
|
||||
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
|
||||
|
||||
" Use previous indentation for comments
|
||||
if l:cur =~# '^\s*%'
|
||||
return indent(v:lnum)
|
||||
return indent(a:lnum)
|
||||
endif
|
||||
|
||||
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 += 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)
|
||||
return l:ind
|
||||
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
|
||||
|
||||
" }}}1
|
||||
function! s:indent_delims(cur, prev) " {{{1
|
||||
let [l:open, l:close] = vimtex#delim#get_valid_regexps(v:lnum, col('.'))
|
||||
function! s:indent_delims(cur, prev, lnum) " {{{1
|
||||
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])
|
||||
\ - max([s:count(a:cur, l:close) - s:count(a:cur, l:open), 0]))
|
||||
endfunction
|
||||
|
@ -168,9 +168,8 @@ Expect tex (Verify):
|
||||
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,
|
||||
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
|
||||
degrees of freedom have dynamics on the time scale of the experiment
|
||||
eq.~\ref{eq:fpe} is an approximation whose coefficients become
|
||||
\emph{non-universal} (dependent on intial conditions) and
|
||||
\emph{time-dependent}.
|
||||
x)$ will be different in the two cases. We conclude that, if unobserved degrees
|
||||
of freedom have dynamics on the time scale of the experiment eq.~\ref{eq:fpe}
|
||||
is an approximation whose coefficients become \emph{non-universal} (dependent
|
||||
on intial conditions) and \emph{time-dependent}.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user