From 6cc76011ca28ff61f1c2f8de6d895d4c6d0a1ad8 Mon Sep 17 00:00:00 2001 From: Jon Huhn Date: Mon, 17 Apr 2023 11:50:05 -0500 Subject: [PATCH] fix(watchfiles): skip Created events when poll starts (#23139) --- runtime/lua/vim/_watch.lua | 10 +++++++++- test/functional/lua/watch_spec.lua | 24 ++++++++---------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/runtime/lua/vim/_watch.lua b/runtime/lua/vim/_watch.lua index dba1522ec8..dbffd726a2 100644 --- a/runtime/lua/vim/_watch.lua +++ b/runtime/lua/vim/_watch.lua @@ -88,6 +88,9 @@ local default_poll_interval_ms = 2000 --- be invoked recursively) --- - children (table|nil) --- A mapping of directory entry name to its recursive watches +-- - started (boolean|nil) +-- Whether or not the watcher has first been initialized. Used +-- to prevent a flood of Created events on startup. local function poll_internal(path, opts, callback, watches) path = vim.fs.normalize(path) local interval = opts and opts.interval or default_poll_interval_ms @@ -112,7 +115,9 @@ local function poll_internal(path, opts, callback, watches) end) ) assert(not start_err, start_err) - callback(path, M.FileChangeType.Created) + if watches.started then + callback(path, M.FileChangeType.Created) + end end watches.cancel = function() @@ -132,6 +137,7 @@ local function poll_internal(path, opts, callback, watches) if not watches.children[name] then watches.children[name] = { is_dir = ftype == 'directory', + started = watches.started, } poll_internal(filepath_join(path, name), opts, callback, watches.children[name]) end @@ -150,6 +156,8 @@ local function poll_internal(path, opts, callback, watches) watches.children = newchildren end + watches.started = true + return watches.cancel end diff --git a/test/functional/lua/watch_spec.lua b/test/functional/lua/watch_spec.lua index bbcfd27cde..ad8678c17a 100644 --- a/test/functional/lua/watch_spec.lua +++ b/test/functional/lua/watch_spec.lua @@ -122,10 +122,6 @@ describe('vim._watch', function() table.insert(events, { path = path, change_type = change_type }) end) - -- polling generates Created events for the existing entries when it starts. - expected_events = expected_events + 1 - wait_for_events() - vim.wait(100) local watched_path = root_dir .. '/file' @@ -158,39 +154,35 @@ describe('vim._watch', function() root_dir ) - eq(5, #result) - eq({ - change_type = exec_lua([[return vim._watch.FileChangeType.Created]]), - path = root_dir, - }, result[1]) + eq(4, #result) eq({ change_type = exec_lua([[return vim._watch.FileChangeType.Created]]), path = root_dir .. '/file', - }, result[2]) + }, result[1]) eq({ change_type = exec_lua([[return vim._watch.FileChangeType.Changed]]), path = root_dir, - }, result[3]) + }, result[2]) -- The file delete and corresponding directory change events do not happen in any -- particular order, so allow either - if result[4].path == root_dir then + if result[3].path == root_dir then eq({ change_type = exec_lua([[return vim._watch.FileChangeType.Changed]]), path = root_dir, - }, result[4]) + }, result[3]) eq({ change_type = exec_lua([[return vim._watch.FileChangeType.Deleted]]), path = root_dir .. '/file', - }, result[5]) + }, result[4]) else eq({ change_type = exec_lua([[return vim._watch.FileChangeType.Deleted]]), path = root_dir .. '/file', - }, result[4]) + }, result[3]) eq({ change_type = exec_lua([[return vim._watch.FileChangeType.Changed]]), path = root_dir, - }, result[5]) + }, result[4]) end end) end)