Skip to content

Commit f79cdcb

Browse files
committed
refactor(clipboard): simplify copying node attribute and allow all to work in visual mode
1 parent ba8e7a1 commit f79cdcb

3 files changed

Lines changed: 50 additions & 45 deletions

File tree

lua/nvim-tree/actions/fs/clipboard.lua

Lines changed: 44 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -462,36 +462,59 @@ function Clipboard:copy_to_reg(content, msg)
462462
end
463463

464464
---@param node Node
465-
function Clipboard:copy_filename(node)
465+
---@return string
466+
function Clipboard:get_node_filename(node)
466467
if node.name == ".." then
467468
-- root
468-
self:copy_to_reg(vim.fn.fnamemodify(self.explorer.absolute_path, ":t"))
469+
return vim.fn.fnamemodify(self.explorer.absolute_path, ":t")
469470
else
470471
-- node
471-
self:copy_to_reg(node.name)
472+
return node.name
472473
end
473474
end
474475

475476
---@param node_or_nodes Node|Node[]
476-
function Clipboard:copy_basename(node_or_nodes)
477+
---@param attribute "absolute_path" | "basename" | "filename" | "relative_path"
478+
function Clipboard:copy_node_attribute(node_or_nodes, attribute)
477479
local content
478-
if self:is_nodes_array(node_or_nodes) == false or #node_or_nodes == 1 then
480+
local node_attribute_getters = {
481+
basename = function(n) return self:get_node_basename(n) end,
482+
filename = function(n) return self:get_node_filename(n) end,
483+
relative_path = function(n) return self:get_node_relative_path(n) end,
484+
absolute_path = function(n) return self:get_node_absolute_path(n) end,
485+
}
486+
487+
local attribute_getter = node_attribute_getters[attribute]
488+
489+
local is_single = self:is_nodes_array(node_or_nodes) == false
490+
if is_single then
479491
local node = #node_or_nodes == 1 and node_or_nodes[0] or node_or_nodes
480-
content = self:get_basename(node)
492+
content = attribute_getter(node)
481493
else
494+
node_or_nodes = utils.filter_descendant_nodes(node_or_nodes)
482495
content = {}
483496
for _, node in ipairs(node_or_nodes) do
484-
table.insert(content, self:get_basename(node))
497+
table.insert(content, attribute_getter(node))
498+
end
499+
end
500+
501+
502+
if content ~= nil then
503+
local message = nil
504+
505+
if not is_single then
506+
message = string.format("%s %s copied to register", #content, attribute:gsub("_", " ") .. "s")
485507
end
508+
self:copy_to_reg(content, message)
486509
end
487-
self:copy_to_reg(content)
488510
end
489511

490512
---@param node Node
491-
function Clipboard:copy_path(node)
513+
---@return string|nil
514+
function Clipboard:get_node_relative_path(node)
492515
if node.name == ".." then
493516
-- root
494-
self:copy_to_reg(utils.path_add_trailing(""))
517+
return utils.path_add_trailing("")
495518
else
496519
-- node
497520
local absolute_path = node.absolute_path
@@ -502,17 +525,17 @@ function Clipboard:copy_path(node)
502525

503526
local relative_path = utils.path_relative(absolute_path, cwd)
504527
if node:is(DirectoryNode) then
505-
self:copy_to_reg(utils.path_add_trailing(relative_path))
528+
return utils.path_add_trailing(relative_path)
506529
else
507-
self:copy_to_reg(relative_path)
530+
return relative_path
508531
end
509532
end
510533
end
511534

512535
---@private
513536
---@param node Node
514537
---@return string
515-
function Clipboard:get_absolute_path(node)
538+
function Clipboard:get_node_absolute_path(node)
516539
if node.name == ".." then
517540
node = self.explorer
518541
end
@@ -521,22 +544,16 @@ function Clipboard:get_absolute_path(node)
521544
return node.nodes ~= nil and utils.path_add_trailing(absolute_path) or absolute_path
522545
end
523546

524-
---@param node_or_nodes Node|Node[]
525-
function Clipboard:copy_absolute_path(node_or_nodes)
526-
local content
527-
local is_single = self:is_nodes_array(node_or_nodes) == false or #node_or_nodes == 1
528-
if is_single then
529-
local node = #node_or_nodes == 1 and node_or_nodes[0] or node_or_nodes
530-
content = self:get_absolute_path(node)
547+
---@param node Node
548+
---@return string
549+
function Clipboard:get_node_basename(node)
550+
if node.name == ".." then
551+
-- root
552+
return vim.fn.fnamemodify(node.explorer.absolute_path, ":t:r")
531553
else
532-
node_or_nodes = utils.filter_descendant_nodes(node_or_nodes)
533-
content = {}
534-
for _, node in ipairs(node_or_nodes) do
535-
table.insert(content, self:get_absolute_path(node))
536-
end
554+
-- node
555+
return vim.fn.fnamemodify(node.name, ":r")
537556
end
538-
539-
self:copy_to_reg(content, string.format("%s paths copied to register", is_single and 1 or #content))
540557
end
541558

542559
---Node is cut. Will not be copied.
@@ -553,16 +570,4 @@ function Clipboard:is_copied(node)
553570
return vim.tbl_contains(self.data.copy, node)
554571
end
555572

556-
---@param node Node
557-
---@return string
558-
function Clipboard:get_basename(node)
559-
if node.name == ".." then
560-
-- root
561-
return vim.fn.fnamemodify(node.explorer.absolute_path, ":t:r")
562-
else
563-
-- node
564-
return vim.fn.fnamemodify(node.name, ":r")
565-
end
566-
end
567-
568573
return Clipboard

lua/nvim-tree/api/impl.lua

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,11 @@ function M.hydrate_post_setup(api)
155155
api.filter.toggle = e_(function(e) e.filters:toggle() end)
156156

157157
api.fs.clear_clipboard = e_(function(e) e.clipboard:clear_clipboard() end)
158-
api.fs.copy.absolute_path = ev(function(e, n) e.clipboard:copy_absolute_path(n) end)
159-
api.fs.copy.basename = ev(function(e, n) e.clipboard:copy_basename(n) end)
160-
api.fs.copy.filename = en(function(e, n) e.clipboard:copy_filename(n) end)
158+
api.fs.copy.absolute_path = ev(function(e, n) e.clipboard:copy_node_attribute(n, "absolute_path") end)
159+
api.fs.copy.basename = ev(function(e, n) e.clipboard:copy_node_attribute(n, "basename") end)
160+
api.fs.copy.filename = ev(function(e, n) e.clipboard:copy_node_attribute(n, "filename") end)
161+
api.fs.copy.relative_path = ev(function(e, n) e.clipboard:copy_node_attribute(n, "relative_path") end)
161162
api.fs.copy.node = ev(function(e, n) e.clipboard:copy(n) end)
162-
api.fs.copy.relative_path = en(function(e, n) e.clipboard:copy_path(n) end)
163163
api.fs.create = _n(function(n) require("nvim-tree.actions.fs.create-file").fn(n) end)
164164
api.fs.cut = ev(function(e, n) e.clipboard:cut(n) end)
165165
api.fs.paste = en(function(e, n) e.clipboard:paste(n) end)

lua/nvim-tree/keymap.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ function M.on_attach_default(bufnr)
114114
vim.keymap.set("n", "U", api.filter.custom.toggle, opts("Toggle Filter: Custom"))
115115
vim.keymap.set("n", "W", api.tree.collapse_all, opts("Collapse All"))
116116
vim.keymap.set({ "n", "x" }, "x", api.fs.cut, opts("Cut"))
117-
vim.keymap.set("n", "y", api.fs.copy.filename, opts("Copy Name"))
118-
vim.keymap.set("n", "Y", api.fs.copy.relative_path, opts("Copy Relative Path"))
117+
vim.keymap.set({ "n", "x" }, "y", api.fs.copy.filename, opts("Copy Name"))
118+
vim.keymap.set({ "n", "x" }, "Y", api.fs.copy.relative_path, opts("Copy Relative Path"))
119119
vim.keymap.set("n", "<2-LeftMouse>", api.node.open.edit, opts("Open"))
120120
vim.keymap.set("n", "<2-RightMouse>", api.tree.change_root_to_node, opts("CD"))
121121
-- END_ON_ATTACH_DEFAULT

0 commit comments

Comments
 (0)