Com que frequência e quando o foldexpr é avaliado?
Quero alternar foldmethodentre expre manualporque se sempre definirmos foldmethod=expr, o cursor tende a se mover lentamente no vim.
Acho que foldexpré avaliado logo após a troca foldmethod=expr, portanto, tento alternar a cada 5000ms da seguinte maneira. No entanto, foldexprnão pode ser avaliado, o que foldexprsignifica que não é avaliado logo após a troca foldmethod=expr.
Então, eu tenho uma dúvida: com que frequência ou quando é foldexpravaliado? Que eu saiba, não existe nenhum documento sobre o momento da avaliação de foldexpr.
function! s:enable_expr(timer_id) abort
setlocal foldmethod=expr
setlocal foldmethod=manual
endfunction
autocmd CursorMoved * call s:cursor_moved()
let s:timer_id = timer_start(5000, function('s:enable_expr'))
function! s:cursor_moved() abort
setlocal foldmethod=manual
call timer_stop(s:timer_id)
let s:timer_id = timer_start(5000, function('s:enable_expr'))
endfunction
OBSERVAÇÃO : eu conheço uma maneira de alterná-los usando InsertEntere InsertLeavecurtir aqui . Mas, se usarmos a alternância dessa forma, a alternância entre o modo de inserção e o modo normal pode se tornar lenta. Além disso, utilizo muito o comando <C-o>em modo de inserção, portanto, queremos evitar essa implementação.
Portanto, quero fazer com que o vim avalie foldexpruma vez em todas as linhas quando o cursor for pressionado.
OBSERVAÇÃO adicional : eu alterno-os com a implementação a seguir por enquanto. Uma desvantagem dessa implementação é que, quando movemos o cursor após 5000 ms sob a posição do cursor, o movimento do cursor se torna lento no início devido à troca foldmethod.
function! s:enable_expr(timer_id) abort
if &l:foldmethod ==# 'manual'
setlocal foldmethod=expr
endif
endfunction
autocmd CursorMoved * call s:cursor_moved()
let s:timer_id = timer_start(5000, function('s:enable_expr'))
function! s:cursor_moved() abort
if &l:foldmethod ==# 'expr'
setlocal foldmethod=manual
endif
call timer_stop(s:timer_id)
let s:timer_id = timer_start(5000, function('s:enable_expr'))
endfunction
Uma solução temporária
augroup foldmethod-syntax
autocmd InsertEnter,CursorMoved,CursorMovedI * if &l:foldmethod ==# 'expr'
\ | setlocal foldmethod=manual
\ | endif
autocmd BufWrite * if &l:foldmethod ==# 'manual'
\ | setlocal foldmethod=expr
\ | endif
augroup END
Respostas
Vamos dar uma olhada no código-fonte do vim:
Existe uma função que é chamada quando uma alteração é feita:
https://github.com/vim/vim/blob/85629985b71035608a37ba3bde86968481490d46/src/change.c#L429
Esta função aciona foldUpdate:
https://github.com/vim/vim/blob/85629985b71035608a37ba3bde86968481490d46/src/change.c#L537
O que faz dobrar (incluindo foldexpr):
https://github.com/vim/vim/blob/81fcb67fb32a12414512b72e691a1bbbff9f8511/src/fold.c#L842
Isso também acontece quando você começa a editar um arquivo:
https://github.com/vim/vim/blob/451c2e3536a3cb77d07faf3cb2b834512e174351/src/ex_cmds.c#L1270
E quando você define foldexpropções:
https://github.com/vim/vim/blob/d43906d2e5969288f239df851f5ad7b1dc2c7251/src/optionstr.c#L1994
E assim por diante.
PS
Existe um plugin https://github.com/Konfekt/FastFold isso provavelmente faz o que você deseja.