From eed501850af3a1760136feaf26970ae546f0742d Mon Sep 17 00:00:00 2001 From: Cor Date: Sat, 17 Jul 2021 09:06:11 +0200 Subject: [PATCH 1/7] Added option to provide a custom config file to the lsp. --- helix-core/src/lib.rs | 2 +- helix-core/src/syntax.rs | 2 +- helix-lsp/src/client.rs | 5 ++++- helix-lsp/src/lib.rs | 37 ++++++++++++++++++++++++++++++++++- runtime/lsp_configs/rust.json | 9 +++++++++ 5 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 runtime/lsp_configs/rust.json diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs index 3684a93ee3c4..8959f5330f61 100644 --- a/helix-core/src/lib.rs +++ b/helix-core/src/lib.rs @@ -27,7 +27,7 @@ pub mod unicode { pub use unicode_width as width; } -static RUNTIME_DIR: once_cell::sync::Lazy = +pub static RUNTIME_DIR: once_cell::sync::Lazy = once_cell::sync::Lazy::new(runtime_dir); pub fn find_first_non_whitespace_char(line: RopeSlice) -> Option { diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index f249f5fe7e3b..e7c3a2210731 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -31,7 +31,7 @@ pub struct Configuration { #[serde(rename_all = "kebab-case")] pub struct LanguageConfiguration { #[serde(rename = "name")] - pub(crate) language_id: String, + pub language_id: String, pub scope: String, // source.rust pub file_types: Vec, // filename ends_with? pub roots: Vec, // these indicate project roots <.git, Cargo.toml> diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index 7f136fe84c58..ebda51892480 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -24,12 +24,14 @@ pub struct Client { request_counter: AtomicU64, capabilities: Option, offset_encoding: OffsetEncoding, + custom_config: Option, } impl Client { pub fn start( cmd: &str, args: &[String], + custom_config: Option, id: usize, ) -> Result<(Self, UnboundedReceiver<(usize, Call)>)> { let process = Command::new(cmd) @@ -57,6 +59,7 @@ impl Client { request_counter: AtomicU64::new(0), capabilities: None, offset_encoding: OffsetEncoding::Utf8, + custom_config, }; // TODO: async client.initialize() @@ -220,7 +223,7 @@ impl Client { // root_path is obsolete, use root_uri root_path: None, root_uri: root, - initialization_options: None, + initialization_options: self.custom_config.clone(), capabilities: lsp::ClientCapabilities { text_document: Some(lsp::TextDocumentClientCapabilities { completion: Some(lsp::CompletionClientCapabilities { diff --git a/helix-lsp/src/lib.rs b/helix-lsp/src/lib.rs index 96a45bb9000f..b9f6c568a423 100644 --- a/helix-lsp/src/lib.rs +++ b/helix-lsp/src/lib.rs @@ -312,7 +312,14 @@ impl Registry { Entry::Vacant(entry) => { // initialize a new client let id = self.counter.fetch_add(1, Ordering::Relaxed); - let (mut client, incoming) = Client::start(&config.command, &config.args, id)?; + let (mut client, incoming) = Client::start( + &config.command, + &config.args, + load_lsp_config_file(&language_config.language_id) + .ok() + .flatten(), + id, + )?; // TODO: run this async without blocking futures_executor::block_on(client.initialize())?; s_incoming.push(UnboundedReceiverStream::new(incoming)); @@ -410,6 +417,34 @@ impl LspProgressMap { } } +fn load_lsp_config_file(language: &str) -> Result> { + let path = helix_core::RUNTIME_DIR + .join("lsp_configs") + .join(language.to_owned() + ".json"); + + let file = match std::fs::File::open(&path) { + Ok(f) => f, + Err(e) => { + log::info!( + "Tried to read lsp config file {:?} for {} => {:?}", + path, + language, + e, + ); + return Err(Error::IO(e)); + } + }; + let reader = std::io::BufReader::new(file); + let config = serde_json::from_reader(reader); + log::info!( + "Read lsp config file {:?} for {} => {:?}", + path, + language, + config, + ); + Ok(config.ok()) +} + // REGISTRY = HashMap>> // spawn one server per language type, need to spawn one per workspace if server doesn't support // workspaces diff --git a/runtime/lsp_configs/rust.json b/runtime/lsp_configs/rust.json new file mode 100644 index 000000000000..01d980856973 --- /dev/null +++ b/runtime/lsp_configs/rust.json @@ -0,0 +1,9 @@ +{ + "cargo": { + "loadOutDirsFromCheck": true + }, + "procMacro": { + "enable": false + } +} + From 08184a0f5208555b18c7ab776b4100e098b6144c Mon Sep 17 00:00:00 2001 From: Cor Date: Sat, 17 Jul 2021 09:46:55 +0200 Subject: [PATCH 2/7] Simplified lsp loading routine with anyhow --- helix-lsp/src/lib.rs | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/helix-lsp/src/lib.rs b/helix-lsp/src/lib.rs index b9f6c568a423..eba8a0997565 100644 --- a/helix-lsp/src/lib.rs +++ b/helix-lsp/src/lib.rs @@ -19,6 +19,7 @@ use std::{ }, }; +use anyhow::Context; use serde::{Deserialize, Serialize}; use thiserror::Error; use tokio_stream::wrappers::UnboundedReceiverStream; @@ -315,9 +316,17 @@ impl Registry { let (mut client, incoming) = Client::start( &config.command, &config.args, - load_lsp_config_file(&language_config.language_id) - .ok() - .flatten(), + match load_lsp_config_file(&language_config.language_id) { + Ok(c) => c, + Err(e) => { + log::info!( + "Loading lsp config file for {} failed => {}", + language_config.language_id, + e + ); + None + } + }, id, )?; // TODO: run this async without blocking @@ -417,32 +426,15 @@ impl LspProgressMap { } } -fn load_lsp_config_file(language: &str) -> Result> { +fn load_lsp_config_file(language: &str) -> anyhow::Result> { let path = helix_core::RUNTIME_DIR .join("lsp_configs") .join(language.to_owned() + ".json"); - let file = match std::fs::File::open(&path) { - Ok(f) => f, - Err(e) => { - log::info!( - "Tried to read lsp config file {:?} for {} => {:?}", - path, - language, - e, - ); - return Err(Error::IO(e)); - } - }; + let file = std::fs::File::open(&path)?; let reader = std::io::BufReader::new(file); let config = serde_json::from_reader(reader); - log::info!( - "Read lsp config file {:?} for {} => {:?}", - path, - language, - config, - ); - Ok(config.ok()) + config.context(format!("Reading lsp config file {:?} failed.", path)) } // REGISTRY = HashMap>> From 1547e8a0e554f64b3905977ad762799e36459b06 Mon Sep 17 00:00:00 2001 From: Cor Date: Sat, 17 Jul 2021 20:26:30 +0200 Subject: [PATCH 3/7] Moved config to language.toml --- helix-core/src/syntax.rs | 1 + helix-lsp/src/client.rs | 4 ++++ helix-lsp/src/lib.rs | 27 ++++----------------------- languages.toml | 10 ++++++++++ runtime/lsp_configs/rust.json | 9 --------- 5 files changed, 19 insertions(+), 32 deletions(-) delete mode 100644 runtime/lsp_configs/rust.json diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index e7c3a2210731..c2095220a647 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -35,6 +35,7 @@ pub struct LanguageConfiguration { pub scope: String, // source.rust pub file_types: Vec, // filename ends_with? pub roots: Vec, // these indicate project roots <.git, Cargo.toml> + pub custom_config: Option, #[serde(default)] pub auto_format: bool, diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index ebda51892480..f87bea94f77a 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -217,6 +217,10 @@ impl Client { // TODO: delay any requests that are triggered prior to initialize let root = find_root(None).and_then(|root| lsp::Url::from_file_path(root).ok()); + if self.custom_config.is_some() { + log::info!("Using custom LSP config: {}", self.custom_config.as_ref().unwrap() ); + } + #[allow(deprecated)] let params = lsp::InitializeParams { process_id: Some(std::process::id()), diff --git a/helix-lsp/src/lib.rs b/helix-lsp/src/lib.rs index eba8a0997565..9ac92694edd1 100644 --- a/helix-lsp/src/lib.rs +++ b/helix-lsp/src/lib.rs @@ -19,7 +19,6 @@ use std::{ }, }; -use anyhow::Context; use serde::{Deserialize, Serialize}; use thiserror::Error; use tokio_stream::wrappers::UnboundedReceiverStream; @@ -316,17 +315,10 @@ impl Registry { let (mut client, incoming) = Client::start( &config.command, &config.args, - match load_lsp_config_file(&language_config.language_id) { - Ok(c) => c, - Err(e) => { - log::info!( - "Loading lsp config file for {} failed => {}", - language_config.language_id, - e - ); - None - } - }, + serde_json::from_str( + language_config.custom_config.as_deref().unwrap_or(""), + ) + .ok(), id, )?; // TODO: run this async without blocking @@ -426,17 +418,6 @@ impl LspProgressMap { } } -fn load_lsp_config_file(language: &str) -> anyhow::Result> { - let path = helix_core::RUNTIME_DIR - .join("lsp_configs") - .join(language.to_owned() + ".json"); - - let file = std::fs::File::open(&path)?; - let reader = std::io::BufReader::new(file); - let config = serde_json::from_reader(reader); - config.context(format!("Reading lsp config file {:?} failed.", path)) -} - // REGISTRY = HashMap>> // spawn one server per language type, need to spawn one per workspace if server doesn't support // workspaces diff --git a/languages.toml b/languages.toml index 204a598789a4..d1fbab7c6423 100644 --- a/languages.toml +++ b/languages.toml @@ -5,6 +5,16 @@ injection-regex = "rust" file-types = ["rs"] roots = [] auto-format = true +custom-config = """ +{ + "cargo": { + "loadOutDirsFromCheck": true + }, + "procMacro": { + "enable": false + } +} +""" language-server = { command = "rust-analyzer" } indent = { tab-width = 4, unit = " " } diff --git a/runtime/lsp_configs/rust.json b/runtime/lsp_configs/rust.json deleted file mode 100644 index 01d980856973..000000000000 --- a/runtime/lsp_configs/rust.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "cargo": { - "loadOutDirsFromCheck": true - }, - "procMacro": { - "enable": false - } -} - From 5e973483f4bc8d72f96a53a6314e6ee173ea060a Mon Sep 17 00:00:00 2001 From: Cor Date: Sat, 17 Jul 2021 20:30:58 +0200 Subject: [PATCH 4/7] Fixed test case --- helix-core/src/indent.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/helix-core/src/indent.rs b/helix-core/src/indent.rs index 1b36db7b1794..344267a61e37 100644 --- a/helix-core/src/indent.rs +++ b/helix-core/src/indent.rs @@ -262,6 +262,7 @@ where file_types: vec!["rs".to_string()], language_id: "Rust".to_string(), highlight_config: OnceCell::new(), + custom_config: None, // roots: vec![], auto_format: false, From 11de737dfdfe1507cb4731d37a6f043dbcafd934 Mon Sep 17 00:00:00 2001 From: Cor Date: Sat, 17 Jul 2021 20:33:11 +0200 Subject: [PATCH 5/7] Cargo fmt --- helix-lsp/src/client.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index f87bea94f77a..1604bb52473c 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -218,9 +218,12 @@ impl Client { let root = find_root(None).and_then(|root| lsp::Url::from_file_path(root).ok()); if self.custom_config.is_some() { - log::info!("Using custom LSP config: {}", self.custom_config.as_ref().unwrap() ); + log::info!( + "Using custom LSP config: {}", + self.custom_config.as_ref().unwrap() + ); } - + #[allow(deprecated)] let params = lsp::InitializeParams { process_id: Some(std::process::id()), From 5effccdc7792b2ec911e4d199d083b71344dfb17 Mon Sep 17 00:00:00 2001 From: Cor Date: Sat, 17 Jul 2021 20:36:57 +0200 Subject: [PATCH 6/7] Revert now-useless changes --- helix-core/src/lib.rs | 2 +- helix-core/src/syntax.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs index 8959f5330f61..3684a93ee3c4 100644 --- a/helix-core/src/lib.rs +++ b/helix-core/src/lib.rs @@ -27,7 +27,7 @@ pub mod unicode { pub use unicode_width as width; } -pub static RUNTIME_DIR: once_cell::sync::Lazy = +static RUNTIME_DIR: once_cell::sync::Lazy = once_cell::sync::Lazy::new(runtime_dir); pub fn find_first_non_whitespace_char(line: RopeSlice) -> Option { diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index c2095220a647..cc6aed236ae0 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -31,7 +31,7 @@ pub struct Configuration { #[serde(rename_all = "kebab-case")] pub struct LanguageConfiguration { #[serde(rename = "name")] - pub language_id: String, + pub(crate) language_id: String, pub scope: String, // source.rust pub file_types: Vec, // filename ends_with? pub roots: Vec, // these indicate project roots <.git, Cargo.toml> From bbe6b43e024c193a0875873828e74739b4569bd3 Mon Sep 17 00:00:00 2001 From: Cor Date: Sun, 18 Jul 2021 07:52:26 +0200 Subject: [PATCH 7/7] Renamed custom_config to config --- helix-core/src/indent.rs | 2 +- helix-core/src/syntax.rs | 2 +- helix-lsp/src/client.rs | 15 ++++++--------- helix-lsp/src/lib.rs | 5 +---- languages.toml | 2 +- 5 files changed, 10 insertions(+), 16 deletions(-) diff --git a/helix-core/src/indent.rs b/helix-core/src/indent.rs index 344267a61e37..292ade4b52c3 100644 --- a/helix-core/src/indent.rs +++ b/helix-core/src/indent.rs @@ -262,7 +262,7 @@ where file_types: vec!["rs".to_string()], language_id: "Rust".to_string(), highlight_config: OnceCell::new(), - custom_config: None, + config: None, // roots: vec![], auto_format: false, diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index cc6aed236ae0..621cd04690bd 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -35,7 +35,7 @@ pub struct LanguageConfiguration { pub scope: String, // source.rust pub file_types: Vec, // filename ends_with? pub roots: Vec, // these indicate project roots <.git, Cargo.toml> - pub custom_config: Option, + pub config: Option, #[serde(default)] pub auto_format: bool, diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index 1604bb52473c..1c2a49b52e41 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -24,14 +24,14 @@ pub struct Client { request_counter: AtomicU64, capabilities: Option, offset_encoding: OffsetEncoding, - custom_config: Option, + config: Option, } impl Client { pub fn start( cmd: &str, args: &[String], - custom_config: Option, + config: Option, id: usize, ) -> Result<(Self, UnboundedReceiver<(usize, Call)>)> { let process = Command::new(cmd) @@ -59,7 +59,7 @@ impl Client { request_counter: AtomicU64::new(0), capabilities: None, offset_encoding: OffsetEncoding::Utf8, - custom_config, + config, }; // TODO: async client.initialize() @@ -217,11 +217,8 @@ impl Client { // TODO: delay any requests that are triggered prior to initialize let root = find_root(None).and_then(|root| lsp::Url::from_file_path(root).ok()); - if self.custom_config.is_some() { - log::info!( - "Using custom LSP config: {}", - self.custom_config.as_ref().unwrap() - ); + if self.config.is_some() { + log::info!("Using custom LSP config: {}", self.config.as_ref().unwrap()); } #[allow(deprecated)] @@ -230,7 +227,7 @@ impl Client { // root_path is obsolete, use root_uri root_path: None, root_uri: root, - initialization_options: self.custom_config.clone(), + initialization_options: self.config.clone(), capabilities: lsp::ClientCapabilities { text_document: Some(lsp::TextDocumentClientCapabilities { completion: Some(lsp::CompletionClientCapabilities { diff --git a/helix-lsp/src/lib.rs b/helix-lsp/src/lib.rs index 9ac92694edd1..72606b709b2d 100644 --- a/helix-lsp/src/lib.rs +++ b/helix-lsp/src/lib.rs @@ -315,10 +315,7 @@ impl Registry { let (mut client, incoming) = Client::start( &config.command, &config.args, - serde_json::from_str( - language_config.custom_config.as_deref().unwrap_or(""), - ) - .ok(), + serde_json::from_str(language_config.config.as_deref().unwrap_or("")).ok(), id, )?; // TODO: run this async without blocking diff --git a/languages.toml b/languages.toml index d1fbab7c6423..ee495635f42b 100644 --- a/languages.toml +++ b/languages.toml @@ -5,7 +5,7 @@ injection-regex = "rust" file-types = ["rs"] roots = [] auto-format = true -custom-config = """ +config = """ { "cargo": { "loadOutDirsFromCheck": true