From 9e869aae22ad95f350b6b079dedf44ead1e448e8 Mon Sep 17 00:00:00 2001 From: mpaulson Date: Thu, 14 Dec 2023 20:09:55 -0700 Subject: [PATCH] feat: harpoon extensions --- lua/harpoon/extensions.lua | 54 ++++++++++++++++++++++++++++++++++ lua/harpoon/init.lua | 13 +++++++-- lua/harpoon/list.lua | 34 ++++++++++----------- lua/harpoon/listeners.lua | 60 -------------------------------------- lua/harpoon/ui.lua | 4 +-- 5 files changed, 83 insertions(+), 82 deletions(-) create mode 100644 lua/harpoon/extensions.lua delete mode 100644 lua/harpoon/listeners.lua diff --git a/lua/harpoon/extensions.lua b/lua/harpoon/extensions.lua new file mode 100644 index 0000000..c5f0f49 --- /dev/null +++ b/lua/harpoon/extensions.lua @@ -0,0 +1,54 @@ +--- TODO: Rename this... its an odd name "listeners" + +---@class HarpoonExtensions +---@field listeners HarpoonExtension[] +local HarpoonExtensions = {} + +---@class HarpoonExtension +---@field ADD? fun(...): nil +---@field SELECT? fun(...): nil +---@field REMOVE? fun(...): nil +---@field REORDER? fun(...): nil +---@field UI_CREATE? fun(...): nil +---@field SETUP_CALLED? fun(...): nil +---@field LIST_CREATED? fun(...): nil + +HarpoonExtensions.__index = HarpoonExtensions + +function HarpoonExtensions:new() + return setmetatable({ + listeners = {}, + }, self) +end + +---@param extension HarpoonExtension +function HarpoonExtensions:add_listener(extension) + table.insert(self.listeners, extension) +end + +function HarpoonExtensions:clear_listeners() + self.listeners = {} +end + +---@param type string +---@param ... any +function HarpoonExtensions:emit(type, ...) + for _, cb in ipairs(self.listeners) do + if cb[type] then + cb[type](...) + end + end +end + +return { + extensions = HarpoonExtensions:new(), + event_names = { + ADD = "ADD", + SELECT = "SELECT", + REMOVE = "REMOVE", + REORDER = "REORDER", + UI_CREATE = "UI_CREATE", + SETUP_CALLED = "SETUP_CALLED", + LIST_CREATED = "LIST_CREATED", + }, +} diff --git a/lua/harpoon/init.lua b/lua/harpoon/init.lua index 1746d2e..1eb9c15 100644 --- a/lua/harpoon/init.lua +++ b/lua/harpoon/init.lua @@ -3,13 +3,13 @@ local Ui = require("harpoon.ui") local Data = require("harpoon.data") local Config = require("harpoon.config") local List = require("harpoon.list") -local Listeners = require("harpoon.listeners") +local Extensions = require("harpoon.extensions") local HarpoonGroup = require("harpoon.autocmd") ---@class Harpoon ---@field config HarpoonConfig ---@field ui HarpoonUI ----@field listeners HarpoonListeners +---@field _extensions HarpoonExtensions ---@field data HarpoonData ---@field logger HarpoonLog ---@field lists {[string]: {[string]: HarpoonList}} @@ -27,7 +27,7 @@ function Harpoon:new() data = Data.Data:new(), logger = Log, ui = Ui:new(config.settings), - listeners = Listeners.listeners, + _extensions = Extensions.extensions, lists = {}, hooks_setup = false, }, self) @@ -62,6 +62,7 @@ function Harpoon:list(name) local list_config = Config.get_config(self.config, name) local list = List.decode(list_config, name, data) + self._extensions:emit(Extensions.event_names.LIST_CREATED, list) lists[name] = list return list @@ -109,6 +110,11 @@ function Harpoon:dump() return self.data._data end +---@param extension HarpoonExtension +function Harpoon:extend(extension) + self._extensions:add_listener(extension) +end + function Harpoon:__debug_reset() require("plenary.reload").reload_module("harpoon") end @@ -128,6 +134,7 @@ function Harpoon.setup(self, partial_config) ---@diagnostic disable-next-line: param-type-mismatch self.config = Config.merge_config(partial_config, self.config) self.ui:configure(self.config.settings) + self._extensions:emit(Extensions.event_names.SETUP_CALLED, self.config) ---TODO: should we go through every seen list and update its config? diff --git a/lua/harpoon/list.lua b/lua/harpoon/list.lua index cbee590..07c19f5 100644 --- a/lua/harpoon/list.lua +++ b/lua/harpoon/list.lua @@ -1,5 +1,5 @@ local Logger = require("harpoon.logger") -local Listeners = require("harpoon.listeners") +local Extensions = require("harpoon.extensions") --- @class HarpoonNavOptions --- @field ui_nav_wrap? boolean @@ -57,8 +57,8 @@ function HarpoonList:append(item) local index = index_of(self.items, item, self.config) Logger:log("HarpoonList:append", { item = item, index = index }) if index == -1 then - Listeners.listeners:emit( - Listeners.event_names.ADD, + Extensions.extensions:emit( + Extensions.event_names.ADD, { list = self, item = item, idx = #self.items + 1 } ) table.insert(self.items, item) @@ -73,8 +73,8 @@ function HarpoonList:prepend(item) local index = index_of(self.items, item, self.config) Logger:log("HarpoonList:prepend", { item = item, index = index }) if index == -1 then - Listeners.listeners:emit( - Listeners.event_names.ADD, + Extensions.extensions:emit( + Extensions.event_names.ADD, { list = self, item = item, idx = 1 } ) table.insert(self.items, 1, item) @@ -88,8 +88,8 @@ function HarpoonList:remove(item) item = item or self.config.create_list_item(self.config) for i, v in ipairs(self.items) do if self.config.equals(v, item) then - Listeners.listeners:emit( - Listeners.event_names.REMOVE, + Extensions.extensions:emit( + Extensions.event_names.REMOVE, { list = self, item = item, idx = i } ) Logger:log("HarpoonList:remove", { item = item, index = i }) @@ -107,8 +107,8 @@ function HarpoonList:removeAt(index) "HarpoonList:removeAt", { item = self.items[index], index = index } ) - Listeners.listeners:emit( - Listeners.event_names.REMOVE, + Extensions.extensions:emit( + Extensions.event_names.REMOVE, { list = self, item = self.items[index], idx = index } ) table.remove(self.items, index) @@ -139,8 +139,8 @@ function HarpoonList:resolve_displayed(displayed) for i, v in ipairs(list_displayed) do local index = index_of(displayed, v) if index == -1 then - Listeners.listeners:emit( - Listeners.event_names.REMOVE, + Extensions.extensions:emit( + Extensions.event_names.REMOVE, { list = self, item = self.items[i], idx = i } ) end @@ -150,14 +150,14 @@ function HarpoonList:resolve_displayed(displayed) local index = index_of(list_displayed, v) if index == -1 then new_list[i] = self.config.create_list_item(self.config, v) - Listeners.listeners:emit( - Listeners.event_names.ADD, + Extensions.extensions:emit( + Extensions.event_names.ADD, { list = self, item = new_list[i], idx = i } ) else if index ~= i then - Listeners.listeners:emit( - Listeners.event_names.REORDER, + Extensions.extensions:emit( + Extensions.event_names.REORDER, { list = self, item = self.items[index], idx = i } ) end @@ -175,8 +175,8 @@ end function HarpoonList:select(index, options) local item = self.items[index] if item or self.config.select_with_nil then - Listeners.listeners:emit( - Listeners.event_names.SELECT, + Extensions.extensions:emit( + Extensions.event_names.SELECT, { list = self, item = item, idx = index } ) self.config.select(item, self, options) diff --git a/lua/harpoon/listeners.lua b/lua/harpoon/listeners.lua deleted file mode 100644 index a8b2b73..0000000 --- a/lua/harpoon/listeners.lua +++ /dev/null @@ -1,60 +0,0 @@ ----@alias HarpoonListener fun(type: string, args: any[] | any | nil): nil - ---- TODO: Rename this... its an odd name "listeners" - ----@class HarpoonListeners ----@field listeners (HarpoonListener)[] ----@field listenersByType (table)[] -local HarpoonListeners = {} - -HarpoonListeners.__index = HarpoonListeners - -function HarpoonListeners:new() - return setmetatable({ - listeners = {}, - listenersByType = {}, - }, self) -end - ----@param cbOrType HarpoonListener | string ----@param cbOrNil HarpoonListener | string -function HarpoonListeners:add_listener(cbOrType, cbOrNil) - if type(cbOrType) == "string" then - if not self.listenersByType[cbOrType] then - self.listenersByType[cbOrType] = {} - end - table.insert(self.listenersByType[cbOrType], cbOrNil) - else - table.insert(self.listeners, cbOrType) - end -end - -function HarpoonListeners:clear_listeners() - self.listeners = {} -end - ----@param type string ----@param args any[] | any | nil -function HarpoonListeners:emit(type, args) - for _, cb in ipairs(self.listeners) do - cb(type, args) - end - - local listeners = self.listenersByType[type] - if listeners ~= nil then - for _, cb in ipairs(listeners) do - cb(type, args) - end - end -end - -return { - listeners = HarpoonListeners:new(), - event_names = { - ADD = "ADD", - SELECT = "SELECT", - REMOVE = "REMOVE", - REORDER = "REORDER", - UI_CREATE = "UI_CREATE", - }, -} diff --git a/lua/harpoon/ui.lua b/lua/harpoon/ui.lua index e412b4c..437c830 100644 --- a/lua/harpoon/ui.lua +++ b/lua/harpoon/ui.lua @@ -1,6 +1,6 @@ local Buffer = require("harpoon.buffer") local Logger = require("harpoon.logger") -local Listeners = require("harpoon.listeners") +local Extensions = require("harpoon.extensions") ---@class HarpoonToggleOptions ---@field border? any this value is directly passed to nvim_open_win @@ -116,7 +116,7 @@ function HarpoonUI:_create_window(toggle_opts) win = win_id, }) - Listeners.listeners:emit(Listeners.event_names.UI_CREATE, { + Extensions.extensions:emit(Extensions.event_names.UI_CREATE, { win_id = win_id, bufnr = bufnr, })