diff options
author | Mathias Fußenegger <mfussenegger@users.noreply.github.com> | 2023-11-19 14:25:32 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-19 14:25:32 +0100 |
commit | de28a0f84c577e264f37cd001b03d640db7d5ef9 (patch) | |
tree | ad69a1e63266b5e20f05b18d84a6d3a457525f45 /test/functional/lua/watch_spec.lua | |
parent | a84b454ebe661981f292ee8fc73be4f9cd3a5884 (diff) | |
download | rneovim-de28a0f84c577e264f37cd001b03d640db7d5ef9.tar.gz rneovim-de28a0f84c577e264f37cd001b03d640db7d5ef9.tar.bz2 rneovim-de28a0f84c577e264f37cd001b03d640db7d5ef9.zip |
perf(lsp): replace file polling on linux with per dir watcher (#26108)
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.
Diffstat (limited to 'test/functional/lua/watch_spec.lua')
-rw-r--r-- | test/functional/lua/watch_spec.lua | 59 |
1 files changed, 19 insertions, 40 deletions
diff --git a/test/functional/lua/watch_spec.lua b/test/functional/lua/watch_spec.lua index 0542522140..711719addb 100644 --- a/test/functional/lua/watch_spec.lua +++ b/test/functional/lua/watch_spec.lua @@ -108,26 +108,24 @@ describe('vim._watch', function() local events = {} - local poll_interval_ms = 1000 - local poll_wait_ms = poll_interval_ms+200 + local debounce = 100 + local wait_ms = debounce + 200 local expected_events = 0 local function wait_for_events() - assert(vim.wait(poll_wait_ms, function() return #events == expected_events end), 'Timed out waiting for expected number of events. Current events seen so far: ' .. vim.inspect(events)) + assert(vim.wait(wait_ms, function() return #events == expected_events end), 'Timed out waiting for expected number of events. Current events seen so far: ' .. vim.inspect(events)) end local incl = lpeg.P(root_dir) * lpeg.P("/file")^-1 local excl = lpeg.P(root_dir..'/file.unwatched') local stop = vim._watch.poll(root_dir, { - interval = poll_interval_ms, + debounce = debounce, include_pattern = incl, exclude_pattern = excl, }, function(path, change_type) table.insert(events, { path = path, change_type = change_type }) end) - vim.wait(100) - local watched_path = root_dir .. '/file' local watched, err = io.open(watched_path, 'w') assert(not err, err) @@ -135,7 +133,7 @@ describe('vim._watch', function() local unwatched, err = io.open(unwatched_path, 'w') assert(not err, err) - expected_events = expected_events + 2 + expected_events = expected_events + 1 wait_for_events() watched:close() @@ -143,7 +141,7 @@ describe('vim._watch', function() unwatched:close() os.remove(unwatched_path) - expected_events = expected_events + 2 + expected_events = expected_events + 1 wait_for_events() stop() @@ -153,8 +151,6 @@ describe('vim._watch', function() local watched, err = io.open(watched_path, 'w') assert(not err, err) - vim.wait(poll_wait_ms) - watched:close() os.remove(watched_path) @@ -163,36 +159,19 @@ describe('vim._watch', function() root_dir ) - eq(4, #result) - eq({ - change_type = exec_lua([[return vim._watch.FileChangeType.Created]]), - path = root_dir .. '/file', - }, result[1]) - eq({ - change_type = exec_lua([[return vim._watch.FileChangeType.Changed]]), - path = root_dir, - }, result[2]) - -- The file delete and corresponding directory change events do not happen in any - -- particular order, so allow either - if result[3].path == root_dir then - eq({ - change_type = exec_lua([[return vim._watch.FileChangeType.Changed]]), - path = root_dir, - }, result[3]) - eq({ - change_type = exec_lua([[return vim._watch.FileChangeType.Deleted]]), - path = root_dir .. '/file', - }, result[4]) - else - eq({ - change_type = exec_lua([[return vim._watch.FileChangeType.Deleted]]), - path = root_dir .. '/file', - }, result[3]) - eq({ - change_type = exec_lua([[return vim._watch.FileChangeType.Changed]]), - path = root_dir, - }, result[4]) - end + local created = exec_lua([[return vim._watch.FileChangeType.Created]]) + local deleted = exec_lua([[return vim._watch.FileChangeType.Deleted]]) + local expected = { + { + change_type = created, + path = root_dir .. "/file", + }, + { + change_type = deleted, + path = root_dir .. "/file", + } + } + eq(expected, result) end) end) end) |