From e868678139bc8f4f5b14236c3c3c3f6aa4aab47b Mon Sep 17 00:00:00 2001 From: Yomain Date: Wed, 8 Nov 2023 19:38:17 +0100 Subject: Add command to move files with LSP support (#8584) * Added rename command * Added an error if the new path already exists * Fixed wrong command name being used * fixed clippy suggestions * removed didRenameFiles call, fixed early return due to path Err * added ':rnm' alias to ':rename' * code cleanup * formatting * removed debug line * cargo fmt * Improved new buffer error message Co-authored-by: Pascal Kuthe * Removed unnecessary path normalizing Co-authored-by: Pascal Kuthe * Update helix-term/src/commands/typed.rs Co-authored-by: Pascal Kuthe * Update helix-term/src/commands/typed.rs Co-authored-by: Pascal Kuthe * Update helix-term/src/commands/typed.rs Co-authored-by: Pascal Kuthe * Update helix-term/src/commands/typed.rs Co-authored-by: Pascal Kuthe * feat: change `rename` command to `move` * feat: add multi lsp support when moving files * feat: allow lsp calls with a custom timeout * feat: sending lsp file_changed event once file has moved --------- Co-authored-by: ontley Co-authored-by: ontley <67148677+ontley@users.noreply.github.com> Co-authored-by: Pascal Kuthe --- helix-lsp/src/client.rs | 76 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) (limited to 'helix-lsp/src') diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index 341702c3..e6e1f8a0 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -401,12 +401,22 @@ impl Client { &self, params: R::Params, ) -> impl Future> + where + R::Params: serde::Serialize, + { + self.call_with_timeout::(params, self.req_timeout) + } + + fn call_with_timeout( + &self, + params: R::Params, + timeout_secs: u64, + ) -> impl Future> where R::Params: serde::Serialize, { let server_tx = self.server_tx.clone(); let id = self.next_request_id(); - let timeout_secs = self.req_timeout; async move { use std::time::Duration; @@ -548,6 +558,11 @@ impl Client { dynamic_registration: Some(true), relative_pattern_support: Some(false), }), + file_operations: Some(lsp::WorkspaceFileOperationsClientCapabilities { + will_rename: Some(true), + did_rename: Some(true), + ..Default::default() + }), ..Default::default() }), text_document: Some(lsp::TextDocumentClientCapabilities { @@ -700,6 +715,65 @@ impl Client { }) } + pub fn prepare_file_rename( + &self, + old_uri: &lsp::Url, + new_uri: &lsp::Url, + ) -> Option>> { + let capabilities = self.capabilities.get().unwrap(); + + // Return early if the server does not support willRename feature + match &capabilities.workspace { + Some(workspace) => match &workspace.file_operations { + Some(op) => { + op.will_rename.as_ref()?; + } + _ => return None, + }, + _ => return None, + } + + let files = vec![lsp::FileRename { + old_uri: old_uri.to_string(), + new_uri: new_uri.to_string(), + }]; + let request = self.call_with_timeout::( + lsp::RenameFilesParams { files }, + 5, + ); + + Some(async move { + let json = request.await?; + let response: Option = serde_json::from_value(json)?; + Ok(response.unwrap_or_default()) + }) + } + + pub fn did_file_rename( + &self, + old_uri: &lsp::Url, + new_uri: &lsp::Url, + ) -> Option>> { + let capabilities = self.capabilities.get().unwrap(); + + // Return early if the server does not support DidRename feature + match &capabilities.workspace { + Some(workspace) => match &workspace.file_operations { + Some(op) => { + op.did_rename.as_ref()?; + } + _ => return None, + }, + _ => return None, + } + + let files = vec![lsp::FileRename { + old_uri: old_uri.to_string(), + new_uri: new_uri.to_string(), + }]; + Some(self.notify::(lsp::RenameFilesParams { files })) + } + // ------------------------------------------------------------------------------------------- // Text document // ------------------------------------------------------------------------------------------- -- cgit v1.2.3-70-g09d2