Wie oft und wann wird foldexpr ausgewertet?
Ich möchte foldmethodzwischen exprund umschalten, manualdenn wenn wir immer setzen foldmethod=expr, bewegt sich der Cursor in vim langsam.
Ich denke, das foldexprwird direkt nach dem Umschalten ausgewertet foldmethod=expr, daher versuche ich, alle 5000 ms auf folgende Weise umzuschalten. Allerdings foldexprkann nicht ausgewertet werden, was bedeutet , foldexprnur nach dem Einschalten wird nicht ausgewertet foldmethod=expr.
Dann habe ich eine Frage: Wie oft oder wann wird foldexprausgewertet? Meines Wissens gibt es kein Dokument über den Zeitpunkt der Bewertung von 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
BEMERKUNG : Ich kenne einen Weg, sie umzuschalten, indem ich hierInsertEnter und InsertLeavewie benutze . Wenn wir den Umschalter jedoch auf diese Weise verwenden, kann das Umschalten zwischen Einfügemodus und Normalmodus langsam werden. Außerdem benutze ich den Befehl häufig im Einfügemodus, daher möchten wir diese Implementierung vermeiden.<C-o>
Daher möchte ich vim foldexpreinmal in allen Zeilen auswerten lassen , wenn der Cursor hält.
Zusätzlicher BEMERKUNG : Ich schalte sie vorerst mit der folgenden Implementierung um. Ein Nachteil dieser Implementierung ist, wenn wir den Cursor nach 5000 ms unter dem Cursor halten, wird die Bewegung des Cursors zu Beginn aufgrund des Umschaltens langsam 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
Eine vorübergehende Lösung
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
Antworten
Schauen wir uns den Quellcode von vim an:
Es gibt eine Funktion, die aufgerufen wird, wenn eine Änderung vorgenommen wurde:
https://github.com/vim/vim/blob/85629985b71035608a37ba3bde86968481490d46/src/change.c#L429
Diese Funktion löst aus foldUpdate:
https://github.com/vim/vim/blob/85629985b71035608a37ba3bde86968481490d46/src/change.c#L537
Was macht Falten (einschließlich foldexpr):
https://github.com/vim/vim/blob/81fcb67fb32a12414512b72e691a1bbbff9f8511/src/fold.c#L842
Dies geschieht auch, wenn Sie mit der Bearbeitung einer Datei beginnen:
https://github.com/vim/vim/blob/451c2e3536a3cb77d07faf3cb2b834512e174351/src/ex_cmds.c#L1270
Und wenn Sie foldexprOptionen festlegen :
https://github.com/vim/vim/blob/d43906d2e5969288f239df851f5ad7b1dc2c7251/src/optionstr.c#L1994
Usw.
PS
Es gibt ein Plugin https://github.com/Konfekt/FastFold das macht wahrscheinlich was du willst.