Skip to content

Commit

Permalink
fix(tree): make sure qf items always have a unique id. Fixes #367
Browse files Browse the repository at this point in the history
  • Loading branch information
folke committed Mar 29, 2024
1 parent d8ade15 commit cb2d3b2
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 7 deletions.
21 changes: 21 additions & 0 deletions lua/trouble/item.lua
Expand Up @@ -36,6 +36,27 @@ function M.new(opts)
return setmetatable(self, M)
end

---@param items trouble.Item[]
---@param fields? string[]
function M.add_id(items, fields)
for _, item in ipairs(items) do
if not item.id then
local id = {
item.source,
item.filename,
item.pos[1] or "",
item.pos[2] or "",
item.end_pos[1] or "",
item.end_pos[2] or "",
}
for _, field in ipairs(fields or {}) do
table.insert(id, item[field] or "")
end
item.id = table.concat(id, ":")
end
end
end

---@return string?
function M:get_ft()
if self.buf and vim.api.nvim_buf_is_loaded(self.buf) then
Expand Down
1 change: 1 addition & 0 deletions lua/trouble/sources/diagnostics.lua
Expand Up @@ -79,6 +79,7 @@ function M.setup()
if buf and vim.api.nvim_buf_is_valid(buf) then
cache[buf] = cache[buf] or {}
table.insert(cache[buf], M.item(diag))
Item.add_id(cache[buf], { "item.source", "severity", "code" })
end
end
end
Expand Down
1 change: 1 addition & 0 deletions lua/trouble/sources/qf.lua
Expand Up @@ -92,6 +92,7 @@ function M.get_list(opts)
ret[#ret].item.text = ret[#ret].item.text .. "\n" .. item.text
end
end
Item.add_id(ret, { "severity" })
Item.add_text(ret, { mode = "full" })
return ret
end
Expand Down
39 changes: 38 additions & 1 deletion lua/trouble/tree.lua
Expand Up @@ -83,7 +83,10 @@ end

function M:add(node)
if node.id then
assert(self.index[node.id] == nil, "node already exists")
if self.index[node.id] then
Util.debug("node already exists:\n" .. node.id)
node.id = node.id .. "_"
end
self.index[node.id] = node
end
node.parent = self
Expand All @@ -95,6 +98,40 @@ function M:is_leaf()
return self.children == nil or #self.children == 0
end

---@param other? trouble.Node
function M:is(other)
if not other then
return false
end

if self == other then
return true
end

if self.id ~= other.id then
return false
end

if self.group ~= other.group then
return false
end

if self.group then
return true
end
assert(self.item, "missing item")

if not other.item then
return false
end

if self.item == other.item then
return true
end

return self.item.id and (self.item.id == other.item.id)
end

--- Build a tree from a list of items and a section.
---@param items trouble.Item[]
---@param section trouble.Section.opts
Expand Down
12 changes: 6 additions & 6 deletions lua/trouble/view/init.lua
Expand Up @@ -464,6 +464,7 @@ function M:render()
return
end

-- fast exit when cursor is already on the right item
local new_loc = self:at()
if new_loc.node and loc.node and new_loc.node.id == loc.node.id then
return
Expand All @@ -472,17 +473,16 @@ function M:render()
-- Move cursor to the same item
local cursor = vim.api.nvim_win_get_cursor(self.win.win)
local item_row ---@type number?
for row, l in pairs(self.renderer._locations) do
if loc.node and loc.item then
if l.node and l.item and loc.node.id == l.node.id and l.item == loc.item then
if loc.node then
for row, l in pairs(self.renderer._locations) do
if loc.node:is(l.node) then
item_row = row
break
end
elseif loc.node and l.node and loc.node.id == l.node.id then
item_row = row
break
end
end

-- Move cursor to the actual item when found
if item_row and item_row ~= cursor[1] then
vim.api.nvim_win_set_cursor(self.win.win, { item_row, cursor[2] })
return
Expand Down

0 comments on commit cb2d3b2

Please sign in to comment.