repositories / dotfiles
dotfiles
bugabingas dorkfiles
owned by admin
neovim/lua/std/rename.lua
Raw-- stolen from https://github.com/folke/snacks.nvim/blob/main/lua/snacks/rename.lua
--- Lets LSP clients know that a file has been renamed
---@param from string
---@param to string
---@param rename? fun()
local function on_rename_file(from, to, rename)
local changes = {
files = { {
oldUri = vim.uri_from_fname(from),
newUri = vim.uri_from_fname(to),
} }
}
local clients = vim.lsp.get_clients { bufnr = 0 }
for _, client in ipairs(clients) do
if client:supports_method("workspace/willRenameFiles") then
local resp = client:request_sync("workspace/willRenameFiles", changes, 1000, 0)
if resp and resp.result ~= nil then
vim.lsp.util.apply_workspace_edit(resp.result, client.offset_encoding)
end
end
end
if rename then
rename()
end
for _, client in ipairs(clients) do
if client:supports_method("workspace/didRenameFiles") then
client:notify("workspace/didRenameFiles", changes)
end
end
end
--- Rename a file and update buffers
---@param from string
---@param to string
---@return boolean ok
local function _rename(from, to)
from = vim.fn.fnamemodify(from, ":p")
to = vim.fn.fnamemodify(to, ":p")
-- rename the file
local ret = vim.fn.rename(from, to)
if ret ~= 0 then
vim.notify("Failed to rename file: `" .. from .. "`", vim.log.levels.ERROR)
return false
end
-- replace buffer in all windows
local from_buf = vim.fn.bufnr(from)
if from_buf >= 0 then
local to_buf = vim.fn.bufadd(to)
vim.bo[to_buf].buflisted = true
for _, win in ipairs(vim.fn.win_findbuf(from_buf)) do
vim.api.nvim_win_call(win, function()
vim.cmd("buffer " .. to_buf)
end)
end
vim.api.nvim_buf_delete(from_buf, { force = true })
end
return true
end
-- Renames the provided file, or the current buffer's file.
-- Prompt for the new filename if `to` is not provided.
-- do the rename, and trigger LSP handlers
---@param opts? {from?: string, to?:string, file?:string, on_rename?: fun(to:string, from:string, ok:boolean)}
local function rename_file(opts)
opts = opts or {}
local from = vim.fn.fnamemodify(opts.from or opts.file or vim.api.nvim_buf_get_name(0), ":p")
local to = opts.to and vim.fn.fnamemodify(opts.to, ":p") or nil
local function rename()
assert(to, "to is required")
on_rename_file(from, to, function()
local ok = _rename(from, to)
if opts.on_rename then
opts.on_rename(to, from, ok)
end
end)
end
if to then
return rename()
end
local root = vim.fn.getcwd()
if from:find(root, 1, true) ~= 1 then
root = vim.fn.fnamemodify(from, ":p:h")
end
local extra = from:sub(#root + 2)
vim.ui.input({
prompt = "New File Name: ",
default = extra,
completion = "file",
}, function(value)
if not value or value == "" or value == extra then
return
end
to = vim.fs.normalize(root .. "/" .. value)
rename()
end)
end
return {
rename_file = rename_file,
on_rename_file = on_rename_file,
}