Skip to content

Commit

Permalink
feat: listeners for list actions
Browse files Browse the repository at this point in the history
one thing to consider is if we want to add filtering to the listeners by
list?  or should we move the listeners to the list?
  • Loading branch information
ThePrimeagen committed Nov 29, 2023
1 parent b22cb4a commit 6fdff8b
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 7 deletions.
6 changes: 3 additions & 3 deletions lua/harpoon2/config.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
local utils = require("harpoon2.utils")
local Listeners = require("harpoon2.listeners")
local listeners = Listeners.listeners

local M = {}

---@alias HarpoonListItem {value: any, context: any}
Expand All @@ -19,7 +21,6 @@ local M = {}
---@field width number
---@field height number


---notehunthoeunthoeunthoeunthoeunthoeunth
---@class HarpoonSettings
---@field save_on_toggle boolean defaults to true
Expand All @@ -31,7 +32,6 @@ local M = {}
---@field jump_to_file_location? boolean
---@field key? (fun(): string)


---@class HarpoonConfig
---@field default HarpoonPartialConfigItem
---@field settings HarpoonSettings
Expand Down
3 changes: 3 additions & 0 deletions lua/harpoon2/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ local Ui = require("harpoon2.ui")
local Data = require("harpoon2.data")
local Config = require("harpoon2.config")
local List = require("harpoon2.list")
local Listeners = require("harpoon2.listeners")

-- setup
-- read from a config file
Expand All @@ -14,6 +15,7 @@ local DEFAULT_LIST = "__harpoon_files"
---@class Harpoon
---@field config HarpoonConfig
---@field ui HarpoonUI
---@field listeners HarpoonListeners
---@field data HarpoonData
---@field lists {[string]: {[string]: HarpoonList}}
---@field hooks_setup boolean
Expand All @@ -29,6 +31,7 @@ function Harpoon:new()
config = config,
data = Data.Data:new(),
ui = Ui:new(config.settings),
listeners = Listeners.listeners,
lists = {},
hooks_setup = false,
}, self)
Expand Down
21 changes: 18 additions & 3 deletions lua/harpoon2/list.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
local Listeners = require("harpoon2.listeners")

local function index_of(items, element, config)
local equals = config and config.equals or function(a, b) return a == b end
local index = -1
Expand Down Expand Up @@ -43,6 +45,7 @@ function HarpoonList:append(item)

local index = index_of(self.items, item, self.config)
if index == -1 then
Listeners.listeners:emit(Listeners.event_names.ADD, {list = self, item = item, idx = #self.items + 1})
table.insert(self.items, item)
end

Expand All @@ -54,6 +57,7 @@ function HarpoonList:prepend(item)
item = item or self.config.add()
local index = index_of(self.items, item, self.config)
if index == -1 then
Listeners.listeners:emit(Listeners.event_names.ADD, {list = self, item = item, idx = 1})
table.insert(self.items, 1, item)
end

Expand All @@ -64,6 +68,7 @@ end
function HarpoonList:remove(item)
for i, v in ipairs(self.items) do
if self.config.equals(v, item) then
Listeners.listeners:emit(Listeners.event_names.REMOVE, {list = self, item = item, idx = i})
table.remove(self.items, i)
break
end
Expand All @@ -73,6 +78,7 @@ end

---@return HarpoonList
function HarpoonList:removeAt(index)
Listeners.listeners:emit(Listeners.event_names.REMOVE, {list = self, item = self.items[index], idx = index})
table.remove(self.items, index)
return self
end
Expand All @@ -97,17 +103,25 @@ function HarpoonList:resolve_displayed(displayed)
local new_list = {}

local list_displayed = self:display()

for i, v in ipairs(list_displayed) do
local index = index_of(list_displayed, v)
if index == -1 then
Listeners.listeners:emit(Listeners.event_names.REMOVE, {list = self, item = v, idx = i})
end
end

for i, v in ipairs(displayed) do
local index = index_of(list_displayed, v)
if index == -1 then
table.insert(new_list, self.config.add(v))
Listeners.listeners:emit(Listeners.event_names.ADD, {list = self, item = v, idx = i})
new_list[i] = self.config.add(v)
else
local index_in_new_list = index_of(new_list, self.items[index], self.config)
if index_in_new_list == -1 then
table.insert(new_list, self.items[index])
new_list[i] = self.items[index]
end
end

end

self.items = new_list
Expand All @@ -116,6 +130,7 @@ end
function HarpoonList:select(index, options)
local item = self.items[index]
if item then
Listeners.listeners:emit(Listeners.event_names.SELECT, {list = self, item = item, idx = index})
self.config.select(item, options)
end
end
Expand Down
57 changes: 57 additions & 0 deletions lua/harpoon2/listeners.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@

---@alias HarpoonListener fun(type: string, args: any[] | any | nil): nil

---@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",
},
}
4 changes: 3 additions & 1 deletion lua/harpoon2/test/ui_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ describe("harpoon", function()
local bufnr = harpoon.ui.bufnr
local win_id = harpoon.ui.win_id

eq(vim.api.nvim_buf_is_valid(bufnr), true)
eq(vim.api.nvim_win_is_valid(win_id), true)

harpoon.ui:toggle_quick_menu()

eq(vim.api.nvim_buf_is_valid(bufnr), false)
eq(vim.api.nvim_win_is_valid(win_id), false)
eq(harpoon.ui.bufnr, nil)
eq(harpoon.ui.win_id, nil)
end)

end)


0 comments on commit 6fdff8b

Please sign in to comment.