commit d9d8c660fd5559d928c8870a21970a375674e310
parent b57ed5e94052252207eb524b8cda2ee561b98159
Author: Oleksandr Chekhovskyi <oleksandr.chekhovskyi@gmail.com>
Date: Tue, 24 Feb 2026 00:33:13 +0200
fix(watch): invalid joined path #37973
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.
Diffstat:
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/runtime/lua/vim/_watch.lua b/runtime/lua/vim/_watch.lua
@@ -69,10 +69,12 @@ function M.watch(path, opts, callback)
local uvflags = opts and opts.uvflags or {}
local handle = assert(uv.new_fs_event())
+ local watching_dir = (uv.fs_stat(path) or {}).type == 'directory'
+
local _, start_err, start_errname = handle:start(path, uvflags, function(err, filename, events)
assert(not err, err)
local fullpath = path
- if filename then
+ if filename and watching_dir then
fullpath = vim.fs.normalize(vim.fs.joinpath(fullpath, filename))
end