diff options
author | Blaž Hrastnik | 2022-04-01 02:20:41 +0000 |
---|---|---|
committer | Blaž Hrastnik | 2022-04-01 02:20:41 +0000 |
commit | 8adf0c1b3a7a2173c80a86da5d435288bab456de (patch) | |
tree | e99b3d67ba027fbd1e3f4428a078d6d28a8f2ab2 /helix-lsp | |
parent | 236c6b77077596f8c7b5a5377e23e96ecec45e07 (diff) |
lsp: Implement support for workspace_folders (currently just one)
Refs #1898
Diffstat (limited to 'helix-lsp')
-rw-r--r-- | helix-lsp/src/client.rs | 53 | ||||
-rw-r--r-- | helix-lsp/src/lib.rs | 4 |
2 files changed, 43 insertions, 14 deletions
diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index dbdd885b..8b14b0b8 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -31,7 +31,9 @@ pub struct Client { pub(crate) capabilities: OnceCell<lsp::ServerCapabilities>, offset_encoding: OffsetEncoding, config: Option<Value>, - root_markers: Vec<String>, + root_path: Option<std::path::PathBuf>, + root_uri: Option<lsp::Url>, + workspace_folders: Vec<lsp::WorkspaceFolder>, } impl Client { @@ -40,7 +42,7 @@ impl Client { cmd: &str, args: &[String], config: Option<Value>, - root_markers: Vec<String>, + root_markers: &[String], id: usize, ) -> Result<(Self, UnboundedReceiver<(usize, Call)>, Arc<Notify>)> { // Resolve path to the binary @@ -65,6 +67,27 @@ impl Client { let (server_rx, server_tx, initialize_notify) = Transport::start(reader, writer, stderr, id); + let root_path = find_root(None, root_markers); + + let root_uri = root_path + .clone() + .and_then(|root| lsp::Url::from_file_path(root).ok()); + + // TODO: support multiple workspace folders + let workspace_folders = root_uri + .clone() + .map(|root| { + vec![lsp::WorkspaceFolder { + name: root + .path_segments() + .and_then(|segments| segments.last()) + .map(|basename| basename.to_string()) + .unwrap_or_default(), + uri: root, + }] + }) + .unwrap_or_default(); + let client = Self { id, _process: process, @@ -73,7 +96,10 @@ impl Client { capabilities: OnceCell::new(), offset_encoding: OffsetEncoding::Utf8, config, - root_markers, + + root_path, + root_uri, + workspace_folders, }; Ok((client, server_rx, initialize_notify)) @@ -117,6 +143,10 @@ impl Client { self.config.as_ref() } + pub fn workspace_folders(&self) -> &[lsp::WorkspaceFolder] { + &self.workspace_folders + } + /// Execute a RPC request on the language server. async fn request<R: lsp::request::Request>(&self, params: R::Params) -> Result<R::Result> where @@ -234,13 +264,6 @@ impl Client { // ------------------------------------------------------------------------------------------- pub(crate) async fn initialize(&self) -> Result<lsp::InitializeResult> { - // TODO: delay any requests that are triggered prior to initialize - let root_path = find_root(None, &self.root_markers); - - let root_uri = root_path - .clone() - .and_then(|root| lsp::Url::from_file_path(root).ok()); - if self.config.is_some() { log::info!("Using custom LSP config: {}", self.config.as_ref().unwrap()); } @@ -248,10 +271,14 @@ impl Client { #[allow(deprecated)] let params = lsp::InitializeParams { process_id: Some(std::process::id()), + workspace_folders: Some(self.workspace_folders.clone()), // root_path is obsolete, but some clients like pyright still use it so we specify both. // clients will prefer _uri if possible - root_path: root_path.and_then(|path| path.to_str().map(|path| path.to_owned())), - root_uri, + root_path: self + .root_path + .clone() + .and_then(|path| path.to_str().map(|path| path.to_owned())), + root_uri: self.root_uri.clone(), initialization_options: self.config.clone(), capabilities: lsp::ClientCapabilities { workspace: Some(lsp::WorkspaceClientCapabilities { @@ -259,6 +286,7 @@ impl Client { did_change_configuration: Some(lsp::DynamicRegistrationClientCapabilities { dynamic_registration: Some(false), }), + workspace_folders: Some(true), ..Default::default() }), text_document: Some(lsp::TextDocumentClientCapabilities { @@ -314,7 +342,6 @@ impl Client { ..Default::default() }, trace: None, - workspace_folders: None, client_info: None, locale: None, // TODO }; diff --git a/helix-lsp/src/lib.rs b/helix-lsp/src/lib.rs index 389dfb4d..76748136 100644 --- a/helix-lsp/src/lib.rs +++ b/helix-lsp/src/lib.rs @@ -191,6 +191,7 @@ pub mod util { pub enum MethodCall { WorkDoneProgressCreate(lsp::WorkDoneProgressCreateParams), ApplyWorkspaceEdit(lsp::ApplyWorkspaceEditParams), + WorkspaceFolders, WorkspaceConfiguration(lsp::ConfigurationParams), } @@ -210,6 +211,7 @@ impl MethodCall { .expect("Failed to parse ApplyWorkspaceEdit params"); Self::ApplyWorkspaceEdit(params) } + lsp::request::WorkspaceFoldersRequest::METHOD => Self::WorkspaceFolders, lsp::request::WorkspaceConfiguration::METHOD => { let params: lsp::ConfigurationParams = params .parse() @@ -320,7 +322,7 @@ impl Registry { &config.command, &config.args, language_config.config.clone(), - language_config.roots.clone(), + &language_config.roots, id, )?; self.incoming.push(UnboundedReceiverStream::new(incoming)); |