103 lines
2.4 KiB
Lua
103 lines
2.4 KiB
Lua
local uv = vim.loop
|
|
|
|
local log = require "nvim-tree.log"
|
|
local utils = require "nvim-tree.utils"
|
|
|
|
local M = {
|
|
_watchers = {},
|
|
}
|
|
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
|
|
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(M._watchers, watcher)
|
|
|
|
return watcher
|
|
end
|
|
|
|
function Watcher:start()
|
|
log.line("watcher", "Watcher:start '%s'", self._opts.absolute_path)
|
|
|
|
local rc, _, name
|
|
|
|
self._e, _, name = uv.new_fs_event()
|
|
if not self._e then
|
|
self._e = nil
|
|
utils.notify.warn(
|
|
string.format("Could not initialize an fs_event watcher for path %s : %s", self._opts.absolute_path, name)
|
|
)
|
|
return nil
|
|
end
|
|
|
|
local event_cb = vim.schedule_wrap(function(err, filename, events)
|
|
if err then
|
|
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 = self._e:start(self._opts.absolute_path, FS_EVENT_FLAGS, event_cb)
|
|
if rc ~= 0 then
|
|
utils.notify.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: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.notify.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
|
|
end
|
|
end
|
|
|
|
M.Watcher = Watcher
|
|
|
|
function M.purge_watchers()
|
|
for _, watcher in pairs(M._watchers) do
|
|
watcher:destroy()
|
|
end
|
|
M._watchers = {}
|
|
end
|
|
|
|
return M
|