Con che frequenza e quando viene valutata foldexpr?

Aug 30 2020

Voglio passare foldmethodda expre manualperché se impostiamo sempre foldmethod=expr, il cursore tende a muoversi lentamente in vim.

Penso che foldexprvenga valutato subito dopo il passaggio foldmethod=expr, quindi provo a commutare ogni 5000 ms nel modo seguente. Tuttavia, foldexprnon può essere valutato, il che implica che foldexprnon viene valutato subito dopo il passaggio foldmethod=expr.

Quindi, ho una domanda: quanto spesso o quando viene foldexprvalutato? Per quanto ne so, non esiste alcun documento sui tempi di valutazione di 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

NOTA : Conosco un modo per alternarli usando InsertEntere InsertLeavecome qui . Ma, se utilizziamo l'interruttore in questo modo, il passaggio dalla modalità di inserimento alla modalità normale può diventare lento. Inoltre, utilizzo molto il comando <C-o>in modalità di inserimento, quindi vogliamo evitare questa implementazione.

Quindi, voglio che vim valuti foldexpruna volta in tutte le righe quando il cursore rimane.

OSSERVAZIONI Aggiuntive : per ora le passo con la seguente implementazione. Uno svantaggio di questa implementazione è che quando spostiamo il cursore dopo 5000 ms sotto il cursore-premuto, lo spostamento del cursore diventa lento all'inizio a causa della commutazione 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

Una soluzione temporanea

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

Risposte

2 MaximKim Sep 04 2020 at 15:31

Diamo un'occhiata al codice sorgente di vim:

C'è una funzione che viene chiamata quando è stata apportata una modifica:

https://github.com/vim/vim/blob/85629985b71035608a37ba3bde86968481490d46/src/change.c#L429

Questa funzione attiva foldUpdate:

https://github.com/vim/vim/blob/85629985b71035608a37ba3bde86968481490d46/src/change.c#L537

Che fa pieghevole (incluso foldexpr):

https://github.com/vim/vim/blob/81fcb67fb32a12414512b72e691a1bbbff9f8511/src/fold.c#L842

Ciò accade anche quando inizi a modificare un file:

https://github.com/vim/vim/blob/451c2e3536a3cb77d07faf3cb2b834512e174351/src/ex_cmds.c#L1270

E quando imposti le foldexpropzioni:

https://github.com/vim/vim/blob/d43906d2e5969288f239df851f5ad7b1dc2c7251/src/optionstr.c#L1994

E così via.

PS

C'è un plugin https://github.com/Konfekt/FastFold probabilmente fa quello che vuoi.