Skip to content

914 allow rename overwrite #1995

New issue

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

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

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
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
32 changes: 29 additions & 3 deletions lua/nvim-tree/actions/fs/rename-file.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,42 @@ local function err_fmt(from, to, reason)
end

function M.rename(node, to)
local success, err, delete_first

if utils.file_exists(to) then
notify.warn(err_fmt(node.absolute_path, to, "file already exists"))
return
local overwrite = false

local prompt_select = "Overwrite " .. to .. " ?"
local prompt_input = prompt_select .. " y/n: "
lib.prompt(prompt_input, prompt_select, { "y", "n" }, { "Yes", "No" }, function(item_short)
utils.clear_prompt()
overwrite = item_short == "y"
end)

if not overwrite then
return
end

-- case insensitive file systems cannot handle renaming clobbering well
if utils.is_macos or utils.is_windows or utils.is_wsl then
delete_first = true
end
end

events._dispatch_will_rename_node(node.absolute_path, to)
local success, err = vim.loop.fs_rename(node.absolute_path, to)

if delete_first then
success, err = vim.loop.fs_unlink(to)
if not success then
return notify.warn(string.format("Cannot delete %s: %s", to, err))
end
end

success, err = vim.loop.fs_rename(node.absolute_path, to)
if not success then
return notify.warn(err_fmt(node.absolute_path, to, err))
end

notify.info(node.absolute_path .. " ➜ " .. to)
utils.rename_loaded_buffers(node.absolute_path, to)
events._dispatch_node_renamed(node.absolute_path, to)
Expand Down
49 changes: 31 additions & 18 deletions lua/nvim-tree/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -154,25 +154,38 @@ function M.get_nodes_by_line(nodes_all, line_start)
return nodes_by_line
end

function M.rename_loaded_buffers(old_path, new_path)
--- Find buffer for path.
--- @param path string absolute path
--- @return number|nil buffer number
local function buf_for_path(path)
for _, buf in pairs(vim.api.nvim_list_bufs()) do
if vim.api.nvim_buf_is_loaded(buf) then
local buf_name = vim.api.nvim_buf_get_name(buf)
local exact_match = buf_name == old_path
local child_match = (
buf_name:sub(1, #old_path) == old_path and buf_name:sub(#old_path + 1, #old_path + 1) == path_separator
)
if exact_match or child_match then
vim.api.nvim_buf_set_name(buf, new_path .. buf_name:sub(#old_path + 1))
-- to avoid the 'overwrite existing file' error message on write for
-- normal files
if vim.api.nvim_buf_get_option(buf, "buftype") == "" then
vim.api.nvim_buf_call(buf, function()
vim.cmd "silent! write!"
vim.cmd "edit"
end)
end
end
if vim.api.nvim_buf_get_name(buf) == path then
return buf
end
end
end

--- Rename a buffer. Deletes to if present.
--- @param from_path string absolute path
--- @param to_path string absolute path
function M.rename_loaded_buffers(from_path, to_path)
-- existing from and to
local from_buf = buf_for_path(from_path)
local to_buf = buf_for_path(to_path)

-- delete the old: this will close the windows it is open in; too bad
if to_buf then
vim.api.nvim_buf_delete(to_buf, { force = true })
end

if from_buf then
-- the actual rename
vim.api.nvim_buf_set_name(from_buf, to_path)

-- following a rename there will be an unlisted empty buffer created; remove it
local from_unlisted = buf_for_path(from_path)
if from_unlisted then
vim.api.nvim_buf_delete(from_unlisted, { force = true })
end
end
end
Expand Down