diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 13158835..2a2cb2ca 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -388,6 +388,7 @@ Following is the default configuration. See |nvim-tree-opts| for details. highlight_diagnostics = false, highlight_opened_files = "none", highlight_modified = "none", + highlight_bookmarks = "none", highlight_clipboard = "name", indent_markers = { enable = false, @@ -412,8 +413,9 @@ Following is the default configuration. See |nvim-tree-opts| for details. }, }, git_placement = "before", - diagnostics_placement = "signcolumn", modified_placement = "after", + diagnostics_placement = "signcolumn", + bookmarks_placement = "signcolumn", padding = " ", symlink_arrow = " ➛ ", show = { @@ -421,8 +423,9 @@ Following is the default configuration. See |nvim-tree-opts| for details. folder = true, folder_arrow = true, git = true, - diagnostics = true, modified = true, + diagnostics = true, + bookmarks = true, }, glyphs = { default = "", @@ -777,7 +780,8 @@ Use nvim-tree in a floating window. ============================================================================== 5.3 OPTS: RENDERER *nvim-tree-opts-renderer* -Highlight precedence: git < opened < modified < diagnostics +Highlight precedence: + clipboard > diagnostics > bookmarked > modified > opened > git *nvim-tree.renderer.add_trailing* Appends a trailing slash to folder names. @@ -819,20 +823,17 @@ Whether to show the destination of the symlink. *nvim-tree.renderer.highlight_git* Enable highlight for git attributes using `NvimTreeGit*` highlight groups. Requires |nvim-tree.git.enable| -This can be used with or without the icons. Type: `boolean`, Default: `false` *nvim-tree.renderer.highlight_diagnostics* Enable highlight for diagnostics using `LspDiagnosticsError*Text` highlight groups. Requires |nvim-tree.diagnostics.enable| -This can be used with or without the icons. Type: `boolean`, Default: `false` *nvim-tree.renderer.highlight_opened_files* Highlight icons and/or names for |bufloaded()| files using the `NvimTreeOpenedFile` highlight group. -See |nvim-tree-api.navigate.opened.next()| and -|nvim-tree-api.navigate.opened.prev()| +See |nvim-tree-api.navigate.opened.next()| and |nvim-tree-api.navigate.opened.prev()| Value can be `"none"`, `"icon"`, `"name"` or `"all"`. Type: `string`, Default: `"none"` @@ -841,7 +842,11 @@ Highlight icons and/or names for modified files using the `NvimTreeModifiedFile` highlight group. Requires |nvim-tree.modified.enable| Value can be `"none"`, `"icon"`, `"name"` or `"all"` -This can be used with or without the icons. + Type: `string`, Default `"none"` + +*nvim-tree.renderer.highlight_bookmarks* +Highlight bookmarked using the `NvimTreeBookmarkHL` group. +Value can be `"none"`, `"icon"`, `"name"` or `"all"` Type: `string`, Default `"none"` *nvim-tree.renderer.highlight_clipboard* @@ -876,7 +881,8 @@ Configuration options for tree indent markers. *nvim-tree.renderer.icons* Configuration options for icons. -Sign column icon precedence: git < modified < diagnostics +Icon sign column precedence: + diagnostics > modified > git > bookmarked *nvim-tree.renderer.icons.web_devicons* Configure optional plugin `"nvim-tree/nvim-web-devicons"` @@ -923,6 +929,12 @@ Sign column icon precedence: git < modified < diagnostics or `"signcolumn"` (requires |nvim-tree.view.signcolumn| enabled). 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). + Type: `string`, Default: `signcolumn` + *nvim-tree.renderer.icons.padding* Inserted between icon and filename. Type: `string`, Default: `" "` @@ -933,6 +945,7 @@ Sign column icon precedence: git < modified < diagnostics *nvim-tree.renderer.icons.show* Configuration options for showing icon types. + Left to right order: file/folder, git, modified, diagnostics, bookmarked. *nvim-tree.renderer.icons.show.file* Show an icon before the file name. @@ -952,14 +965,18 @@ Sign column icon precedence: git < modified < diagnostics Requires |git.enable| `= true` Type: `boolean`, Default: `true` + *nvim-tree.renderer.icons.show.modified* + Show a modified icon, see |renderer.icons.modified_placement| + Requires |modified.enable| `= true` + Type: `boolean`, Default: `true` + *nvim-tree.renderer.icons.show.diagnostics* Show a diagnostics status icon, see |renderer.icons.diagnostics_placement| Requires |diagnostics.enable| `= true` Type: `boolean`, Default: `true` - *nvim-tree.renderer.icons.show.modified* - Show a modified icon, see |renderer.icons.modified_placement| - Requires |modified.enable| `= true` + *nvim-tree.renderer.icons.show.bookmarks* + Show a bookmark icon, see |renderer.icons.bookmarks_placement| Type: `boolean`, Default: `true` *nvim-tree.renderer.icons.glyphs* @@ -2153,7 +2170,6 @@ Icon: > NvimTreeFolderIcon NvimTreeOpenedFolderIcon NvimTreeFolderIcon NvimTreeClosedFolderIcon NvimTreeFolderIcon - NvimTreeBookmark NvimTreeFolderArrowClosed NvimTreeIndentMarker NvimTreeFolderArrowOpen NvimTreeIndentMarker < @@ -2182,6 +2198,12 @@ Clipboard: > NvimTreeCopiedHL SpellRare NvimTreeCutHL SpellBad < +Bookmark Icon: > + NvimTreeBookmark +< +Bookmark Highlight: > + NvimTreeBookmarkHL SpellLocal +< Picker: > NvimTreeWindowPicker < diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index bddd1123..0305e9a5 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -417,6 +417,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS highlight_diagnostics = false, highlight_opened_files = "none", highlight_modified = "none", + highlight_bookmarks = "none", highlight_clipboard = "name", indent_markers = { enable = false, @@ -441,8 +442,9 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS }, }, git_placement = "before", - diagnostics_placement = "signcolumn", modified_placement = "after", + diagnostics_placement = "signcolumn", + bookmarks_placement = "signcolumn", padding = " ", symlink_arrow = " ➛ ", show = { @@ -450,8 +452,9 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS folder = true, folder_arrow = true, git = true, - diagnostics = true, modified = true, + diagnostics = true, + bookmarks = true, }, glyphs = { default = "", @@ -659,10 +662,13 @@ local ACCEPTED_STRINGS = { renderer = { highlight_opened_files = { "none", "icon", "name", "all" }, highlight_modified = { "none", "icon", "name", "all" }, + highlight_bookmarks = { "none", "icon", "name", "all" }, + highlight_clipboard = { "none", "icon", "name", "all" }, icons = { git_placement = { "before", "after", "signcolumn" }, - diagnostics_placement = { "before", "after", "signcolumn" }, modified_placement = { "before", "after", "signcolumn" }, + diagnostics_placement = { "before", "after", "signcolumn" }, + bookmarks_placement = { "before", "after", "signcolumn" }, }, }, } diff --git a/lua/nvim-tree/actions/fs/copy-paste.lua b/lua/nvim-tree/actions/fs/copy-paste.lua index de21d0ed..abf25cf3 100644 --- a/lua/nvim-tree/actions/fs/copy-paste.lua +++ b/lua/nvim-tree/actions/fs/copy-paste.lua @@ -5,6 +5,7 @@ local core = require "nvim-tree.core" local events = require "nvim-tree.events" local notify = require "nvim-tree.notify" local renderer = require "nvim-tree.renderer" +local reloaders = require "nvim-tree.actions.reloaders.reloaders" local HL_POSITION = require("nvim-tree.enum").HL_POSITION @@ -195,7 +196,7 @@ local function do_paste(node, action_type, action_fn) clipboard[action_type] = {} if not M.config.filesystem_watchers.enable then - return require("nvim-tree.actions.reloaders.reloaders").reload_explorer() + return reloaders.reload_explorer() end end @@ -300,7 +301,7 @@ end function M.setup(opts) M.config.filesystem_watchers = opts.filesystem_watchers M.config.actions = opts.actions - M.hl_pos = HL_POSITION[opts.renderer.highlight_clipboard] + M.hl_pos = HL_POSITION[opts.renderer.highlight_clipboard] or HL_POSITION.none end return M diff --git a/lua/nvim-tree/colors.lua b/lua/nvim-tree/colors.lua index 62b67658..7487c05e 100644 --- a/lua/nvim-tree/colors.lua +++ b/lua/nvim-tree/colors.lua @@ -108,6 +108,7 @@ local function get_links() SignColumn = "NvimTreeNormal", CutHL = "SpellBad", CopiedHL = "SpellRare", + BookmarkHL = "SpellLocal", } end diff --git a/lua/nvim-tree/marks/init.lua b/lua/nvim-tree/marks/init.lua index c3008ebd..7b5773a6 100644 --- a/lua/nvim-tree/marks/init.lua +++ b/lua/nvim-tree/marks/init.lua @@ -1,6 +1,4 @@ -local view = require "nvim-tree.view" -local Iterator = require "nvim-tree.iterators.node-iterator" -local core = require "nvim-tree.core" +local renderer = {} -- circular dependency local NvimTreeMarks = {} @@ -8,12 +6,14 @@ local M = {} local function add_mark(node) NvimTreeMarks[node.absolute_path] = node - M.draw() + + renderer.draw() end local function remove_mark(node) NvimTreeMarks[node.absolute_path] = nil - M.draw() + + renderer.draw() end function M.toggle_mark(node) @@ -26,11 +26,14 @@ function M.toggle_mark(node) else add_mark(node) end + + renderer.draw() end function M.clear_marks() NvimTreeMarks = {} - M.draw() + + renderer.draw() end function M.get_mark(node) @@ -45,36 +48,9 @@ function M.get_marks() return list end -local GROUP = "NvimTreeMarkSigns" -local SIGN_NAME = "NvimTreeMark" - -function M.clear() - vim.fn.sign_unplace(GROUP) -end - -function M.draw() - if not view.is_visible() then - return - end - - M.clear() - - local buf = view.get_bufnr() - local add = core.get_nodes_starting_line() - 1 - Iterator.builder(core.get_explorer().nodes) - :recursor(function(node) - return node.group_next and { node.group_next } or (node.open and node.nodes) - end) - :applier(function(node, idx) - if M.get_mark(node) then - vim.fn.sign_place(0, GROUP, SIGN_NAME, buf, { lnum = idx + add, priority = 3 }) - end - end) - :iterate() -end - function M.setup(opts) - vim.fn.sign_define(SIGN_NAME, { text = opts.renderer.icons.glyphs.bookmark, texthl = "NvimTreeBookmark" }) + renderer = require "nvim-tree.renderer" + require("nvim-tree.marks.bulk-delete").setup(opts) require("nvim-tree.marks.bulk-trash").setup(opts) require("nvim-tree.marks.bulk-move").setup(opts) diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index ad39e7f3..727d16a3 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -6,6 +6,7 @@ local pad = require "nvim-tree.renderer.components.padding" local icons = require "nvim-tree.renderer.components.icons" local modified = require "nvim-tree.renderer.components.modified" local diagnostics = require "nvim-tree.renderer.components.diagnostics" +local bookmarks = require "nvim-tree.renderer.components.bookmarks" local HL_POSITION = require("nvim-tree.enum").HL_POSITION @@ -83,6 +84,14 @@ function Builder:configure_diagnostics_icon_placement(where) return self end +function Builder:configure_bookmark_icon_placement(where) + if where ~= "after" and where ~= "before" and where ~= "signcolumn" then + where = "before" -- default before + end + self.bookmarks_placement = where + return self +end + function Builder:configure_modified_placement(where) if where ~= "after" and where ~= "before" and where ~= "signcolumn" then where = "after" -- default after @@ -245,12 +254,21 @@ function Builder:_get_modified_icon(node) return modified_icon end +---@param node table +---@return HighlightedString[]|nil icon +function Builder:_get_bookmark_icon(node) + local bookmark_icon = bookmarks.get_icon(node) + if bookmark_icon and self.bookmarks_placement == "signcolumn" then + table.insert(self.signs, { sign = bookmark_icon.hl[1], lnum = self.index + 1, priority = 4 }) + bookmark_icon = nil + end + return bookmark_icon +end + ---@param node table ---@return string|nil icon_hl ---@return string|nil name_hl function Builder:_get_highlight_override(node, unloaded_bufnr) - -- highlights precedence: - -- original < git < opened_file < modified local name_hl, icon_hl -- git @@ -311,8 +329,18 @@ end ---@param git_icons HighlightedString[]|nil ---@param diagnostics_icon HighlightedString|nil ---@param modified_icon HighlightedString|nil +---@param bookmark_icon HighlightedString|nil ---@return HighlightedString[] -function Builder:_format_line(indent_markers, arrows, icon, name, git_icons, diagnostics_icon, modified_icon) +function Builder:_format_line( + indent_markers, + arrows, + icon, + name, + git_icons, + diagnostics_icon, + modified_icon, + bookmark_icon +) local added_len = 0 local function add_to_end(t1, t2) for _, v in ipairs(t2) do @@ -341,6 +369,9 @@ function Builder:_format_line(indent_markers, arrows, icon, name, git_icons, dia if diagnostics_icon and self.diagnostics_placement == "before" then add_to_end(line, { diagnostics_icon }) end + if bookmark_icon and self.bookmarks_placement == "before" then + add_to_end(line, { bookmark_icon }) + end add_to_end(line, { name }) @@ -353,6 +384,9 @@ function Builder:_format_line(indent_markers, arrows, icon, name, git_icons, dia if diagnostics_icon and self.diagnostics_placement == "after" then add_to_end(line, { diagnostics_icon }) end + if bookmark_icon and self.bookmarks_placement == "after" then + add_to_end(line, { bookmark_icon }) + end return line end @@ -363,6 +397,9 @@ function Builder:_build_line(node, idx, num_children, unloaded_bufnr) -- various components local indent_markers = pad.get_indent_markers(self.depth, idx, num_children, node, self.markers) local arrows = pad.get_arrows(node) + + -- adds icons to signcolumn + local bookmark_icon = self:_get_bookmark_icon(node) local git_icons = self:_get_git_icons(node) local modified_icon = self:_get_modified_icon(node) local diagnostics_icon = self:_get_diagnostics_icon(node) @@ -389,10 +426,12 @@ function Builder:_build_line(node, idx, num_children, unloaded_bufnr) end -- extra highighting + self:_append_highlight(node, bookmarks.get_highlight, icon.hl, name.hl) self:_append_highlight(node, diagnostics.get_highlight, icon.hl, name.hl) self:_append_highlight(node, copy_paste.get_highlight, icon.hl, name.hl) - local line = self:_format_line(indent_markers, arrows, icon, name, git_icons, diagnostics_icon, modified_icon) + local line = + self:_format_line(indent_markers, arrows, icon, name, git_icons, diagnostics_icon, modified_icon, bookmark_icon) self:_insert_line(self:_unwrap_highlighted_strings(line)) self.index = self.index + 1 diff --git a/lua/nvim-tree/renderer/components/bookmarks.lua b/lua/nvim-tree/renderer/components/bookmarks.lua new file mode 100644 index 00000000..d9dfb729 --- /dev/null +++ b/lua/nvim-tree/renderer/components/bookmarks.lua @@ -0,0 +1,51 @@ +local marks = require "nvim-tree.marks" + +local HL_POSITION = require("nvim-tree.enum").HL_POSITION + +local M = { + ICON = {}, + hl_pos = HL_POSITION.none, +} + +---Bookmark highlight group and position when highlight_bookmark. +---@param node table +---@return HL_POSITION position none when clipboard empty +---@return string|nil group only when node present in clipboard +function M.get_highlight(node) + if M.hl_pos == HL_POSITION.none then + return HL_POSITION.none, nil + end + + local mark = marks.get_mark(node) + if mark then + return M.hl_pos, "NvimTreeBookmarkHL" + else + return HL_POSITION.none, nil + end +end + +---bookmark icon if marked +---@param node table +---@return HighlightedString|nil bookmark icon +function M.get_icon(node) + if M.config.renderer.icons.show.bookmarks and marks.get_mark(node) then + return M.ICON + end +end + +function M.setup(opts) + M.config = { + renderer = opts.renderer, + } + + M.hl_pos = HL_POSITION[opts.renderer.highlight_bookmarks] or HL_POSITION.none + + M.ICON = { + str = opts.renderer.icons.glyphs.bookmark, + hl = { "NvimTreeBookmark" }, + } + + vim.fn.sign_define(M.ICON.hl[1], { text = M.ICON.str, texthl = M.ICON.hl[1] }) +end + +return M diff --git a/lua/nvim-tree/renderer/init.lua b/lua/nvim-tree/renderer/init.lua index 72e04df0..c5249c20 100644 --- a/lua/nvim-tree/renderer/init.lua +++ b/lua/nvim-tree/renderer/init.lua @@ -11,7 +11,7 @@ local git = require "nvim-tree.renderer.components.git" local diagnostics = require "nvim-tree.renderer.components.diagnostics" local Builder = require "nvim-tree.renderer.builder" local live_filter = require "nvim-tree.live-filter" -local marks = require "nvim-tree.marks" +local bookmarks = require "nvim-tree.renderer.components.bookmarks" local M = { last_highlights = {}, @@ -74,6 +74,7 @@ function M.draw(unloaded_bufnr) :configure_icon_padding(M.config.icons.padding) :configure_git_icons_placement(M.config.icons.git_placement) :configure_diagnostics_icon_placement(M.config.icons.diagnostics_placement) + :configure_bookmark_icon_placement(M.config.icons.bookmarks_placement) :configure_modified_placement(M.config.icons.modified_placement) :configure_symlink_destination(M.config.symlink_destination) :configure_filter(live_filter.filter, live_filter.prefix) @@ -89,8 +90,6 @@ function M.draw(unloaded_bufnr) vim.api.nvim_win_set_cursor(view.get_winnr(), cursor) end - marks.draw() - view.grow_from_content() log.profile_end(profile) @@ -107,6 +106,7 @@ function M.setup(opts) git.setup(opts) modified.setup(opts) diagnostics.setup(opts) + bookmarks.setup(opts) icon_component.setup(opts) end