Skip to content
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

Adds support for workspace/willRenameFiles #33

Merged
merged 4 commits into from
Oct 6, 2023
Merged
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `"`.
Expand Down
37 changes: 35 additions & 2 deletions lua/genghis.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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: "
Expand Down Expand Up @@ -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)
Expand Down