vim lazyredraw for a batch-editing workload: which redraw behavior should stay enabled
0 reputation · 14 Feb 2025, 10:19 UTC
0 reputation · 14 Feb 2025, 10:19 UTC
I run vim non-interactively on a low-traffic server to apply scripted edits over many files, and I want to cut unnecessary terminal redraw overhead. The documented lazyredraw option postpones screen updates until a command, macro, or script finishes, which seems well suited to this batch-style workload.
What I am unsure about is the boundary of the setting. My scripts mix :normal sequences, :global substitutions, and one plugin that opens a scratch buffer during initialization. I do not know whether lazyredraw covers all of these uniformly, or whether some paths (for example plugin-driven buffer updates or :redraw calls inside third-party code) bypass it entirely.
I also read that ttyfast is sometimes paired with lazyredraw, but my sessions run over a modern local terminal, so I am not convinced the pairing matters here. Assume vim 9.x on Linux.
Does lazyredraw apply to every scripted screen update, or only to macros and mappings? Can a plugin's explicit :redraw override it, and if so is there a way to scope that? Is ttyfast worth setting when the terminal is already fast, or does it change anything measurable in a batch context?
34775 reputation · 14 Feb 2025, 13:21 UTC
lazyredraw applies to every scripted screen update, not just macros and mappings. It postpones the physical screen paint for the duration of any command, macro, or script, including :normal, :global, and :substitute. An explicit :redraw inside a plugin will override it, and there is no built-in way to scope that. ttyfast is not worth setting on a modern local terminal; it is a no-op in this context.
lazyredraw is not limited to interactive macros. It defers screen updates for the duration of a single command, macro, or script execution. This applies uniformly to :normal, :global, :substitute, and other Ex commands run from scripts or the command line. The option is about the physical screen paint, not buffer-content changes. In non-interactive use (vim -es, -c, -S, or Ex mode), Vim often skips screen updates entirely unless :redraw is invoked, making lazyredraw largely redundant. The option matters most in interactive macro/script runs where the UI stays visible.
An explicit :redraw (or :redraw!) forces an immediate screen update regardless of lazyredraw. Plugins that call :redraw will bypass the deferral; there is no built-in mechanism to suppress or scope a plugin's :redraw short of patching the plugin or wrapping its calls. If your scratch-buffer plugin calls :redraw during initialization, it will force a redraw. The only way to prevent this is to patch the plugin or wrap its calls. If the plugin uses :redraw! (force redraw including status lines), it cannot be silenced by configuration; consider filing an upstream issue or forking if the redraw is costly.
ttyfast tells Vim the terminal can handle fast output (e.g., no padding delays). On a modern local terminal (Linux console, xterm, Wayland terminal emulators) it has no measurable effect in batch mode because Vim already detects a fast terminal and because batch scripts typically run with 'silent' or redirected output where terminal capabilities are irrelevant. In batch context, ttyfast is a no-op.
To confirm no other script overrides lazyredraw or ttyfast, check :verbose set lazyredraw? ttyfast?. To profile the effect of lazyredraw, run vim --startuptime /tmp/vim.log -S yourscript.vim and compare elapsed time with and without lazyredraw; on batch workloads the difference is typically <1%.
lazyredraw applies uniformly to scripted screen updates, including :normal, :global, and :substitute. An explicit :redraw in a plugin will override it. ttyfast is not worth setting on a modern local terminal.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.