fix: replace_at causes duplicates

This commit is contained in:
theprimeagen 2024-04-04 09:30:55 -06:00
parent 2e25a13fa4
commit 0d959f34c0
3 changed files with 45 additions and 13 deletions

View File

@ -149,6 +149,7 @@ function M.get_default_config()
elseif list_item_a == nil or list_item_b == nil then elseif list_item_a == nil or list_item_b == nil then
return false return false
end end
return list_item_a.value == list_item_b.value return list_item_a.value == list_item_b.value
end, end,

View File

@ -29,13 +29,14 @@ end
---@param items any[] ---@param items any[]
---@param element any ---@param element any
---@param config HarpoonPartialConfigItem? ---@param config HarpoonPartialConfigItem?
local function index_of(items, element, config) local function index_of(items, length, element, config)
local equals = config and config.equals local equals = config and config.equals
or function(a, b) or function(a, b)
return a == b return a == b
end end
local index = -1 local index = -1
for i, item in ipairs(items) do for i = 1, length do
local item = items[i]
if equals(element, item) then if equals(element, item) then
index = i index = i
break break
@ -81,8 +82,8 @@ function HarpoonList:new(config, name, items)
return setmetatable({ return setmetatable({
items = items, items = items,
config = config, config = config,
_length = guess_length(items),
name = name, name = name,
_length = guess_length(items),
_index = 1, _index = 1,
}, self) }, self)
end end
@ -108,21 +109,31 @@ end
---@param item? HarpoonListItem ---@param item? HarpoonListItem
function HarpoonList:replace_at(idx, item) function HarpoonList:replace_at(idx, item)
item = item or self.config.create_list_item(self.config) item = item or self.config.create_list_item(self.config)
local current_idx = index_of(self.items, self._length, item, self.config)
self.items[idx] = item
if current_idx ~= idx then
self.items[current_idx] = nil
end
if idx > self._length then
self._length = idx
else
self._length = determine_length(self.items, self._length)
end
Extensions.extensions:emit( Extensions.extensions:emit(
Extensions.event_names.REPLACE, Extensions.event_names.REPLACE,
{ list = self, item = item, idx = idx } { list = self, item = item, idx = idx }
) )
self.items[idx] = item
if idx > self._length then
self._length = idx
end
end end
---@param item? HarpoonListItem ---@param item? HarpoonListItem
function HarpoonList:add(item) function HarpoonList:add(item)
item = item or self.config.create_list_item(self.config) item = item or self.config.create_list_item(self.config)
local index = index_of(self.items, item, self.config) local index = index_of(self.items, self._length, item, self.config)
Logger:log("HarpoonList:add", { item = item, index = index }) Logger:log("HarpoonList:add", { item = item, index = index })
if index == -1 then if index == -1 then
@ -151,7 +162,7 @@ end
---@return HarpoonList ---@return HarpoonList
function HarpoonList:prepend(item) function HarpoonList:prepend(item)
item = item or self.config.create_list_item(self.config) item = item or self.config.create_list_item(self.config)
local index = index_of(self.items, item, self.config) local index = index_of(self.items, self._length, item, self.config)
Logger:log("HarpoonList:prepend", { item = item, index = index }) Logger:log("HarpoonList:prepend", { item = item, index = index })
if index == -1 then if index == -1 then
local stop_idx = prepend_to_array(self.items, item) local stop_idx = prepend_to_array(self.items, item)
@ -214,7 +225,7 @@ end
function HarpoonList:get_by_display(name) function HarpoonList:get_by_display(name)
local displayed = self:display() local displayed = self:display()
local index = index_of(displayed, name, self.config) local index = index_of(displayed, #displayed, name, self.config)
if index == -1 then if index == -1 then
return nil return nil
end end
@ -232,7 +243,7 @@ function HarpoonList:resolve_displayed(displayed, length)
local change = 0 local change = 0
for i = 1, self._length do for i = 1, self._length do
local v = self.items[i] local v = self.items[i]
local index = index_of(displayed, v) local index = index_of(displayed, self._length, v)
if index == -1 then if index == -1 then
change = change + 1 change = change + 1
end end
@ -240,7 +251,7 @@ function HarpoonList:resolve_displayed(displayed, length)
for i = 1, length do for i = 1, length do
local v = displayed[i] local v = displayed[i]
local index = index_of(list_displayed, v) local index = index_of(list_displayed, self._length, v)
if v == "" then if v == "" then
new_list[i] = nil new_list[i] = nil
elseif index == -1 then elseif index == -1 then
@ -248,7 +259,7 @@ function HarpoonList:resolve_displayed(displayed, length)
change = change + 1 change = change + 1
else else
local index_in_new_list = local index_in_new_list =
index_of(new_list, self.items[index], self.config) index_of(new_list, length, self.items[index], self.config)
if index_in_new_list == -1 then if index_in_new_list == -1 then
new_list[i] = self.items[index] new_list[i] = self.items[index]

View File

@ -251,6 +251,26 @@ describe("list", function()
{ value = "threethree" }, { value = "threethree" },
{ value = "four" }, { value = "four" },
}, list.items) }, list.items)
list:replace_at(2, { value = "one" })
eq(4, list:length())
eq({
nil,
{ value = "one" },
{ value = "threethree" },
{ value = "four" },
}, list.items)
list:replace_at(5, { value = "one" })
eq(5, list:length())
eq({
nil,
nil,
{ value = "threethree" },
{ value = "four" },
{ value = "one" },
}, list.items)
end) end)
it("resolve_displayed", function() it("resolve_displayed", function()