diff --git a/lua/harpoon2/config.lua b/lua/harpoon2/config.lua index c10a6643..6bd375ef 100644 --- a/lua/harpoon2/config.lua +++ b/lua/harpoon2/config.lua @@ -10,7 +10,7 @@ local M = {} ---@field display? (fun(list_item: HarpoonListItem): string) ---@field select? (fun(list_item: HarpoonListItem): nil) ---@field equals? (fun(list_line_a: HarpoonListItem, list_line_b: HarpoonListItem): boolean) ----@field add? fun(): HarpoonListItem +---@field add? fun(item: any?): HarpoonListItem ---@class HarpoonSettings ---@field save_on_toggle boolean defaults to true @@ -90,10 +90,17 @@ function M.get_default_config() return list_item_a.value == list_item_b.value end, + ---@param value any ---@return HarpoonListItem - add = function() - local name = vim.api.nvim_buf_get_name(vim.api.nvim_get_current_buf()) - local pos = vim.api.nvim_win_get_cursor(0) + add = function(name) + name = name or vim.api.nvim_buf_get_name(vim.api.nvim_get_current_buf()) + local bufnr = vim.fn.bufnr(name, false) + + local pos = {1, 0} + if bufnr ~= -1 then + pos = vim.api.nvim_win_get_cursor(0) + end + return { value = name, context = { diff --git a/lua/harpoon2/list.lua b/lua/harpoon2/list.lua index fe7727d0..d7a2adc2 100644 --- a/lua/harpoon2/list.lua +++ b/lua/harpoon2/list.lua @@ -1,7 +1,8 @@ -local function index_of(config, items, element) +local function index_of(items, element, config) + local equals = config and config.equals or function(a, b) return a == b end local index = -1 for i, item in ipairs(items) do - if config.equals(element, item) then + if equals(element, item) then index = i break end @@ -33,7 +34,7 @@ end function HarpoonList:append(item) item = item or self.config.add() - local index = index_of(self.config, self.items, item) + local index = index_of(self.items, item, self.config) if index == -1 then table.insert(self.items, item) end @@ -44,7 +45,7 @@ end ---@return HarpoonList function HarpoonList:prepend(item) item = item or self.config.add() - local index = index_of(self.config, self.items, item) + local index = index_of(self.items, item, self.config) if index == -1 then table.insert(self.items, 1, item) end @@ -76,25 +77,23 @@ end --- much inefficiencies. dun care ---@param displayed string[] function HarpoonList:resolve_displayed(displayed) - local not_found = {} - - for _, v in ipairs(displayed) do - local found = false - for _, in_table in ipairs(self.items) do - if self.config.display(in_table) == v then - found = true - break + local new_list = {} + + local list_displayed = self:display() + 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)) + 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]) end end - if not found then - table.insert(not_found, v) - end end - for _, v in ipairs(not_found) do - self:remove(v) - end + self.items = new_list end --- @return string[] diff --git a/lua/harpoon2/test/harpoon_spec.lua b/lua/harpoon2/test/harpoon_spec.lua index e37427b3..60f1cb9e 100644 --- a/lua/harpoon2/test/harpoon_spec.lua +++ b/lua/harpoon2/test/harpoon_spec.lua @@ -74,6 +74,103 @@ describe("harpoon", function() }) end) + + it("ui - display resolve", function() + harpoon:setup({ + default = { + display = function(item) + -- split string on / + local parts = vim.split(item.value, "/") + return parts[#parts] + end + } + }) + + local file_names = { + "/tmp/harpoon-test-1", + "/tmp/harpoon-test-2", + "/tmp/harpoon-test-3", + "/tmp/harpoon-test-4", + } + + local contents = { "foo", "bar", "baz", "qux" } + + local bufnrs = {} + local list = harpoon:list() + for _, v in ipairs(file_names) do + table.insert(bufnrs, utils.create_file(v, contents)) + harpoon:list():append() + end + + local displayed = list:display() + eq(displayed, { + "harpoon-test-1", + "harpoon-test-2", + "harpoon-test-3", + "harpoon-test-4", + }) + + table.remove(displayed, 3) + table.remove(displayed, 2) + + list:resolve_displayed(displayed) + + eq(list.items, { + {value = file_names[1], context = {row = 4, col = 2}}, + {value = file_names[4], context = {row = 4, col = 2}}, + }) + end) + + it("ui - display resolve", function() + local file_names = { + "/tmp/harpoon-test-1", + "/tmp/harpoon-test-2", + "/tmp/harpoon-test-3", + "/tmp/harpoon-test-4", + } + + local contents = { "foo", "bar", "baz", "qux" } + + local bufnrs = {} + local list = harpoon:list() + for _, v in ipairs(file_names) do + table.insert(bufnrs, utils.create_file(v, contents)) + harpoon:list():append() + end + + local displayed = list:display() + eq(displayed, { + "/tmp/harpoon-test-1", + "/tmp/harpoon-test-2", + "/tmp/harpoon-test-3", + "/tmp/harpoon-test-4", + }) + + table.remove(displayed, 3) + table.remove(displayed, 2) + + table.insert(displayed, "/tmp/harpoon-test-other-file-1") + table.insert(displayed, "/tmp/harpoon-test-other-file-2") + + list:resolve_displayed(displayed) + + eq(list.items, { + {value = file_names[1], context = {row = 4, col = 2}}, + {value = file_names[4], context = {row = 4, col = 2}}, + {value = "/tmp/harpoon-test-other-file-1", context = {row = 1, col = 0}}, + {value = "/tmp/harpoon-test-other-file-2", context = {row = 1, col = 0}}, + }) + + table.remove(displayed, 3) + table.insert(displayed, "/tmp/harpoon-test-4") + list:resolve_displayed(displayed) + + eq(list.items, { + {value = file_names[1], context = {row = 4, col = 2}}, + {value = file_names[4], context = {row = 4, col = 2}}, + {value = "/tmp/harpoon-test-other-file-2", context = {row = 1, col = 0}}, + }) + end) end)