Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions lua/nvim-tree/actions/fs/rename-file.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ local utils = require("nvim-tree.utils")
local events = require("nvim-tree.events")
local notify = require("nvim-tree.notify")
local config = require("nvim-tree.config")
local lib = require("nvim-tree.lib")

local find_file = require("nvim-tree.actions.finders.find-file").fn

Expand Down Expand Up @@ -47,7 +48,9 @@ end

---@param node Node
---@param to string
function M.rename(node, to)
---@param opts? { notify?: boolean }
function M.rename(node, to, opts)
opts = opts and opts or {}
local notify_from = notify.render_path(node.absolute_path)
local notify_to = notify.render_path(to)

Expand Down Expand Up @@ -92,7 +95,9 @@ function M.rename(node, to)
end

if not is_error then
notify.info(string.format("%s -> %s", notify_from, notify_to))
if opts.notify ~= false then
notify.info(string.format("%s -> %s", notify_from, notify_to))
end
utils.rename_loaded_buffers(node.absolute_path, to)
events._dispatch_node_renamed(node.absolute_path, to)
end
Expand Down Expand Up @@ -192,4 +197,24 @@ function M.rename_full(node)
prompt_to_rename(node, ":p")
end

---@param nodes Node[]
---@param old_part string
---@param new_part string
function M.bulk_rename(nodes, old_part, new_part)
local prompt_select = string.format("Substitute '%s' for '%s' in %s files?", old_part, new_part, #nodes)

lib.prompt(prompt_select .. " Y/n: ", prompt_select, ({ "", "y" }), { "No", "Yes" }, "nvimtree_bulk_rename", function(answer)
utils.clear_prompt()
if answer == "n" then return end

for _, node in ipairs(nodes) do
local new_name = node.name:gsub(old_part, new_part)
local new_full_path = vim.fn.fnamemodify(node.absolute_path, ":h") .. "/" .. new_name
M.rename(node, new_full_path, { notify = false })
end

notify.info(string.format("%s nodes substituted from %s -> %s", #nodes, old_part, new_part))
end)
end

return M
46 changes: 46 additions & 0 deletions lua/nvim-tree/autocmd.lua
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,52 @@ function M.global()
end,
})
end

vim.api.nvim_create_autocmd("CmdlineLeave", {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Firstly, I apologise for the state of autocommands. Having them all in one place is not desirable, and was done purely for startup performance.

Fortunately, this does not have to be a global - it can be placed in it's correct place - rename-file.lua

It can be created when needed i.e. user invokes bulk_rename and removed once the operation is complete. We could probably automatically clean it up after it is done via the {once} option of :help nvim_create_autocmd(). See help.lua for an example.

group = augroup_id,
pattern = ":",
callback = function(ev)
if require("nvim-tree.view").get_bufnr() == ev.buf then
local cmd = vim.fn.getcmdline()

if cmd:match("s([^%w])") then
local delimiter = cmd:match("s([^%w])")
local escaped_delim = delimiter:gsub("[%%%.%+%-%*%?%^%$%(%)%[%]]", "%%%1")

-- Looks for: s <delimiter> <old> <delimiter> <new> <delimiter or end>
local pattern = "s" .. escaped_delim .. "([^" .. escaped_delim .. "]*)" .. escaped_delim .. "([^" .. escaped_delim .. "]*)"

local old_part, new_part = cmd:match(pattern)

local core = require("nvim-tree.core")
local explorer = core.get_explorer()
local utils = require("nvim-tree.utils")
Comment on lines +160 to +162

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

rename-file.lua already has these, so we should be able to remove these lines 🤞

local bulk_rename = require("nvim-tree.actions.fs.rename-file").bulk_rename

local visual_marker = "'<,'>"
local nodes = cmd:sub(1, #visual_marker) == visual_marker and
utils.get_visual_nodes({ use_native = true, should_exit = false }) or
explorer and explorer:get_nodes_by_line(core.get_nodes_starting_line()) or {}
local matching_nodes = {}

for i = #nodes, 1, -1 do
local node = nodes[i]
if node and node.name:find(old_part) ~= nil then
table.insert(matching_nodes, node)
end
end

if #matching_nodes > 0 then
bulk_rename(matching_nodes, old_part, new_part)
else
require("nvim-tree.notify").notify(string.format("Not matching nodes with '%s'", old_part))
end

vim.fn.setcmdline("")
end
end
end
})
end

return M
14 changes: 10 additions & 4 deletions lua/nvim-tree/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -527,19 +527,25 @@ function M.exit_visual_mode()
end

---Get the visual selection range nodes, exiting visual mode.
---@param opts? { should_exit?: boolean, use_native?: boolean }
---@return Node[]?
function M.get_visual_nodes()
function M.get_visual_nodes(opts)
opts = opts and opts or {}

local explorer = require("nvim-tree.core").get_explorer()
if not explorer then
return nil
end
local start_line = vim.fn.line("v")
local end_line = vim.fn.line(".")
local start_line = vim.fn.line(opts.use_native == true and "'<" or "v")
local end_line = vim.fn.line(opts.use_native == true and "'>" or ".")
Comment on lines +539 to +540

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Good catch

if start_line > end_line then
start_line, end_line = end_line, start_line
end
local nodes = explorer:get_nodes_in_range(start_line, end_line)
M.exit_visual_mode()

if opts.should_exit ~= false then
M.exit_visual_mode()
end
return nodes
end

Expand Down
Loading