diff options
| author | Lewis Russell <lewis6991@gmail.com> | 2026-09-30 17:15:20 +0100 |
|---|---|---|
| committer | Lewis Russell <lewis6991@gmail.com> | 2026-10-05 15:28:15 +0100 |
| commit | 209b78e36b7e5aba3033c98242c31617f25e3f82 (patch) | |
| tree | 678e2426dc077768ad604756376e22fa22be3e9b /runtime/lua/vim/_ftplugin/lua.lua | |
| parent | 8577e795bfb66dbdf1808828576683bfa1ab400c (diff) | |
| download | rneovim-209b78e36b7e5aba3033c98242c31617f25e3f82.tar.gz rneovim-209b78e36b7e5aba3033c98242c31617f25e3f82.tar.bz2 rneovim-209b78e36b7e5aba3033c98242c31617f25e3f82.zip | |
perf(watch): skip directories outside include glob prefixes
Problem: watchdirs() scans and watches every directory that is not
excluded, even when a glob only matches files in one subtree. Some
language servers register absolute dependency filenames separately.
Neovim uses the workspace root for these string globs, so each extra
registration can scan and allocate libuv handles across the whole tree.
Solution: Keep each glob's literal directory prefix with its compiled
matcher. A directory must be allowed by both the include filter and at
least one watch rule. Skip unrelated subtrees, including new directories
created later. Keep ancestors watched so matching directories can still
be found. Report events only when they match the full patterns.
For example, watching /project for /project/src/**/*.lua only needs the
src tree and /project itself:
/project/ watched
|-- src/ watched
| `-- lib/ watched
|-- tests/ skipped
| `-- fixtures/ skipped
`-- vendor/ skipped
`-- pkg/ skipped
With no exclusions, this uses three watches instead of seven.
The gain can be large, but depends on the server's patterns and the
workspace layout. Separate watches for absolute dependency filenames can
skip most directories.
For example, a test workspace has 213 directories, including 201 under
build/. The two dependency files in this example are under packages/ and
styles/, so their watches can skip build/. Before this change, each
watch starts at the workspace root, scans all 213 directories and
creates 213 libuv handles.
With this change:
- Haskell Language Server: a separate watch for
/project/packages/demo/demo.cabal watches four directories: the
project root, packages/, demo/ and its src/ child. This cuts that
watch's scans and handles by 98%. With one broad source watch and this
dependency watch, the total falls by 49%.
- Tailwind CSS v4: a separate watch for the imported
/project/styles/themes/colors.css watches three directories: the
project root, styles/ and themes/. This cuts that watch's scans and
handles by 99%. With two broad watches and this dependency watch, the
total falls by 33%.
The broad watches still cover all 213 directories. The saving comes from
avoiding repeated scans and extra handles for each dependency watch.
Most servers with watch registrations in the survey do not benefit.
Their patterns match throughout the watch root, or their watches already
start at the relevant directory. In both cases, the glob prefix cannot
exclude more directories.
AI-assisted
Diffstat (limited to 'runtime/lua/vim/_ftplugin/lua.lua')
0 files changed, 0 insertions, 0 deletions