| Commit message (Collapse) | Author | Age |
| |
|
|
|
|
|
|
|
|
|
|
| |
Problem: watchdirs() keeps its state in large nested callbacks in
_watch.lua, which makes its directory tracking logic harder to change.
Solution: Move the backend into its own module and store its state in a
WatchDirs instance. Split setup, event handling and cleanup into
methods. Extend the existing test to cover cancellation while a
directory stat is pending.
AI-assisted
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
| |
|
|
|
|
|
|
|
| |
Problem: Argument type mismatches are excluded from EmmyLua checks.
Solution: Correct runtime annotations and calls, document local checker
workarounds, and enable the diagnostic.
AI-assisted
|
| |
|
|
|
|
|
|
|
|
|
| |
Enable EmmyLua's assign-type-mismatch diagnostic after correcting the
runtime annotations and assignments it flags.
Correct option, tuple, and return types, and use separate locals when a
value changes representation. Add guards and narrow casts where needed
so the runtime passes the stricter check. Regenerate the affected docs.
AI-assisted
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Enable EmmyLua's need-check-nil diagnostic and resolve nullable values
through more precise types, explicit invariants, and guards for missing
runtime state. Keep analyzer-specific workarounds local and update the
affected API documentation.
Exclude the bundled re.lua from analysis so its nil-check warnings do
not fail CI.
AI-assisted
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Problem:
LSP servers can register identical file watchers before removing old
registrations. Each registration creates another watcher tree, making
setup and teardown expensive in large workspaces.
Solution:
Move glob compilation into vim._watch and accept rules for multiple
roots alongside existing single-path and LPeg inputs. Share compatible
backends until their last subscription is cancelled.
Ref: #23291
AI-assisted
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
Problem: Watcher failures are reported inconsistently, and callers
cannot detect when a watcher is no longer usable.
Solution: Route startup and event failures and unexpected inotifywait
exits through an optional on_error callback. Log to nvim-watch.log by
default. Ignore disappearing child directories and exits caused by
cancellation. Let LSP log failures and notify once per message, using
INFO for missing roots and ERROR otherwise, without interrupting
registration.
AI-assisted
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- call-non-callable
- missing-fields
- redefined-label
- redefined-local
- undefined-field
- unreachable-code
Promote redefined-local and unreachable-code to warnings.
Fix DOS line-ending handling for multiline semantic tokens, and support
intersection types in the help parser.
AI-assisted
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Problem:
The LSP client excludes paths such as Git objects and installed
dependencies from file watching. However, watchdirs() still traverses
these subtrees before filtering which directories receive watchers,
paying the filesystem and Lua traversal cost for excluded content.
Solution:
Prune excluded subdirectories during the initial walk, and document
that excluding a directory also excludes its descendants.
Using the LSP client's existing **/node_modules/*/** exclusion on a
synthetic macOS tree with 100 installed packages and 4,000 files:
Before After
Directory scans 503 103
Entries inspected 4502 202
Directory watchers 103 103
The measurements use real filesystem calls and watcher handles, with
identical watcher paths for this exclusion.
Ref: #23291
AI-assisted
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Problem:
When vim._watch.watch() is used to watch a single file, libuv returns
the basename as the filename argument in the callback. The code joins
this with the watched path, producing a nonsensical path like
"/path/to/file.lua/file.lua", which causes ENOTDIR errors on
subsequent fs_stat calls.
Solution:
Check whether the watched path is a directory before joining the
filename. When watching a file, ignore the filename from libuv and
use the watched path directly.
|
| |
|
|
|
|
|
|
| |
This fixes the following warning in tests with ASAN or TSAN:
-------- Running tests from test/functional/lua/watch_spec.lua
RUN T4253 vim._watch watch() ignores nonexistent paths: 29.00 ms OK
nvim took 2006 milliseconds to exit after last test
This indicates a likely problem with the test even if it passed!
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
Problem:
`vim.validate()` takes two forms when it only needs one.
Solution:
- Teach the fast form all the features of the spec form.
- Deprecate the spec form.
- General optimizations for both forms.
- Add a `message` argument which can be used alongside or in place
of the `optional` argument.
|
| |
|
|
|
| |
- Also fix `vim.validate()` for PUC Lua when showing errors for values
that aren't string or number.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Problem:
The `_watch.watch()` strategy may fail if the given path does not exist:
…/vim/_watch.lua:101: ENOENT: no such file or directory
stack traceback:
[C]: in function 'assert'
…/vim/_watch.lua:101: in function <…/vim/_watch.lua:61>
[string "<nvim>"]:5: in main chunk
- `_watch.watch()` actively asserts any error returned by `handle:start()`.
- whereas `_watch.watchdirs()` just ignores the result of `root_handle:start()`.
Servers may send "client/registerCapability" with "workspace/didChangeWatchedFiles"
item(s) (`baseUri`) which do not actually exist on the filesystem:
https://github.com/neovim/neovim/issues/28058#issuecomment-2189929424
{
method = "client/registerCapability",
params = {
registrations = { {
method = "workspace/didChangeWatchedFiles",
registerOptions = {
watchers = { {
globPattern = {
baseUri = "file:///Users/does/not/exist",
pattern = "**/*.{ts,js,mts,mjs,cjs,cts,json,svelte}"
}
},
...
}
Solution:
- Remove the assert in `_watch.watch()`.
- Show a once-only message for both cases.
- More detailed logging is blocked until we have `nvim_log` / `vim.log`.
fix #28058
|
| |
|
|
|
|
| |
inotifywait man page specifies:
The file must be specified with a relative or absolute path according to whether a relative or absolute path is given for watched directories.
So it would only work this way in case the path is relative (which at least for gopls it is not)
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
This patch replaces fswatch with inotifywait from inotify-toools:
https://github.com/inotify-tools/inotify-tools
fswatch takes ~1min to set up recursively for the Samba source code
directory. inotifywait needs less than a second to do the same thing.
https://github.com/emcrisostomo/fswatch/issues/321
Also it fswatch seems to be unmaintained in the meantime.
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Doesn't have a huge impact, but showed up in profile output using
`require("jit.p").start("i1", "/tmp/profile")`
before:
31% joinpath
25% fs.lua:0
13% normalize
13% skip
8% _watchfunc
5% gsplit
3% spairs
after:
34% skip
29% fs.lua:0
12% joinpath
7% normalize
5% _watchfunc
5% spairs
|
| |
|
|
|
|
| |
Fixes issue reported in the original PR:
https://github.com/neovim/neovim/pull/27810
Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
|
| |
|
|
|
|
|
|
|
| |
- Add :h fswatch-limitations that notifies user about default inotify
limitations on linux and how to adjust them
- Check for Event queue overflow message from fswatch and refer user to
new documentation
Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
|
| | |
|
| |
|
|
|
|
| |
Resolves #27713
Co-authored-by: Tomasz N <przepompownia@users.noreply.github.com>
|
| |
|
|
|
|
|
|
|
|
|
| |
Problem:
vim._watch.watchdirs has terrible performance.
Solution:
- On linux use fswatch as a watcher backend if available.
- Add File watcher section to health:vim.lsp. Warn if watchfunc is
libuv-poll.
|
| | |
|
| |
|
|
|
|
| |
- Rename watch.poll to watch.watchdirs
- Unify how include and exclude is applied
- Improve type hints
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Should help with https://github.com/neovim/neovim/issues/23291
On linux `new_fs_event` doesn't support recursive watching, but we can
still use it to watch folders.
The downside of this approach is that we may end up sending some false
`Deleted` events. For example, if you save a file named `foo` there will
be a intermediate `foo~` due to the save mechanism of neovim.
The events we get from vim.uv in that case are:
- rename: foo~
- rename: foo~
- rename: foo
- rename: foo
- change: foo
- change: foo
The mechanism in this PR uses a debounce to reduce this to:
- deleted: foo~
- changed: foo
`foo~` will be the false positive.
I suspect that for the LSP case this is good enough. If not, we may need
to follow up on this and keep a table in memory that tracks available
files.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Problem: luals returns stricter diagnostics with bundled luarc.json
Solution: Improve some function and type annotations:
* use recognized uv.* types
* disable diagnostic for global `vim` in shared.lua
* docs: don't start comment lines with taglink (otherwise LuaLS will interpret it as a type)
* add type alias for lpeg pattern
* fix return annotation for `vim.secure.trust`
* rename local Range object in vim.version (shadows `Range` in vim.treesitter)
* fix some "missing fields" warnings
* add missing required fields for test functions in eval.lua
* rename lsp meta files for consistency
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* docs(lua): teach lua2dox how to table
* docs(lua): teach gen_vimdoc.py about local functions
No more need to mark local functions with @private
* docs(lua): mention @nodoc and @meta in dev-lua-doc
* fixup!
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
---------
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
|
| | |
|
| |
|
| |
Co-authored-by: Lewis Russell <lewis6991@gmail.com>
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
| |
This reverts commit 5732aa706c639b3d775573d91d1139f24624629c.
Causes editor to freeze in projects with many watcher registrations
|
| |
|