summaryrefslogtreecommitdiff
path: root/helix-lsp/src/client.rs
diff options
context:
space:
mode:
Diffstat (limited to 'helix-lsp/src/client.rs')
-rw-r--r--helix-lsp/src/client.rs76
1 files changed, 75 insertions, 1 deletions
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
@@ -404,9 +404,19 @@ impl Client {
where
R::Params: serde::Serialize,
{
+ self.call_with_timeout::<R>(params, self.req_timeout)
+ }
+
+ fn call_with_timeout<R: lsp::request::Request>(
+ &self,
+ params: R::Params,
+ timeout_secs: u64,
+ ) -> impl Future<Output = Result<Value>>
+ 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<impl Future<Output = Result<lsp::WorkspaceEdit>>> {
+ 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::request::WillRenameFiles>(
+ lsp::RenameFilesParams { files },
+ 5,
+ );
+
+ Some(async move {
+ let json = request.await?;
+ let response: Option<lsp::WorkspaceEdit> = 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<impl Future<Output = std::result::Result<(), Error>>> {
+ 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::notification::DidRenameFiles>(lsp::RenameFilesParams { files }))
+ }
+
// -------------------------------------------------------------------------------------------
// Text document
// -------------------------------------------------------------------------------------------