chore(watchers): refactor events and make debouncer safe

- fs poll -> fs events
- make debouncer safe and fix diagnostics events
This commit is contained in:
Alexander Courtis
2022-07-17 16:50:24 +10:00
committed by GitHub
parent 26512c369f
commit 06e48c29c4
12 changed files with 155 additions and 82 deletions

View File

@@ -9,6 +9,13 @@ local M = {
local Watcher = {}
Watcher.__index = Watcher
local FS_EVENT_FLAGS = {
-- inotify or equivalent will be used; fallback to stat has not yet been implemented
stat = false,
-- recursive is not functional in neovim's libuv implementation
recursive = false,
}
function Watcher.new(opts)
for _, existing in ipairs(M._watchers) do
if existing._opts.absolute_path == opts.absolute_path then
@@ -35,40 +42,47 @@ function Watcher:start()
local rc, _, name
self._p, _, name = uv.new_fs_poll()
if not self._p then
self._p = nil
self._e, _, name = uv.new_fs_event()
if not self._e then
self._e = nil
utils.warn(
string.format("Could not initialize an fs_poll watcher for path %s : %s", self._opts.absolute_path, name)
string.format("Could not initialize an fs_event watcher for path %s : %s", self._opts.absolute_path, name)
)
return nil
end
local poll_cb = vim.schedule_wrap(function(err)
local event_cb = vim.schedule_wrap(function(err, filename, events)
if err then
log.line("watcher", "poll_cb for %s fail : %s", self._opts.absolute_path, err)
log.line("watcher", "event_cb for %s fail : %s", self._opts.absolute_path, err)
else
log.line("watcher", "event_cb '%s' '%s' %s", self._opts.absolute_path, filename, vim.inspect(events))
self._opts.on_event(self._opts)
end
end)
rc, _, name = uv.fs_poll_start(self._p, self._opts.absolute_path, self._opts.interval, poll_cb)
rc, _, name = self._e:start(self._opts.absolute_path, FS_EVENT_FLAGS, event_cb)
if rc ~= 0 then
utils.warn(string.format("Could not start the fs_poll watcher for path %s : %s", self._opts.absolute_path, name))
utils.warn(string.format("Could not start the fs_event watcher for path %s : %s", self._opts.absolute_path, name))
return nil
end
return self
end
function Watcher:stop()
log.line("watcher", "Watcher:stop '%s'", self._opts.absolute_path)
if self._p then
local rc, _, name = uv.fs_poll_stop(self._p)
function Watcher:destroy()
log.line("watcher", "Watcher:destroy '%s'", self._opts.absolute_path)
if self._e then
local rc, _, name = self._e:stop()
if rc ~= 0 then
utils.warn(string.format("Could not stop the fs_poll watcher for path %s : %s", self._opts.absolute_path, name))
utils.warn(string.format("Could not stop the fs_event watcher for path %s : %s", self._opts.absolute_path, name))
end
self._e = nil
end
for i, w in ipairs(M._watchers) do
if w == self then
table.remove(M._watchers, i)
break
end
self._p = nil
end
end
@@ -76,7 +90,7 @@ M.Watcher = Watcher
function M.purge_watchers()
for _, watcher in pairs(M._watchers) do
watcher:stop()
watcher:destroy()
end
M._watchers = {}
end