From ddbc033b904badc65b28d5f96e0cb9df23717284 Mon Sep 17 00:00:00 2001 From: uanela Date: Thu, 11 Jun 2026 10:07:58 +0200 Subject: [PATCH 01/31] feat: add copy absolute path with protocol into public api --- lua/nvim-tree/_meta/api/fs.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lua/nvim-tree/_meta/api/fs.lua b/lua/nvim-tree/_meta/api/fs.lua index dfab8610434..3ab3625414c 100644 --- a/lua/nvim-tree/_meta/api/fs.lua +++ b/lua/nvim-tree/_meta/api/fs.lua @@ -14,6 +14,12 @@ nvim_tree.api.fs.copy = {} ---@param node? nvim_tree.api.Node function nvim_tree.api.fs.copy.absolute_path(node) end +--- +---Copy the absolute path to the system clipboard with nvim-tree protocol. +--- +---@param node? nvim_tree.api.Node +function nvim_tree.api.fs.copy.absolute_path_with_protocol(node) end + --- ---Copy the name with extension omitted to the system clipboard. --- From c842a086a3eb0e02ca80a43c7ec99c3b2b591b4e Mon Sep 17 00:00:00 2001 From: uanela Date: Thu, 11 Jun 2026 10:08:41 +0200 Subject: [PATCH 02/31] feat: add helper get_basename into node --- lua/nvim-tree/node/init.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lua/nvim-tree/node/init.lua b/lua/nvim-tree/node/init.lua index c89d9e7171c..d2fd2c208c6 100644 --- a/lua/nvim-tree/node/init.lua +++ b/lua/nvim-tree/node/init.lua @@ -159,4 +159,14 @@ function Node:expand(expand_opts) end end +function Node:get_basename() + if self.name == ".." then + -- root + return vim.fn.fnamemodify(self.explorer.absolute_path, ":t:r") + else + -- node + return vim.fn.fnamemodify(self.name, ":r") + end +end + return Node From 058e5081cd39de8d6a3ad6776aa08daef7c6ff72 Mon Sep 17 00:00:00 2001 From: uanela Date: Thu, 11 Jun 2026 10:11:10 +0200 Subject: [PATCH 03/31] feat: add gby keymap, and allow visual mode for copy.basename|absolute_path --- lua/nvim-tree/keymap.lua | 119 ++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 59 deletions(-) diff --git a/lua/nvim-tree/keymap.lua b/lua/nvim-tree/keymap.lua index 044bf6c9a9b..0fc6e5bae5e 100644 --- a/lua/nvim-tree/keymap.lua +++ b/lua/nvim-tree/keymap.lua @@ -57,65 +57,66 @@ function M.on_attach_default(bufnr) end -- BEGIN_ON_ATTACH_DEFAULT - vim.keymap.set("n", "", api.tree.change_root_to_node, opts("CD")) - vim.keymap.set("n", "", api.node.open.replace_tree_buffer, opts("Open: In Place")) - vim.keymap.set("n", "", api.node.show_info_popup, opts("Info")) - vim.keymap.set("n", "", api.fs.rename_sub, opts("Rename: Omit Filename")) - vim.keymap.set("n", "", api.node.open.tab, opts("Open: New Tab")) - vim.keymap.set("n", "", api.node.open.vertical, opts("Open: Vertical Split")) - vim.keymap.set("n", "", api.node.open.horizontal, opts("Open: Horizontal Split")) - vim.keymap.set("n", "", api.node.navigate.parent_close, opts("Close Directory")) - vim.keymap.set("n", "", api.node.open.edit, opts("Open")) - vim.keymap.set({ "n", "x" }, "", api.fs.remove, opts("Delete")) - vim.keymap.set("n", "", api.node.open.preview, opts("Open Preview")) - vim.keymap.set("n", ">", api.node.navigate.sibling.next, opts("Next Sibling")) - vim.keymap.set("n", "<", api.node.navigate.sibling.prev, opts("Previous Sibling")) - vim.keymap.set("n", ".", api.node.run.cmd, opts("Run Command")) - vim.keymap.set("n", "-", api.tree.change_root_to_parent, opts("Up")) - vim.keymap.set("n", "a", api.fs.create, opts("Create File Or Directory")) - vim.keymap.set("n", "bd", api.marks.bulk.delete, opts("Delete Bookmarked")) - vim.keymap.set("n", "bt", api.marks.bulk.trash, opts("Trash Bookmarked")) - vim.keymap.set("n", "bmv", api.marks.bulk.move, opts("Move Bookmarked")) - vim.keymap.set("n", "B", api.filter.no_buffer.toggle, opts("Toggle Filter: No Buffer")) - vim.keymap.set({ "n", "x" }, "c", api.fs.copy.node, opts("Copy")) - vim.keymap.set("n", "C", api.filter.git.clean.toggle, opts("Toggle Filter: Git Clean")) - vim.keymap.set("n", "[c", api.node.navigate.git.prev, opts("Prev Git")) - vim.keymap.set("n", "]c", api.node.navigate.git.next, opts("Next Git")) - vim.keymap.set({ "n", "x" }, "d", api.fs.remove, opts("Delete")) - vim.keymap.set({ "n", "x" }, "D", api.fs.trash, opts("Trash")) - vim.keymap.set("n", "E", api.tree.expand_all, opts("Expand All")) - vim.keymap.set("n", "e", api.fs.rename_basename, opts("Rename: Basename")) - vim.keymap.set("n", "]e", api.node.navigate.diagnostics.next, opts("Next Diagnostic")) - vim.keymap.set("n", "[e", api.node.navigate.diagnostics.prev, opts("Prev Diagnostic")) - vim.keymap.set("n", "F", api.filter.live.clear, opts("Live Filter: Clear")) - vim.keymap.set("n", "f", api.filter.live.start, opts("Live Filter: Start")) - vim.keymap.set("n", "g?", api.tree.toggle_help, opts("Help")) - vim.keymap.set("n", "gy", api.fs.copy.absolute_path, opts("Copy Absolute Path")) - vim.keymap.set("n", "ge", api.fs.copy.basename, opts("Copy Basename")) - vim.keymap.set("n", "H", api.filter.dotfiles.toggle, opts("Toggle Filter: Dotfiles")) - vim.keymap.set("n", "I", api.filter.git.ignored.toggle, opts("Toggle Filter: Git Ignored")) - vim.keymap.set("n", "J", api.node.navigate.sibling.last, opts("Last Sibling")) - vim.keymap.set("n", "K", api.node.navigate.sibling.first, opts("First Sibling")) - vim.keymap.set("n", "L", api.node.open.toggle_group_empty, opts("Toggle Group Empty")) - vim.keymap.set("n", "M", api.filter.no_bookmark.toggle, opts("Toggle Filter: No Bookmark")) - vim.keymap.set({ "n", "x" }, "m", api.marks.toggle, opts("Toggle Bookmark")) - vim.keymap.set("n", "o", api.node.open.edit, opts("Open")) - vim.keymap.set("n", "O", api.node.open.no_window_picker, opts("Open: No Window Picker")) - vim.keymap.set("n", "p", api.fs.paste, opts("Paste")) - vim.keymap.set("n", "P", api.node.navigate.parent, opts("Parent Directory")) - vim.keymap.set("n", "q", api.tree.close, opts("Close")) - vim.keymap.set("n", "r", api.fs.rename, opts("Rename")) - vim.keymap.set("n", "R", api.tree.reload, opts("Refresh")) - vim.keymap.set("n", "s", api.node.run.system, opts("Run System")) - vim.keymap.set("n", "S", api.tree.search_node, opts("Search")) - vim.keymap.set("n", "u", api.fs.rename_full, opts("Rename: Full Path")) - vim.keymap.set("n", "U", api.filter.custom.toggle, opts("Toggle Filter: Custom")) - vim.keymap.set("n", "W", api.tree.collapse_all, opts("Collapse All")) - vim.keymap.set({ "n", "x" }, "x", api.fs.cut, opts("Cut")) - vim.keymap.set("n", "y", api.fs.copy.filename, opts("Copy Name")) - vim.keymap.set("n", "Y", api.fs.copy.relative_path, opts("Copy Relative Path")) - vim.keymap.set("n", "<2-LeftMouse>", api.node.open.edit, opts("Open")) - vim.keymap.set("n", "<2-RightMouse>", api.tree.change_root_to_node, opts("CD")) + vim.keymap.set("n", "", api.tree.change_root_to_node, opts("CD")) + vim.keymap.set("n", "", api.node.open.replace_tree_buffer, opts("Open: In Place")) + vim.keymap.set("n", "", api.node.show_info_popup, opts("Info")) + vim.keymap.set("n", "", api.fs.rename_sub, opts("Rename: Omit Filename")) + vim.keymap.set("n", "", api.node.open.tab, opts("Open: New Tab")) + vim.keymap.set("n", "", api.node.open.vertical, opts("Open: Vertical Split")) + vim.keymap.set("n", "", api.node.open.horizontal, opts("Open: Horizontal Split")) + vim.keymap.set("n", "", api.node.navigate.parent_close, opts("Close Directory")) + vim.keymap.set("n", "", api.node.open.edit, opts("Open")) + vim.keymap.set({ "n", "x" }, "", api.fs.remove, opts("Delete")) + vim.keymap.set("n", "", api.node.open.preview, opts("Open Preview")) + vim.keymap.set("n", ">", api.node.navigate.sibling.next, opts("Next Sibling")) + vim.keymap.set("n", "<", api.node.navigate.sibling.prev, opts("Previous Sibling")) + vim.keymap.set("n", ".", api.node.run.cmd, opts("Run Command")) + vim.keymap.set("n", "-", api.tree.change_root_to_parent, opts("Up")) + vim.keymap.set("n", "a", api.fs.create, opts("Create File Or Directory")) + vim.keymap.set("n", "bd", api.marks.bulk.delete, opts("Delete Bookmarked")) + vim.keymap.set("n", "bt", api.marks.bulk.trash, opts("Trash Bookmarked")) + vim.keymap.set("n", "bmv", api.marks.bulk.move, opts("Move Bookmarked")) + vim.keymap.set("n", "B", api.filter.no_buffer.toggle, opts("Toggle Filter: No Buffer")) + vim.keymap.set({ "n", "x" }, "c", api.fs.copy.node, opts("Copy")) + vim.keymap.set("n", "C", api.filter.git.clean.toggle, opts("Toggle Filter: Git Clean")) + vim.keymap.set("n", "[c", api.node.navigate.git.prev, opts("Prev Git")) + vim.keymap.set("n", "]c", api.node.navigate.git.next, opts("Next Git")) + vim.keymap.set({ "n", "x" }, "d", api.fs.remove, opts("Delete")) + vim.keymap.set({ "n", "x" }, "D", api.fs.trash, opts("Trash")) + vim.keymap.set("n", "E", api.tree.expand_all, opts("Expand All")) + vim.keymap.set("n", "e", api.fs.rename_basename, opts("Rename: Basename")) + vim.keymap.set("n", "]e", api.node.navigate.diagnostics.next, opts("Next Diagnostic")) + vim.keymap.set("n", "[e", api.node.navigate.diagnostics.prev, opts("Prev Diagnostic")) + vim.keymap.set("n", "F", api.filter.live.clear, opts("Live Filter: Clear")) + vim.keymap.set("n", "f", api.filter.live.start, opts("Live Filter: Start")) + vim.keymap.set("n", "g?", api.tree.toggle_help, opts("Help")) + vim.keymap.set({ "n", "x" }, "gy", api.fs.copy.absolute_path, opts("Copy Absolute Path")) + vim.keymap.set({ "n", "x" }, "bgy", api.fs.copy.absolute_path_with_protocol, opts("Copy Absolute Path With Protocol")) + vim.keymap.set({ "n", "x" }, "ge", api.fs.copy.basename, opts("Copy Basename")) + vim.keymap.set("n", "H", api.filter.dotfiles.toggle, opts("Toggle Filter: Dotfiles")) + vim.keymap.set("n", "I", api.filter.git.ignored.toggle, opts("Toggle Filter: Git Ignored")) + vim.keymap.set("n", "J", api.node.navigate.sibling.last, opts("Last Sibling")) + vim.keymap.set("n", "K", api.node.navigate.sibling.first, opts("First Sibling")) + vim.keymap.set("n", "L", api.node.open.toggle_group_empty, opts("Toggle Group Empty")) + vim.keymap.set("n", "M", api.filter.no_bookmark.toggle, opts("Toggle Filter: No Bookmark")) + vim.keymap.set({ "n", "x" }, "m", api.marks.toggle, opts("Toggle Bookmark")) + vim.keymap.set("n", "o", api.node.open.edit, opts("Open")) + vim.keymap.set("n", "O", api.node.open.no_window_picker, opts("Open: No Window Picker")) + vim.keymap.set("n", "p", api.fs.paste, opts("Paste")) + vim.keymap.set("n", "P", api.node.navigate.parent, opts("Parent Directory")) + vim.keymap.set("n", "q", api.tree.close, opts("Close")) + vim.keymap.set("n", "r", api.fs.rename, opts("Rename")) + vim.keymap.set("n", "R", api.tree.reload, opts("Refresh")) + vim.keymap.set("n", "s", api.node.run.system, opts("Run System")) + vim.keymap.set("n", "S", api.tree.search_node, opts("Search")) + vim.keymap.set("n", "u", api.fs.rename_full, opts("Rename: Full Path")) + vim.keymap.set("n", "U", api.filter.custom.toggle, opts("Toggle Filter: Custom")) + vim.keymap.set("n", "W", api.tree.collapse_all, opts("Collapse All")) + vim.keymap.set({ "n", "x" }, "x", api.fs.cut, opts("Cut")) + vim.keymap.set("n", "y", api.fs.copy.filename, opts("Copy Name")) + vim.keymap.set("n", "Y", api.fs.copy.relative_path, opts("Copy Relative Path")) + vim.keymap.set("n", "<2-LeftMouse>", api.node.open.edit, opts("Open")) + vim.keymap.set("n", "<2-RightMouse>", api.tree.change_root_to_node, opts("CD")) -- END_ON_ATTACH_DEFAULT end From 89edce64c1e30c5d19b9b041672b0365b64a99ce Mon Sep 17 00:00:00 2001 From: uanela Date: Thu, 11 Jun 2026 10:14:19 +0200 Subject: [PATCH 04/31] feat(clipboard): add opts for adding protocol in reg operations --- lua/nvim-tree/actions/fs/clipboard.lua | 73 +++++++++++++++++++++----- 1 file changed, 61 insertions(+), 12 deletions(-) diff --git a/lua/nvim-tree/actions/fs/clipboard.lua b/lua/nvim-tree/actions/fs/clipboard.lua index e3abe5efd1f..cc7b2741ed4 100644 --- a/lua/nvim-tree/actions/fs/clipboard.lua +++ b/lua/nvim-tree/actions/fs/clipboard.lua @@ -43,6 +43,9 @@ function Clipboard:new(args) self.reg = self.explorer.opts.actions.use_system_clipboard and "+" or "1" end +---@class RegOperationOptions +---@field use_protocol? boolean + ---@param source string ---@param destination string ---@return boolean @@ -176,10 +179,20 @@ function Clipboard:bulk_clipboard(nodes, from, to, verb) self.explorer.renderer:draw() end +---@private +---@param node_or_nodes Node|Node[] +---@return boolean +function Clipboard:is_nodes_array(node_or_nodes) + if type(node_or_nodes) == "table" and node_or_nodes.is and node_or_nodes:is(Node) then + return false + end + return true +end + ---Copy one or more nodes ---@param node_or_nodes Node|Node[] function Clipboard:copy(node_or_nodes) - if type(node_or_nodes) == "table" and node_or_nodes.is and node_or_nodes:is(Node) then + if self:is_nodes_array(node_or_nodes) == false then utils.array_remove(self.data.cut, node_or_nodes) toggle(node_or_nodes, self.data.copy) self.explorer.renderer:draw() @@ -413,7 +426,14 @@ function Clipboard:print_clipboard() end ---@param content string -function Clipboard:copy_to_reg(content) +---@param opts? RegOperationOptions +function Clipboard:copy_to_reg(content, opts) + local use_protocol = opts and opts.use_protocol and true or false + + if use_protocol then + content = "nvim-tree: " .. content + end + -- manually firing TextYankPost does not set vim.v.event -- workaround: create a scratch buffer with the clipboard contents and send a yank command local temp_buf = vim.api.nvim_create_buf(false, true) @@ -437,15 +457,23 @@ function Clipboard:copy_filename(node) end end ----@param node Node -function Clipboard:copy_basename(node) - if node.name == ".." then - -- root - self:copy_to_reg(vim.fn.fnamemodify(self.explorer.absolute_path, ":t:r")) +---@param node_or_nodes Node|Node[] +---@param opts? RegOperationOptions +function Clipboard:copy_basename(node_or_nodes, opts) + local content = "" + if self:is_nodes_array(node_or_nodes) == false or #node_or_nodes == 1 then + local node = #node_or_nodes == 1 and node_or_nodes[0] or node_or_nodes + content = node:get_basename() else - -- node - self:copy_to_reg(vim.fn.fnamemodify(node.name, ":r")) + for i, node in ipairs(node_or_nodes) do + if i == 1 then + content = node:get_basename() + else + content = content .. ", " .. node:get_basename() + end + end end + self:copy_to_reg(content, opts) end ---@param node Node @@ -470,15 +498,36 @@ function Clipboard:copy_path(node) end end +---@private ---@param node Node -function Clipboard:copy_absolute_path(node) +---@return string +function Clipboard:get_absolute_path(node) if node.name == ".." then node = self.explorer end local absolute_path = node.absolute_path - local content = node.nodes ~= nil and utils.path_add_trailing(absolute_path) or absolute_path - self:copy_to_reg(content) + return node.nodes ~= nil and utils.path_add_trailing(absolute_path) or absolute_path +end + +---@param node_or_nodes Node|Node[] +---@param opts? RegOperationOptions +function Clipboard:copy_absolute_path(node_or_nodes, opts) + local content = "" + if self:is_nodes_array(node_or_nodes) == false or #node_or_nodes == 1 then + local node = #node_or_nodes == 1 and node_or_nodes[0] or node_or_nodes + content = self:get_absolute_path(node) + else + for i, node in ipairs(node_or_nodes) do + if i == 1 then + content = self:get_absolute_path(node) + else + content = content .. ", " .. self:get_absolute_path(node) + end + end + end + + self:copy_to_reg(content, opts) end ---Node is cut. Will not be copied. From b98e0c4ba4ef51c0e5443071315a6a5564d7ae4b Mon Sep 17 00:00:00 2001 From: uanela Date: Thu, 11 Jun 2026 10:15:11 +0200 Subject: [PATCH 05/31] feat(api): allow visual operation in absolute_path* --- lua/nvim-tree/api/impl.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lua/nvim-tree/api/impl.lua b/lua/nvim-tree/api/impl.lua index f17fa4ee825..efebb3ef288 100644 --- a/lua/nvim-tree/api/impl.lua +++ b/lua/nvim-tree/api/impl.lua @@ -155,8 +155,9 @@ function M.hydrate_post_setup(api) api.filter.toggle = e_(function(e) e.filters:toggle() end) api.fs.clear_clipboard = e_(function(e) e.clipboard:clear_clipboard() end) - api.fs.copy.absolute_path = en(function(e, n) e.clipboard:copy_absolute_path(n) end) - api.fs.copy.basename = en(function(e, n) e.clipboard:copy_basename(n) end) + api.fs.copy.absolute_path = ev(function(e, n) e.clipboard:copy_absolute_path(n) end) + api.fs.copy.absolute_path_with_protocol = ev(function(e, n) e.clipboard:copy_absolute_path(n, { use_protocol = true }) end) + api.fs.copy.basename = ev(function(e, n) e.clipboard:copy_basename(n) end) api.fs.copy.filename = en(function(e, n) e.clipboard:copy_filename(n) end) api.fs.copy.node = ev(function(e, n) e.clipboard:copy(n) end) api.fs.copy.relative_path = en(function(e, n) e.clipboard:copy_path(n) end) From f2269a1be749ce97e74f2a90848682fb59b5e3c0 Mon Sep 17 00:00:00 2001 From: uanela Date: Thu, 11 Jun 2026 15:41:20 +0200 Subject: [PATCH 06/31] feat: add paste with protocol to keymap+api --- lua/nvim-tree/_meta/api/fs.lua | 8 ++++++++ lua/nvim-tree/api/impl.lua | 1 + lua/nvim-tree/keymap.lua | 1 + 3 files changed, 10 insertions(+) diff --git a/lua/nvim-tree/_meta/api/fs.lua b/lua/nvim-tree/_meta/api/fs.lua index 3ab3625414c..7c5705b79bc 100644 --- a/lua/nvim-tree/_meta/api/fs.lua +++ b/lua/nvim-tree/_meta/api/fs.lua @@ -72,6 +72,14 @@ function nvim_tree.api.fs.cut(node) end ---@param node? nvim_tree.api.Node function nvim_tree.api.fs.paste(node) end +--- +---Paste nodes from the nvim-tree clipboard using protocol. +--- +---If {node} is a file it will pasted in the parent directory. +--- +---@param node? nvim_tree.api.Node +function nvim_tree.api.fs.paste_with_protocol(node) end + --- ---Print the contents of the nvim-tree clipboard. --- diff --git a/lua/nvim-tree/api/impl.lua b/lua/nvim-tree/api/impl.lua index efebb3ef288..db49404ae6c 100644 --- a/lua/nvim-tree/api/impl.lua +++ b/lua/nvim-tree/api/impl.lua @@ -164,6 +164,7 @@ function M.hydrate_post_setup(api) api.fs.create = _n(function(n) require("nvim-tree.actions.fs.create-file").fn(n) end) api.fs.cut = ev(function(e, n) e.clipboard:cut(n) end) api.fs.paste = en(function(e, n) e.clipboard:paste(n) end) + api.fs.paste_with_protocol = en(function(e, n) e.clipboard:paste(n, { use_protocol = true }) end) api.fs.print_clipboard = e_(function(e) e.clipboard:print_clipboard() end) api.fs.remove = _v(function(n) require("nvim-tree.actions.fs.remove-file").fn(n) end) api.fs.rename = _n(function(n) require("nvim-tree.actions.fs.rename-file").rename_node(n) end) diff --git a/lua/nvim-tree/keymap.lua b/lua/nvim-tree/keymap.lua index 0fc6e5bae5e..84bf4db4b44 100644 --- a/lua/nvim-tree/keymap.lua +++ b/lua/nvim-tree/keymap.lua @@ -103,6 +103,7 @@ function M.on_attach_default(bufnr) vim.keymap.set("n", "o", api.node.open.edit, opts("Open")) vim.keymap.set("n", "O", api.node.open.no_window_picker, opts("Open: No Window Picker")) vim.keymap.set("n", "p", api.fs.paste, opts("Paste")) + vim.keymap.set("n", "gp", api.fs.paste_with_protocol, opts("Paste With Protocol")) vim.keymap.set("n", "P", api.node.navigate.parent, opts("Parent Directory")) vim.keymap.set("n", "q", api.tree.close, opts("Close")) vim.keymap.set("n", "r", api.fs.rename, opts("Rename")) From cdc7b28c76f6a30e0558e9259c5bd8e9f8a7ff7d Mon Sep 17 00:00:00 2001 From: uanela Date: Thu, 11 Jun 2026 15:42:31 +0200 Subject: [PATCH 07/31] feat: add paste with protocol to clipboard --- lua/nvim-tree/actions/fs/clipboard.lua | 50 ++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/lua/nvim-tree/actions/fs/clipboard.lua b/lua/nvim-tree/actions/fs/clipboard.lua index cc7b2741ed4..7a542b3e3cb 100644 --- a/lua/nvim-tree/actions/fs/clipboard.lua +++ b/lua/nvim-tree/actions/fs/clipboard.lua @@ -9,6 +9,7 @@ local find_file = require("nvim-tree.actions.finders.find-file").fn local Class = require("nvim-tree.classic") local DirectoryNode = require("nvim-tree.node.directory") +local FileNode = require("nvim-tree.node.file") local Node = require("nvim-tree.node") ---@alias ClipboardAction "copy" | "cut" @@ -21,6 +22,7 @@ local Node = require("nvim-tree.node") ---@field private data ClipboardData ---@field private clipboard_name string ---@field private reg string +---@field private protocol string local Clipboard = Class:extend() ---@class Clipboard @@ -41,6 +43,9 @@ function Clipboard:new(args) self.clipboard_name = self.explorer.opts.actions.use_system_clipboard and "system" or "neovim" self.reg = self.explorer.opts.actions.use_system_clipboard and "+" or "1" + -- TODO + -- self.protocol = self.explorer.actions.clipboard.protocol or "nvim-tree" + self.protocol = "nvim-tree" end ---@class RegOperationOptions @@ -317,12 +322,42 @@ function Clipboard:resolve_conflicts(conflict, destination, action, action_fn) end) end +--- Transforms the copied absolute paths with protocols to node +---@private +function Clipboard:get_nodes_from_reg() + local content = vim.fn.getreg(self.reg) + + if #content == 0 then + return + end + + local prefix = self.protocol .. ": " + if content:sub(1, #prefix) ~= prefix then + return + end + + local nodes = {} + local absolute_paths = vim.split(content:sub(#prefix + 1, #content), ", ") + + for _, absolute_path in ipairs(absolute_paths) do + local node_args = { absolute_path = absolute_path, name = vim.fn.fnamemodify(absolute_path, ":t"), explorer = self.explorer } + if absolute_path:sub(-1) == "/" then + node_args.name = vim.fn.fnamemodify(absolute_path:sub(1, -2), ":t") + table.insert(nodes, DirectoryNode(node_args)) + else + table.insert(nodes, FileNode(node_args)) + end + end + return nodes +end + ---Paste cut or copy with batch conflict resolution. ---@private ---@param node Node ---@param action ClipboardAction ---@param action_fn ClipboardActionFn -function Clipboard:do_paste(node, action, action_fn) +---@param opts? RegOperationOptions +function Clipboard:do_paste(node, action, action_fn, opts) if node.name == ".." then node = self.explorer else @@ -331,7 +366,7 @@ function Clipboard:do_paste(node, action, action_fn) node = dir:last_group_node() end end - local clip = self.data[action] + local clip = opts and opts.use_protocol and self:get_nodes_from_reg() or self.data[action] if #clip == 0 then return end @@ -399,11 +434,12 @@ end ---Paste cut (if present) or copy (if present) ---@param node Node -function Clipboard:paste(node) +---@param opts? RegOperationOptions +function Clipboard:paste(node, opts) if self.data.cut[1] ~= nil then - self:do_paste(node, "cut", do_cut) - elseif self.data.copy[1] ~= nil then - self:do_paste(node, "copy", do_copy) + self:do_paste(node, "cut", do_cut, opts) + elseif self.data.copy[1] ~= nil or opts and opts.use_protocol then + self:do_paste(node, "copy", do_copy, opts) end end @@ -431,7 +467,7 @@ function Clipboard:copy_to_reg(content, opts) local use_protocol = opts and opts.use_protocol and true or false if use_protocol then - content = "nvim-tree: " .. content + content = self.protocol .. ": " .. content end -- manually firing TextYankPost does not set vim.v.event From 38ada4688120ff3d545b67e52ffa51ed997e1e85 Mon Sep 17 00:00:00 2001 From: uanela Date: Thu, 11 Jun 2026 16:34:57 +0200 Subject: [PATCH 08/31] feat: add configurable clipboard protocol --- lua/nvim-tree/_meta/config/actions.lua | 10 +++++++++- lua/nvim-tree/actions/fs/clipboard.lua | 4 +--- lua/nvim-tree/config.lua | 3 +++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/lua/nvim-tree/_meta/config/actions.lua b/lua/nvim-tree/_meta/config/actions.lua index 012f4c364d9..066a50a443d 100644 --- a/lua/nvim-tree/_meta/config/actions.lua +++ b/lua/nvim-tree/_meta/config/actions.lua @@ -9,6 +9,9 @@ error("Cannot require a meta file") ---(default: `true`) ---@field use_system_clipboard? boolean --- +---[nvim_tree.config.actions.clipboard] +---@field clipboard? nvim_tree.config.actions.clipboard +--- ---[nvim_tree.config.actions.change_dir] ---@field change_dir? nvim_tree.config.actions.change_dir --- @@ -24,7 +27,12 @@ error("Cannot require a meta file") ---[nvim_tree.config.actions.remove_file] ---@field remove_file? nvim_tree.config.actions.remove_file - +--- Customizes nvim-tree clipboard behaviour +---@class nvim_tree.config.actions.clipboard +--- +---Change the protocol prefix to be used on multiple nvim instances operations +---(default: `nvim-tree`) +---@field protocol? string --- vim [current-directory] behaviour ---@class nvim_tree.config.actions.change_dir diff --git a/lua/nvim-tree/actions/fs/clipboard.lua b/lua/nvim-tree/actions/fs/clipboard.lua index 7a542b3e3cb..2e9e8365faf 100644 --- a/lua/nvim-tree/actions/fs/clipboard.lua +++ b/lua/nvim-tree/actions/fs/clipboard.lua @@ -43,9 +43,7 @@ function Clipboard:new(args) self.clipboard_name = self.explorer.opts.actions.use_system_clipboard and "system" or "neovim" self.reg = self.explorer.opts.actions.use_system_clipboard and "+" or "1" - -- TODO - -- self.protocol = self.explorer.actions.clipboard.protocol or "nvim-tree" - self.protocol = "nvim-tree" + self.protocol = self.explorer.opts.actions.clipboard.protocol or "nvim-tree" end ---@class RegOperationOptions diff --git a/lua/nvim-tree/config.lua b/lua/nvim-tree/config.lua index 24d87c389a2..3a39d283657 100644 --- a/lua/nvim-tree/config.lua +++ b/lua/nvim-tree/config.lua @@ -232,6 +232,9 @@ M.d = { -- config-default-start }, actions = { use_system_clipboard = true, + clipboard = { + protocol = "nvim-tree" + }, change_dir = { enable = true, global = false, From b9e9b7a67c690782e80474fb2636ab0f4200e952 Mon Sep 17 00:00:00 2001 From: uanela Date: Thu, 11 Jun 2026 16:36:20 +0200 Subject: [PATCH 09/31] fix: filter descendant nodes on copy_absolute_path_with_protocol --- lua/nvim-tree/actions/fs/clipboard.lua | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lua/nvim-tree/actions/fs/clipboard.lua b/lua/nvim-tree/actions/fs/clipboard.lua index 2e9e8365faf..1fd17c720c1 100644 --- a/lua/nvim-tree/actions/fs/clipboard.lua +++ b/lua/nvim-tree/actions/fs/clipboard.lua @@ -207,7 +207,7 @@ end ---Cut one or more nodes ---@param node_or_nodes Node|Node[] function Clipboard:cut(node_or_nodes) - if type(node_or_nodes) == "table" and node_or_nodes.is and node_or_nodes:is(Node) then + if self:is_nodes_array(node_or_nodes) == false then utils.array_remove(self.data.copy, node_or_nodes) toggle(node_or_nodes, self.data.cut) self.explorer.renderer:draw() @@ -461,7 +461,8 @@ end ---@param content string ---@param opts? RegOperationOptions -function Clipboard:copy_to_reg(content, opts) +---@param msg? string +function Clipboard:copy_to_reg(content, opts, msg) local use_protocol = opts and opts.use_protocol and true or false if use_protocol then @@ -477,7 +478,7 @@ function Clipboard:copy_to_reg(content, opts) end) vim.api.nvim_buf_delete(temp_buf, {}) - notify.info(string.format("Copied %s to %s clipboard!", content, self.clipboard_name)) + notify.info(msg or string.format("Copied %s to %s clipboard!", content, self.clipboard_name)) end ---@param node Node @@ -548,10 +549,12 @@ end ---@param opts? RegOperationOptions function Clipboard:copy_absolute_path(node_or_nodes, opts) local content = "" - if self:is_nodes_array(node_or_nodes) == false or #node_or_nodes == 1 then + local is_single = self:is_nodes_array(node_or_nodes) == false or #node_or_nodes == 1 + if is_single then local node = #node_or_nodes == 1 and node_or_nodes[0] or node_or_nodes content = self:get_absolute_path(node) else + node_or_nodes = utils.filter_descendant_nodes(node_or_nodes) for i, node in ipairs(node_or_nodes) do if i == 1 then content = self:get_absolute_path(node) @@ -561,7 +564,7 @@ function Clipboard:copy_absolute_path(node_or_nodes, opts) end end - self:copy_to_reg(content, opts) + self:copy_to_reg(content, opts, string.format("%s nodes copied to register", is_single and #node_or_nodes or 1)) end ---Node is cut. Will not be copied. From 877e726a77eecdc02fdf40317c7516655f4b4063 Mon Sep 17 00:00:00 2001 From: uanela Date: Thu, 11 Jun 2026 16:57:54 +0200 Subject: [PATCH 10/31] refactor: change clip protocol keymaps to bgy and bgp --- lua/nvim-tree/keymap.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/nvim-tree/keymap.lua b/lua/nvim-tree/keymap.lua index 84bf4db4b44..d7c288538af 100644 --- a/lua/nvim-tree/keymap.lua +++ b/lua/nvim-tree/keymap.lua @@ -91,7 +91,7 @@ function M.on_attach_default(bufnr) vim.keymap.set("n", "f", api.filter.live.start, opts("Live Filter: Start")) vim.keymap.set("n", "g?", api.tree.toggle_help, opts("Help")) vim.keymap.set({ "n", "x" }, "gy", api.fs.copy.absolute_path, opts("Copy Absolute Path")) - vim.keymap.set({ "n", "x" }, "bgy", api.fs.copy.absolute_path_with_protocol, opts("Copy Absolute Path With Protocol")) + vim.keymap.set({ "n", "x" }, "bgy", api.fs.copy.absolute_path_with_protocol, opts("Copy With Protocol")) vim.keymap.set({ "n", "x" }, "ge", api.fs.copy.basename, opts("Copy Basename")) vim.keymap.set("n", "H", api.filter.dotfiles.toggle, opts("Toggle Filter: Dotfiles")) vim.keymap.set("n", "I", api.filter.git.ignored.toggle, opts("Toggle Filter: Git Ignored")) @@ -103,7 +103,7 @@ function M.on_attach_default(bufnr) vim.keymap.set("n", "o", api.node.open.edit, opts("Open")) vim.keymap.set("n", "O", api.node.open.no_window_picker, opts("Open: No Window Picker")) vim.keymap.set("n", "p", api.fs.paste, opts("Paste")) - vim.keymap.set("n", "gp", api.fs.paste_with_protocol, opts("Paste With Protocol")) + vim.keymap.set("n", "bgp", api.fs.paste_with_protocol, opts("Paste With Protocol")) vim.keymap.set("n", "P", api.node.navigate.parent, opts("Parent Directory")) vim.keymap.set("n", "q", api.tree.close, opts("Close")) vim.keymap.set("n", "r", api.fs.rename, opts("Rename")) From 885b4d9ec315f97729de77256d38330202c692d6 Mon Sep 17 00:00:00 2001 From: uanela Date: Thu, 11 Jun 2026 16:59:17 +0200 Subject: [PATCH 11/31] wip --- doc/nvim-tree-lua.txt | 589 ++++++++++++++++++++++-------------------- 1 file changed, 310 insertions(+), 279 deletions(-) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 9892b524591..b7c29f5c037 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -142,8 +142,9 @@ Show the mappings: `g?` `F` n Live Filter: Clear |nvim_tree.api.filter.live.clear()| `f` n Live Filter: Start |nvim_tree.api.filter.live.start()| `g?` n Help |nvim_tree.api.tree.toggle_help()| - `gy` n Copy Absolute Path |nvim_tree.api.fs.copy.absolute_path()| - `ge` n Copy Basename |nvim_tree.api.fs.copy.basename()| + `gy` nx Copy Absolute Path |nvim_tree.api.fs.copy.absolute_path()| + `bgy` nx Copy With Protocol |nvim_tree.api.fs.copy.absolute_path_with_protocol()| + `ge` nx Copy Basename |nvim_tree.api.fs.copy.basename()| `H` n Toggle Filter: Dotfiles |nvim_tree.api.filter.dotfiles.toggle()| `I` n Toggle Filter: Git Ignored |nvim_tree.api.filter.git.ignored.toggle()| `J` n Last Sibling |nvim_tree.api.node.navigate.sibling.last()| @@ -154,6 +155,7 @@ Show the mappings: `g?` `o` n Open |nvim_tree.api.node.open.edit()| `O` n Open: No Window Picker |nvim_tree.api.node.open.no_window_picker()| `p` n Paste |nvim_tree.api.fs.paste()| + `bgp` n Paste With Protocol |nvim_tree.api.fs.paste_with_protocol()| `P` n Parent Directory |nvim_tree.api.node.navigate.parent()| `q` n Close |nvim_tree.api.tree.close()| `r` n Rename |nvim_tree.api.fs.rename()| @@ -402,65 +404,67 @@ You are encouraged to copy these to your {on_attach} function. >lua end -- BEGIN_ON_ATTACH_DEFAULT - vim.keymap.set("n", "", api.tree.change_root_to_node, opts("CD")) - vim.keymap.set("n", "", api.node.open.replace_tree_buffer, opts("Open: In Place")) - vim.keymap.set("n", "", api.node.show_info_popup, opts("Info")) - vim.keymap.set("n", "", api.fs.rename_sub, opts("Rename: Omit Filename")) - vim.keymap.set("n", "", api.node.open.tab, opts("Open: New Tab")) - vim.keymap.set("n", "", api.node.open.vertical, opts("Open: Vertical Split")) - vim.keymap.set("n", "", api.node.open.horizontal, opts("Open: Horizontal Split")) - vim.keymap.set("n", "", api.node.navigate.parent_close, opts("Close Directory")) - vim.keymap.set("n", "", api.node.open.edit, opts("Open")) - vim.keymap.set({ "n", "x" }, "", api.fs.remove, opts("Delete")) - vim.keymap.set("n", "", api.node.open.preview, opts("Open Preview")) - vim.keymap.set("n", ">", api.node.navigate.sibling.next, opts("Next Sibling")) - vim.keymap.set("n", "<", api.node.navigate.sibling.prev, opts("Previous Sibling")) - vim.keymap.set("n", ".", api.node.run.cmd, opts("Run Command")) - vim.keymap.set("n", "-", api.tree.change_root_to_parent, opts("Up")) - vim.keymap.set("n", "a", api.fs.create, opts("Create File Or Directory")) - vim.keymap.set("n", "bd", api.marks.bulk.delete, opts("Delete Bookmarked")) - vim.keymap.set("n", "bt", api.marks.bulk.trash, opts("Trash Bookmarked")) - vim.keymap.set("n", "bmv", api.marks.bulk.move, opts("Move Bookmarked")) - vim.keymap.set("n", "B", api.filter.no_buffer.toggle, opts("Toggle Filter: No Buffer")) - vim.keymap.set({ "n", "x" }, "c", api.fs.copy.node, opts("Copy")) - vim.keymap.set("n", "C", api.filter.git.clean.toggle, opts("Toggle Filter: Git Clean")) - vim.keymap.set("n", "[c", api.node.navigate.git.prev, opts("Prev Git")) - vim.keymap.set("n", "]c", api.node.navigate.git.next, opts("Next Git")) - vim.keymap.set({ "n", "x" }, "d", api.fs.remove, opts("Delete")) - vim.keymap.set({ "n", "x" }, "D", api.fs.trash, opts("Trash")) - vim.keymap.set("n", "E", api.tree.expand_all, opts("Expand All")) - vim.keymap.set("n", "e", api.fs.rename_basename, opts("Rename: Basename")) - vim.keymap.set("n", "]e", api.node.navigate.diagnostics.next, opts("Next Diagnostic")) - vim.keymap.set("n", "[e", api.node.navigate.diagnostics.prev, opts("Prev Diagnostic")) - vim.keymap.set("n", "F", api.filter.live.clear, opts("Live Filter: Clear")) - vim.keymap.set("n", "f", api.filter.live.start, opts("Live Filter: Start")) - vim.keymap.set("n", "g?", api.tree.toggle_help, opts("Help")) - vim.keymap.set("n", "gy", api.fs.copy.absolute_path, opts("Copy Absolute Path")) - vim.keymap.set("n", "ge", api.fs.copy.basename, opts("Copy Basename")) - vim.keymap.set("n", "H", api.filter.dotfiles.toggle, opts("Toggle Filter: Dotfiles")) - vim.keymap.set("n", "I", api.filter.git.ignored.toggle, opts("Toggle Filter: Git Ignored")) - vim.keymap.set("n", "J", api.node.navigate.sibling.last, opts("Last Sibling")) - vim.keymap.set("n", "K", api.node.navigate.sibling.first, opts("First Sibling")) - vim.keymap.set("n", "L", api.node.open.toggle_group_empty, opts("Toggle Group Empty")) - vim.keymap.set("n", "M", api.filter.no_bookmark.toggle, opts("Toggle Filter: No Bookmark")) - vim.keymap.set({ "n", "x" }, "m", api.marks.toggle, opts("Toggle Bookmark")) - vim.keymap.set("n", "o", api.node.open.edit, opts("Open")) - vim.keymap.set("n", "O", api.node.open.no_window_picker, opts("Open: No Window Picker")) - vim.keymap.set("n", "p", api.fs.paste, opts("Paste")) - vim.keymap.set("n", "P", api.node.navigate.parent, opts("Parent Directory")) - vim.keymap.set("n", "q", api.tree.close, opts("Close")) - vim.keymap.set("n", "r", api.fs.rename, opts("Rename")) - vim.keymap.set("n", "R", api.tree.reload, opts("Refresh")) - vim.keymap.set("n", "s", api.node.run.system, opts("Run System")) - vim.keymap.set("n", "S", api.tree.search_node, opts("Search")) - vim.keymap.set("n", "u", api.fs.rename_full, opts("Rename: Full Path")) - vim.keymap.set("n", "U", api.filter.custom.toggle, opts("Toggle Filter: Custom")) - vim.keymap.set("n", "W", api.tree.collapse_all, opts("Collapse All")) - vim.keymap.set({ "n", "x" }, "x", api.fs.cut, opts("Cut")) - vim.keymap.set("n", "y", api.fs.copy.filename, opts("Copy Name")) - vim.keymap.set("n", "Y", api.fs.copy.relative_path, opts("Copy Relative Path")) - vim.keymap.set("n", "<2-LeftMouse>", api.node.open.edit, opts("Open")) - vim.keymap.set("n", "<2-RightMouse>", api.tree.change_root_to_node, opts("CD")) + vim.keymap.set("n", "", api.tree.change_root_to_node, opts("CD")) + vim.keymap.set("n", "", api.node.open.replace_tree_buffer, opts("Open: In Place")) + vim.keymap.set("n", "", api.node.show_info_popup, opts("Info")) + vim.keymap.set("n", "", api.fs.rename_sub, opts("Rename: Omit Filename")) + vim.keymap.set("n", "", api.node.open.tab, opts("Open: New Tab")) + vim.keymap.set("n", "", api.node.open.vertical, opts("Open: Vertical Split")) + vim.keymap.set("n", "", api.node.open.horizontal, opts("Open: Horizontal Split")) + vim.keymap.set("n", "", api.node.navigate.parent_close, opts("Close Directory")) + vim.keymap.set("n", "", api.node.open.edit, opts("Open")) + vim.keymap.set({ "n", "x" }, "", api.fs.remove, opts("Delete")) + vim.keymap.set("n", "", api.node.open.preview, opts("Open Preview")) + vim.keymap.set("n", ">", api.node.navigate.sibling.next, opts("Next Sibling")) + vim.keymap.set("n", "<", api.node.navigate.sibling.prev, opts("Previous Sibling")) + vim.keymap.set("n", ".", api.node.run.cmd, opts("Run Command")) + vim.keymap.set("n", "-", api.tree.change_root_to_parent, opts("Up")) + vim.keymap.set("n", "a", api.fs.create, opts("Create File Or Directory")) + vim.keymap.set("n", "bd", api.marks.bulk.delete, opts("Delete Bookmarked")) + vim.keymap.set("n", "bt", api.marks.bulk.trash, opts("Trash Bookmarked")) + vim.keymap.set("n", "bmv", api.marks.bulk.move, opts("Move Bookmarked")) + vim.keymap.set("n", "B", api.filter.no_buffer.toggle, opts("Toggle Filter: No Buffer")) + vim.keymap.set({ "n", "x" }, "c", api.fs.copy.node, opts("Copy")) + vim.keymap.set("n", "C", api.filter.git.clean.toggle, opts("Toggle Filter: Git Clean")) + vim.keymap.set("n", "[c", api.node.navigate.git.prev, opts("Prev Git")) + vim.keymap.set("n", "]c", api.node.navigate.git.next, opts("Next Git")) + vim.keymap.set({ "n", "x" }, "d", api.fs.remove, opts("Delete")) + vim.keymap.set({ "n", "x" }, "D", api.fs.trash, opts("Trash")) + vim.keymap.set("n", "E", api.tree.expand_all, opts("Expand All")) + vim.keymap.set("n", "e", api.fs.rename_basename, opts("Rename: Basename")) + vim.keymap.set("n", "]e", api.node.navigate.diagnostics.next, opts("Next Diagnostic")) + vim.keymap.set("n", "[e", api.node.navigate.diagnostics.prev, opts("Prev Diagnostic")) + vim.keymap.set("n", "F", api.filter.live.clear, opts("Live Filter: Clear")) + vim.keymap.set("n", "f", api.filter.live.start, opts("Live Filter: Start")) + vim.keymap.set("n", "g?", api.tree.toggle_help, opts("Help")) + vim.keymap.set({ "n", "x" }, "gy", api.fs.copy.absolute_path, opts("Copy Absolute Path")) + vim.keymap.set({ "n", "x" }, "bgy", api.fs.copy.absolute_path_with_protocol, opts("Copy With Protocol")) + vim.keymap.set({ "n", "x" }, "ge", api.fs.copy.basename, opts("Copy Basename")) + vim.keymap.set("n", "H", api.filter.dotfiles.toggle, opts("Toggle Filter: Dotfiles")) + vim.keymap.set("n", "I", api.filter.git.ignored.toggle, opts("Toggle Filter: Git Ignored")) + vim.keymap.set("n", "J", api.node.navigate.sibling.last, opts("Last Sibling")) + vim.keymap.set("n", "K", api.node.navigate.sibling.first, opts("First Sibling")) + vim.keymap.set("n", "L", api.node.open.toggle_group_empty, opts("Toggle Group Empty")) + vim.keymap.set("n", "M", api.filter.no_bookmark.toggle, opts("Toggle Filter: No Bookmark")) + vim.keymap.set({ "n", "x" }, "m", api.marks.toggle, opts("Toggle Bookmark")) + vim.keymap.set("n", "o", api.node.open.edit, opts("Open")) + vim.keymap.set("n", "O", api.node.open.no_window_picker, opts("Open: No Window Picker")) + vim.keymap.set("n", "p", api.fs.paste, opts("Paste")) + vim.keymap.set("n", "bgp", api.fs.paste_with_protocol, opts("Paste With Protocol")) + vim.keymap.set("n", "P", api.node.navigate.parent, opts("Parent Directory")) + vim.keymap.set("n", "q", api.tree.close, opts("Close")) + vim.keymap.set("n", "r", api.fs.rename, opts("Rename")) + vim.keymap.set("n", "R", api.tree.reload, opts("Refresh")) + vim.keymap.set("n", "s", api.node.run.system, opts("Run System")) + vim.keymap.set("n", "S", api.tree.search_node, opts("Search")) + vim.keymap.set("n", "u", api.fs.rename_full, opts("Rename: Full Path")) + vim.keymap.set("n", "U", api.filter.custom.toggle, opts("Toggle Filter: Custom")) + vim.keymap.set("n", "W", api.tree.collapse_all, opts("Collapse All")) + vim.keymap.set({ "n", "x" }, "x", api.fs.cut, opts("Cut")) + vim.keymap.set("n", "y", api.fs.copy.filename, opts("Copy Name")) + vim.keymap.set("n", "Y", api.fs.copy.relative_path, opts("Copy Relative Path")) + vim.keymap.set("n", "<2-LeftMouse>", api.node.open.edit, opts("Open")) + vim.keymap.set("n", "<2-RightMouse>", api.tree.change_root_to_node, opts("CD")) -- END_ON_ATTACH_DEFAULT < Alternatively, you may apply these default mappings from your @@ -1021,59 +1025,59 @@ Config *nvim-tree-config* telescope-ui-select.nvim Fields: ~ - • {on_attach}? (`"default"|(fun(bufnr: integer))`) - (default: `default`) - • {hijack_cursor}? (`boolean`) (default: `false`) + • {actions}? (`nvim_tree.config.actions`) + |nvim_tree.config.actions| • {auto_reload_on_write}? (`boolean`) (default: `true`) + • {bookmarks}? (`nvim_tree.config.bookmarks`) + |nvim_tree.config.bookmarks| + • {diagnostics}? (`nvim_tree.config.diagnostics`) + |nvim_tree.config.diagnostics| • {disable_netrw}? (`boolean`) (default: `false`) + • {experimental}? (`nvim_tree.config.experimental`) + |nvim_tree.config.experimental| + • {filesystem_watchers}? (`nvim_tree.config.filesystem_watchers`) + |nvim_tree.config.filesystem_watchers| + • {filters}? (`nvim_tree.config.filters`) + |nvim_tree.config.filters| + • {git}? (`nvim_tree.config.git`) + |nvim_tree.config.git| + • {help}? (`nvim_tree.config.help`) + |nvim_tree.config.help| + • {hijack_cursor}? (`boolean`) (default: `false`) + • {hijack_directories}? (`nvim_tree.config.hijack_directories`) + |nvim_tree.config.hijack_directories| • {hijack_netrw}? (`boolean`) (default: `true`) • {hijack_unnamed_buffer_when_opening}? (`boolean`) (default: `false`) - • {root_dirs}? (`string[]`) (default: `{}`) + • {live_filter}? (`nvim_tree.config.live_filter`) + |nvim_tree.config.live_filter| + • {log}? (`nvim_tree.config.log`) + |nvim_tree.config.log| + • {modified}? (`nvim_tree.config.modified`) + |nvim_tree.config.modified| + • {notify}? (`nvim_tree.config.notify`) + |nvim_tree.config.notify| + • {on_attach}? (`"default"|(fun(bufnr: integer))`) + (default: `default`) • {prefer_startup_root}? (`boolean`) (default: `false`) - • {sync_root_with_cwd}? (`boolean`) (default: `false`) • {reload_on_bufenter}? (`boolean`) (default: `false`) + • {renderer}? (`nvim_tree.config.renderer`) + |nvim_tree.config.renderer| • {respect_buf_cwd}? (`boolean`) (default: `false`) + • {root_dirs}? (`string[]`) (default: `{}`) • {select_prompts}? (`boolean`) (default: `false`) • {sort}? (`nvim_tree.config.sort`) |nvim_tree.config.sort| - • {view}? (`nvim_tree.config.view`) - |nvim_tree.config.view| - • {renderer}? (`nvim_tree.config.renderer`) - |nvim_tree.config.renderer| - • {hijack_directories}? (`nvim_tree.config.hijack_directories`) - |nvim_tree.config.hijack_directories| - • {update_focused_file}? (`nvim_tree.config.update_focused_file`) - |nvim_tree.config.update_focused_file| - • {git}? (`nvim_tree.config.git`) - |nvim_tree.config.git| - • {diagnostics}? (`nvim_tree.config.diagnostics`) - |nvim_tree.config.diagnostics| - • {modified}? (`nvim_tree.config.modified`) - |nvim_tree.config.modified| - • {filters}? (`nvim_tree.config.filters`) - |nvim_tree.config.filters| - • {live_filter}? (`nvim_tree.config.live_filter`) - |nvim_tree.config.live_filter| - • {filesystem_watchers}? (`nvim_tree.config.filesystem_watchers`) - |nvim_tree.config.filesystem_watchers| - • {actions}? (`nvim_tree.config.actions`) - |nvim_tree.config.actions| - • {trash}? (`nvim_tree.config.trash`) - |nvim_tree.config.trash| + • {sync_root_with_cwd}? (`boolean`) (default: `false`) • {tab}? (`nvim_tree.config.tab`) |nvim_tree.config.tab| - • {bookmarks}? (`nvim_tree.config.bookmarks`) - |nvim_tree.config.bookmarks| - • {notify}? (`nvim_tree.config.notify`) - |nvim_tree.config.notify| - • {help}? (`nvim_tree.config.help`) - |nvim_tree.config.help| + • {trash}? (`nvim_tree.config.trash`) + |nvim_tree.config.trash| • {ui}? (`nvim_tree.config.ui`) |nvim_tree.config.ui| - • {experimental}? (`nvim_tree.config.experimental`) - |nvim_tree.config.experimental| - • {log}? (`nvim_tree.config.log`) - |nvim_tree.config.log| + • {update_focused_file}? (`nvim_tree.config.update_focused_file`) + |nvim_tree.config.update_focused_file| + • {view}? (`nvim_tree.config.view`) + |nvim_tree.config.view| ============================================================================== Config: sort *nvim-tree-config-sort* @@ -1105,13 +1109,13 @@ Config: sort *nvim-tree-config-sort* {sorter} may be a function that returns a |nvim_tree.config.sort.Sorter| Fields: ~ - • {sorter}? (`nvim_tree.config.sort.Sorter|(fun(nodes: nvim_tree.api.Node[]): nvim_tree.config.sort.Sorter?)`) - (default: `"name"`) - • {folders_first}? (`boolean`, default: `true`) Sort folders before - files. Has no effect when {sorter} is a function. • {files_first}? (`boolean`, default: `false`) Sort files before folders. Has no effect when {sorter} is a function. Overrides {folders_first}. + • {folders_first}? (`boolean`, default: `true`) Sort folders before + files. Has no effect when {sorter} is a function. + • {sorter}? (`nvim_tree.config.sort.Sorter|(fun(nodes: nvim_tree.api.Node[]): nvim_tree.config.sort.Sorter?)`) + (default: `"name"`) ============================================================================== Config: view *nvim-tree-config-view* @@ -1145,22 +1149,22 @@ Config: view *nvim-tree-config-view* refresh operations. Increase if you experience performance issues around screen refresh. - • {side}? (`"left"|"right"`) (default: `"left"`) + • {float}? (`nvim_tree.config.view.float`) + |nvim_tree.config.view.float| + • {number}? (`boolean`, default: `false`) + |'number'| • {preserve_window_proportions}? (`boolean`, default: `false`) Preserves window proportions when opening a file. If `false`, the height and width of windows other than nvim-tree will be equalized. - • {number}? (`boolean`, default: `false`) - |'number'| • {relativenumber}? (`boolean`, default: `false`) |'relativenumber'| + • {side}? (`"left"|"right"`) (default: `"left"`) • {signcolumn}? (`"yes"|"auto"|"no"`, default: `"yes"`) |'signcolumn'| • {width}? (`nvim_tree.config.view.width.spec|nvim_tree.config.view.width`) (default: `30`) - • {float}? (`nvim_tree.config.view.float`) - |nvim_tree.config.view.float| *nvim_tree.config.view.float* Configure floating window behaviour @@ -1178,22 +1182,22 @@ Config: view *nvim-tree-config-view* Fields: ~ • {enable}? (`boolean`) (default: `false`) - • {quit_on_focus_loss}? (`boolean`, default: `true`) Close the floating - window when it loses focus. • {open_win_config}? (`vim.api.keyset.win_config|(fun(): vim.api.keyset.win_config)`) (default: `{ relative = "editor", border = "rounded", width = 30, height = 30, row = 1, col = 1, }`) + • {quit_on_focus_loss}? (`boolean`, default: `true`) Close the floating + window when it loses focus. *nvim_tree.config.view.width* Configure dynamic width based on longest line. Fields: ~ - • {min}? (`nvim_tree.config.view.width.spec`) (default: - `30`) - • {max}? (`nvim_tree.config.view.width.spec`, default: `-1`) - -1 for unbounded. • {lines_excluded}? (`("root")[]`, default: `{ "root" }`) Exclude these lines when computing width. + • {max}? (`nvim_tree.config.view.width.spec`, default: `-1`) + -1 for unbounded. + • {min}? (`nvim_tree.config.view.width.spec`) (default: + `30`) • {padding}? (`nvim_tree.config.view.width.spec`, default: `1`) Extra padding to the right. @@ -1258,46 +1262,46 @@ Config: renderer *nvim-tree-config-renderer* • {add_trailing}? (`boolean`, default: `false`) Appends a trailing slash to folder and symlink folder target names. + • {decorators}? (`nvim_tree.config.renderer.decorator[]`, default: `{ "Git", "Open", "Hidden", "Modified", "Bookmark", "Diagnostics", "Copied", "Cut", }`) + List in order of additive precedence. + • {full_name}? (`boolean`, default: `false`) Display nodes + whose name length is wider than the width + of nvim-tree window in floating window. • {group_empty}? (`boolean|(fun(relative_path: string): string)`, default: `false`) Compact folders that only contain a single folder into one node. Function variant takes the relative path of grouped folders and returns a string to be displayed. - • {full_name}? (`boolean`, default: `false`) Display nodes - whose name length is wider than the width - of nvim-tree window in floating window. - • {root_folder_label}? (`nvim_tree.config.renderer.root_folder_label`, default: `":~:s?$?/..?"`) - |nvim_tree.config.renderer.root_folder_label| - • {indent_width}? (`integer`, default: `2`) Number of spaces - for each tree nesting level. Minimum 1. • {hidden_display}? (`nvim_tree.config.renderer.hidden_display`, default: `none`) |nvim_tree.config.renderer.hidden_display| - • {symlink_destination}? (`boolean`, default: `true`) Appends an - arrow followed by the target of the - symlink. - • {decorators}? (`nvim_tree.config.renderer.decorator[]`, default: `{ "Git", "Open", "Hidden", "Modified", "Bookmark", "Diagnostics", "Copied", "Cut", }`) - List in order of additive precedence. - • {highlight_git}? (`nvim_tree.config.renderer.highlight`) + • {highlight_bookmarks}? (`nvim_tree.config.renderer.highlight`) (default: `"none"`) - • {highlight_opened_files}? (`nvim_tree.config.renderer.highlight`) + • {highlight_clipboard}? (`nvim_tree.config.renderer.highlight`) + (default: `"name"`) + • {highlight_diagnostics}? (`nvim_tree.config.renderer.highlight`) + (default: `"none"`) + • {highlight_git}? (`nvim_tree.config.renderer.highlight`) (default: `"none"`) • {highlight_hidden}? (`nvim_tree.config.renderer.highlight`) (default: `"none"`) • {highlight_modified}? (`nvim_tree.config.renderer.highlight`) (default: `"none"`) - • {highlight_bookmarks}? (`nvim_tree.config.renderer.highlight`) - (default: `"none"`) - • {highlight_diagnostics}? (`nvim_tree.config.renderer.highlight`) + • {highlight_opened_files}? (`nvim_tree.config.renderer.highlight`) (default: `"none"`) - • {highlight_clipboard}? (`nvim_tree.config.renderer.highlight`) - (default: `"name"`) + • {icons}? (`nvim_tree.config.renderer.icons`) + |nvim_tree.config.renderer.icons| + • {indent_markers}? (`nvim_tree.config.renderer.indent_markers`) + |nvim_tree.config.renderer.indent_markers| + • {indent_width}? (`integer`, default: `2`) Number of spaces + for each tree nesting level. Minimum 1. + • {root_folder_label}? (`nvim_tree.config.renderer.root_folder_label`, default: `":~:s?$?/..?"`) + |nvim_tree.config.renderer.root_folder_label| • {special_files}? (`string[]`, default: `{ "Cargo.toml", "Makefile", "README.md", "readme.md", }`) Highlight special files and directories with `NvimTreeSpecial*`. - • {indent_markers}? (`nvim_tree.config.renderer.indent_markers`) - |nvim_tree.config.renderer.indent_markers| - • {icons}? (`nvim_tree.config.renderer.icons`) - |nvim_tree.config.renderer.icons| + • {symlink_destination}? (`boolean`, default: `true`) Appends an + arrow followed by the target of the + symlink. *nvim_tree.config.renderer.hidden_stats* Number of hidden nodes in a directory by reason: the filter that hid the @@ -1338,29 +1342,29 @@ Config: renderer *nvim-tree-config-renderer* • `"right_align"`: far right Fields: ~ + • {bookmarks_placement}? (`nvim_tree.config.renderer.icons.placement`) + (default: `signcolumn`) + • {diagnostics_placement}? (`nvim_tree.config.renderer.icons.placement`) + (default: `signcolumn`) • {git_placement}? (`nvim_tree.config.renderer.icons.placement`) (default: `before`) + • {glyphs}? (`nvim_tree.config.renderer.icons.glyphs`) + |nvim_tree.config.renderer.icons.glyphs| • {hidden_placement}? (`nvim_tree.config.renderer.icons.placement`) (default: `after`) • {modified_placement}? (`nvim_tree.config.renderer.icons.placement`) (default: `after`) - • {bookmarks_placement}? (`nvim_tree.config.renderer.icons.placement`) - (default: `signcolumn`) - • {diagnostics_placement}? (`nvim_tree.config.renderer.icons.placement`) - (default: `signcolumn`) • {padding}? (`table`) *nvim_tree.config.renderer.icons.padding* - • {icon}? (`string`, default: `" "`) Between - icon and filename. • {folder_arrow}? (`string`, default: `" "`) Between folder arrow icon and file/folder icon. - • {symlink_arrow}? (`string`, default: `" ➛ "`) Separator - between symlink source and target. + • {icon}? (`string`, default: `" "`) Between + icon and filename. • {show}? (`nvim_tree.config.renderer.icons.show`) |nvim_tree.config.renderer.icons.show| - • {glyphs}? (`nvim_tree.config.renderer.icons.glyphs`) - |nvim_tree.config.renderer.icons.glyphs| + • {symlink_arrow}? (`string`, default: `" ➛ "`) Separator + between symlink source and target. • {web_devicons}? (`nvim_tree.config.renderer.icons.web_devicons`) |nvim_tree.config.renderer.icons.web_devicons| @@ -1370,44 +1374,44 @@ Config: renderer *nvim-tree-config-renderer* Glyphs that appear in the sign column must have length <= 2 Fields: ~ - • {default}? (`string`, default: `""`) Files - • {symlink}? (`string`) (default: `""`) • {bookmark}? (`string`) (default: `"󰆤"`) - • {modified}? (`string`) (default: `"●"`) - • {hidden}? (`string`) (default: `"󰜌"`) + • {default}? (`string`, default: `""`) Files • {folder}? (`table`) *nvim_tree.config.renderer.icons.glyphs.folder* • {arrow_closed}? (`string`) (default: left arrow) • {arrow_open}? (`string`) (default: down arrow) • {default}? (`string`) (default: `""`) - • {open}? (`string`) (default: `""`) • {empty}? (`string`) (default: `""`) • {empty_open}? (`string`) (default: `""`) + • {open}? (`string`) (default: `""`) • {symlink}? (`string`) (default: `""`) • {symlink_open}? (`string`) (default: `""`) • {git}? (`table`) *nvim_tree.config.renderer.icons.glyphs.git* - • {unstaged}? (`string`) (default: `"✗"`) + • {deleted}? (`string`) (default: `""`) + • {ignored}? (`string`) (default: `"◌"`) + • {renamed}? (`string`) (default: `"➜"`) • {staged}? (`string`) (default: `"✓"`) • {unmerged}? (`string`) (default: `""`) - • {renamed}? (`string`) (default: `"➜"`) + • {unstaged}? (`string`) (default: `"✗"`) • {untracked}? (`string`) (default: `"★"`) - • {deleted}? (`string`) (default: `""`) - • {ignored}? (`string`) (default: `"◌"`) + • {hidden}? (`string`) (default: `"󰜌"`) + • {modified}? (`string`) (default: `"●"`) + • {symlink}? (`string`) (default: `""`) *nvim_tree.config.renderer.icons.show* See |nvim-tree-icons-highlighting|. Fields: ~ + • {bookmarks}? (`boolean`) (default: `true`) + • {diagnostics}? (`boolean`) (default: `true`) • {file}? (`boolean`) (default: `true`) • {folder}? (`boolean`) (default: `true`) - • {git}? (`boolean`) (default: `true`) - • {modified}? (`boolean`) (default: `true`) - • {hidden}? (`boolean`) (default: `false`) - • {diagnostics}? (`boolean`) (default: `true`) - • {bookmarks}? (`boolean`) (default: `true`) • {folder_arrow}? (`boolean`, default: `true`) Show a small arrow before the folder node. Arrow will be a part of the node when using |nvim_tree.config.renderer.indent_markers|. + • {git}? (`boolean`) (default: `true`) + • {hidden}? (`boolean`) (default: `false`) + • {modified}? (`boolean`) (default: `true`) *nvim_tree.config.renderer.icons.web_devicons* Configure optional plugin `nvim-tree/nvim-web-devicons`, see @@ -1416,30 +1420,30 @@ Config: renderer *nvim-tree-config-renderer* Fields: ~ • {file}? (`table`) *nvim_tree.config.renderer.icons.web_devicons.file* - • {enable}? (`boolean`) (default: `true`) • {color}? (`boolean`) (default: `true`) + • {enable}? (`boolean`) (default: `true`) • {folder}? (`table`) *nvim_tree.config.renderer.icons.web_devicons.folder* - • {enable}? (`boolean`) (default: `false`) • {color}? (`boolean`) (default: `true`) + • {enable}? (`boolean`) (default: `false`) *nvim_tree.config.renderer.indent_markers* Fields: ~ • {enable}? (`boolean`, default: `false`) Display indent markers when folders are open. - • {inline_arrows}? (`boolean`, default: `true`) Display folder arrows - in the same column as indent marker when using - |nvim_tree.config.renderer.icons.padding| - {folder_arrow} • {icons}? (`table`) *nvim_tree.config.renderer.indent_markers.icons* Before the file/directory, length 1. + • {bottom}? (`string`) (default: `"─"`) • {corner}? (`string`) (default: `"└"`) • {edge}? (`string`) (default: `"│"`) • {item}? (`string`) (default: `"│"`) - • {bottom}? (`string`) (default: `"─"`) • {none}? (`string`) (default: `" "`) + • {inline_arrows}? (`boolean`, default: `true`) Display folder arrows + in the same column as indent marker when using + |nvim_tree.config.renderer.icons.padding| + {folder_arrow} ============================================================================== Config: hijack_directories *nvim-tree-config-hijack-directories* @@ -1453,9 +1457,9 @@ Config: hijack_directories *nvim-tree-config-hijack-directories* feature will be disabled. Fields: ~ - • {enable}? (`boolean`) (default: `true`) • {auto_open}? (`boolean`, default: `true`) Open if the tree was previously closed. + • {enable}? (`boolean`) (default: `true`) ============================================================================== Config: update_focused_file *nvim-tree-config-update-focused-file* @@ -1465,11 +1469,11 @@ Config: update_focused_file *nvim-tree-config-update-focused-file* Fields: ~ • {enable}? (`boolean`) (default: `false`) - • {update_root}? (`nvim_tree.config.update_focused_file.update_root`) - |nvim_tree.config.update_focused_file.update_root| • {exclude}? (`boolean|(fun(args: vim.api.keyset.create_autocmd.callback_args): boolean)`, default: `false`) A function called on |BufEnter| that returns true if the file should not be focused when opening. + • {update_root}? (`nvim_tree.config.update_focused_file.update_root`) + |nvim_tree.config.update_focused_file.update_root| *nvim_tree.config.update_focused_file.update_root* Update the root directory of the tree if the file is not under the current @@ -1505,6 +1509,10 @@ Config: git *nvim-tree-config-git* See |nvim-tree-icons-highlighting|. Fields: ~ + • {cygwin_support}? (`boolean`, default: `false`) Use `cygpath` if + available to resolve paths for git. + • {disable_for_dirs}? (`string[]|(fun(path: string): boolean)`, + default: `{}`) Disable for top level paths. • {enable}? (`boolean`) (default: `true`) • {show_on_dirs}? (`boolean`, default: `true`) Show status icons of children when directory itself has no status @@ -1512,12 +1520,8 @@ Config: git *nvim-tree-config-git* • {show_on_open_dirs}? (`boolean`, default: `true`) Show status icons of children on directories that are open. Requires {show_on_dirs}. - • {disable_for_dirs}? (`string[]|(fun(path: string): boolean)`, - default: `{}`) Disable for top level paths. • {timeout}? (`integer`, default: `400`) `git` processes timeout milliseconds. - • {cygwin_support}? (`boolean`, default: `false`) Use `cygpath` if - available to resolve paths for git. ============================================================================== Config: diagnostics *nvim-tree-config-diagnostics* @@ -1528,28 +1532,28 @@ Config: diagnostics *nvim-tree-config-diagnostics* See |nvim-tree-icons-highlighting|. Fields: ~ - • {enable}? (`boolean`) (default: `false`) • {debounce_delay}? (`integer`, default: `500`) Idle milliseconds between diagnostic event and tree update. - • {show_on_dirs}? (`boolean`, default: `false`) Show diagnostic - icons on parent directories. - • {show_on_open_dirs}? (`boolean`, default: `true`) Show diagnostics - icons on directories that are open. Requires - {show_on_dirs}. • {diagnostic_opts}? (`boolean`, default: `false`) Global |vim.diagnostic.Opts| overrides {severity} and {icons} - • {severity}? (`table`) - *nvim_tree.config.diagnostics.severity* - • {min}? (`vim.diagnostic.Severity`, default: - HINT) |vim.diagnostic.severity| - • {max}? (`vim.diagnostic.Severity`, default: - ERROR) |vim.diagnostic.severity| + • {enable}? (`boolean`) (default: `false`) • {icons}? (`table`) *nvim_tree.config.diagnostics.icons* + • {error}? (`string`) (default: `""` ) • {hint}? (`string`) (default: `""` ) • {info}? (`string`) (default: `""` ) • {warning}? (`string`) (default: `""` ) - • {error}? (`string`) (default: `""` ) + • {severity}? (`table`) + *nvim_tree.config.diagnostics.severity* + • {max}? (`vim.diagnostic.Severity`, default: + ERROR) |vim.diagnostic.severity| + • {min}? (`vim.diagnostic.Severity`, default: + HINT) |vim.diagnostic.severity| + • {show_on_dirs}? (`boolean`, default: `false`) Show diagnostic + icons on parent directories. + • {show_on_open_dirs}? (`boolean`, default: `true`) Show diagnostics + icons on directories that are open. Requires + {show_on_dirs}. ============================================================================== Config: modified *nvim-tree-config-modified* @@ -1614,15 +1618,15 @@ Config: filters *nvim-tree-config-filters* shown, overriding {git_ignored}, {dotfiles} and {custom}. Fields: ~ - • {enable}? (`boolean`, default: `true`) Enable all filters. - • {git_ignored}? (`boolean`) (default: `true`) - • {dotfiles}? (`boolean`) (default: `false`) - • {git_clean}? (`boolean`) (default: `false`) - • {no_buffer}? (`boolean`) (default: `false`) - • {no_bookmark}? (`boolean`) (default: `false`) • {custom}? (`string[]|(fun(absolute_path: string): boolean)`) (default: `{}`) + • {dotfiles}? (`boolean`) (default: `false`) + • {enable}? (`boolean`, default: `true`) Enable all filters. • {exclude}? (`string[]`) (default: `{}`) + • {git_clean}? (`boolean`) (default: `false`) + • {git_ignored}? (`boolean`) (default: `true`) + • {no_bookmark}? (`boolean`) (default: `false`) + • {no_buffer}? (`boolean`) (default: `false`) ============================================================================== Config: live_filter *nvim-tree-config-live-filter* @@ -1635,10 +1639,10 @@ Config: live_filter *nvim-tree-config-live-filter* with the `F` key by default. Fields: ~ - • {prefix}? (`string`, default: `"[FILTER]: "`) Prefix of - the filter displayed in the buffer. • {always_show_folders}? (`boolean`, default: `true`) Whether to filter folders or not. + • {prefix}? (`string`, default: `"[FILTER]: "`) Prefix of + the filter displayed in the buffer. ============================================================================== Config: filesystem_watchers *nvim-tree-config-filesystem-watchers* @@ -1672,19 +1676,19 @@ Config: filesystem_watchers *nvim-tree-config-filesystem-watchers* By default, {max_events} is only enabled for windows. Fields: ~ - • {enable}? (`boolean`) (default: `true`) • {debounce_delay}? (`integer`, default: `50`) Idle milliseconds between filesystem change and tree update. + • {enable}? (`boolean`) (default: `true`) • {ignore_dirs}? (`string[]|(fun(path: string): boolean)`, default: `{ "/.ccls-cache", "/build", "/node_modules", "/target", "/.zig-cache"}`) Disable for specific directories. - • {whitelist_dirs}? (`string[]|(fun(path: string): boolean)`, default: - `{}`) Optionally enable only for specific - directories. • {max_events}? (`integer`, default: `0` or `1000` on windows) Disable for a single directory after {max_events} consecutive events with an interval < {debounce_delay}. Set to 0 to allow unlimited consecutive events. + • {whitelist_dirs}? (`string[]|(fun(path: string): boolean)`, default: + `{}`) Optionally enable only for specific + directories. ============================================================================== Config: actions *nvim-tree-config-actions* @@ -1692,12 +1696,10 @@ Config: actions *nvim-tree-config-actions* *nvim_tree.config.actions* Fields: ~ - • {use_system_clipboard}? (`boolean`, default: `true`) Use the system - clipboard for copy/paste. Copied text will be - stored in registers `+` (system), otherwise, - it will be stored in `1` and `"` • {change_dir}? (`nvim_tree.config.actions.change_dir`) |nvim_tree.config.actions.change_dir| + • {clipboard}? (`nvim_tree.config.actions.clipboard`) + |nvim_tree.config.actions.clipboard| • {expand_all}? (`nvim_tree.config.actions.expand_all`) |nvim_tree.config.actions.expand_all| • {file_popup}? (`nvim_tree.config.actions.file_popup`) @@ -1706,6 +1708,10 @@ Config: actions *nvim-tree-config-actions* |nvim_tree.config.actions.open_file| • {remove_file}? (`nvim_tree.config.actions.remove_file`) |nvim_tree.config.actions.remove_file| + • {use_system_clipboard}? (`boolean`, default: `true`) Use the system + clipboard for copy/paste. Copied text will be + stored in registers `+` (system), otherwise, + it will be stored in `1` and `"` *nvim_tree.config.actions.change_dir* vim |current-directory| behaviour @@ -1718,19 +1724,26 @@ Config: actions *nvim-tree-config-actions* • {restrict_above_cwd}? (`boolean`, default: `false`) Restrict changing to a directory above the global cwd. +*nvim_tree.config.actions.clipboard* + Customizes nvim-tree clipboard behaviour + + Fields: ~ + • {protocol}? (`string`, default: `nvim-tree`) Change the protocol + prefix to be used on multiple nvim instances operations + *nvim_tree.config.actions.expand_all* Configure |nvim_tree.api.tree.expand_all()| and |nvim_tree.api.node.expand()| Fields: ~ - • {max_folder_discovery}? (`integer`, default: `300`) Limit the number - of folders being explored when expanding - every folder. Avoids hanging Nvim when - running this action on very large folders. • {exclude}? (`string[]`, default: `{}`) A list of directories that should not be expanded automatically e.g `{ ".git", "target", "build" }` + • {max_folder_discovery}? (`integer`, default: `300`) Limit the number + of folders being explored when expanding + every folder. Avoids hanging Nvim when + running this action on very large folders. *nvim_tree.config.actions.file_popup* {file_popup} floating window. @@ -1756,10 +1769,10 @@ Config: actions *nvim-tree-config-actions* Opening files. Fields: ~ - • {quit_on_open}? (`boolean`, default: `false`) Closes the explorer - when opening a file • {eject}? (`boolean`, default: `true`) Prevent new opened file from opening in the same window as the tree. + • {quit_on_open}? (`boolean`, default: `false`) Closes the explorer + when opening a file • {resize_window}? (`boolean`, default: `true`) Resizes the tree when opening a file • {window_picker}? (`nvim_tree.config.actions.open_file.window_picker`) @@ -1778,14 +1791,14 @@ Config: actions *nvim-tree-config-actions* cancelled the action. The picker may create a new window. Fields: ~ - • {enable}? (`boolean`) (default: `true`) - • {picker}? (`"default"|(fun(): integer)`, default: `"default"`) - Change the default window picker or define your own. • {chars}? (`string`, default: `"ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"`) Identifier characters to use. + • {enable}? (`boolean`) (default: `true`) • {exclude}? (`nvim_tree.config.actions.open_file.window_picker.exclude`) |nvim_tree.config.actions.open_file.window_picker.exclude| + • {picker}? (`"default"|(fun(): integer)`, default: `"default"`) + Change the default window picker or define your own. *nvim_tree.config.actions.open_file.window_picker.exclude* Tables of buffer option names mapped to a list of option values. Windows @@ -1794,10 +1807,10 @@ Config: actions *nvim-tree-config-actions* • selected when not using a window picker Fields: ~ - • {filetype}? (`string[]`) (default: - `{ "notify", "lazy", "qf", "diff", "fugitive", "fugitiveblame", }`) • {buftype}? (`string[]`) (default: `{ "nofile", "terminal", "help", }`) + • {filetype}? (`string[]`) (default: + `{ "notify", "lazy", "qf", "diff", "fugitive", "fugitiveblame", }`) *nvim_tree.config.actions.remove_file* Removing files. @@ -1831,13 +1844,13 @@ Config: tab *nvim-tree-config-tab* *nvim_tree.config.tab.sync* Fields: ~ - • {open}? (`boolean`, default: `false`) Opens the tree automatically - when switching tabpage or opening a new tabpage if the tree - was previously open. • {close}? (`boolean`, default: `false`) Closes the tree across all tabpages when the tree is closed. • {ignore}? (`string[]`, default: `{}`) List of filetypes or buffer names on new tab that will prevent `open` and `close` + • {open}? (`boolean`, default: `false`) Opens the tree automatically + when switching tabpage or opening a new tabpage if the tree + was previously open. ============================================================================== Config: notify *nvim-tree-config-notify* @@ -1851,10 +1864,10 @@ Config: notify *nvim-tree-config-notify* closing operations. Fields: ~ - • {threshold}? (`vim.log.levels`, default: `vim.log.levels.INFO`) - Specify minimum notification |vim.log.levels| • {absolute_path}? (`boolean`, default: `true`) Use absolute paths in FS action notifications, otherwise item names. + • {threshold}? (`vim.log.levels`, default: `vim.log.levels.INFO`) + Specify minimum notification |vim.log.levels| ============================================================================== Config: bookmarks *nvim-tree-config-bookmarks* @@ -1894,10 +1907,10 @@ Config: ui *nvim-tree-config-ui* Confirmation prompts. Fields: ~ - • {remove}? (`boolean`, default: `true`) Prompt before removing. - • {trash}? (`boolean`, default: `true`) Prompt before trashing. • {default_yes}? (`boolean`, default: `false`) If `true` the prompt will be `Y/n`, otherwise `y/N` + • {remove}? (`boolean`, default: `true`) Prompt before removing. + • {trash}? (`boolean`, default: `true`) Prompt before trashing. ============================================================================== Config: experimental *nvim-tree-config-experimental* @@ -1927,8 +1940,6 @@ Config: log *nvim-tree-config-log* Fields: ~ • {all}? (`boolean`, default: `false`) Everything. - • {profile}? (`boolean`, default: `false`) Timing of some - operations. • {config}? (`boolean`, default: `false`) Config and mappings, at startup. • {copy_paste}? (`boolean`, default: `false`) File copy and paste @@ -1938,6 +1949,8 @@ Config: log *nvim-tree-config-log* • {diagnostics}? (`boolean`, default: `false`) LSP and COC processing, verbose. • {git}? (`boolean`, default: `false`) Git processing, verbose. + • {profile}? (`boolean`, default: `false`) Timing of some + operations. • {watcher}? (`boolean`, default: `false`) |nvim_tree.config.filesystem_watchers| processing, verbose. @@ -2148,6 +2161,9 @@ Following is the default configuration, see |nvim_tree.config| for details. >lua }, actions = { use_system_clipboard = true, + clipboard = { + protocol = "nvim-tree" + }, change_dir = { enable = true, global = false, @@ -2284,16 +2300,16 @@ e.g. the following are functionally identical: >lua Fields: ~ • {absolute_path} (`string`) of the file or directory - • {name} (`string`) file or directory name - • {parent}? (`nvim_tree.api.DirectoryNode`) parent directory, - nil for root - • {type} (`"file"|"directory"|"link"`) |uv.fs_stat()| {type} + • {diag_severity}? (`lsp.DiagnosticSeverity`) diagnostic status • {executable} (`boolean`) file is executable • {fs_stat}? (`uv.fs_stat.result`) at time of last tree display, see |uv.fs_stat()| • {git_status} (`nvim_tree.git.Status?`) for files and directories - • {diag_severity}? (`lsp.DiagnosticSeverity`) diagnostic status • {hidden} (`boolean`) node is not visible in the tree + • {name} (`string`) file or directory name + • {parent}? (`nvim_tree.api.DirectoryNode`) parent directory, + nil for root + • {type} (`"file"|"directory"|"link"`) |uv.fs_stat()| {type} *nvim_tree.git.Status* Git statuses for a single node. @@ -2306,9 +2322,9 @@ e.g. the following are functionally identical: >lua • `indirect`: inherited from child directories Fields: ~ - • {file}? (`nvim_tree.git.XY`) status of a file node • {dir}? (`table<"direct"|"indirect", nvim_tree.git.XY[]>`) direct inclusive-or indirect status + • {file}? (`nvim_tree.git.XY`) status of a file node ============================================================================== API: appearance *nvim-tree-api-appearance* @@ -2331,10 +2347,10 @@ get() *nvim_tree.api.commands.get()* Return: ~ (`table[]`) - • {name} (`string`) name of the `:NvimTree*` command • {command} (`fun(args: vim.api.keyset.create_user_command.command_args)`) function that the command will execute + • {name} (`string`) name of the `:NvimTree*` command • {opts} (`vim.api.keyset.user_command`) |command-attributes| @@ -2412,6 +2428,13 @@ clear_clipboard() *nvim_tree.api.fs.clear_clipboard()* copy.absolute_path({node}) *nvim_tree.api.fs.copy.absolute_path()* Copy the absolute path to the system clipboard. + Parameters: ~ + • {node} (`nvim_tree.api.Node?`) + + *nvim_tree.api.fs.copy.absolute_path_with_protocol()* +copy.absolute_path_with_protocol({node}) + Copy the absolute path to the system clipboard with nvim-tree protocol. + Parameters: ~ • {node} (`nvim_tree.api.Node?`) @@ -2467,6 +2490,14 @@ paste({node}) *nvim_tree.api.fs.paste()* Parameters: ~ • {node} (`nvim_tree.api.Node?`) +paste_with_protocol({node}) *nvim_tree.api.fs.paste_with_protocol()* + Paste nodes from the nvim-tree clipboard using protocol. + + If {node} is a file it will pasted in the parent directory. + + Parameters: ~ + • {node} (`nvim_tree.api.Node?`) + print_clipboard() *nvim_tree.api.fs.print_clipboard()* Print the contents of the nvim-tree clipboard. @@ -2780,10 +2811,10 @@ open.edit({node}, {opts}) *nvim_tree.api.node.open.edit()* Parameters: ~ • {node} (`nvim_tree.api.Node?`) directory or file • {opts} (`table?`) optional - • {quit_on_open}? (`boolean`, default: false) Quits the tree - when opening the file. • {focus}? (`boolean`, default: false) Keep focus in the tree when opening the file. + • {quit_on_open}? (`boolean`, default: false) Quits the tree + when opening the file. open.horizontal({node}, {opts}) *nvim_tree.api.node.open.horizontal()* Open file in a new horizontal split. @@ -2791,9 +2822,9 @@ open.horizontal({node}, {opts}) *nvim_tree.api.node.open.horizontal()* Parameters: ~ • {node} (`nvim_tree.api.Node?`) file • {opts} (`table?`) optional - • {quit_on_open}? (`boolean`, default: false) Quits the tree - when opening the file. • {focus}? (`boolean`, default: false) Keep focus in the tree + when opening the file. + • {quit_on_open}? (`boolean`, default: false) Quits the tree when opening the file. *nvim_tree.api.node.open.horizontal_no_picker()* @@ -2803,9 +2834,9 @@ open.horizontal_no_picker({node}, {opts}) Parameters: ~ • {node} (`nvim_tree.api.Node?`) file • {opts} (`table?`) optional - • {quit_on_open}? (`boolean`, default: false) Quits the tree - when opening the file. • {focus}? (`boolean`, default: false) Keep focus in the tree + when opening the file. + • {quit_on_open}? (`boolean`, default: false) Quits the tree when opening the file. *nvim_tree.api.node.open.no_window_picker()* @@ -2815,10 +2846,10 @@ open.no_window_picker({node}, {opts}) Parameters: ~ • {node} (`nvim_tree.api.Node?`) file • {opts} (`table?`) optional - • {quit_on_open}? (`boolean`, default: false) Quits the tree - when opening the file. • {focus}? (`boolean`, default: false) Keep focus in the tree when opening the file. + • {quit_on_open}? (`boolean`, default: false) Quits the tree + when opening the file. open.preview({node}, {opts}) *nvim_tree.api.node.open.preview()* Open file with |'bufhidden'| set to `delete`. @@ -2826,9 +2857,9 @@ open.preview({node}, {opts}) *nvim_tree.api.node.open.preview()* Parameters: ~ • {node} (`nvim_tree.api.Node?`) directory or file • {opts} (`table?`) optional - • {quit_on_open}? (`boolean`, default: false) Quits the tree - when opening the file. • {focus}? (`boolean`, default: false) Keep focus in the tree + when opening the file. + • {quit_on_open}? (`boolean`, default: false) Quits the tree when opening the file. *nvim_tree.api.node.open.preview_no_picker()* @@ -2839,9 +2870,9 @@ open.preview_no_picker({node}, {opts}) Parameters: ~ • {node} (`nvim_tree.api.Node?`) directory or file • {opts} (`table?`) optional - • {quit_on_open}? (`boolean`, default: false) Quits the tree - when opening the file. • {focus}? (`boolean`, default: false) Keep focus in the tree + when opening the file. + • {quit_on_open}? (`boolean`, default: false) Quits the tree when opening the file. *nvim_tree.api.node.open.replace_tree_buffer()* @@ -2857,10 +2888,10 @@ open.tab({node}, {opts}) *nvim_tree.api.node.open.tab()* Parameters: ~ • {node} (`nvim_tree.api.Node?`) directory or file • {opts} (`table?`) optional - • {quit_on_open}? (`boolean`, default: false) Quits the tree - when opening the file. • {focus}? (`boolean`, default: false) Keep focus in the tree when opening the file. + • {quit_on_open}? (`boolean`, default: false) Quits the tree + when opening the file. open.tab_drop({node}) *nvim_tree.api.node.open.tab_drop()* Switch to tab containing window with selected file if it exists, otherwise @@ -2883,9 +2914,9 @@ open.vertical({node}, {opts}) *nvim_tree.api.node.open.vertical()* Parameters: ~ • {node} (`nvim_tree.api.Node?`) file • {opts} (`table?`) optional - • {quit_on_open}? (`boolean`, default: false) Quits the tree - when opening the file. • {focus}? (`boolean`, default: false) Keep focus in the tree + when opening the file. + • {quit_on_open}? (`boolean`, default: false) Quits the tree when opening the file. *nvim_tree.api.node.open.vertical_no_picker()* @@ -2895,10 +2926,10 @@ open.vertical_no_picker({node}, {opts}) Parameters: ~ • {node} (`nvim_tree.api.Node?`) file • {opts} (`table?`) optional - • {quit_on_open}? (`boolean`, default: false) Quits the tree - when opening the file. • {focus}? (`boolean`, default: false) Keep focus in the tree when opening the file. + • {quit_on_open}? (`boolean`, default: false) Quits the tree + when opening the file. run.cmd({node}) *nvim_tree.api.node.run.cmd()* Enter |cmdline| with the full path of the node and the cursor at the start @@ -2979,16 +3010,16 @@ find_file({opts}) *nvim_tree.api.tree.find_file()* • {opts} (`table?`) optional • {buf}? (`string|integer`) Absolute/relative path OR `bufnr` to find. - • {open}? (`boolean`, default: false) Open the tree if - necessary. • {current_window}? (`boolean`, default: false) Requires {open}: open in the current window. - • {winid}? (`integer`) Open the tree in the specified - |window-ID|, overrides {current_window} + • {focus}? (`boolean`, default: false) Focus the tree window. + • {open}? (`boolean`, default: false) Open the tree if + necessary. • {update_root}? (`boolean`, default: false) Update root after find, see |nvim_tree.config.update_focused_file| {update_root} - • {focus}? (`boolean`, default: false) Focus the tree window. + • {winid}? (`integer`) Open the tree in the specified + |window-ID|, overrides {current_window} focus() *nvim_tree.api.tree.focus()* Focus the tree, opening it if necessary. Retained for compatibility, use @@ -3020,9 +3051,9 @@ is_visible({opts}) *nvim_tree.api.tree.is_visible()* Parameters: ~ • {opts} (`table?`) optional - • {tabpage}? (`integer`) |tab-ID| 0 or nil for current. • {any_tabpage}? (`boolean`, default: false) Visible on any tab. + • {tabpage}? (`integer`) |tab-ID| 0 or nil for current. Return: ~ (`boolean`) @@ -3032,16 +3063,16 @@ open({opts}) *nvim_tree.api.tree.open()* Parameters: ~ • {opts} (`table?`) optional - • {path}? (`string`) Root directory for the tree • {current_window}? (`boolean`, default: false) Open the tree in the current window - • {winid}? (`integer`) Open the tree in the specified - |window-ID|, overrides {current_window} • {find_file}? (`boolean`, default: false) Find the current buffer. + • {path}? (`string`) Root directory for the tree • {update_root}? (`boolean`, default: false) Update root following {find_file}, see |nvim_tree.config.update_focused_file| {update_root} + • {winid}? (`integer`) Open the tree in the specified + |window-ID|, overrides {current_window} reload() *nvim_tree.api.tree.reload()* Refresh the tree. Does nothing if closed. @@ -3058,11 +3089,11 @@ resize({opts}) *nvim_tree.api.tree.resize()* Parameters: ~ • {opts} (`table?`) optional + • {absolute}? (`integer`) Set the width. + • {relative}? (`integer`) Increase or decrease the width. • {width}? (`nvim_tree.config.view.width.spec|nvim_tree.config.view.width`) New |nvim_tree.config.view| {width} value. - • {absolute}? (`integer`) Set the width. - • {relative}? (`integer`) Increase or decrease the width. search_node() *nvim_tree.api.tree.search_node()* Open the search dialogue. @@ -3072,18 +3103,18 @@ toggle({opts}) *nvim_tree.api.tree.toggle()* Parameters: ~ • {opts} (`table?`) optional - • {path}? (`string`) Root directory for the tree • {current_window}? (`boolean`, default: false) Open the tree in the current window - • {winid}? (`integer`) Open the tree in the specified - |window-ID|, overrides {current_window} • {find_file}? (`boolean`, default: false) Find the current buffer. + • {focus}? (`boolean`, default: true) Focus the tree when + opening. + • {path}? (`string`) Root directory for the tree • {update_root}? (`boolean`, default: false) Update root following {find_file}, see |nvim_tree.config.update_focused_file| {update_root} - • {focus}? (`boolean`, default: true) Focus the tree when - opening. + • {winid}? (`integer`) Open the tree in the specified + |window-ID|, overrides {current_window} toggle_help() *nvim_tree.api.tree.toggle_help()* Toggle help view. @@ -3171,10 +3202,8 @@ the meta method `__call` with arguments and return: >lua *nvim_tree.Class* Fields: ~ - • {super} (`nvim_tree.Class`) Parent class, `Class` for base - classes. - • {new} (`fun(self: nvim_tree.Class, ...: any)`) See - |nvim_tree.Class:new()|. + • {as} (`fun(self: nvim_tree.Class, class: T): T?`) See + |nvim_tree.Class:as()|. • {destroy} (`fun(self: nvim_tree.Class)`) See |nvim_tree.Class:destroy()|. • {extend} (`fun(self: nvim_tree.Class): [nvim_tree.Class]`) See @@ -3183,10 +3212,12 @@ the meta method `__call` with arguments and return: >lua See |nvim_tree.Class:implement()|. • {is} (`fun(self: nvim_tree.Class, class: T): boolean`) See |nvim_tree.Class:is()|. - • {as} (`fun(self: nvim_tree.Class, class: T): T?`) See - |nvim_tree.Class:as()|. + • {new} (`fun(self: nvim_tree.Class, ...: any)`) See + |nvim_tree.Class:new()|. • {nop} (`fun(self: nvim_tree.Class, ...: any)`) See |nvim_tree.Class:nop()|. + • {super} (`nvim_tree.Class`) Parent class, `Class` for base + classes. Class:as({class}) *nvim_tree.Class:as()* @@ -3298,28 +3329,28 @@ Your class may: Decorator interface Fields: ~ + • {define_sign} (`fun(self: nvim_tree.api.Decorator, icon: nvim_tree.api.highlighted_string?)`) + See |nvim_tree.api.Decorator:define_sign()|. • {enabled} (`boolean`) Enable this decorator. + • {highlight_group} (`fun(self: nvim_tree.api.Decorator, node: nvim_tree.api.Node): string?`) + See |nvim_tree.api.Decorator:highlight_group()|. • {highlight_range} (`nvim_tree.config.renderer.highlight`) What to highlight: |nvim_tree.config.renderer.highlight| + • {icon_node} (`fun(self: nvim_tree.api.Decorator, node: nvim_tree.api.Node): nvim_tree.api.highlighted_string?`) + See |nvim_tree.api.Decorator:icon_node()|. • {icon_placement} (`"none"|nvim_tree.config.renderer.icons.placement`) Where to place the icons: |nvim_tree.config.renderer.icons.placement| - • {icon_node} (`fun(self: nvim_tree.api.Decorator, node: nvim_tree.api.Node): nvim_tree.api.highlighted_string?`) - See |nvim_tree.api.Decorator:icon_node()|. • {icons} (`fun(self: nvim_tree.api.Decorator, node: nvim_tree.api.Node): nvim_tree.api.highlighted_string[]?`) See |nvim_tree.api.Decorator:icons()|. - • {highlight_group} (`fun(self: nvim_tree.api.Decorator, node: nvim_tree.api.Node): string?`) - See |nvim_tree.api.Decorator:highlight_group()|. - • {define_sign} (`fun(self: nvim_tree.api.Decorator, icon: nvim_tree.api.highlighted_string?)`) - See |nvim_tree.api.Decorator:define_sign()|. *nvim_tree.api.highlighted_string* Text or glyphs with optional highlight group names to apply to it. Fields: ~ - • {str} (`string`) One or many glyphs/characters. • {hl} (`string[]`) Highlight group names to apply in order. Empty table for no highlighting. + • {str} (`string`) One or many glyphs/characters. Decorator:define_sign({icon}) *nvim_tree.api.Decorator:define_sign()* From 2c56cc6a1ace72e18dbac4fbba0d5daac94bcc8f Mon Sep 17 00:00:00 2001 From: uanela Date: Thu, 11 Jun 2026 17:20:09 +0200 Subject: [PATCH 12/31] fix(clipboad): correctly show the number of copied nodes on bgy --- lua/nvim-tree/actions/fs/clipboard.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/nvim-tree/actions/fs/clipboard.lua b/lua/nvim-tree/actions/fs/clipboard.lua index 1fd17c720c1..34a3963bd3e 100644 --- a/lua/nvim-tree/actions/fs/clipboard.lua +++ b/lua/nvim-tree/actions/fs/clipboard.lua @@ -564,7 +564,7 @@ function Clipboard:copy_absolute_path(node_or_nodes, opts) end end - self:copy_to_reg(content, opts, string.format("%s nodes copied to register", is_single and #node_or_nodes or 1)) + self:copy_to_reg(content, opts, string.format("%s nodes copied to register", is_single and 1 or #node_or_nodes)) end ---Node is cut. Will not be copied. From 77325e556c7f813c29a12b6bc87ab756ef7efaf5 Mon Sep 17 00:00:00 2001 From: uanela Date: Mon, 15 Jun 2026 00:10:03 +0200 Subject: [PATCH 13/31] chore: remove bgy, bgp and add gp + gx --- lua/nvim-tree/keymap.lua | 122 +++++++++++++++++++-------------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/lua/nvim-tree/keymap.lua b/lua/nvim-tree/keymap.lua index d7c288538af..4c2075fe4a8 100644 --- a/lua/nvim-tree/keymap.lua +++ b/lua/nvim-tree/keymap.lua @@ -57,67 +57,67 @@ function M.on_attach_default(bufnr) end -- BEGIN_ON_ATTACH_DEFAULT - vim.keymap.set("n", "", api.tree.change_root_to_node, opts("CD")) - vim.keymap.set("n", "", api.node.open.replace_tree_buffer, opts("Open: In Place")) - vim.keymap.set("n", "", api.node.show_info_popup, opts("Info")) - vim.keymap.set("n", "", api.fs.rename_sub, opts("Rename: Omit Filename")) - vim.keymap.set("n", "", api.node.open.tab, opts("Open: New Tab")) - vim.keymap.set("n", "", api.node.open.vertical, opts("Open: Vertical Split")) - vim.keymap.set("n", "", api.node.open.horizontal, opts("Open: Horizontal Split")) - vim.keymap.set("n", "", api.node.navigate.parent_close, opts("Close Directory")) - vim.keymap.set("n", "", api.node.open.edit, opts("Open")) - vim.keymap.set({ "n", "x" }, "", api.fs.remove, opts("Delete")) - vim.keymap.set("n", "", api.node.open.preview, opts("Open Preview")) - vim.keymap.set("n", ">", api.node.navigate.sibling.next, opts("Next Sibling")) - vim.keymap.set("n", "<", api.node.navigate.sibling.prev, opts("Previous Sibling")) - vim.keymap.set("n", ".", api.node.run.cmd, opts("Run Command")) - vim.keymap.set("n", "-", api.tree.change_root_to_parent, opts("Up")) - vim.keymap.set("n", "a", api.fs.create, opts("Create File Or Directory")) - vim.keymap.set("n", "bd", api.marks.bulk.delete, opts("Delete Bookmarked")) - vim.keymap.set("n", "bt", api.marks.bulk.trash, opts("Trash Bookmarked")) - vim.keymap.set("n", "bmv", api.marks.bulk.move, opts("Move Bookmarked")) - vim.keymap.set("n", "B", api.filter.no_buffer.toggle, opts("Toggle Filter: No Buffer")) - vim.keymap.set({ "n", "x" }, "c", api.fs.copy.node, opts("Copy")) - vim.keymap.set("n", "C", api.filter.git.clean.toggle, opts("Toggle Filter: Git Clean")) - vim.keymap.set("n", "[c", api.node.navigate.git.prev, opts("Prev Git")) - vim.keymap.set("n", "]c", api.node.navigate.git.next, opts("Next Git")) - vim.keymap.set({ "n", "x" }, "d", api.fs.remove, opts("Delete")) - vim.keymap.set({ "n", "x" }, "D", api.fs.trash, opts("Trash")) - vim.keymap.set("n", "E", api.tree.expand_all, opts("Expand All")) - vim.keymap.set("n", "e", api.fs.rename_basename, opts("Rename: Basename")) - vim.keymap.set("n", "]e", api.node.navigate.diagnostics.next, opts("Next Diagnostic")) - vim.keymap.set("n", "[e", api.node.navigate.diagnostics.prev, opts("Prev Diagnostic")) - vim.keymap.set("n", "F", api.filter.live.clear, opts("Live Filter: Clear")) - vim.keymap.set("n", "f", api.filter.live.start, opts("Live Filter: Start")) - vim.keymap.set("n", "g?", api.tree.toggle_help, opts("Help")) - vim.keymap.set({ "n", "x" }, "gy", api.fs.copy.absolute_path, opts("Copy Absolute Path")) - vim.keymap.set({ "n", "x" }, "bgy", api.fs.copy.absolute_path_with_protocol, opts("Copy With Protocol")) - vim.keymap.set({ "n", "x" }, "ge", api.fs.copy.basename, opts("Copy Basename")) - vim.keymap.set("n", "H", api.filter.dotfiles.toggle, opts("Toggle Filter: Dotfiles")) - vim.keymap.set("n", "I", api.filter.git.ignored.toggle, opts("Toggle Filter: Git Ignored")) - vim.keymap.set("n", "J", api.node.navigate.sibling.last, opts("Last Sibling")) - vim.keymap.set("n", "K", api.node.navigate.sibling.first, opts("First Sibling")) - vim.keymap.set("n", "L", api.node.open.toggle_group_empty, opts("Toggle Group Empty")) - vim.keymap.set("n", "M", api.filter.no_bookmark.toggle, opts("Toggle Filter: No Bookmark")) - vim.keymap.set({ "n", "x" }, "m", api.marks.toggle, opts("Toggle Bookmark")) - vim.keymap.set("n", "o", api.node.open.edit, opts("Open")) - vim.keymap.set("n", "O", api.node.open.no_window_picker, opts("Open: No Window Picker")) - vim.keymap.set("n", "p", api.fs.paste, opts("Paste")) - vim.keymap.set("n", "bgp", api.fs.paste_with_protocol, opts("Paste With Protocol")) - vim.keymap.set("n", "P", api.node.navigate.parent, opts("Parent Directory")) - vim.keymap.set("n", "q", api.tree.close, opts("Close")) - vim.keymap.set("n", "r", api.fs.rename, opts("Rename")) - vim.keymap.set("n", "R", api.tree.reload, opts("Refresh")) - vim.keymap.set("n", "s", api.node.run.system, opts("Run System")) - vim.keymap.set("n", "S", api.tree.search_node, opts("Search")) - vim.keymap.set("n", "u", api.fs.rename_full, opts("Rename: Full Path")) - vim.keymap.set("n", "U", api.filter.custom.toggle, opts("Toggle Filter: Custom")) - vim.keymap.set("n", "W", api.tree.collapse_all, opts("Collapse All")) - vim.keymap.set({ "n", "x" }, "x", api.fs.cut, opts("Cut")) - vim.keymap.set("n", "y", api.fs.copy.filename, opts("Copy Name")) - vim.keymap.set("n", "Y", api.fs.copy.relative_path, opts("Copy Relative Path")) - vim.keymap.set("n", "<2-LeftMouse>", api.node.open.edit, opts("Open")) - vim.keymap.set("n", "<2-RightMouse>", api.tree.change_root_to_node, opts("CD")) + vim.keymap.set("n", "", api.tree.change_root_to_node, opts("CD")) + vim.keymap.set("n", "", api.node.open.replace_tree_buffer, opts("Open: In Place")) + vim.keymap.set("n", "", api.node.show_info_popup, opts("Info")) + vim.keymap.set("n", "", api.fs.rename_sub, opts("Rename: Omit Filename")) + vim.keymap.set("n", "", api.node.open.tab, opts("Open: New Tab")) + vim.keymap.set("n", "", api.node.open.vertical, opts("Open: Vertical Split")) + vim.keymap.set("n", "", api.node.open.horizontal, opts("Open: Horizontal Split")) + vim.keymap.set("n", "", api.node.navigate.parent_close, opts("Close Directory")) + vim.keymap.set("n", "", api.node.open.edit, opts("Open")) + vim.keymap.set({ "n", "x" }, "", api.fs.remove, opts("Delete")) + vim.keymap.set("n", "", api.node.open.preview, opts("Open Preview")) + vim.keymap.set("n", ">", api.node.navigate.sibling.next, opts("Next Sibling")) + vim.keymap.set("n", "<", api.node.navigate.sibling.prev, opts("Previous Sibling")) + vim.keymap.set("n", ".", api.node.run.cmd, opts("Run Command")) + vim.keymap.set("n", "-", api.tree.change_root_to_parent, opts("Up")) + vim.keymap.set("n", "a", api.fs.create, opts("Create File Or Directory")) + vim.keymap.set("n", "bd", api.marks.bulk.delete, opts("Delete Bookmarked")) + vim.keymap.set("n", "bt", api.marks.bulk.trash, opts("Trash Bookmarked")) + vim.keymap.set("n", "bmv", api.marks.bulk.move, opts("Move Bookmarked")) + vim.keymap.set("n", "B", api.filter.no_buffer.toggle, opts("Toggle Filter: No Buffer")) + vim.keymap.set({ "n", "x" }, "c", api.fs.copy.node, opts("Copy")) + vim.keymap.set("n", "C", api.filter.git.clean.toggle, opts("Toggle Filter: Git Clean")) + vim.keymap.set("n", "[c", api.node.navigate.git.prev, opts("Prev Git")) + vim.keymap.set("n", "]c", api.node.navigate.git.next, opts("Next Git")) + vim.keymap.set({ "n", "x" }, "d", api.fs.remove, opts("Delete")) + vim.keymap.set({ "n", "x" }, "D", api.fs.trash, opts("Trash")) + vim.keymap.set("n", "E", api.tree.expand_all, opts("Expand All")) + vim.keymap.set("n", "e", api.fs.rename_basename, opts("Rename: Basename")) + vim.keymap.set("n", "]e", api.node.navigate.diagnostics.next, opts("Next Diagnostic")) + vim.keymap.set("n", "[e", api.node.navigate.diagnostics.prev, opts("Prev Diagnostic")) + vim.keymap.set("n", "F", api.filter.live.clear, opts("Live Filter: Clear")) + vim.keymap.set("n", "f", api.filter.live.start, opts("Live Filter: Start")) + vim.keymap.set("n", "g?", api.tree.toggle_help, opts("Help")) + vim.keymap.set({ "n", "x" }, "gy", api.fs.copy.absolute_path, opts("Copy Absolute Path")) + vim.keymap.set({ "n", "x" }, "ge", api.fs.copy.basename, opts("Copy Basename")) + vim.keymap.set("n", "H", api.filter.dotfiles.toggle, opts("Toggle Filter: Dotfiles")) + vim.keymap.set("n", "I", api.filter.git.ignored.toggle, opts("Toggle Filter: Git Ignored")) + vim.keymap.set("n", "J", api.node.navigate.sibling.last, opts("Last Sibling")) + vim.keymap.set("n", "K", api.node.navigate.sibling.first, opts("First Sibling")) + vim.keymap.set("n", "L", api.node.open.toggle_group_empty, opts("Toggle Group Empty")) + vim.keymap.set("n", "M", api.filter.no_bookmark.toggle, opts("Toggle Filter: No Bookmark")) + vim.keymap.set({ "n", "x" }, "m", api.marks.toggle, opts("Toggle Bookmark")) + vim.keymap.set("n", "o", api.node.open.edit, opts("Open")) + vim.keymap.set("n", "O", api.node.open.no_window_picker, opts("Open: No Window Picker")) + vim.keymap.set("n", "p", api.fs.paste, opts("Paste")) + vim.keymap.set("n", "gp", api.fs.paste_from_clipboard_copying, opts("Paste From Cliboard - Copying")) + vim.keymap.set("n", "gx", api.fs.paste_from_clipboard_cutting, opts("Paste From Cliboard - Cutting")) + vim.keymap.set("n", "P", api.node.navigate.parent, opts("Parent Directory")) + vim.keymap.set("n", "q", api.tree.close, opts("Close")) + vim.keymap.set("n", "r", api.fs.rename, opts("Rename")) + vim.keymap.set("n", "R", api.tree.reload, opts("Refresh")) + vim.keymap.set("n", "s", api.node.run.system, opts("Run System")) + vim.keymap.set("n", "S", api.tree.search_node, opts("Search")) + vim.keymap.set("n", "u", api.fs.rename_full, opts("Rename: Full Path")) + vim.keymap.set("n", "U", api.filter.custom.toggle, opts("Toggle Filter: Custom")) + vim.keymap.set("n", "W", api.tree.collapse_all, opts("Collapse All")) + vim.keymap.set({ "n", "x" }, "x", api.fs.cut, opts("Cut")) + vim.keymap.set("n", "y", api.fs.copy.filename, opts("Copy Name")) + vim.keymap.set("n", "Y", api.fs.copy.relative_path, opts("Copy Relative Path")) + vim.keymap.set("n", "<2-LeftMouse>", api.node.open.edit, opts("Open")) + vim.keymap.set("n", "<2-RightMouse>", api.tree.change_root_to_node, opts("CD")) -- END_ON_ATTACH_DEFAULT end From a9253ded6f1939d43c62813e4b04fa618ffa9786 Mon Sep 17 00:00:00 2001 From: uanela Date: Mon, 15 Jun 2026 00:25:47 +0200 Subject: [PATCH 14/31] chore: update api/fs.lua and api impl.lua to match new keymaps --- lua/nvim-tree/_meta/api/fs.lua | 18 +++++++-------- lua/nvim-tree/actions/fs/clipboard.lua | 32 +++++++++----------------- lua/nvim-tree/api/impl.lua | 4 ++-- 3 files changed, 21 insertions(+), 33 deletions(-) diff --git a/lua/nvim-tree/_meta/api/fs.lua b/lua/nvim-tree/_meta/api/fs.lua index 7c5705b79bc..d58cc8248d2 100644 --- a/lua/nvim-tree/_meta/api/fs.lua +++ b/lua/nvim-tree/_meta/api/fs.lua @@ -14,12 +14,6 @@ nvim_tree.api.fs.copy = {} ---@param node? nvim_tree.api.Node function nvim_tree.api.fs.copy.absolute_path(node) end ---- ----Copy the absolute path to the system clipboard with nvim-tree protocol. ---- ----@param node? nvim_tree.api.Node -function nvim_tree.api.fs.copy.absolute_path_with_protocol(node) end - --- ---Copy the name with extension omitted to the system clipboard. --- @@ -73,12 +67,16 @@ function nvim_tree.api.fs.cut(node) end function nvim_tree.api.fs.paste(node) end --- ----Paste nodes from the nvim-tree clipboard using protocol. +---Paste nodes from the system register as files to nvim-tree while copying. --- ----If {node} is a file it will pasted in the parent directory. +---@param node_or_nodes? nvim_tree.api.Node | nvim_tree.api.Node[] +function nvim_tree.api.fs.paste_from_register_copying(node_or_nodes) end + --- ----@param node? nvim_tree.api.Node -function nvim_tree.api.fs.paste_with_protocol(node) end +---Paste nodes from the system register as files to nvim-tree while cutting. +--- +---@param node_or_nodes? nvim_tree.api.Node | nvim_tree.api.Node[] +function nvim_tree.api.fs.paste_from_register_cutting(node_or_nodes) end --- ---Print the contents of the nvim-tree clipboard. diff --git a/lua/nvim-tree/actions/fs/clipboard.lua b/lua/nvim-tree/actions/fs/clipboard.lua index 34a3963bd3e..633635f4ab2 100644 --- a/lua/nvim-tree/actions/fs/clipboard.lua +++ b/lua/nvim-tree/actions/fs/clipboard.lua @@ -22,7 +22,6 @@ local Node = require("nvim-tree.node") ---@field private data ClipboardData ---@field private clipboard_name string ---@field private reg string ----@field private protocol string local Clipboard = Class:extend() ---@class Clipboard @@ -43,11 +42,11 @@ function Clipboard:new(args) self.clipboard_name = self.explorer.opts.actions.use_system_clipboard and "system" or "neovim" self.reg = self.explorer.opts.actions.use_system_clipboard and "+" or "1" - self.protocol = self.explorer.opts.actions.clipboard.protocol or "nvim-tree" end ---@class RegOperationOptions ----@field use_protocol? boolean +---@field use_register? boolean +---@field cut? boolean ---@param source string ---@param destination string @@ -434,9 +433,9 @@ end ---@param node Node ---@param opts? RegOperationOptions function Clipboard:paste(node, opts) - if self.data.cut[1] ~= nil then + if self.data.cut[1] ~= nil or opts and opts.use_register and opts.cut then self:do_paste(node, "cut", do_cut, opts) - elseif self.data.copy[1] ~= nil or opts and opts.use_protocol then + elseif self.data.copy[1] ~= nil or opts and opts.use_register then self:do_paste(node, "copy", do_copy, opts) end end @@ -460,15 +459,8 @@ function Clipboard:print_clipboard() end ---@param content string ----@param opts? RegOperationOptions ---@param msg? string -function Clipboard:copy_to_reg(content, opts, msg) - local use_protocol = opts and opts.use_protocol and true or false - - if use_protocol then - content = self.protocol .. ": " .. content - end - +function Clipboard:copy_to_reg(content, msg) -- manually firing TextYankPost does not set vim.v.event -- workaround: create a scratch buffer with the clipboard contents and send a yank command local temp_buf = vim.api.nvim_create_buf(false, true) @@ -493,8 +485,7 @@ function Clipboard:copy_filename(node) end ---@param node_or_nodes Node|Node[] ----@param opts? RegOperationOptions -function Clipboard:copy_basename(node_or_nodes, opts) +function Clipboard:copy_basename(node_or_nodes) local content = "" if self:is_nodes_array(node_or_nodes) == false or #node_or_nodes == 1 then local node = #node_or_nodes == 1 and node_or_nodes[0] or node_or_nodes @@ -504,11 +495,11 @@ function Clipboard:copy_basename(node_or_nodes, opts) if i == 1 then content = node:get_basename() else - content = content .. ", " .. node:get_basename() + content = content .. "," .. node:get_basename() end end end - self:copy_to_reg(content, opts) + self:copy_to_reg(content) end ---@param node Node @@ -546,8 +537,7 @@ function Clipboard:get_absolute_path(node) end ---@param node_or_nodes Node|Node[] ----@param opts? RegOperationOptions -function Clipboard:copy_absolute_path(node_or_nodes, opts) +function Clipboard:copy_absolute_path(node_or_nodes) local content = "" local is_single = self:is_nodes_array(node_or_nodes) == false or #node_or_nodes == 1 if is_single then @@ -559,12 +549,12 @@ function Clipboard:copy_absolute_path(node_or_nodes, opts) if i == 1 then content = self:get_absolute_path(node) else - content = content .. ", " .. self:get_absolute_path(node) + content = content .. "," .. self:get_absolute_path(node) end end end - self:copy_to_reg(content, opts, string.format("%s nodes copied to register", is_single and 1 or #node_or_nodes)) + self:copy_to_reg(content, string.format("%s paths copied to register", is_single and 1 or #node_or_nodes)) end ---Node is cut. Will not be copied. diff --git a/lua/nvim-tree/api/impl.lua b/lua/nvim-tree/api/impl.lua index db49404ae6c..d92b82600c8 100644 --- a/lua/nvim-tree/api/impl.lua +++ b/lua/nvim-tree/api/impl.lua @@ -156,7 +156,6 @@ function M.hydrate_post_setup(api) api.fs.clear_clipboard = e_(function(e) e.clipboard:clear_clipboard() end) api.fs.copy.absolute_path = ev(function(e, n) e.clipboard:copy_absolute_path(n) end) - api.fs.copy.absolute_path_with_protocol = ev(function(e, n) e.clipboard:copy_absolute_path(n, { use_protocol = true }) end) api.fs.copy.basename = ev(function(e, n) e.clipboard:copy_basename(n) end) api.fs.copy.filename = en(function(e, n) e.clipboard:copy_filename(n) end) api.fs.copy.node = ev(function(e, n) e.clipboard:copy(n) end) @@ -164,7 +163,8 @@ function M.hydrate_post_setup(api) api.fs.create = _n(function(n) require("nvim-tree.actions.fs.create-file").fn(n) end) api.fs.cut = ev(function(e, n) e.clipboard:cut(n) end) api.fs.paste = en(function(e, n) e.clipboard:paste(n) end) - api.fs.paste_with_protocol = en(function(e, n) e.clipboard:paste(n, { use_protocol = true }) end) + api.fs.paste_from_register_copying = en(function(e, n) e.clipboard:paste(n, { use_register = true }) end) + api.fs.paste_from_register_cutting = en(function(e, n) e.clipboard:paste(n, { use_register = true, cut = true }) end) api.fs.print_clipboard = e_(function(e) e.clipboard:print_clipboard() end) api.fs.remove = _v(function(n) require("nvim-tree.actions.fs.remove-file").fn(n) end) api.fs.rename = _n(function(n) require("nvim-tree.actions.fs.rename-file").rename_node(n) end) From 0fd8cfadf52970e35b3e3a55fec0cf545c807b77 Mon Sep 17 00:00:00 2001 From: uanela Date: Mon, 15 Jun 2026 00:41:48 +0200 Subject: [PATCH 15/31] fix: correctly pass the function to new keymaps --- lua/nvim-tree/keymap.lua | 122 +++++++++++++++++++-------------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/lua/nvim-tree/keymap.lua b/lua/nvim-tree/keymap.lua index 4c2075fe4a8..f68c1e2ce5d 100644 --- a/lua/nvim-tree/keymap.lua +++ b/lua/nvim-tree/keymap.lua @@ -57,67 +57,67 @@ function M.on_attach_default(bufnr) end -- BEGIN_ON_ATTACH_DEFAULT - vim.keymap.set("n", "", api.tree.change_root_to_node, opts("CD")) - vim.keymap.set("n", "", api.node.open.replace_tree_buffer, opts("Open: In Place")) - vim.keymap.set("n", "", api.node.show_info_popup, opts("Info")) - vim.keymap.set("n", "", api.fs.rename_sub, opts("Rename: Omit Filename")) - vim.keymap.set("n", "", api.node.open.tab, opts("Open: New Tab")) - vim.keymap.set("n", "", api.node.open.vertical, opts("Open: Vertical Split")) - vim.keymap.set("n", "", api.node.open.horizontal, opts("Open: Horizontal Split")) - vim.keymap.set("n", "", api.node.navigate.parent_close, opts("Close Directory")) - vim.keymap.set("n", "", api.node.open.edit, opts("Open")) - vim.keymap.set({ "n", "x" }, "", api.fs.remove, opts("Delete")) - vim.keymap.set("n", "", api.node.open.preview, opts("Open Preview")) - vim.keymap.set("n", ">", api.node.navigate.sibling.next, opts("Next Sibling")) - vim.keymap.set("n", "<", api.node.navigate.sibling.prev, opts("Previous Sibling")) - vim.keymap.set("n", ".", api.node.run.cmd, opts("Run Command")) - vim.keymap.set("n", "-", api.tree.change_root_to_parent, opts("Up")) - vim.keymap.set("n", "a", api.fs.create, opts("Create File Or Directory")) - vim.keymap.set("n", "bd", api.marks.bulk.delete, opts("Delete Bookmarked")) - vim.keymap.set("n", "bt", api.marks.bulk.trash, opts("Trash Bookmarked")) - vim.keymap.set("n", "bmv", api.marks.bulk.move, opts("Move Bookmarked")) - vim.keymap.set("n", "B", api.filter.no_buffer.toggle, opts("Toggle Filter: No Buffer")) - vim.keymap.set({ "n", "x" }, "c", api.fs.copy.node, opts("Copy")) - vim.keymap.set("n", "C", api.filter.git.clean.toggle, opts("Toggle Filter: Git Clean")) - vim.keymap.set("n", "[c", api.node.navigate.git.prev, opts("Prev Git")) - vim.keymap.set("n", "]c", api.node.navigate.git.next, opts("Next Git")) - vim.keymap.set({ "n", "x" }, "d", api.fs.remove, opts("Delete")) - vim.keymap.set({ "n", "x" }, "D", api.fs.trash, opts("Trash")) - vim.keymap.set("n", "E", api.tree.expand_all, opts("Expand All")) - vim.keymap.set("n", "e", api.fs.rename_basename, opts("Rename: Basename")) - vim.keymap.set("n", "]e", api.node.navigate.diagnostics.next, opts("Next Diagnostic")) - vim.keymap.set("n", "[e", api.node.navigate.diagnostics.prev, opts("Prev Diagnostic")) - vim.keymap.set("n", "F", api.filter.live.clear, opts("Live Filter: Clear")) - vim.keymap.set("n", "f", api.filter.live.start, opts("Live Filter: Start")) - vim.keymap.set("n", "g?", api.tree.toggle_help, opts("Help")) - vim.keymap.set({ "n", "x" }, "gy", api.fs.copy.absolute_path, opts("Copy Absolute Path")) - vim.keymap.set({ "n", "x" }, "ge", api.fs.copy.basename, opts("Copy Basename")) - vim.keymap.set("n", "H", api.filter.dotfiles.toggle, opts("Toggle Filter: Dotfiles")) - vim.keymap.set("n", "I", api.filter.git.ignored.toggle, opts("Toggle Filter: Git Ignored")) - vim.keymap.set("n", "J", api.node.navigate.sibling.last, opts("Last Sibling")) - vim.keymap.set("n", "K", api.node.navigate.sibling.first, opts("First Sibling")) - vim.keymap.set("n", "L", api.node.open.toggle_group_empty, opts("Toggle Group Empty")) - vim.keymap.set("n", "M", api.filter.no_bookmark.toggle, opts("Toggle Filter: No Bookmark")) - vim.keymap.set({ "n", "x" }, "m", api.marks.toggle, opts("Toggle Bookmark")) - vim.keymap.set("n", "o", api.node.open.edit, opts("Open")) - vim.keymap.set("n", "O", api.node.open.no_window_picker, opts("Open: No Window Picker")) - vim.keymap.set("n", "p", api.fs.paste, opts("Paste")) - vim.keymap.set("n", "gp", api.fs.paste_from_clipboard_copying, opts("Paste From Cliboard - Copying")) - vim.keymap.set("n", "gx", api.fs.paste_from_clipboard_cutting, opts("Paste From Cliboard - Cutting")) - vim.keymap.set("n", "P", api.node.navigate.parent, opts("Parent Directory")) - vim.keymap.set("n", "q", api.tree.close, opts("Close")) - vim.keymap.set("n", "r", api.fs.rename, opts("Rename")) - vim.keymap.set("n", "R", api.tree.reload, opts("Refresh")) - vim.keymap.set("n", "s", api.node.run.system, opts("Run System")) - vim.keymap.set("n", "S", api.tree.search_node, opts("Search")) - vim.keymap.set("n", "u", api.fs.rename_full, opts("Rename: Full Path")) - vim.keymap.set("n", "U", api.filter.custom.toggle, opts("Toggle Filter: Custom")) - vim.keymap.set("n", "W", api.tree.collapse_all, opts("Collapse All")) - vim.keymap.set({ "n", "x" }, "x", api.fs.cut, opts("Cut")) - vim.keymap.set("n", "y", api.fs.copy.filename, opts("Copy Name")) - vim.keymap.set("n", "Y", api.fs.copy.relative_path, opts("Copy Relative Path")) - vim.keymap.set("n", "<2-LeftMouse>", api.node.open.edit, opts("Open")) - vim.keymap.set("n", "<2-RightMouse>", api.tree.change_root_to_node, opts("CD")) + vim.keymap.set("n", "", api.tree.change_root_to_node, opts("CD")) + vim.keymap.set("n", "", api.node.open.replace_tree_buffer, opts("Open: In Place")) + vim.keymap.set("n", "", api.node.show_info_popup, opts("Info")) + vim.keymap.set("n", "", api.fs.rename_sub, opts("Rename: Omit Filename")) + vim.keymap.set("n", "", api.node.open.tab, opts("Open: New Tab")) + vim.keymap.set("n", "", api.node.open.vertical, opts("Open: Vertical Split")) + vim.keymap.set("n", "", api.node.open.horizontal, opts("Open: Horizontal Split")) + vim.keymap.set("n", "", api.node.navigate.parent_close, opts("Close Directory")) + vim.keymap.set("n", "", api.node.open.edit, opts("Open")) + vim.keymap.set({ "n", "x" }, "", api.fs.remove, opts("Delete")) + vim.keymap.set("n", "", api.node.open.preview, opts("Open Preview")) + vim.keymap.set("n", ">", api.node.navigate.sibling.next, opts("Next Sibling")) + vim.keymap.set("n", "<", api.node.navigate.sibling.prev, opts("Previous Sibling")) + vim.keymap.set("n", ".", api.node.run.cmd, opts("Run Command")) + vim.keymap.set("n", "-", api.tree.change_root_to_parent, opts("Up")) + vim.keymap.set("n", "a", api.fs.create, opts("Create File Or Directory")) + vim.keymap.set("n", "bd", api.marks.bulk.delete, opts("Delete Bookmarked")) + vim.keymap.set("n", "bt", api.marks.bulk.trash, opts("Trash Bookmarked")) + vim.keymap.set("n", "bmv", api.marks.bulk.move, opts("Move Bookmarked")) + vim.keymap.set("n", "B", api.filter.no_buffer.toggle, opts("Toggle Filter: No Buffer")) + vim.keymap.set({ "n", "x" }, "c", api.fs.copy.node, opts("Copy")) + vim.keymap.set("n", "C", api.filter.git.clean.toggle, opts("Toggle Filter: Git Clean")) + vim.keymap.set("n", "[c", api.node.navigate.git.prev, opts("Prev Git")) + vim.keymap.set("n", "]c", api.node.navigate.git.next, opts("Next Git")) + vim.keymap.set({ "n", "x" }, "d", api.fs.remove, opts("Delete")) + vim.keymap.set({ "n", "x" }, "D", api.fs.trash, opts("Trash")) + vim.keymap.set("n", "E", api.tree.expand_all, opts("Expand All")) + vim.keymap.set("n", "e", api.fs.rename_basename, opts("Rename: Basename")) + vim.keymap.set("n", "]e", api.node.navigate.diagnostics.next, opts("Next Diagnostic")) + vim.keymap.set("n", "[e", api.node.navigate.diagnostics.prev, opts("Prev Diagnostic")) + vim.keymap.set("n", "F", api.filter.live.clear, opts("Live Filter: Clear")) + vim.keymap.set("n", "f", api.filter.live.start, opts("Live Filter: Start")) + vim.keymap.set("n", "g?", api.tree.toggle_help, opts("Help")) + vim.keymap.set({ "n", "x" }, "gy", api.fs.copy.absolute_path, opts("Copy Absolute Path")) + vim.keymap.set({ "n", "x" }, "ge", api.fs.copy.basename, opts("Copy Basename")) + vim.keymap.set("n", "H", api.filter.dotfiles.toggle, opts("Toggle Filter: Dotfiles")) + vim.keymap.set("n", "I", api.filter.git.ignored.toggle, opts("Toggle Filter: Git Ignored")) + vim.keymap.set("n", "J", api.node.navigate.sibling.last, opts("Last Sibling")) + vim.keymap.set("n", "K", api.node.navigate.sibling.first, opts("First Sibling")) + vim.keymap.set("n", "L", api.node.open.toggle_group_empty, opts("Toggle Group Empty")) + vim.keymap.set("n", "M", api.filter.no_bookmark.toggle, opts("Toggle Filter: No Bookmark")) + vim.keymap.set({ "n", "x" }, "m", api.marks.toggle, opts("Toggle Bookmark")) + vim.keymap.set("n", "o", api.node.open.edit, opts("Open")) + vim.keymap.set("n", "O", api.node.open.no_window_picker, opts("Open: No Window Picker")) + vim.keymap.set("n", "p", api.fs.paste, opts("Paste")) + vim.keymap.set("n", "gp", api.fs.paste_from_register_copying, opts("Paste From Register - Copying")) + vim.keymap.set("n", "gx", api.fs.paste_from_register_cutting, opts("Paste From Register - Cutting")) + vim.keymap.set("n", "P", api.node.navigate.parent, opts("Parent Directory")) + vim.keymap.set("n", "q", api.tree.close, opts("Close")) + vim.keymap.set("n", "r", api.fs.rename, opts("Rename")) + vim.keymap.set("n", "R", api.tree.reload, opts("Refresh")) + vim.keymap.set("n", "s", api.node.run.system, opts("Run System")) + vim.keymap.set("n", "S", api.tree.search_node, opts("Search")) + vim.keymap.set("n", "u", api.fs.rename_full, opts("Rename: Full Path")) + vim.keymap.set("n", "U", api.filter.custom.toggle, opts("Toggle Filter: Custom")) + vim.keymap.set("n", "W", api.tree.collapse_all, opts("Collapse All")) + vim.keymap.set({ "n", "x" }, "x", api.fs.cut, opts("Cut")) + vim.keymap.set("n", "y", api.fs.copy.filename, opts("Copy Name")) + vim.keymap.set("n", "Y", api.fs.copy.relative_path, opts("Copy Relative Path")) + vim.keymap.set("n", "<2-LeftMouse>", api.node.open.edit, opts("Open")) + vim.keymap.set("n", "<2-RightMouse>", api.tree.change_root_to_node, opts("CD")) -- END_ON_ATTACH_DEFAULT end From 073fac1056623bbcda8ef0e4d753799d02bcf993 Mon Sep 17 00:00:00 2001 From: uanela Date: Mon, 15 Jun 2026 00:43:23 +0200 Subject: [PATCH 16/31] chore: remove use_protocol and use use_register + cut options --- lua/nvim-tree/actions/fs/clipboard.lua | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/lua/nvim-tree/actions/fs/clipboard.lua b/lua/nvim-tree/actions/fs/clipboard.lua index 633635f4ab2..d3a32629feb 100644 --- a/lua/nvim-tree/actions/fs/clipboard.lua +++ b/lua/nvim-tree/actions/fs/clipboard.lua @@ -44,7 +44,7 @@ function Clipboard:new(args) self.reg = self.explorer.opts.actions.use_system_clipboard and "+" or "1" end ----@class RegOperationOptions +---@class PasteOptions ---@field use_register? boolean ---@field cut? boolean @@ -328,13 +328,8 @@ function Clipboard:get_nodes_from_reg() return end - local prefix = self.protocol .. ": " - if content:sub(1, #prefix) ~= prefix then - return - end - local nodes = {} - local absolute_paths = vim.split(content:sub(#prefix + 1, #content), ", ") + local absolute_paths = vim.split(content:sub(1, #content), ",") for _, absolute_path in ipairs(absolute_paths) do local node_args = { absolute_path = absolute_path, name = vim.fn.fnamemodify(absolute_path, ":t"), explorer = self.explorer } @@ -353,7 +348,7 @@ end ---@param node Node ---@param action ClipboardAction ---@param action_fn ClipboardActionFn ----@param opts? RegOperationOptions +---@param opts? PasteOptions function Clipboard:do_paste(node, action, action_fn, opts) if node.name == ".." then node = self.explorer @@ -363,7 +358,7 @@ function Clipboard:do_paste(node, action, action_fn, opts) node = dir:last_group_node() end end - local clip = opts and opts.use_protocol and self:get_nodes_from_reg() or self.data[action] + local clip = opts and opts.use_register and self:get_nodes_from_reg() or self.data[action] if #clip == 0 then return end @@ -431,7 +426,7 @@ end ---Paste cut (if present) or copy (if present) ---@param node Node ----@param opts? RegOperationOptions +---@param opts? PasteOptions function Clipboard:paste(node, opts) if self.data.cut[1] ~= nil or opts and opts.use_register and opts.cut then self:do_paste(node, "cut", do_cut, opts) From 27f5254cab82714502b6ef31be4115a1bf248c16 Mon Sep 17 00:00:00 2001 From: uanela Date: Mon, 15 Jun 2026 00:50:13 +0200 Subject: [PATCH 17/31] chore: update docs --- doc/nvim-tree-lua.txt | 159 ++++++++++++------------- lua/nvim-tree/_meta/config/actions.lua | 10 -- lua/nvim-tree/actions/fs/clipboard.lua | 2 +- lua/nvim-tree/config.lua | 3 - lua/nvim-tree/keymap.lua | 4 +- 5 files changed, 76 insertions(+), 102 deletions(-) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index b7c29f5c037..e25904e703a 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -143,7 +143,6 @@ Show the mappings: `g?` `f` n Live Filter: Start |nvim_tree.api.filter.live.start()| `g?` n Help |nvim_tree.api.tree.toggle_help()| `gy` nx Copy Absolute Path |nvim_tree.api.fs.copy.absolute_path()| - `bgy` nx Copy With Protocol |nvim_tree.api.fs.copy.absolute_path_with_protocol()| `ge` nx Copy Basename |nvim_tree.api.fs.copy.basename()| `H` n Toggle Filter: Dotfiles |nvim_tree.api.filter.dotfiles.toggle()| `I` n Toggle Filter: Git Ignored |nvim_tree.api.filter.git.ignored.toggle()| @@ -155,7 +154,8 @@ Show the mappings: `g?` `o` n Open |nvim_tree.api.node.open.edit()| `O` n Open: No Window Picker |nvim_tree.api.node.open.no_window_picker()| `p` n Paste |nvim_tree.api.fs.paste()| - `bgp` n Paste With Protocol |nvim_tree.api.fs.paste_with_protocol()| + `gp` n Paste Using Register |nvim_tree.api.fs.paste_from_register_copying()| + `gx` n Move Using Register |nvim_tree.api.fs.paste_from_register_cutting()| `P` n Parent Directory |nvim_tree.api.node.navigate.parent()| `q` n Close |nvim_tree.api.tree.close()| `r` n Rename |nvim_tree.api.fs.rename()| @@ -404,67 +404,67 @@ You are encouraged to copy these to your {on_attach} function. >lua end -- BEGIN_ON_ATTACH_DEFAULT - vim.keymap.set("n", "", api.tree.change_root_to_node, opts("CD")) - vim.keymap.set("n", "", api.node.open.replace_tree_buffer, opts("Open: In Place")) - vim.keymap.set("n", "", api.node.show_info_popup, opts("Info")) - vim.keymap.set("n", "", api.fs.rename_sub, opts("Rename: Omit Filename")) - vim.keymap.set("n", "", api.node.open.tab, opts("Open: New Tab")) - vim.keymap.set("n", "", api.node.open.vertical, opts("Open: Vertical Split")) - vim.keymap.set("n", "", api.node.open.horizontal, opts("Open: Horizontal Split")) - vim.keymap.set("n", "", api.node.navigate.parent_close, opts("Close Directory")) - vim.keymap.set("n", "", api.node.open.edit, opts("Open")) - vim.keymap.set({ "n", "x" }, "", api.fs.remove, opts("Delete")) - vim.keymap.set("n", "", api.node.open.preview, opts("Open Preview")) - vim.keymap.set("n", ">", api.node.navigate.sibling.next, opts("Next Sibling")) - vim.keymap.set("n", "<", api.node.navigate.sibling.prev, opts("Previous Sibling")) - vim.keymap.set("n", ".", api.node.run.cmd, opts("Run Command")) - vim.keymap.set("n", "-", api.tree.change_root_to_parent, opts("Up")) - vim.keymap.set("n", "a", api.fs.create, opts("Create File Or Directory")) - vim.keymap.set("n", "bd", api.marks.bulk.delete, opts("Delete Bookmarked")) - vim.keymap.set("n", "bt", api.marks.bulk.trash, opts("Trash Bookmarked")) - vim.keymap.set("n", "bmv", api.marks.bulk.move, opts("Move Bookmarked")) - vim.keymap.set("n", "B", api.filter.no_buffer.toggle, opts("Toggle Filter: No Buffer")) - vim.keymap.set({ "n", "x" }, "c", api.fs.copy.node, opts("Copy")) - vim.keymap.set("n", "C", api.filter.git.clean.toggle, opts("Toggle Filter: Git Clean")) - vim.keymap.set("n", "[c", api.node.navigate.git.prev, opts("Prev Git")) - vim.keymap.set("n", "]c", api.node.navigate.git.next, opts("Next Git")) - vim.keymap.set({ "n", "x" }, "d", api.fs.remove, opts("Delete")) - vim.keymap.set({ "n", "x" }, "D", api.fs.trash, opts("Trash")) - vim.keymap.set("n", "E", api.tree.expand_all, opts("Expand All")) - vim.keymap.set("n", "e", api.fs.rename_basename, opts("Rename: Basename")) - vim.keymap.set("n", "]e", api.node.navigate.diagnostics.next, opts("Next Diagnostic")) - vim.keymap.set("n", "[e", api.node.navigate.diagnostics.prev, opts("Prev Diagnostic")) - vim.keymap.set("n", "F", api.filter.live.clear, opts("Live Filter: Clear")) - vim.keymap.set("n", "f", api.filter.live.start, opts("Live Filter: Start")) - vim.keymap.set("n", "g?", api.tree.toggle_help, opts("Help")) - vim.keymap.set({ "n", "x" }, "gy", api.fs.copy.absolute_path, opts("Copy Absolute Path")) - vim.keymap.set({ "n", "x" }, "bgy", api.fs.copy.absolute_path_with_protocol, opts("Copy With Protocol")) - vim.keymap.set({ "n", "x" }, "ge", api.fs.copy.basename, opts("Copy Basename")) - vim.keymap.set("n", "H", api.filter.dotfiles.toggle, opts("Toggle Filter: Dotfiles")) - vim.keymap.set("n", "I", api.filter.git.ignored.toggle, opts("Toggle Filter: Git Ignored")) - vim.keymap.set("n", "J", api.node.navigate.sibling.last, opts("Last Sibling")) - vim.keymap.set("n", "K", api.node.navigate.sibling.first, opts("First Sibling")) - vim.keymap.set("n", "L", api.node.open.toggle_group_empty, opts("Toggle Group Empty")) - vim.keymap.set("n", "M", api.filter.no_bookmark.toggle, opts("Toggle Filter: No Bookmark")) - vim.keymap.set({ "n", "x" }, "m", api.marks.toggle, opts("Toggle Bookmark")) - vim.keymap.set("n", "o", api.node.open.edit, opts("Open")) - vim.keymap.set("n", "O", api.node.open.no_window_picker, opts("Open: No Window Picker")) - vim.keymap.set("n", "p", api.fs.paste, opts("Paste")) - vim.keymap.set("n", "bgp", api.fs.paste_with_protocol, opts("Paste With Protocol")) - vim.keymap.set("n", "P", api.node.navigate.parent, opts("Parent Directory")) - vim.keymap.set("n", "q", api.tree.close, opts("Close")) - vim.keymap.set("n", "r", api.fs.rename, opts("Rename")) - vim.keymap.set("n", "R", api.tree.reload, opts("Refresh")) - vim.keymap.set("n", "s", api.node.run.system, opts("Run System")) - vim.keymap.set("n", "S", api.tree.search_node, opts("Search")) - vim.keymap.set("n", "u", api.fs.rename_full, opts("Rename: Full Path")) - vim.keymap.set("n", "U", api.filter.custom.toggle, opts("Toggle Filter: Custom")) - vim.keymap.set("n", "W", api.tree.collapse_all, opts("Collapse All")) - vim.keymap.set({ "n", "x" }, "x", api.fs.cut, opts("Cut")) - vim.keymap.set("n", "y", api.fs.copy.filename, opts("Copy Name")) - vim.keymap.set("n", "Y", api.fs.copy.relative_path, opts("Copy Relative Path")) - vim.keymap.set("n", "<2-LeftMouse>", api.node.open.edit, opts("Open")) - vim.keymap.set("n", "<2-RightMouse>", api.tree.change_root_to_node, opts("CD")) + vim.keymap.set("n", "", api.tree.change_root_to_node, opts("CD")) + vim.keymap.set("n", "", api.node.open.replace_tree_buffer, opts("Open: In Place")) + vim.keymap.set("n", "", api.node.show_info_popup, opts("Info")) + vim.keymap.set("n", "", api.fs.rename_sub, opts("Rename: Omit Filename")) + vim.keymap.set("n", "", api.node.open.tab, opts("Open: New Tab")) + vim.keymap.set("n", "", api.node.open.vertical, opts("Open: Vertical Split")) + vim.keymap.set("n", "", api.node.open.horizontal, opts("Open: Horizontal Split")) + vim.keymap.set("n", "", api.node.navigate.parent_close, opts("Close Directory")) + vim.keymap.set("n", "", api.node.open.edit, opts("Open")) + vim.keymap.set({ "n", "x" }, "", api.fs.remove, opts("Delete")) + vim.keymap.set("n", "", api.node.open.preview, opts("Open Preview")) + vim.keymap.set("n", ">", api.node.navigate.sibling.next, opts("Next Sibling")) + vim.keymap.set("n", "<", api.node.navigate.sibling.prev, opts("Previous Sibling")) + vim.keymap.set("n", ".", api.node.run.cmd, opts("Run Command")) + vim.keymap.set("n", "-", api.tree.change_root_to_parent, opts("Up")) + vim.keymap.set("n", "a", api.fs.create, opts("Create File Or Directory")) + vim.keymap.set("n", "bd", api.marks.bulk.delete, opts("Delete Bookmarked")) + vim.keymap.set("n", "bt", api.marks.bulk.trash, opts("Trash Bookmarked")) + vim.keymap.set("n", "bmv", api.marks.bulk.move, opts("Move Bookmarked")) + vim.keymap.set("n", "B", api.filter.no_buffer.toggle, opts("Toggle Filter: No Buffer")) + vim.keymap.set({ "n", "x" }, "c", api.fs.copy.node, opts("Copy")) + vim.keymap.set("n", "C", api.filter.git.clean.toggle, opts("Toggle Filter: Git Clean")) + vim.keymap.set("n", "[c", api.node.navigate.git.prev, opts("Prev Git")) + vim.keymap.set("n", "]c", api.node.navigate.git.next, opts("Next Git")) + vim.keymap.set({ "n", "x" }, "d", api.fs.remove, opts("Delete")) + vim.keymap.set({ "n", "x" }, "D", api.fs.trash, opts("Trash")) + vim.keymap.set("n", "E", api.tree.expand_all, opts("Expand All")) + vim.keymap.set("n", "e", api.fs.rename_basename, opts("Rename: Basename")) + vim.keymap.set("n", "]e", api.node.navigate.diagnostics.next, opts("Next Diagnostic")) + vim.keymap.set("n", "[e", api.node.navigate.diagnostics.prev, opts("Prev Diagnostic")) + vim.keymap.set("n", "F", api.filter.live.clear, opts("Live Filter: Clear")) + vim.keymap.set("n", "f", api.filter.live.start, opts("Live Filter: Start")) + vim.keymap.set("n", "g?", api.tree.toggle_help, opts("Help")) + vim.keymap.set({ "n", "x" }, "gy", api.fs.copy.absolute_path, opts("Copy Absolute Path")) + vim.keymap.set({ "n", "x" }, "ge", api.fs.copy.basename, opts("Copy Basename")) + vim.keymap.set("n", "H", api.filter.dotfiles.toggle, opts("Toggle Filter: Dotfiles")) + vim.keymap.set("n", "I", api.filter.git.ignored.toggle, opts("Toggle Filter: Git Ignored")) + vim.keymap.set("n", "J", api.node.navigate.sibling.last, opts("Last Sibling")) + vim.keymap.set("n", "K", api.node.navigate.sibling.first, opts("First Sibling")) + vim.keymap.set("n", "L", api.node.open.toggle_group_empty, opts("Toggle Group Empty")) + vim.keymap.set("n", "M", api.filter.no_bookmark.toggle, opts("Toggle Filter: No Bookmark")) + vim.keymap.set({ "n", "x" }, "m", api.marks.toggle, opts("Toggle Bookmark")) + vim.keymap.set("n", "o", api.node.open.edit, opts("Open")) + vim.keymap.set("n", "O", api.node.open.no_window_picker, opts("Open: No Window Picker")) + vim.keymap.set("n", "p", api.fs.paste, opts("Paste")) + vim.keymap.set("n", "gp", api.fs.paste_from_register_copying, opts("Paste Using Register")) + vim.keymap.set("n", "gx", api.fs.paste_from_register_cutting, opts("Move Using Register")) + vim.keymap.set("n", "P", api.node.navigate.parent, opts("Parent Directory")) + vim.keymap.set("n", "q", api.tree.close, opts("Close")) + vim.keymap.set("n", "r", api.fs.rename, opts("Rename")) + vim.keymap.set("n", "R", api.tree.reload, opts("Refresh")) + vim.keymap.set("n", "s", api.node.run.system, opts("Run System")) + vim.keymap.set("n", "S", api.tree.search_node, opts("Search")) + vim.keymap.set("n", "u", api.fs.rename_full, opts("Rename: Full Path")) + vim.keymap.set("n", "U", api.filter.custom.toggle, opts("Toggle Filter: Custom")) + vim.keymap.set("n", "W", api.tree.collapse_all, opts("Collapse All")) + vim.keymap.set({ "n", "x" }, "x", api.fs.cut, opts("Cut")) + vim.keymap.set("n", "y", api.fs.copy.filename, opts("Copy Name")) + vim.keymap.set("n", "Y", api.fs.copy.relative_path, opts("Copy Relative Path")) + vim.keymap.set("n", "<2-LeftMouse>", api.node.open.edit, opts("Open")) + vim.keymap.set("n", "<2-RightMouse>", api.tree.change_root_to_node, opts("CD")) -- END_ON_ATTACH_DEFAULT < Alternatively, you may apply these default mappings from your @@ -1698,8 +1698,6 @@ Config: actions *nvim-tree-config-actions* Fields: ~ • {change_dir}? (`nvim_tree.config.actions.change_dir`) |nvim_tree.config.actions.change_dir| - • {clipboard}? (`nvim_tree.config.actions.clipboard`) - |nvim_tree.config.actions.clipboard| • {expand_all}? (`nvim_tree.config.actions.expand_all`) |nvim_tree.config.actions.expand_all| • {file_popup}? (`nvim_tree.config.actions.file_popup`) @@ -1724,13 +1722,6 @@ Config: actions *nvim-tree-config-actions* • {restrict_above_cwd}? (`boolean`, default: `false`) Restrict changing to a directory above the global cwd. -*nvim_tree.config.actions.clipboard* - Customizes nvim-tree clipboard behaviour - - Fields: ~ - • {protocol}? (`string`, default: `nvim-tree`) Change the protocol - prefix to be used on multiple nvim instances operations - *nvim_tree.config.actions.expand_all* Configure |nvim_tree.api.tree.expand_all()| and |nvim_tree.api.node.expand()| @@ -2161,9 +2152,6 @@ Following is the default configuration, see |nvim_tree.config| for details. >lua }, actions = { use_system_clipboard = true, - clipboard = { - protocol = "nvim-tree" - }, change_dir = { enable = true, global = false, @@ -2428,13 +2416,6 @@ clear_clipboard() *nvim_tree.api.fs.clear_clipboard()* copy.absolute_path({node}) *nvim_tree.api.fs.copy.absolute_path()* Copy the absolute path to the system clipboard. - Parameters: ~ - • {node} (`nvim_tree.api.Node?`) - - *nvim_tree.api.fs.copy.absolute_path_with_protocol()* -copy.absolute_path_with_protocol({node}) - Copy the absolute path to the system clipboard with nvim-tree protocol. - Parameters: ~ • {node} (`nvim_tree.api.Node?`) @@ -2490,13 +2471,19 @@ paste({node}) *nvim_tree.api.fs.paste()* Parameters: ~ • {node} (`nvim_tree.api.Node?`) -paste_with_protocol({node}) *nvim_tree.api.fs.paste_with_protocol()* - Paste nodes from the nvim-tree clipboard using protocol. + *nvim_tree.api.fs.paste_from_register_copying()* +paste_from_register_copying({node_or_nodes}) + Paste nodes from the system register as files to nvim-tree while copying. - If {node} is a file it will pasted in the parent directory. + Parameters: ~ + • {node_or_nodes} (`nvim_tree.api.Node|nvim_tree.api.Node[]?`) + + *nvim_tree.api.fs.paste_from_register_cutting()* +paste_from_register_cutting({node_or_nodes}) + Paste nodes from the system register as files to nvim-tree while cutting. Parameters: ~ - • {node} (`nvim_tree.api.Node?`) + • {node_or_nodes} (`nvim_tree.api.Node|nvim_tree.api.Node[]?`) print_clipboard() *nvim_tree.api.fs.print_clipboard()* Print the contents of the nvim-tree clipboard. diff --git a/lua/nvim-tree/_meta/config/actions.lua b/lua/nvim-tree/_meta/config/actions.lua index 066a50a443d..8b9891f66d8 100644 --- a/lua/nvim-tree/_meta/config/actions.lua +++ b/lua/nvim-tree/_meta/config/actions.lua @@ -9,9 +9,6 @@ error("Cannot require a meta file") ---(default: `true`) ---@field use_system_clipboard? boolean --- ----[nvim_tree.config.actions.clipboard] ----@field clipboard? nvim_tree.config.actions.clipboard ---- ---[nvim_tree.config.actions.change_dir] ---@field change_dir? nvim_tree.config.actions.change_dir --- @@ -27,13 +24,6 @@ error("Cannot require a meta file") ---[nvim_tree.config.actions.remove_file] ---@field remove_file? nvim_tree.config.actions.remove_file ---- Customizes nvim-tree clipboard behaviour ----@class nvim_tree.config.actions.clipboard ---- ----Change the protocol prefix to be used on multiple nvim instances operations ----(default: `nvim-tree`) ----@field protocol? string - --- vim [current-directory] behaviour ---@class nvim_tree.config.actions.change_dir --- diff --git a/lua/nvim-tree/actions/fs/clipboard.lua b/lua/nvim-tree/actions/fs/clipboard.lua index d3a32629feb..a001ce6403a 100644 --- a/lua/nvim-tree/actions/fs/clipboard.lua +++ b/lua/nvim-tree/actions/fs/clipboard.lua @@ -319,7 +319,7 @@ function Clipboard:resolve_conflicts(conflict, destination, action, action_fn) end) end ---- Transforms the copied absolute paths with protocols to node +--- Transforms the copied absolute paths on register to node ---@private function Clipboard:get_nodes_from_reg() local content = vim.fn.getreg(self.reg) diff --git a/lua/nvim-tree/config.lua b/lua/nvim-tree/config.lua index 3a39d283657..24d87c389a2 100644 --- a/lua/nvim-tree/config.lua +++ b/lua/nvim-tree/config.lua @@ -232,9 +232,6 @@ M.d = { -- config-default-start }, actions = { use_system_clipboard = true, - clipboard = { - protocol = "nvim-tree" - }, change_dir = { enable = true, global = false, diff --git a/lua/nvim-tree/keymap.lua b/lua/nvim-tree/keymap.lua index f68c1e2ce5d..3c4bbfd5e29 100644 --- a/lua/nvim-tree/keymap.lua +++ b/lua/nvim-tree/keymap.lua @@ -102,8 +102,8 @@ function M.on_attach_default(bufnr) vim.keymap.set("n", "o", api.node.open.edit, opts("Open")) vim.keymap.set("n", "O", api.node.open.no_window_picker, opts("Open: No Window Picker")) vim.keymap.set("n", "p", api.fs.paste, opts("Paste")) - vim.keymap.set("n", "gp", api.fs.paste_from_register_copying, opts("Paste From Register - Copying")) - vim.keymap.set("n", "gx", api.fs.paste_from_register_cutting, opts("Paste From Register - Cutting")) + vim.keymap.set("n", "gp", api.fs.paste_from_register_copying, opts("Paste Using Register")) + vim.keymap.set("n", "gx", api.fs.paste_from_register_cutting, opts("Move Using Register")) vim.keymap.set("n", "P", api.node.navigate.parent, opts("Parent Directory")) vim.keymap.set("n", "q", api.tree.close, opts("Close")) vim.keymap.set("n", "r", api.fs.rename, opts("Rename")) From 4f787e0db3707685ec24294a42f27f5b2fdc6f5d Mon Sep 17 00:00:00 2001 From: uanela Date: Thu, 18 Jun 2026 08:23:50 +0200 Subject: [PATCH 18/31] chore: move node:get_basename to cliboard_ --- lua/nvim-tree/actions/fs/clipboard.lua | 18 +++++++++++++++--- lua/nvim-tree/node/init.lua | 10 ---------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/lua/nvim-tree/actions/fs/clipboard.lua b/lua/nvim-tree/actions/fs/clipboard.lua index a001ce6403a..5ccb2ce7dc3 100644 --- a/lua/nvim-tree/actions/fs/clipboard.lua +++ b/lua/nvim-tree/actions/fs/clipboard.lua @@ -484,13 +484,13 @@ function Clipboard:copy_basename(node_or_nodes) local content = "" if self:is_nodes_array(node_or_nodes) == false or #node_or_nodes == 1 then local node = #node_or_nodes == 1 and node_or_nodes[0] or node_or_nodes - content = node:get_basename() + content = self:get_basename(node) else for i, node in ipairs(node_or_nodes) do if i == 1 then - content = node:get_basename() + content = self:get_basename(node) else - content = content .. "," .. node:get_basename() + content = content .. "," .. self:get_basename(node) end end end @@ -566,4 +566,16 @@ function Clipboard:is_copied(node) return vim.tbl_contains(self.data.copy, node) end +---@param node Node +---@return string +function Clipboard:get_basename(node) + if node.name == ".." then + -- root + return vim.fn.fnamemodify(node.explorer.absolute_path, ":t:r") + else + -- node + return vim.fn.fnamemodify(node.name, ":r") + end +end + return Clipboard diff --git a/lua/nvim-tree/node/init.lua b/lua/nvim-tree/node/init.lua index d2fd2c208c6..c89d9e7171c 100644 --- a/lua/nvim-tree/node/init.lua +++ b/lua/nvim-tree/node/init.lua @@ -159,14 +159,4 @@ function Node:expand(expand_opts) end end -function Node:get_basename() - if self.name == ".." then - -- root - return vim.fn.fnamemodify(self.explorer.absolute_path, ":t:r") - else - -- node - return vim.fn.fnamemodify(self.name, ":r") - end -end - return Node From a7e647bf834377ece8a122f99c26ef2b4668c11d Mon Sep 17 00:00:00 2001 From: uanela Date: Thu, 18 Jun 2026 09:05:28 +0200 Subject: [PATCH 19/31] chore(clipboard): remove vim.cmd workaround in favor of vim.fn.setreg --- lua/nvim-tree/actions/fs/clipboard.lua | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/lua/nvim-tree/actions/fs/clipboard.lua b/lua/nvim-tree/actions/fs/clipboard.lua index 5ccb2ce7dc3..c48cdd66777 100644 --- a/lua/nvim-tree/actions/fs/clipboard.lua +++ b/lua/nvim-tree/actions/fs/clipboard.lua @@ -456,14 +456,7 @@ end ---@param content string ---@param msg? string function Clipboard:copy_to_reg(content, msg) - -- manually firing TextYankPost does not set vim.v.event - -- workaround: create a scratch buffer with the clipboard contents and send a yank command - local temp_buf = vim.api.nvim_create_buf(false, true) - vim.api.nvim_buf_set_text(temp_buf, 0, 0, 0, 0, { content }) - vim.api.nvim_buf_call(temp_buf, function() - vim.cmd(string.format('normal! "%sy$', self.reg)) - end) - vim.api.nvim_buf_delete(temp_buf, {}) + vim.fn.setreg(self.reg, type(content) == "table" and content or { content }, "v") notify.info(msg or string.format("Copied %s to %s clipboard!", content, self.clipboard_name)) end From ba8e7a1c56a2b7acacf2694038fe98bb9db8c4b6 Mon Sep 17 00:00:00 2001 From: uanela Date: Thu, 18 Jun 2026 09:12:14 +0200 Subject: [PATCH 20/31] chore: use newline as separator instead of comma --- lua/nvim-tree/actions/fs/clipboard.lua | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/lua/nvim-tree/actions/fs/clipboard.lua b/lua/nvim-tree/actions/fs/clipboard.lua index c48cdd66777..6a07e1331d2 100644 --- a/lua/nvim-tree/actions/fs/clipboard.lua +++ b/lua/nvim-tree/actions/fs/clipboard.lua @@ -329,7 +329,7 @@ function Clipboard:get_nodes_from_reg() end local nodes = {} - local absolute_paths = vim.split(content:sub(1, #content), ",") + local absolute_paths = vim.split(content:sub(1, #content), "\n") for _, absolute_path in ipairs(absolute_paths) do local node_args = { absolute_path = absolute_path, name = vim.fn.fnamemodify(absolute_path, ":t"), explorer = self.explorer } @@ -474,17 +474,14 @@ end ---@param node_or_nodes Node|Node[] function Clipboard:copy_basename(node_or_nodes) - local content = "" + local content if self:is_nodes_array(node_or_nodes) == false or #node_or_nodes == 1 then local node = #node_or_nodes == 1 and node_or_nodes[0] or node_or_nodes content = self:get_basename(node) else - for i, node in ipairs(node_or_nodes) do - if i == 1 then - content = self:get_basename(node) - else - content = content .. "," .. self:get_basename(node) - end + content = {} + for _, node in ipairs(node_or_nodes) do + table.insert(content, self:get_basename(node)) end end self:copy_to_reg(content) @@ -526,23 +523,20 @@ end ---@param node_or_nodes Node|Node[] function Clipboard:copy_absolute_path(node_or_nodes) - local content = "" + local content local is_single = self:is_nodes_array(node_or_nodes) == false or #node_or_nodes == 1 if is_single then local node = #node_or_nodes == 1 and node_or_nodes[0] or node_or_nodes content = self:get_absolute_path(node) else node_or_nodes = utils.filter_descendant_nodes(node_or_nodes) - for i, node in ipairs(node_or_nodes) do - if i == 1 then - content = self:get_absolute_path(node) - else - content = content .. "," .. self:get_absolute_path(node) - end + content = {} + for _, node in ipairs(node_or_nodes) do + table.insert(content, self:get_absolute_path(node)) end end - self:copy_to_reg(content, string.format("%s paths copied to register", is_single and 1 or #node_or_nodes)) + self:copy_to_reg(content, string.format("%s paths copied to register", is_single and 1 or #content)) end ---Node is cut. Will not be copied. From f79cdcb708c3aa04eae06cc79fcb67151f4bece1 Mon Sep 17 00:00:00 2001 From: uanela Date: Thu, 18 Jun 2026 10:02:52 +0200 Subject: [PATCH 21/31] refactor(clipboard): simplify copying node attribute and allow all to work in visual mode --- lua/nvim-tree/actions/fs/clipboard.lua | 83 ++++++++++++++------------ lua/nvim-tree/api/impl.lua | 8 +-- lua/nvim-tree/keymap.lua | 4 +- 3 files changed, 50 insertions(+), 45 deletions(-) diff --git a/lua/nvim-tree/actions/fs/clipboard.lua b/lua/nvim-tree/actions/fs/clipboard.lua index 6a07e1331d2..db242ddcd6c 100644 --- a/lua/nvim-tree/actions/fs/clipboard.lua +++ b/lua/nvim-tree/actions/fs/clipboard.lua @@ -462,36 +462,59 @@ function Clipboard:copy_to_reg(content, msg) end ---@param node Node -function Clipboard:copy_filename(node) +---@return string +function Clipboard:get_node_filename(node) if node.name == ".." then -- root - self:copy_to_reg(vim.fn.fnamemodify(self.explorer.absolute_path, ":t")) + return vim.fn.fnamemodify(self.explorer.absolute_path, ":t") else -- node - self:copy_to_reg(node.name) + return node.name end end ---@param node_or_nodes Node|Node[] -function Clipboard:copy_basename(node_or_nodes) +---@param attribute "absolute_path" | "basename" | "filename" | "relative_path" +function Clipboard:copy_node_attribute(node_or_nodes, attribute) local content - if self:is_nodes_array(node_or_nodes) == false or #node_or_nodes == 1 then + local node_attribute_getters = { + basename = function(n) return self:get_node_basename(n) end, + filename = function(n) return self:get_node_filename(n) end, + relative_path = function(n) return self:get_node_relative_path(n) end, + absolute_path = function(n) return self:get_node_absolute_path(n) end, + } + + local attribute_getter = node_attribute_getters[attribute] + + local is_single = self:is_nodes_array(node_or_nodes) == false + if is_single then local node = #node_or_nodes == 1 and node_or_nodes[0] or node_or_nodes - content = self:get_basename(node) + content = attribute_getter(node) else + node_or_nodes = utils.filter_descendant_nodes(node_or_nodes) content = {} for _, node in ipairs(node_or_nodes) do - table.insert(content, self:get_basename(node)) + table.insert(content, attribute_getter(node)) + end + end + + + if content ~= nil then + local message = nil + + if not is_single then + message = string.format("%s %s copied to register", #content, attribute:gsub("_", " ") .. "s") end + self:copy_to_reg(content, message) end - self:copy_to_reg(content) end ---@param node Node -function Clipboard:copy_path(node) +---@return string|nil +function Clipboard:get_node_relative_path(node) if node.name == ".." then -- root - self:copy_to_reg(utils.path_add_trailing("")) + return utils.path_add_trailing("") else -- node local absolute_path = node.absolute_path @@ -502,9 +525,9 @@ function Clipboard:copy_path(node) local relative_path = utils.path_relative(absolute_path, cwd) if node:is(DirectoryNode) then - self:copy_to_reg(utils.path_add_trailing(relative_path)) + return utils.path_add_trailing(relative_path) else - self:copy_to_reg(relative_path) + return relative_path end end end @@ -512,7 +535,7 @@ end ---@private ---@param node Node ---@return string -function Clipboard:get_absolute_path(node) +function Clipboard:get_node_absolute_path(node) if node.name == ".." then node = self.explorer end @@ -521,22 +544,16 @@ function Clipboard:get_absolute_path(node) return node.nodes ~= nil and utils.path_add_trailing(absolute_path) or absolute_path end ----@param node_or_nodes Node|Node[] -function Clipboard:copy_absolute_path(node_or_nodes) - local content - local is_single = self:is_nodes_array(node_or_nodes) == false or #node_or_nodes == 1 - if is_single then - local node = #node_or_nodes == 1 and node_or_nodes[0] or node_or_nodes - content = self:get_absolute_path(node) +---@param node Node +---@return string +function Clipboard:get_node_basename(node) + if node.name == ".." then + -- root + return vim.fn.fnamemodify(node.explorer.absolute_path, ":t:r") else - node_or_nodes = utils.filter_descendant_nodes(node_or_nodes) - content = {} - for _, node in ipairs(node_or_nodes) do - table.insert(content, self:get_absolute_path(node)) - end + -- node + return vim.fn.fnamemodify(node.name, ":r") end - - self:copy_to_reg(content, string.format("%s paths copied to register", is_single and 1 or #content)) end ---Node is cut. Will not be copied. @@ -553,16 +570,4 @@ function Clipboard:is_copied(node) return vim.tbl_contains(self.data.copy, node) end ----@param node Node ----@return string -function Clipboard:get_basename(node) - if node.name == ".." then - -- root - return vim.fn.fnamemodify(node.explorer.absolute_path, ":t:r") - else - -- node - return vim.fn.fnamemodify(node.name, ":r") - end -end - return Clipboard diff --git a/lua/nvim-tree/api/impl.lua b/lua/nvim-tree/api/impl.lua index d92b82600c8..5be33607ef0 100644 --- a/lua/nvim-tree/api/impl.lua +++ b/lua/nvim-tree/api/impl.lua @@ -155,11 +155,11 @@ function M.hydrate_post_setup(api) api.filter.toggle = e_(function(e) e.filters:toggle() end) api.fs.clear_clipboard = e_(function(e) e.clipboard:clear_clipboard() end) - api.fs.copy.absolute_path = ev(function(e, n) e.clipboard:copy_absolute_path(n) end) - api.fs.copy.basename = ev(function(e, n) e.clipboard:copy_basename(n) end) - api.fs.copy.filename = en(function(e, n) e.clipboard:copy_filename(n) end) + api.fs.copy.absolute_path = ev(function(e, n) e.clipboard:copy_node_attribute(n, "absolute_path") end) + api.fs.copy.basename = ev(function(e, n) e.clipboard:copy_node_attribute(n, "basename") end) + api.fs.copy.filename = ev(function(e, n) e.clipboard:copy_node_attribute(n, "filename") end) + api.fs.copy.relative_path = ev(function(e, n) e.clipboard:copy_node_attribute(n, "relative_path") end) api.fs.copy.node = ev(function(e, n) e.clipboard:copy(n) end) - api.fs.copy.relative_path = en(function(e, n) e.clipboard:copy_path(n) end) api.fs.create = _n(function(n) require("nvim-tree.actions.fs.create-file").fn(n) end) api.fs.cut = ev(function(e, n) e.clipboard:cut(n) end) api.fs.paste = en(function(e, n) e.clipboard:paste(n) end) diff --git a/lua/nvim-tree/keymap.lua b/lua/nvim-tree/keymap.lua index 3c4bbfd5e29..035d0064484 100644 --- a/lua/nvim-tree/keymap.lua +++ b/lua/nvim-tree/keymap.lua @@ -114,8 +114,8 @@ function M.on_attach_default(bufnr) vim.keymap.set("n", "U", api.filter.custom.toggle, opts("Toggle Filter: Custom")) vim.keymap.set("n", "W", api.tree.collapse_all, opts("Collapse All")) vim.keymap.set({ "n", "x" }, "x", api.fs.cut, opts("Cut")) - vim.keymap.set("n", "y", api.fs.copy.filename, opts("Copy Name")) - vim.keymap.set("n", "Y", api.fs.copy.relative_path, opts("Copy Relative Path")) + vim.keymap.set({ "n", "x" }, "y", api.fs.copy.filename, opts("Copy Name")) + vim.keymap.set({ "n", "x" }, "Y", api.fs.copy.relative_path, opts("Copy Relative Path")) vim.keymap.set("n", "<2-LeftMouse>", api.node.open.edit, opts("Open")) vim.keymap.set("n", "<2-RightMouse>", api.tree.change_root_to_node, opts("CD")) -- END_ON_ATTACH_DEFAULT From 356c083687a25c6449aaaf0c9d2486385905b53e Mon Sep 17 00:00:00 2001 From: uanela Date: Thu, 18 Jun 2026 10:30:09 +0200 Subject: [PATCH 22/31] refactor(keymap): remove gx, use gp to move --- lua/nvim-tree/keymap.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lua/nvim-tree/keymap.lua b/lua/nvim-tree/keymap.lua index 035d0064484..9441bde0a3d 100644 --- a/lua/nvim-tree/keymap.lua +++ b/lua/nvim-tree/keymap.lua @@ -102,8 +102,7 @@ function M.on_attach_default(bufnr) vim.keymap.set("n", "o", api.node.open.edit, opts("Open")) vim.keymap.set("n", "O", api.node.open.no_window_picker, opts("Open: No Window Picker")) vim.keymap.set("n", "p", api.fs.paste, opts("Paste")) - vim.keymap.set("n", "gp", api.fs.paste_from_register_copying, opts("Paste Using Register")) - vim.keymap.set("n", "gx", api.fs.paste_from_register_cutting, opts("Move Using Register")) + vim.keymap.set("n", "gp", api.fs.paste_while_cutting, opts("Move")) vim.keymap.set("n", "P", api.node.navigate.parent, opts("Parent Directory")) vim.keymap.set("n", "q", api.tree.close, opts("Close")) vim.keymap.set("n", "r", api.fs.rename, opts("Rename")) From 6f1b818356102965b1bd8137802d39536b13fa4a Mon Sep 17 00:00:00 2001 From: uanela Date: Thu, 18 Jun 2026 10:31:05 +0200 Subject: [PATCH 23/31] feat(clipboard): always copy/cut to register and make `p` pick local data or register data --- lua/nvim-tree/actions/fs/clipboard.lua | 41 +++++++++++++++----------- lua/nvim-tree/api/impl.lua | 3 +- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/lua/nvim-tree/actions/fs/clipboard.lua b/lua/nvim-tree/actions/fs/clipboard.lua index db242ddcd6c..bb4234498e2 100644 --- a/lua/nvim-tree/actions/fs/clipboard.lua +++ b/lua/nvim-tree/actions/fs/clipboard.lua @@ -44,10 +44,6 @@ function Clipboard:new(args) self.reg = self.explorer.opts.actions.use_system_clipboard and "+" or "1" end ----@class PasteOptions ----@field use_register? boolean ----@field cut? boolean - ---@param source string ---@param destination string ---@return boolean @@ -201,6 +197,7 @@ function Clipboard:copy(node_or_nodes) else self:bulk_clipboard(utils.filter_descendant_nodes(node_or_nodes), self.data.cut, self.data.copy, "added to") end + self:copy_node_attribute(node_or_nodes, "absolute_path", { notify = false }) end ---Cut one or more nodes @@ -213,6 +210,7 @@ function Clipboard:cut(node_or_nodes) else self:bulk_clipboard(utils.filter_descendant_nodes(node_or_nodes), self.data.copy, self.data.cut, "cut to") end + self:copy_node_attribute(node_or_nodes, "absolute_path", { notify = false }) end ---Clear clipboard for action and reload to reflect filesystem changes from paste. @@ -325,7 +323,7 @@ function Clipboard:get_nodes_from_reg() local content = vim.fn.getreg(self.reg) if #content == 0 then - return + return {} end local nodes = {} @@ -348,8 +346,7 @@ end ---@param node Node ---@param action ClipboardAction ---@param action_fn ClipboardActionFn ----@param opts? PasteOptions -function Clipboard:do_paste(node, action, action_fn, opts) +function Clipboard:do_paste(node, action, action_fn) if node.name == ".." then node = self.explorer else @@ -358,7 +355,8 @@ function Clipboard:do_paste(node, action, action_fn, opts) node = dir:last_group_node() end end - local clip = opts and opts.use_register and self:get_nodes_from_reg() or self.data[action] + local clip = #self.data[action] > 0 and self.data[action] or self:get_nodes_from_reg() + if #clip == 0 then return end @@ -426,12 +424,13 @@ end ---Paste cut (if present) or copy (if present) ---@param node Node ----@param opts? PasteOptions +---@param opts? { cut?: boolean } function Clipboard:paste(node, opts) - if self.data.cut[1] ~= nil or opts and opts.use_register and opts.cut then - self:do_paste(node, "cut", do_cut, opts) - elseif self.data.copy[1] ~= nil or opts and opts.use_register then - self:do_paste(node, "copy", do_copy, opts) + opts = opts and opts or {} + if self.data.cut[1] ~= nil or opts.cut == true then + self:do_paste(node, "cut", do_cut) + else + self:do_paste(node, "copy", do_copy) end end @@ -454,11 +453,15 @@ function Clipboard:print_clipboard() end ---@param content string ----@param msg? string -function Clipboard:copy_to_reg(content, msg) +---@param message? string +---@param opts? { notify?: boolean } +function Clipboard:copy_to_reg(content, message, opts) + opts = opts and opts or {} vim.fn.setreg(self.reg, type(content) == "table" and content or { content }, "v") - notify.info(msg or string.format("Copied %s to %s clipboard!", content, self.clipboard_name)) + if opts.notify ~= false then + notify.info(message or string.format("Copied %s to %s clipboard!", content, self.clipboard_name)) + end end ---@param node Node @@ -475,7 +478,9 @@ end ---@param node_or_nodes Node|Node[] ---@param attribute "absolute_path" | "basename" | "filename" | "relative_path" -function Clipboard:copy_node_attribute(node_or_nodes, attribute) +---@param opts? { notify?: boolean } +function Clipboard:copy_node_attribute(node_or_nodes, attribute, opts) + opts = opts and opts or {} local content local node_attribute_getters = { basename = function(n) return self:get_node_basename(n) end, @@ -505,7 +510,7 @@ function Clipboard:copy_node_attribute(node_or_nodes, attribute) if not is_single then message = string.format("%s %s copied to register", #content, attribute:gsub("_", " ") .. "s") end - self:copy_to_reg(content, message) + self:copy_to_reg(content, message, opts) end end diff --git a/lua/nvim-tree/api/impl.lua b/lua/nvim-tree/api/impl.lua index 5be33607ef0..27e05cfe52c 100644 --- a/lua/nvim-tree/api/impl.lua +++ b/lua/nvim-tree/api/impl.lua @@ -163,8 +163,7 @@ function M.hydrate_post_setup(api) api.fs.create = _n(function(n) require("nvim-tree.actions.fs.create-file").fn(n) end) api.fs.cut = ev(function(e, n) e.clipboard:cut(n) end) api.fs.paste = en(function(e, n) e.clipboard:paste(n) end) - api.fs.paste_from_register_copying = en(function(e, n) e.clipboard:paste(n, { use_register = true }) end) - api.fs.paste_from_register_cutting = en(function(e, n) e.clipboard:paste(n, { use_register = true, cut = true }) end) + api.fs.paste_while_cutting = en(function(e, n) e.clipboard:paste(n, { cut = true }) end) api.fs.print_clipboard = e_(function(e) e.clipboard:print_clipboard() end) api.fs.remove = _v(function(n) require("nvim-tree.actions.fs.remove-file").fn(n) end) api.fs.rename = _n(function(n) require("nvim-tree.actions.fs.rename-file").rename_node(n) end) From 887e6c129e69e07a9694dd69dd0b395f3ade0103 Mon Sep 17 00:00:00 2001 From: uanela Date: Thu, 18 Jun 2026 10:52:10 +0200 Subject: [PATCH 24/31] refactor(docs): update api docs and rename paste_while_cutting to move --- doc/nvim-tree-lua.txt | 14 ++++++-------- lua/nvim-tree/api/impl.lua | 2 +- lua/nvim-tree/keymap.lua | 2 +- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index e25904e703a..4cb37117cc4 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -154,8 +154,7 @@ Show the mappings: `g?` `o` n Open |nvim_tree.api.node.open.edit()| `O` n Open: No Window Picker |nvim_tree.api.node.open.no_window_picker()| `p` n Paste |nvim_tree.api.fs.paste()| - `gp` n Paste Using Register |nvim_tree.api.fs.paste_from_register_copying()| - `gx` n Move Using Register |nvim_tree.api.fs.paste_from_register_cutting()| + `gp` n Move |nvim_tree.api.fs.move()| `P` n Parent Directory |nvim_tree.api.node.navigate.parent()| `q` n Close |nvim_tree.api.tree.close()| `r` n Rename |nvim_tree.api.fs.rename()| @@ -166,8 +165,8 @@ Show the mappings: `g?` `U` n Toggle Filter: Custom |nvim_tree.api.filter.custom.toggle()| `W` n Collapse All |nvim_tree.api.tree.collapse_all()| `x` nx Cut |nvim_tree.api.fs.cut()| - `y` n Copy Name |nvim_tree.api.fs.copy.filename()| - `Y` n Copy Relative Path |nvim_tree.api.fs.copy.relative_path()| + `y` nx Copy Name |nvim_tree.api.fs.copy.filename()| + `Y` nx Copy Relative Path |nvim_tree.api.fs.copy.relative_path()| `<2-LeftMouse>` n Open |nvim_tree.api.node.open.edit()| `<2-RightMouse>` n CD |nvim_tree.api.tree.change_root_to_node()| @@ -449,8 +448,7 @@ You are encouraged to copy these to your {on_attach} function. >lua vim.keymap.set("n", "o", api.node.open.edit, opts("Open")) vim.keymap.set("n", "O", api.node.open.no_window_picker, opts("Open: No Window Picker")) vim.keymap.set("n", "p", api.fs.paste, opts("Paste")) - vim.keymap.set("n", "gp", api.fs.paste_from_register_copying, opts("Paste Using Register")) - vim.keymap.set("n", "gx", api.fs.paste_from_register_cutting, opts("Move Using Register")) + vim.keymap.set("n", "gp", api.fs.move, opts("Move")) vim.keymap.set("n", "P", api.node.navigate.parent, opts("Parent Directory")) vim.keymap.set("n", "q", api.tree.close, opts("Close")) vim.keymap.set("n", "r", api.fs.rename, opts("Rename")) @@ -461,8 +459,8 @@ You are encouraged to copy these to your {on_attach} function. >lua vim.keymap.set("n", "U", api.filter.custom.toggle, opts("Toggle Filter: Custom")) vim.keymap.set("n", "W", api.tree.collapse_all, opts("Collapse All")) vim.keymap.set({ "n", "x" }, "x", api.fs.cut, opts("Cut")) - vim.keymap.set("n", "y", api.fs.copy.filename, opts("Copy Name")) - vim.keymap.set("n", "Y", api.fs.copy.relative_path, opts("Copy Relative Path")) + vim.keymap.set({ "n", "x" }, "y", api.fs.copy.filename, opts("Copy Name")) + vim.keymap.set({ "n", "x" }, "Y", api.fs.copy.relative_path, opts("Copy Relative Path")) vim.keymap.set("n", "<2-LeftMouse>", api.node.open.edit, opts("Open")) vim.keymap.set("n", "<2-RightMouse>", api.tree.change_root_to_node, opts("CD")) -- END_ON_ATTACH_DEFAULT diff --git a/lua/nvim-tree/api/impl.lua b/lua/nvim-tree/api/impl.lua index 27e05cfe52c..4f697713603 100644 --- a/lua/nvim-tree/api/impl.lua +++ b/lua/nvim-tree/api/impl.lua @@ -163,7 +163,7 @@ function M.hydrate_post_setup(api) api.fs.create = _n(function(n) require("nvim-tree.actions.fs.create-file").fn(n) end) api.fs.cut = ev(function(e, n) e.clipboard:cut(n) end) api.fs.paste = en(function(e, n) e.clipboard:paste(n) end) - api.fs.paste_while_cutting = en(function(e, n) e.clipboard:paste(n, { cut = true }) end) + api.fs.move = en(function(e, n) e.clipboard:paste(n, { cut = true }) end) api.fs.print_clipboard = e_(function(e) e.clipboard:print_clipboard() end) api.fs.remove = _v(function(n) require("nvim-tree.actions.fs.remove-file").fn(n) end) api.fs.rename = _n(function(n) require("nvim-tree.actions.fs.rename-file").rename_node(n) end) diff --git a/lua/nvim-tree/keymap.lua b/lua/nvim-tree/keymap.lua index 9441bde0a3d..6666441e187 100644 --- a/lua/nvim-tree/keymap.lua +++ b/lua/nvim-tree/keymap.lua @@ -102,7 +102,7 @@ function M.on_attach_default(bufnr) vim.keymap.set("n", "o", api.node.open.edit, opts("Open")) vim.keymap.set("n", "O", api.node.open.no_window_picker, opts("Open: No Window Picker")) vim.keymap.set("n", "p", api.fs.paste, opts("Paste")) - vim.keymap.set("n", "gp", api.fs.paste_while_cutting, opts("Move")) + vim.keymap.set("n", "gp", api.fs.move, opts("Move")) vim.keymap.set("n", "P", api.node.navigate.parent, opts("Parent Directory")) vim.keymap.set("n", "q", api.tree.close, opts("Close")) vim.keymap.set("n", "r", api.fs.rename, opts("Rename")) From 859f733ea38cce5b830a65bae8243473fd0234e9 Mon Sep 17 00:00:00 2001 From: uanela Date: Thu, 18 Jun 2026 10:57:55 +0200 Subject: [PATCH 25/31] fix: correctly format keymaps --- lua/nvim-tree/keymap.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/nvim-tree/keymap.lua b/lua/nvim-tree/keymap.lua index 6666441e187..3250470db70 100644 --- a/lua/nvim-tree/keymap.lua +++ b/lua/nvim-tree/keymap.lua @@ -102,7 +102,7 @@ function M.on_attach_default(bufnr) vim.keymap.set("n", "o", api.node.open.edit, opts("Open")) vim.keymap.set("n", "O", api.node.open.no_window_picker, opts("Open: No Window Picker")) vim.keymap.set("n", "p", api.fs.paste, opts("Paste")) - vim.keymap.set("n", "gp", api.fs.move, opts("Move")) + vim.keymap.set("n", "gp", api.fs.move, opts("Move")) vim.keymap.set("n", "P", api.node.navigate.parent, opts("Parent Directory")) vim.keymap.set("n", "q", api.tree.close, opts("Close")) vim.keymap.set("n", "r", api.fs.rename, opts("Rename")) From b1662a5d06689e55ea468e1ce9f184579163c334 Mon Sep 17 00:00:00 2001 From: uanela Date: Thu, 18 Jun 2026 11:01:35 +0200 Subject: [PATCH 26/31] chore: regenerate docs --- doc/nvim-tree-lua.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 4cb37117cc4..baae74b0003 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -448,7 +448,7 @@ You are encouraged to copy these to your {on_attach} function. >lua vim.keymap.set("n", "o", api.node.open.edit, opts("Open")) vim.keymap.set("n", "O", api.node.open.no_window_picker, opts("Open: No Window Picker")) vim.keymap.set("n", "p", api.fs.paste, opts("Paste")) - vim.keymap.set("n", "gp", api.fs.move, opts("Move")) + vim.keymap.set("n", "gp", api.fs.move, opts("Move")) vim.keymap.set("n", "P", api.node.navigate.parent, opts("Parent Directory")) vim.keymap.set("n", "q", api.tree.close, opts("Close")) vim.keymap.set("n", "r", api.fs.rename, opts("Rename")) From fa2b18661ced0ef83c0e3ef12dfad2056c736c5f Mon Sep 17 00:00:00 2001 From: uanela Date: Mon, 22 Jun 2026 08:57:05 +0200 Subject: [PATCH 27/31] fix: remove unused apis --- lua/nvim-tree/_meta/api/fs.lua | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/lua/nvim-tree/_meta/api/fs.lua b/lua/nvim-tree/_meta/api/fs.lua index d58cc8248d2..dfab8610434 100644 --- a/lua/nvim-tree/_meta/api/fs.lua +++ b/lua/nvim-tree/_meta/api/fs.lua @@ -66,18 +66,6 @@ function nvim_tree.api.fs.cut(node) end ---@param node? nvim_tree.api.Node function nvim_tree.api.fs.paste(node) end ---- ----Paste nodes from the system register as files to nvim-tree while copying. ---- ----@param node_or_nodes? nvim_tree.api.Node | nvim_tree.api.Node[] -function nvim_tree.api.fs.paste_from_register_copying(node_or_nodes) end - ---- ----Paste nodes from the system register as files to nvim-tree while cutting. ---- ----@param node_or_nodes? nvim_tree.api.Node | nvim_tree.api.Node[] -function nvim_tree.api.fs.paste_from_register_cutting(node_or_nodes) end - --- ---Print the contents of the nvim-tree clipboard. --- From 4bd13ec53b91871490dc72e0a32b9008b9ca51a4 Mon Sep 17 00:00:00 2001 From: uanela Date: Mon, 22 Jun 2026 08:58:50 +0200 Subject: [PATCH 28/31] chore: copy clipboard.data to register on copy/cut --- lua/nvim-tree/actions/fs/clipboard.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/nvim-tree/actions/fs/clipboard.lua b/lua/nvim-tree/actions/fs/clipboard.lua index bb4234498e2..66368d6d67c 100644 --- a/lua/nvim-tree/actions/fs/clipboard.lua +++ b/lua/nvim-tree/actions/fs/clipboard.lua @@ -197,7 +197,7 @@ function Clipboard:copy(node_or_nodes) else self:bulk_clipboard(utils.filter_descendant_nodes(node_or_nodes), self.data.cut, self.data.copy, "added to") end - self:copy_node_attribute(node_or_nodes, "absolute_path", { notify = false }) + self:copy_absolute_path(self.data.copy, { notify = false }) end ---Cut one or more nodes @@ -210,7 +210,7 @@ function Clipboard:cut(node_or_nodes) else self:bulk_clipboard(utils.filter_descendant_nodes(node_or_nodes), self.data.copy, self.data.cut, "cut to") end - self:copy_node_attribute(node_or_nodes, "absolute_path", { notify = false }) + self:copy_absolute_path(self.data.cut, { notify = false }) end ---Clear clipboard for action and reload to reflect filesystem changes from paste. From 062a2d280018085195756742ee1b78e89537963a Mon Sep 17 00:00:00 2001 From: uanela Date: Mon, 22 Jun 2026 08:59:51 +0200 Subject: [PATCH 29/31] chore: revert copy_node_attribute --- lua/nvim-tree/actions/fs/clipboard.lua | 97 ++++++++++++-------------- lua/nvim-tree/api/impl.lua | 8 +-- 2 files changed, 47 insertions(+), 58 deletions(-) diff --git a/lua/nvim-tree/actions/fs/clipboard.lua b/lua/nvim-tree/actions/fs/clipboard.lua index 66368d6d67c..e7281918782 100644 --- a/lua/nvim-tree/actions/fs/clipboard.lua +++ b/lua/nvim-tree/actions/fs/clipboard.lua @@ -465,61 +465,34 @@ function Clipboard:copy_to_reg(content, message, opts) end ---@param node Node ----@return string -function Clipboard:get_node_filename(node) +function Clipboard:copy_filename(node) if node.name == ".." then -- root - return vim.fn.fnamemodify(self.explorer.absolute_path, ":t") + self:copy_to_reg(vim.fn.fnamemodify(self.explorer.absolute_path, ":t")) else -- node - return node.name + self:copy_to_reg(node.name) end end ----@param node_or_nodes Node|Node[] ----@param attribute "absolute_path" | "basename" | "filename" | "relative_path" ----@param opts? { notify?: boolean } -function Clipboard:copy_node_attribute(node_or_nodes, attribute, opts) - opts = opts and opts or {} - local content - local node_attribute_getters = { - basename = function(n) return self:get_node_basename(n) end, - filename = function(n) return self:get_node_filename(n) end, - relative_path = function(n) return self:get_node_relative_path(n) end, - absolute_path = function(n) return self:get_node_absolute_path(n) end, - } - - local attribute_getter = node_attribute_getters[attribute] - - local is_single = self:is_nodes_array(node_or_nodes) == false - if is_single then - local node = #node_or_nodes == 1 and node_or_nodes[0] or node_or_nodes - content = attribute_getter(node) - else - node_or_nodes = utils.filter_descendant_nodes(node_or_nodes) - content = {} - for _, node in ipairs(node_or_nodes) do - table.insert(content, attribute_getter(node)) - end +---@private +---@param node Node +---@return string +function Clipboard:get_absolute_path(node) + if node.name == ".." then + node = self.explorer end - - if content ~= nil then - local message = nil - - if not is_single then - message = string.format("%s %s copied to register", #content, attribute:gsub("_", " ") .. "s") - end - self:copy_to_reg(content, message, opts) - end + local absolute_path = node.absolute_path + return node.nodes ~= nil and utils.path_add_trailing(absolute_path) or absolute_path end ---@param node Node ---@return string|nil -function Clipboard:get_node_relative_path(node) +function Clipboard:copy_path(node) if node.name == ".." then -- root - return utils.path_add_trailing("") + self:copy_to_reg(utils.path_add_trailing("")) else -- node local absolute_path = node.absolute_path @@ -530,34 +503,50 @@ function Clipboard:get_node_relative_path(node) local relative_path = utils.path_relative(absolute_path, cwd) if node:is(DirectoryNode) then - return utils.path_add_trailing(relative_path) + self:copy_to_reg(utils.path_add_trailing(relative_path)) else - return relative_path + self:copy_to_reg(relative_path) end end end ----@private ----@param node Node ----@return string -function Clipboard:get_node_absolute_path(node) - if node.name == ".." then - node = self.explorer +---@param node_or_nodes Node|Node[] +---@param opts? { notify?: boolean } +function Clipboard:copy_absolute_path(node_or_nodes, opts) + opts = opts and opts or {} + local content + + local is_single = self:is_nodes_array(node_or_nodes) == false + if is_single then + local node = #node_or_nodes == 1 and node_or_nodes[0] or node_or_nodes + content = self:get_absolute_path(node) + else + node_or_nodes = utils.filter_descendant_nodes(node_or_nodes) + content = {} + for _, node in ipairs(node_or_nodes) do + table.insert(content, self:get_absolute_path(node)) + end end - local absolute_path = node.absolute_path - return node.nodes ~= nil and utils.path_add_trailing(absolute_path) or absolute_path + + if content ~= nil then + local message = nil + + if not is_single then + message = string.format("%s %s copied to register", #content, #content > 1 and "absolute paths" or "absolute path") + end + self:copy_to_reg(content, message, opts) + end end ---@param node Node ----@return string -function Clipboard:get_node_basename(node) +function Clipboard:copy_basename(node) if node.name == ".." then -- root - return vim.fn.fnamemodify(node.explorer.absolute_path, ":t:r") + self:copy_to_reg(vim.fn.fnamemodify(node.explorer.absolute_path, ":t:r")) else -- node - return vim.fn.fnamemodify(node.name, ":r") + self:copy_to_reg(vim.fn.fnamemodify(node.name, ":r")) end end diff --git a/lua/nvim-tree/api/impl.lua b/lua/nvim-tree/api/impl.lua index 4f697713603..7e0f32192b6 100644 --- a/lua/nvim-tree/api/impl.lua +++ b/lua/nvim-tree/api/impl.lua @@ -155,10 +155,10 @@ function M.hydrate_post_setup(api) api.filter.toggle = e_(function(e) e.filters:toggle() end) api.fs.clear_clipboard = e_(function(e) e.clipboard:clear_clipboard() end) - api.fs.copy.absolute_path = ev(function(e, n) e.clipboard:copy_node_attribute(n, "absolute_path") end) - api.fs.copy.basename = ev(function(e, n) e.clipboard:copy_node_attribute(n, "basename") end) - api.fs.copy.filename = ev(function(e, n) e.clipboard:copy_node_attribute(n, "filename") end) - api.fs.copy.relative_path = ev(function(e, n) e.clipboard:copy_node_attribute(n, "relative_path") end) + api.fs.copy.absolute_path = ev(function(e, n) e.clipboard:copy_absolute_path(n) end) + api.fs.copy.basename = en(function(e, n) e.clipboard:copy_basename(n) end) + api.fs.copy.filename = en(function(e, n) e.clipboard:copy_filename(n) end) + api.fs.copy.relative_path = en(function(e, n) e.clipboard:copy_path(n) end) api.fs.copy.node = ev(function(e, n) e.clipboard:copy(n) end) api.fs.create = _n(function(n) require("nvim-tree.actions.fs.create-file").fn(n) end) api.fs.cut = ev(function(e, n) e.clipboard:cut(n) end) From f10f779baf1348eea021d018ba0edca7a9d41889 Mon Sep 17 00:00:00 2001 From: uanela Date: Mon, 22 Jun 2026 09:00:31 +0200 Subject: [PATCH 30/31] refactor: remove visual mode from copy.basename|filename|path --- lua/nvim-tree/_meta/config/actions.lua | 2 ++ lua/nvim-tree/keymap.lua | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lua/nvim-tree/_meta/config/actions.lua b/lua/nvim-tree/_meta/config/actions.lua index 8b9891f66d8..012f4c364d9 100644 --- a/lua/nvim-tree/_meta/config/actions.lua +++ b/lua/nvim-tree/_meta/config/actions.lua @@ -24,6 +24,8 @@ error("Cannot require a meta file") ---[nvim_tree.config.actions.remove_file] ---@field remove_file? nvim_tree.config.actions.remove_file + + --- vim [current-directory] behaviour ---@class nvim_tree.config.actions.change_dir --- diff --git a/lua/nvim-tree/keymap.lua b/lua/nvim-tree/keymap.lua index 3250470db70..4516eda542d 100644 --- a/lua/nvim-tree/keymap.lua +++ b/lua/nvim-tree/keymap.lua @@ -91,7 +91,7 @@ function M.on_attach_default(bufnr) vim.keymap.set("n", "f", api.filter.live.start, opts("Live Filter: Start")) vim.keymap.set("n", "g?", api.tree.toggle_help, opts("Help")) vim.keymap.set({ "n", "x" }, "gy", api.fs.copy.absolute_path, opts("Copy Absolute Path")) - vim.keymap.set({ "n", "x" }, "ge", api.fs.copy.basename, opts("Copy Basename")) + vim.keymap.set("n", "ge", api.fs.copy.basename, opts("Copy Basename")) vim.keymap.set("n", "H", api.filter.dotfiles.toggle, opts("Toggle Filter: Dotfiles")) vim.keymap.set("n", "I", api.filter.git.ignored.toggle, opts("Toggle Filter: Git Ignored")) vim.keymap.set("n", "J", api.node.navigate.sibling.last, opts("Last Sibling")) @@ -113,8 +113,8 @@ function M.on_attach_default(bufnr) vim.keymap.set("n", "U", api.filter.custom.toggle, opts("Toggle Filter: Custom")) vim.keymap.set("n", "W", api.tree.collapse_all, opts("Collapse All")) vim.keymap.set({ "n", "x" }, "x", api.fs.cut, opts("Cut")) - vim.keymap.set({ "n", "x" }, "y", api.fs.copy.filename, opts("Copy Name")) - vim.keymap.set({ "n", "x" }, "Y", api.fs.copy.relative_path, opts("Copy Relative Path")) + vim.keymap.set("n", "y", api.fs.copy.filename, opts("Copy Name")) + vim.keymap.set("n", "Y", api.fs.copy.relative_path, opts("Copy Relative Path")) vim.keymap.set("n", "<2-LeftMouse>", api.node.open.edit, opts("Open")) vim.keymap.set("n", "<2-RightMouse>", api.tree.change_root_to_node, opts("CD")) -- END_ON_ATTACH_DEFAULT From 1b6737155aa0f4fdb14840dfecfffff2eac16eaf Mon Sep 17 00:00:00 2001 From: uanela Date: Mon, 22 Jun 2026 09:06:33 +0200 Subject: [PATCH 31/31] chore: update docs --- doc/nvim-tree-lua.txt | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index baae74b0003..c0a2745a7a6 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -143,7 +143,7 @@ Show the mappings: `g?` `f` n Live Filter: Start |nvim_tree.api.filter.live.start()| `g?` n Help |nvim_tree.api.tree.toggle_help()| `gy` nx Copy Absolute Path |nvim_tree.api.fs.copy.absolute_path()| - `ge` nx Copy Basename |nvim_tree.api.fs.copy.basename()| + `ge` n Copy Basename |nvim_tree.api.fs.copy.basename()| `H` n Toggle Filter: Dotfiles |nvim_tree.api.filter.dotfiles.toggle()| `I` n Toggle Filter: Git Ignored |nvim_tree.api.filter.git.ignored.toggle()| `J` n Last Sibling |nvim_tree.api.node.navigate.sibling.last()| @@ -165,8 +165,8 @@ Show the mappings: `g?` `U` n Toggle Filter: Custom |nvim_tree.api.filter.custom.toggle()| `W` n Collapse All |nvim_tree.api.tree.collapse_all()| `x` nx Cut |nvim_tree.api.fs.cut()| - `y` nx Copy Name |nvim_tree.api.fs.copy.filename()| - `Y` nx Copy Relative Path |nvim_tree.api.fs.copy.relative_path()| + `y` n Copy Name |nvim_tree.api.fs.copy.filename()| + `Y` n Copy Relative Path |nvim_tree.api.fs.copy.relative_path()| `<2-LeftMouse>` n Open |nvim_tree.api.node.open.edit()| `<2-RightMouse>` n CD |nvim_tree.api.tree.change_root_to_node()| @@ -437,7 +437,7 @@ You are encouraged to copy these to your {on_attach} function. >lua vim.keymap.set("n", "f", api.filter.live.start, opts("Live Filter: Start")) vim.keymap.set("n", "g?", api.tree.toggle_help, opts("Help")) vim.keymap.set({ "n", "x" }, "gy", api.fs.copy.absolute_path, opts("Copy Absolute Path")) - vim.keymap.set({ "n", "x" }, "ge", api.fs.copy.basename, opts("Copy Basename")) + vim.keymap.set("n", "ge", api.fs.copy.basename, opts("Copy Basename")) vim.keymap.set("n", "H", api.filter.dotfiles.toggle, opts("Toggle Filter: Dotfiles")) vim.keymap.set("n", "I", api.filter.git.ignored.toggle, opts("Toggle Filter: Git Ignored")) vim.keymap.set("n", "J", api.node.navigate.sibling.last, opts("Last Sibling")) @@ -459,8 +459,8 @@ You are encouraged to copy these to your {on_attach} function. >lua vim.keymap.set("n", "U", api.filter.custom.toggle, opts("Toggle Filter: Custom")) vim.keymap.set("n", "W", api.tree.collapse_all, opts("Collapse All")) vim.keymap.set({ "n", "x" }, "x", api.fs.cut, opts("Cut")) - vim.keymap.set({ "n", "x" }, "y", api.fs.copy.filename, opts("Copy Name")) - vim.keymap.set({ "n", "x" }, "Y", api.fs.copy.relative_path, opts("Copy Relative Path")) + vim.keymap.set("n", "y", api.fs.copy.filename, opts("Copy Name")) + vim.keymap.set("n", "Y", api.fs.copy.relative_path, opts("Copy Relative Path")) vim.keymap.set("n", "<2-LeftMouse>", api.node.open.edit, opts("Open")) vim.keymap.set("n", "<2-RightMouse>", api.tree.change_root_to_node, opts("CD")) -- END_ON_ATTACH_DEFAULT @@ -2469,20 +2469,6 @@ paste({node}) *nvim_tree.api.fs.paste()* Parameters: ~ • {node} (`nvim_tree.api.Node?`) - *nvim_tree.api.fs.paste_from_register_copying()* -paste_from_register_copying({node_or_nodes}) - Paste nodes from the system register as files to nvim-tree while copying. - - Parameters: ~ - • {node_or_nodes} (`nvim_tree.api.Node|nvim_tree.api.Node[]?`) - - *nvim_tree.api.fs.paste_from_register_cutting()* -paste_from_register_cutting({node_or_nodes}) - Paste nodes from the system register as files to nvim-tree while cutting. - - Parameters: ~ - • {node_or_nodes} (`nvim_tree.api.Node|nvim_tree.api.Node[]?`) - print_clipboard() *nvim_tree.api.fs.print_clipboard()* Print the contents of the nvim-tree clipboard.