Skip to content

feat(#2349): add "right_align" option for renderer.icons.*_placement #2846

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
26 changes: 11 additions & 15 deletions doc/nvim-tree-lua.txt
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,12 @@ Configuration options for icons.
Icon order and sign column precedence:
git < hidden < modified < bookmarked < diagnostics

`renderer.icons.*_placement` options may be:
- `"before"` : before file/folder, after the file/folders icons
- `"after"` : after file/folder
- `"signcolumn"` : far left, requires |nvim-tree.view.signcolumn| enabled
- `"right_align"` : far right

*nvim-tree.renderer.icons.web_devicons*
Configure optional plugin `"nvim-tree/nvim-web-devicons"`

Expand Down Expand Up @@ -983,33 +989,23 @@ Icon order and sign column precedence:
Type: `boolean`, Default: `true`

*nvim-tree.renderer.icons.git_placement*
Place where the git icons will be rendered.
Can be `"after"` or `"before"` filename (after the file/folders icons)
or `"signcolumn"` (requires |nvim-tree.view.signcolumn| enabled).
Git icons placement.
Type: `string`, Default: `"before"`

*nvim-tree.renderer.icons.diagnostics_placement*
Place where the diagnostics icon will be rendered.
Can be `"after"` or `"before"` filename (after the file/folders icons)
or `"signcolumn"` (requires |nvim-tree.view.signcolumn| enabled).
Diganostic icon placement.
Type: `string`, Default: `"signcolumn"`

*nvim-tree.renderer.icons.modified_placement*
Place where the modified icon will be rendered.
Can be `"after"` or `"before"` filename (after the file/folders icons)
or `"signcolumn"` (requires |nvim-tree.view.signcolumn| enabled).
Modified icon placement.
Type: `string`, Default: `"after"`

*nvim-tree.renderer.icons.hidden_placement*
Place where the hidden (dotfile) icon will be rendered.
Can be `"after"` or `"before"` filename (after the file/folders icons)
or `"signcolumn"` (requires |nvim-tree.view.signcolumn| enabled).
Hidden icon placement.
Type: `string`, Default: `"after"`

*nvim-tree.renderer.icons.bookmarks_placement*
Place where the bookmarks icon will be rendered.
Can be `"after"` or `"before"` filename (after the file/folders icons)
or `"signcolumn"` (requires |nvim-tree.view.signcolumn| enabled).
Bookmark icon placement.
Type: `string`, Default: `signcolumn`

*nvim-tree.renderer.icons.padding*
Expand Down
10 changes: 5 additions & 5 deletions lua/nvim-tree.lua
Original file line number Diff line number Diff line change
Expand Up @@ -688,11 +688,11 @@ local ACCEPTED_STRINGS = {
highlight_diagnostics = { "none", "icon", "name", "all" },
highlight_clipboard = { "none", "icon", "name", "all" },
icons = {
git_placement = { "before", "after", "signcolumn" },
modified_placement = { "before", "after", "signcolumn" },
hidden_placement = { "before", "after", "signcolumn" },
diagnostics_placement = { "before", "after", "signcolumn" },
bookmarks_placement = { "before", "after", "signcolumn" },
git_placement = { "before", "after", "signcolumn", "right_align" },
modified_placement = { "before", "after", "signcolumn", "right_align" },
hidden_placement = { "before", "after", "signcolumn", "right_align" },
diagnostics_placement = { "before", "after", "signcolumn", "right_align" },
bookmarks_placement = { "before", "after", "signcolumn", "right_align" },
},
},
help = {
Expand Down
1 change: 1 addition & 0 deletions lua/nvim-tree/enum.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ M.ICON_PLACEMENT = {
signcolumn = 1,
before = 2,
after = 3,
right_align = 4,
}

return M
9 changes: 9 additions & 0 deletions lua/nvim-tree/renderer/builder.lua
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ function Builder:new()
lines = {},
markers = {},
signs = {},
extmarks = {},
}
setmetatable(o, self)
self.__index = self
Expand Down Expand Up @@ -229,6 +230,14 @@ function Builder:format_line(indent_markers, arrows, icon, name, node)
add_to_end(line, M.decorators[i]:icons_after(node))
end

local rights = {}
for i = #M.decorators, 1, -1 do
add_to_end(rights, M.decorators[i]:icons_right_align(node))
end
if #rights > 0 then
self.extmarks[self.index] = rights
end

return line
end

Expand Down
11 changes: 11 additions & 0 deletions lua/nvim-tree/renderer/decorator/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,17 @@ function Decorator:icons_after(node)
return self:calculate_icons(node)
end

---Icons when ICON_PLACEMENT.right_align
---@param node Node
---@return HighlightedString[]|nil icons
function Decorator:icons_right_align(node)
if not self.enabled or self.icon_placement ~= ICON_PLACEMENT.right_align then
return
end

return self:calculate_icons(node)
end

---Maybe icons, optionally implemented
---@protected
---@param _ Node
Expand Down
22 changes: 17 additions & 5 deletions lua/nvim-tree/renderer/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ local M = {}

local SIGN_GROUP = "NvimTreeRendererSigns"

local namespace_id = vim.api.nvim_create_namespace "NvimTreeHighlights"
local namespace_highlights_id = vim.api.nvim_create_namespace "NvimTreeHighlights"
local namespace_extmarks_id = vim.api.nvim_create_namespace "NvimTreeExtmarks"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice find.

Could we play this a bit safer and have a separate namespace for full-name as well?

It's using "NvimTreeHighlights" which is a little concerning now that we've learned of the namespace sharing difficulties.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to rename it too, indeed, doesn't have to happen here though.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked at the the namespace usage in full_name.lua, and it seems to rely on the NvimTreeHighlights namespace being set up beforehand. I thought this because of line 69:

local extmarks = vim.api.nvim_buf_get_extmarks(0, ns_id, { line_nr - 1, 0 }, { line_nr - 1, -1 }, { details = true })

Because of that I don't think I can introduce a separate namespace for full_name rn, also
I did not wrote any code in that file I'm not so sure what I could safely change.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough; there may all sorts of assumptions there.


---@param bufnr number
---@param lines string[]
---@param hl_args AddHighlightArgs[]
---@param signs string[]
local function _draw(bufnr, lines, hl_args, signs)
local function _draw(bufnr, lines, hl_args, signs, extmarks)
if vim.fn.has "nvim-0.10" == 1 then
vim.api.nvim_set_option_value("modifiable", true, { buf = bufnr })
else
Expand All @@ -38,17 +39,28 @@ local function _draw(bufnr, lines, hl_args, signs)
for i, sign_name in pairs(signs) do
vim.fn.sign_place(0, SIGN_GROUP, sign_name, bufnr, { lnum = i + 1 })
end

vim.api.nvim_buf_clear_namespace(bufnr, namespace_extmarks_id, 0, -1)
for i, extname in pairs(extmarks) do
for _, mark in ipairs(extname) do
vim.api.nvim_buf_set_extmark(bufnr, namespace_extmarks_id, i, -1, {
virt_text = { { mark.str, mark.hl } },
virt_text_pos = "right_align",
hl_mode = "combine",
})
end
end
end

function M.render_hl(bufnr, hl)
if not bufnr or not vim.api.nvim_buf_is_loaded(bufnr) then
return
end
vim.api.nvim_buf_clear_namespace(bufnr, namespace_id, 0, -1)
vim.api.nvim_buf_clear_namespace(bufnr, namespace_highlights_id, 0, -1)
for _, data in ipairs(hl) do
if type(data[1]) == "table" then
for _, group in ipairs(data[1]) do
vim.api.nvim_buf_add_highlight(bufnr, namespace_id, group, data[2], data[3], data[4])
vim.api.nvim_buf_add_highlight(bufnr, namespace_highlights_id, group, data[2], data[3], data[4])
end
end
end
Expand All @@ -67,7 +79,7 @@ function M.draw()

local builder = Builder:new():build()

_draw(bufnr, builder.lines, builder.hl_args, builder.signs)
_draw(bufnr, builder.lines, builder.hl_args, builder.signs, builder.extmarks)

if cursor and #builder.lines >= cursor[1] then
vim.api.nvim_win_set_cursor(view.get_winnr() or 0, cursor)
Expand Down
Loading