Wie oft und wann wird foldexpr ausgewertet?

Aug 30 2020

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

2 MaximKim Sep 04 2020 at 15:31

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.