Meh I'll figure out submodules later
This commit is contained in:
parent
4ca9d44a90
commit
8cb281f436
352 changed files with 66107 additions and 0 deletions
|
|
@ -0,0 +1,110 @@
|
|||
local q = require("neo-tree.events.queue")
|
||||
local log = require("neo-tree.log")
|
||||
local utils = require("neo-tree.utils")
|
||||
|
||||
---@class neotree.event.Functions
|
||||
local M = {
|
||||
-- Well known event names, you can make up your own
|
||||
AFTER_RENDER = "after_render",
|
||||
BEFORE_FILE_ADD = "before_file_add",
|
||||
BEFORE_FILE_DELETE = "before_file_delete",
|
||||
BEFORE_FILE_MOVE = "before_file_move",
|
||||
BEFORE_FILE_RENAME = "before_file_rename",
|
||||
BEFORE_RENDER = "before_render",
|
||||
FILE_ADDED = "file_added",
|
||||
FILE_DELETED = "file_deleted",
|
||||
FILE_MOVED = "file_moved",
|
||||
FILE_OPENED = "file_opened",
|
||||
FILE_OPEN_REQUESTED = "file_open_requested",
|
||||
FILE_RENAMED = "file_renamed",
|
||||
FS_EVENT = "fs_event",
|
||||
GIT_EVENT = "git_event",
|
||||
GIT_STATUS_CHANGED = "git_status_changed",
|
||||
STATE_CREATED = "state_created",
|
||||
NEO_TREE_BUFFER_ENTER = "neo_tree_buffer_enter",
|
||||
NEO_TREE_BUFFER_LEAVE = "neo_tree_buffer_leave",
|
||||
NEO_TREE_LSP_UPDATE = "neo_tree_lsp_update",
|
||||
NEO_TREE_POPUP_BUFFER_ENTER = "neo_tree_popup_buffer_enter",
|
||||
NEO_TREE_POPUP_BUFFER_LEAVE = "neo_tree_popup_buffer_leave",
|
||||
NEO_TREE_POPUP_INPUT_READY = "neo_tree_popup_input_ready",
|
||||
NEO_TREE_WINDOW_AFTER_CLOSE = "neo_tree_window_after_close",
|
||||
NEO_TREE_WINDOW_AFTER_OPEN = "neo_tree_window_after_open",
|
||||
NEO_TREE_WINDOW_BEFORE_CLOSE = "neo_tree_window_before_close",
|
||||
NEO_TREE_WINDOW_BEFORE_OPEN = "neo_tree_window_before_open",
|
||||
NEO_TREE_PREVIEW_BEFORE_RENDER = "neo_tree_preview_before_render",
|
||||
VIM_AFTER_SESSION_LOAD = "vim_after_session_load",
|
||||
VIM_BUFFER_ADDED = "vim_buffer_added",
|
||||
VIM_BUFFER_CHANGED = "vim_buffer_changed",
|
||||
VIM_BUFFER_DELETED = "vim_buffer_deleted",
|
||||
VIM_BUFFER_ENTER = "vim_buffer_enter",
|
||||
VIM_BUFFER_MODIFIED_SET = "vim_buffer_modified_set",
|
||||
VIM_COLORSCHEME = "vim_colorscheme",
|
||||
VIM_CURSOR_MOVED = "vim_cursor_moved",
|
||||
VIM_DIAGNOSTIC_CHANGED = "vim_diagnostic_changed",
|
||||
VIM_DIR_CHANGED = "vim_dir_changed",
|
||||
VIM_INSERT_LEAVE = "vim_insert_leave",
|
||||
VIM_LEAVE = "vim_leave",
|
||||
VIM_LSP_REQUEST = "vim_lsp_request",
|
||||
VIM_RESIZED = "vim_resized",
|
||||
VIM_TAB_CLOSED = "vim_tab_closed",
|
||||
VIM_TERMINAL_ENTER = "vim_terminal_enter",
|
||||
VIM_TEXT_CHANGED_NORMAL = "vim_text_changed_normal",
|
||||
VIM_WIN_CLOSED = "vim_win_closed",
|
||||
VIM_WIN_ENTER = "vim_win_enter",
|
||||
}
|
||||
|
||||
---@param autocmds string
|
||||
---@return string event
|
||||
---@return string? pattern
|
||||
local parse_autocmd_string = function(autocmds)
|
||||
local parsed = vim.split(autocmds, " ")
|
||||
return parsed[1], parsed[2]
|
||||
end
|
||||
|
||||
---@param event_name neotree.EventName|string
|
||||
---@param autocmds string[]
|
||||
---@param debounce_frequency integer?
|
||||
---@param seed_fn function?
|
||||
---@param nested boolean?
|
||||
M.define_autocmd_event = function(event_name, autocmds, debounce_frequency, seed_fn, nested)
|
||||
log.debug("Defining autocmd event: %s", event_name)
|
||||
local augroup_name = "NeoTreeEvent_" .. event_name
|
||||
q.define_event(event_name, {
|
||||
setup = function()
|
||||
local augroup = vim.api.nvim_create_augroup(augroup_name, { clear = false })
|
||||
for _, autocmd in ipairs(autocmds) do
|
||||
local event, pattern = parse_autocmd_string(autocmd)
|
||||
log.trace("Registering autocmds on %s %s", event, pattern or "")
|
||||
vim.api.nvim_create_autocmd({ event }, {
|
||||
pattern = pattern or "*",
|
||||
group = augroup,
|
||||
nested = nested,
|
||||
callback = function(args)
|
||||
---@class neotree.event.Autocmd.CallbackArgs : neotree._vim.api.keyset.create_autocmd.callback_args
|
||||
---@field afile string
|
||||
local event_args = args --[[@as neotree._vim.api.keyset.create_autocmd.callback_args]]
|
||||
event_args.afile = args.file or ""
|
||||
M.fire_event(event_name, event_args)
|
||||
end,
|
||||
})
|
||||
end
|
||||
end,
|
||||
seed = seed_fn,
|
||||
teardown = function()
|
||||
log.trace("Teardown autocmds for ", event_name)
|
||||
vim.api.nvim_create_augroup(augroup_name, { clear = true })
|
||||
end,
|
||||
debounce_frequency = debounce_frequency,
|
||||
debounce_strategy = utils.debounce_strategy.CALL_LAST_ONLY,
|
||||
})
|
||||
end
|
||||
|
||||
M.clear_all_events = q.clear_all_events
|
||||
M.define_event = q.define_event
|
||||
M.destroy_event = q.destroy_event
|
||||
M.fire_event = q.fire_event
|
||||
|
||||
M.subscribe = q.subscribe
|
||||
M.unsubscribe = q.unsubscribe
|
||||
|
||||
return M
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
local utils = require("neo-tree.utils")
|
||||
local log = require("neo-tree.log")
|
||||
local Queue = require("neo-tree.collections").Queue
|
||||
|
||||
---@type table<string, neotree.collections.Queue?>
|
||||
local event_queues = {}
|
||||
---@type table <string, neotree.event.Definition?>
|
||||
local event_definitions = {}
|
||||
local M = {}
|
||||
|
||||
---@class neotree.event.Handler.Result
|
||||
---@field handled boolean?
|
||||
|
||||
---@class neotree.event.Handler
|
||||
---@field event neotree.EventName|string
|
||||
---@field handler fun(table?):(neotree.event.Handler.Result?)
|
||||
---@field id string?
|
||||
|
||||
local typecheck = require("neo-tree.health.typecheck")
|
||||
local validate = typecheck.validate
|
||||
---@param event_handler neotree.event.Handler
|
||||
local validate_event_handler = function(event_handler)
|
||||
return validate("event_handler", event_handler, function(eh)
|
||||
validate("event", eh.event, "string")
|
||||
validate("handler", eh.handler, "function")
|
||||
end)
|
||||
end
|
||||
|
||||
M.clear_all_events = function()
|
||||
for event_name, queue in pairs(event_queues) do
|
||||
M.destroy_event(event_name)
|
||||
end
|
||||
event_queues = {}
|
||||
end
|
||||
|
||||
---@class neotree.event.Definition
|
||||
---@field teardown function?
|
||||
---@field setup function?
|
||||
---@field setup_was_run boolean?
|
||||
|
||||
---@param event_name neotree.EventName|string
|
||||
---@param opts neotree.event.Definition
|
||||
M.define_event = function(event_name, opts)
|
||||
local existing = event_definitions[event_name]
|
||||
if existing ~= nil then
|
||||
error("Event already defined: " .. event_name)
|
||||
end
|
||||
event_definitions[event_name] = opts
|
||||
end
|
||||
|
||||
---@param event_name neotree.EventName|string
|
||||
---@return boolean existed_and_destroyed
|
||||
M.destroy_event = function(event_name)
|
||||
local existing = event_definitions[event_name]
|
||||
if existing == nil then
|
||||
return false
|
||||
end
|
||||
if existing.setup_was_run and type(existing.teardown) == "function" then
|
||||
local success, result = pcall(existing.teardown)
|
||||
if not success then
|
||||
error("Error in teardown for " .. event_name .. ": " .. result)
|
||||
end
|
||||
existing.setup_was_run = false
|
||||
end
|
||||
event_queues[event_name] = nil
|
||||
return true
|
||||
end
|
||||
|
||||
---@param event neotree.EventName|string
|
||||
---@param args table
|
||||
local fire_event_internal = function(event, args)
|
||||
local queue = event_queues[event]
|
||||
if queue == nil then
|
||||
return nil
|
||||
end
|
||||
--log.trace("Firing event: ", event, " with args: ", args)
|
||||
|
||||
if queue:is_empty() then
|
||||
--log.trace("Event queue is empty")
|
||||
return nil
|
||||
end
|
||||
local seed = utils.get_value(event_definitions, event .. ".seed")
|
||||
if seed ~= nil then
|
||||
local success, result = pcall(seed, args)
|
||||
if success and result then
|
||||
log.trace("Seed for " .. event .. " returned: " .. tostring(result))
|
||||
elseif success then
|
||||
log.trace("Seed for " .. event .. " returned falsy, cancelling event")
|
||||
else
|
||||
log.error("Error in seed function for " .. event .. ": " .. result)
|
||||
end
|
||||
end
|
||||
|
||||
return queue:for_each(function(event_handler)
|
||||
local remove_node = event_handler == nil or event_handler.cancelled
|
||||
if not remove_node then
|
||||
local success, result = pcall(event_handler.handler, args)
|
||||
local id = event_handler.id or event_handler
|
||||
if success then
|
||||
log.trace("Handler ", id, " for " .. event .. " called successfully.")
|
||||
else
|
||||
log.error(string.format("Error in event handler for event %s[%s]: %s", event, id, result))
|
||||
end
|
||||
if event_handler.once then
|
||||
event_handler.cancelled = true
|
||||
return true
|
||||
end
|
||||
return result
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
---@param event neotree.EventName|string
|
||||
---@param args any?
|
||||
M.fire_event = function(event, args)
|
||||
local freq = utils.get_value(event_definitions, event .. ".debounce_frequency", 0, true)
|
||||
local strategy = utils.get_value(event_definitions, event .. ".debounce_strategy", 0, true)
|
||||
log.trace("Firing event: ", event, " with args: ", args)
|
||||
if freq > 0 then
|
||||
utils.debounce("EVENT_FIRED: " .. event, function()
|
||||
fire_event_internal(event, args or {})
|
||||
end, freq, strategy)
|
||||
else
|
||||
return fire_event_internal(event, args or {})
|
||||
end
|
||||
end
|
||||
|
||||
---@param event_handler neotree.event.Handler
|
||||
M.subscribe = function(event_handler)
|
||||
validate_event_handler(event_handler)
|
||||
|
||||
local queue = event_queues[event_handler.event]
|
||||
if queue == nil then
|
||||
log.debug("Creating queue for event: " .. event_handler.event)
|
||||
queue = Queue:new()
|
||||
local def = event_definitions[event_handler.event]
|
||||
if def and type(def.setup) == "function" then
|
||||
local success, result = pcall(def.setup)
|
||||
if success then
|
||||
def.setup_was_run = true
|
||||
log.debug("Setup for event " .. event_handler.event .. " was run")
|
||||
else
|
||||
log.error("Error in setup for " .. event_handler.event .. ": " .. result)
|
||||
end
|
||||
end
|
||||
event_queues[event_handler.event] = queue
|
||||
end
|
||||
log.debug("Adding event handler [", event_handler.id, "] for event: ", event_handler.event)
|
||||
queue:add(event_handler)
|
||||
end
|
||||
|
||||
---@param event_handler neotree.event.Handler
|
||||
M.unsubscribe = function(event_handler)
|
||||
local queue = event_queues[event_handler.event]
|
||||
if queue == nil then
|
||||
return nil
|
||||
end
|
||||
queue:remove_by_id(event_handler.id or event_handler)
|
||||
if queue:is_empty() then
|
||||
M.destroy_event(event_handler.event)
|
||||
event_queues[event_handler.event] = nil
|
||||
else
|
||||
event_queues[event_handler.event] = queue
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
Loading…
Add table
Add a link
Reference in a new issue