diff --git a/lua/codediff/ui/lib/tree.lua b/lua/codediff/ui/lib/tree.lua index e1485118..b83a11f6 100644 --- a/lua/codediff/ui/lib/tree.lua +++ b/lua/codediff/ui/lib/tree.lua @@ -250,11 +250,16 @@ function Tree:render() -- Build lines and collect highlight info local lines = {} local line_highlights = {} -- [line_idx] = { {col_start, col_end, hl_group}, ... } + local line_spacers = {} -- [line_idx] = spacer_size for i, node in ipairs(visible_nodes) do node._line = i self._line_to_node[i] = node + if node.data and node.data.type == "group" and i > 1 then + line_spacers[i] = 1 + end + if self._prepare_node then local line_obj = self._prepare_node(node) if line_obj and line_obj._segments then @@ -287,6 +292,19 @@ function Tree:render() -- Apply highlights vim.api.nvim_buf_clear_namespace(self._bufnr, self._ns_id, 0, -1) + + -- Apply virtual line spacers + for line_idx, spacer_size in pairs(line_spacers) do + local virt_lines = {} + for _ = 1, spacer_size do + table.insert(virt_lines, { { "", "" } }) + end + pcall(vim.api.nvim_buf_set_extmark, self._bufnr, self._ns_id, line_idx - 1, 0, { + virt_lines = virt_lines, + virt_lines_above = true, + }) + end + for line_idx, entries in pairs(line_highlights) do for _, entry in ipairs(entries) do pcall(vim.api.nvim_buf_set_extmark, self._bufnr, self._ns_id, line_idx - 1, entry[1], { diff --git a/tests/ui/lib/lib_spec.lua b/tests/ui/lib/lib_spec.lua index d396ea65..bed2cb7b 100644 --- a/tests/ui/lib/lib_spec.lua +++ b/tests/ui/lib/lib_spec.lua @@ -510,4 +510,17 @@ describe("Tree", function() local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false) assert.same({ "Changes" }, lines) end) + + it("applies a virtual top margin to group nodes that are not the first line", function() + local tree = Tree({ bufnr = bufnr, nodes = { + Tree.Node({ data = { type = "group" } }), + Tree.Node({ data = { type = "group" } }) + }}) + + tree:render() + + local marks = vim.api.nvim_buf_get_extmarks(bufnr, tree._ns_id, 0, -1, { details = true }) + assert.equals(1, #marks[1][4].virt_lines) + assert.is_true(marks[1][4].virt_lines_above) + end) end)