feat(explorer): add filesystem watchers (#1304)
* feat(explorer): add experimental watchers This commit introduces watchers to update the tree. This behavior is introduced behind an "filesystem_watchers" option which should prevent instabilities. It will become the default at some point. Co-authored-by: Alexander Courtis <alex@courtis.org>
This commit is contained in:
77
lua/nvim-tree/watcher.lua
Normal file
77
lua/nvim-tree/watcher.lua
Normal file
@@ -0,0 +1,77 @@
|
||||
local uv = vim.loop
|
||||
|
||||
local log = require "nvim-tree.log"
|
||||
local utils = require "nvim-tree.utils"
|
||||
|
||||
local M = {}
|
||||
local Watcher = {
|
||||
_watchers = {},
|
||||
}
|
||||
Watcher.__index = Watcher
|
||||
|
||||
function Watcher.new(opts)
|
||||
for _, existing in ipairs(Watcher._watchers) do
|
||||
if existing._opts.absolute_path == opts.absolute_path then
|
||||
log.line("watcher", "Watcher:new using existing '%s'", opts.absolute_path)
|
||||
return existing
|
||||
end
|
||||
end
|
||||
|
||||
log.line("watcher", "Watcher:new '%s'", opts.absolute_path)
|
||||
|
||||
local watcher = setmetatable({
|
||||
_opts = opts,
|
||||
}, Watcher)
|
||||
|
||||
watcher = watcher:start()
|
||||
|
||||
table.insert(Watcher._watchers, watcher)
|
||||
|
||||
return watcher
|
||||
end
|
||||
|
||||
function Watcher:start()
|
||||
log.line("watcher", "Watcher:start '%s'", self._opts.absolute_path)
|
||||
|
||||
local rc, _, name
|
||||
|
||||
self._p, _, name = uv.new_fs_poll()
|
||||
if not self._p then
|
||||
self._p = nil
|
||||
utils.warn(
|
||||
string.format("Could not initialize an fs_poll watcher for path %s : %s", self._opts.absolute_path, name)
|
||||
)
|
||||
return nil
|
||||
end
|
||||
|
||||
local poll_cb = vim.schedule_wrap(function(err)
|
||||
if err then
|
||||
log.line("watcher", "poll_cb for %s fail : %s", self._opts.absolute_path, err)
|
||||
else
|
||||
self._opts.on_event(self._opts.absolute_path)
|
||||
end
|
||||
end)
|
||||
|
||||
rc, _, name = uv.fs_poll_start(self._p, self._opts.absolute_path, self._opts.interval, poll_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))
|
||||
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)
|
||||
if rc ~= 0 then
|
||||
utils.warn(string.format("Could not stop the fs_poll watcher for path %s : %s", self._opts.absolute_path, name))
|
||||
end
|
||||
self._p = nil
|
||||
end
|
||||
end
|
||||
|
||||
M.Watcher = Watcher
|
||||
|
||||
return M
|
||||
Reference in New Issue
Block a user