aboutsummaryrefslogtreecommitdiff
path: root/helix-lsp/src
diff options
context:
space:
mode:
authorBlaž Hrastnik2022-04-01 02:20:41 +0000
committerBlaž Hrastnik2022-04-01 02:20:41 +0000
commit8adf0c1b3a7a2173c80a86da5d435288bab456de (patch)
treee99b3d67ba027fbd1e3f4428a078d6d28a8f2ab2 /helix-lsp/src
parent236c6b77077596f8c7b5a5377e23e96ecec45e07 (diff)
lsp: Implement support for workspace_folders (currently just one)
Refs #1898
Diffstat (limited to 'helix-lsp/src')
-rw-r--r--helix-lsp/src/client.rs53
-rw-r--r--helix-lsp/src/lib.rs4
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));