mirror of
https://github.com/ThePrimeagen/harpoon.git
synced 2025-08-29 16:40:24 +00:00
feat: harpoon extensions
This commit is contained in:
parent
8f67088e9d
commit
9e869aae22
54
lua/harpoon/extensions.lua
Normal file
54
lua/harpoon/extensions.lua
Normal file
@ -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",
|
||||
},
|
||||
}
|
@ -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?
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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<string, HarpoonListener>)[]
|
||||
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",
|
||||
},
|
||||
}
|
@ -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,
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user