Make workspace/willRenameFiles working #2531
Make workspace/willRenameFiles working #2531przepompownia wants to merge 1 commit intophpactor:masterfrom
workspace/willRenameFiles working #2531Conversation
|
@dantleech at the moment it seems to work on simple cases but
|
|
To test it with Neovim (master) I use local function willRenameFilesHandler(response)
for clientId, clientResponse in pairs(response) do
local client = vim.lsp.get_client_by_id(clientId)
if nil == client then
vim.notify(('Client %s does not exist'):format(clientId), vim.log.levels.ERROR, {title = 'LSP: workspace/willRenameFiles'})
return
end
vim.lsp.util.apply_workspace_edit(clientResponse.result, client.offset_encoding)
-- vim.print(clientResponse.result)
end
end
local function willRenameCurrentBuffer(newPath)
if not vim.startswith(newPath, '/') then
newPath = vim.fs.joinpath(vim.uv.cwd(), newPath)
end
vim.lsp.buf_request_all(
0,
'workspace/willRenameFiles',
{
files = { { oldUri = vim.uri_from_bufnr(0), newUri = vim.uri_from_fname(newPath) } },
},
willRenameFilesHandler
)
end
vim.api.nvim_create_user_command('WillRenameCurrentBuffer', function (opts)
willRenameCurrentBuffer(opts.args)
end, {nargs = 1, complete = 'file'}) |
At the moment both above things are done:
|
|
Composing the summarized |
lib/Extension/LanguageServerRename/Handler/FileRenameHandler.php
Outdated
Show resolved
Hide resolved
lib/Extension/LanguageServerRename/Handler/FileRenameHandler.php
Outdated
Show resolved
Hide resolved
| * @return Promise<LocatedTextEditsMap> | ||
| */ | ||
| public function renameFile(TextDocumentUri $from, TextDocumentUri $to): Promise | ||
| public function renameFile(TextDocumentUri $from, TextDocumentUri $to): Generator |
There was a problem hiding this comment.
why using a generator? in general public APIs should use Promise? can we switch back? that would also make the diff easier to read :)
There was a problem hiding this comment.
I switched to using generator in similar way like in ClassRenamer (please compare what happens there) to smuggle RenameResult through getReturn() and avoid changes in models (as I mentioned above).
There was a problem hiding this comment.
Using Promise would require some new class (Phpactor\Rename\Model\RenameEdit?) composed of LocatedTextEditsMap and RenameResult.
There was a problem hiding this comment.
RenameEdit class couldn't simply look like
<?php
namespace Phpactor\Rename\Model;
class RenameEdit
{
public function __construct(
public readonly LocatedTextEditsMap $locatedTextEditsMap,
public readonly RenameResult $renameResult,
) {
}
}because it'd loss the order of edits. Such class should be similar to WorkspaceEdit which allows ordered edits of different types.
There was a problem hiding this comment.
I converted the adapter to return Promise and created RenameEdit - initially as iterable class.
|
I;d really need to test this against a real client implementation, I initially developed it against the CoC implementation - what implementation is there for NVIM LSP? Is it supported by VS code? What is the end state of this feature from your perspective? how would you use it? |
|
Honestly, at the moment I couldn't think of anything more than that using a simple prompt with path completion to send such request (like the example above) but as a nvim-tree user I could extend it like here I haven't tested it on nvim-oil yet maybe because built-in nvim feature Maybe I'll find some free time to install oil.nvim and CoC in separate environments. It's possible that some other clients do not apply
|
6967e7c to
8331057
Compare
|
Intentionally I didn't merge the recent master here yet because of #2607. |
|
lib/Rename/Model/RenameEdit.php
Outdated
| */ | ||
| class RenameEdit extends ArrayIterator | ||
| { | ||
| public function __construct(LocatedTextEditsMap|RenameResult|null ...$edits) |
There was a problem hiding this comment.
why is this a variadic?
There was a problem hiding this comment.
Only for enforcing types without using docblock.
There was a problem hiding this comment.
Ok, let's use the docblock then :)
There was a problem hiding this comment.
No problem, regardless, I'd like to know why you think this is probably bad practice (especially that in practice the constructor gets max two arguments).
There was a problem hiding this comment.
variadics are fine but i'm confused: why is it an array at all and not LocatedTextEdits $edits, RenameResult $result ?
There was a problem hiding this comment.
I'm still confused. The result of the Promise in lib/Rename/Adapter/ClassMover/FileRenamer.php is:
return new WorkspaceRenameEdits([
LocatedTextEditsMap::fromLocatedEdits($locatedEdits),
new RenameResult($from, $to),
]);
i.e. why not:
return new WorkspaceRenameEdits(
LocatedTextEditsMap::fromLocatedEdits($locatedEdits),
new RenameResult($from, $to),
);
It doesn't need to be an array?
There was a problem hiding this comment.
It doesn't need to be an array?
It's (similarly to WorkspaceEdit's documentChanges elements) the only way to keep the order of operations here.
There was a problem hiding this comment.
Just to clarify though, it's not needed now?
There was a problem hiding this comment.
I mean, we are also passing an aggregate of located text edits, rather than the individual edits. So it's a bit ... weird. If this is gojg to be a list of operations then we should or bably not use the LocatedTextEditsMap here, as that' not an atomic operation.
There was a problem hiding this comment.
I agree that this separation is far from the best and even weird. I would like to leave some design assumptions to you, but I realize that this may mean a lot of reconstruction (and, in effect, wait probably long time). Please feel free to replace it with something better. I'm not attached in any way the current form of solution. It would be good to have working such LSP request.
lib/Extension/LanguageServerRename/Util/RenameEditConverter.php
Outdated
Show resolved
Hide resolved
|
I'm confused about why phpstan is complaining about changes unrelated to this PR after merge #2614 Edit: most of them were probably secondary to the few unsilenced. |
| $previous = $error->getPrevious(); | ||
|
|
||
| $this->clientApi->window()->showMessage()->error(sprintf( | ||
| $error->getMessage() . ($previous?->getTraceAsString() ?? '') |
There was a problem hiding this comment.
is sprintf missing a format string? %s %s why do we get the trace from $previous?
There was a problem hiding this comment.
I copied catching CouldNotRename from RenameHandler to have the same way of error handling and don't know what the trace was needed for in the original place:
|
I've made a PR on your PR: przepompownia#1 would be great if you can verify that it's all working. |
|
Any updates on this? I'd love to have this feature ❤️ |
|
Which client are you using that can take advantage of it? |
|
So there's this plugin for neovim at least which integrates with neo-tree and nvim-tree: https://github.com/antosha417/nvim-lsp-file-operations will try this out soon, sorry for the delay. |
|
There's also https://github.com/stevearc/oil.nvim, that's what I'm using and it has support for this. |
2ebe118 to
5e85ba7
Compare
6fc4bca to
1546a97
Compare
1546a97 to
3a90f03
Compare
3a90f03 to
fd1630a
Compare
Fixes #2522
Fixes #2523