feat: renaming commands support LSP's `workspace/willRenameFiles` (#33)

remotes/origin/HEAD
Oliver Jan Krylow 2023-10-06 17:57:21 +02:00 committed by GitHub
parent d98fe544e4
commit ec447d08d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 2 deletions

View File

@ -62,6 +62,8 @@ The following applies to all commands above:
- If the new file name includes a `/`, the new file is placed in the respective subdirectory, creating any non-existing folders. Except for `.moveAndRenameFile`, all operations take only place in the current working directory, so `.moveAndRenameFile` is the only command that can move to a parent directory.
- All commands support [autocompletion of existing directories](#autocompletion-of-directories).
`renameFile` and `moveAndRenameFile` will notify any running LSP client about the renaming. LSP servers supporting the `workspace/willRenameFiles` method can use this information to update various code parts, for example `use` or `import` statements.
### File Utility Commands
- `.trashFile{trashLocation = "/your/path/"}` or `:Trash`: Move the current file to the trash location. [Defaults to the operating-system-specific trash directory.](https://github.com/chrisgrieser/nvim-genghis/blob/main/lua/genghis.lua#L164) ⚠️ Any existing file in the trash location with the same name is overwritten, making that file irretrievable. If [bufdelete.nvim](https://github.com/famiu/bufdelete.nvim) is available, `require'bufdelete.nvim'.bufwipeout` would be used to keep window layout intact instead of `vim.cmd.bwipeout`.
- `.copyFilename` or `:CopyFilename`: Copy the file name. When `clipboard="unnamed[plus]"` has been set, copies to the `+` register, otherwise to `"`.

View File

@ -4,11 +4,40 @@ local expand = vim.fn.expand
local fn = vim.fn
local cmd = vim.cmd
local LSP_METHOD_WILL_RENAME_FILES = "workspace/willRenameFiles"
local function bwipeout(bufnr)
bufnr = bufnr and fn.bufnr(bufnr) or 0
vim.api.nvim_buf_delete(bufnr, { force = true })
end
--- Requests a 'workspace/willRenameFiles' on any running LSP client, that supports it
--- stolen from https://github.com/LazyVim/LazyVim/blob/fecc5faca25c209ed62e3658dd63731e26c0c643/lua/lazyvim/util/init.lua#L304
local function onRename(from, to)
local clients = vim.lsp.get_active_clients()
for _, client in ipairs(clients) do
-- avoid calling `any_lsp_supports` as to not loop clients twice
if client:supports_method(LSP_METHOD_WILL_RENAME_FILES) then
local resp = client.request_sync(LSP_METHOD_WILL_RENAME_FILES, {
files = {
{
oldUri = vim.uri_from_fname(from),
newUri = vim.uri_from_fname(to),
},
},
}, 1000)
if resp and resp.result ~= nil then
vim.lsp.util.apply_workspace_edit(resp.result, client.offset_encoding)
end
end
end
end
local function anyLspSupports(method)
local clients = vim.lsp.get_active_clients()
return vim.iter(clients):any(function(client) return client:supports_method(method) end)
end
-- https://github.com/neovim/neovim/issues/17735#issuecomment-1068525617
local function leaveVisualMode()
local escKey = vim.api.nvim_replace_termcodes("<Esc>", false, true, true)
@ -64,15 +93,18 @@ local function fileOp(op)
cmd([['<,'>delete z]])
end
local lspWillRename = anyLspSupports(LSP_METHOD_WILL_RENAME_FILES)
local promptStr, prefill
if op == "duplicate" then
promptStr = "Duplicate File as: "
prefill = oldNameNoExt .. "-1"
elseif op == "rename" then
promptStr = "Rename File to: "
promptStr = lspWillRename and "Rename File to (will notify LSPs): " or "Rename File to: "
prefill = oldNameNoExt
elseif op == "move-rename" then
promptStr = "Move & Rename File to: "
promptStr = lspWillRename and "Move & Rename File to (will notify LSPs): "
or "Move & Rename File to: "
prefill = dir .. "/"
elseif op == "new" or op == "newFromSel" then
promptStr = "Name for New File: "
@ -135,6 +167,7 @@ local function fileOp(op)
notify(("Duplicated %q as %q."):format(oldName, newName))
end
elseif op == "rename" or op == "move-rename" then
onRename(oldFilePath, newFilePath)
local success = moveFile(oldFilePath, newFilePath)
if success then
cmd.edit(newFilePath)