From 6af4bf7a8d27e653d2e6316172fe140871054d27 Mon Sep 17 00:00:00 2001 From: Emil Lauridsen Date: Wed, 25 Dec 2019 16:50:38 +0100 Subject: Configuration plumbing for cargo watcher --- crates/ra_lsp_server/src/cargo_check.rs | 50 +++++++++++++++++++++++++++------ crates/ra_lsp_server/src/config.rs | 7 +++++ crates/ra_lsp_server/src/main_loop.rs | 3 ++ crates/ra_lsp_server/src/world.rs | 5 +++- 4 files changed, 55 insertions(+), 10 deletions(-) (limited to 'crates/ra_lsp_server') diff --git a/crates/ra_lsp_server/src/cargo_check.rs b/crates/ra_lsp_server/src/cargo_check.rs index d5ff02154..f98b4f69c 100644 --- a/crates/ra_lsp_server/src/cargo_check.rs +++ b/crates/ra_lsp_server/src/cargo_check.rs @@ -1,3 +1,4 @@ +use crate::world::Options; use cargo_metadata::{ diagnostic::{ Applicability, Diagnostic as RustDiagnostic, DiagnosticLevel, DiagnosticSpan, @@ -30,14 +31,17 @@ pub struct CheckWatcher { } impl CheckWatcher { - pub fn new(workspace_root: PathBuf) -> CheckWatcher { + pub fn new(options: &Options, workspace_root: PathBuf) -> CheckWatcher { + let check_command = options.cargo_check_command.clone(); + let check_args = options.cargo_check_args.clone(); let shared = Arc::new(RwLock::new(CheckWatcherSharedState::new())); let (task_send, task_recv) = unbounded::(); let (cmd_send, cmd_recv) = unbounded::(); let shared_ = shared.clone(); let handle = std::thread::spawn(move || { - let mut check = CheckWatcherState::new(shared_, workspace_root); + let mut check = + CheckWatcherState::new(check_command, check_args, workspace_root, shared_); check.run(&task_send, &cmd_recv); }); @@ -50,6 +54,8 @@ impl CheckWatcher { } pub struct CheckWatcherState { + check_command: Option, + check_args: Vec, workspace_root: PathBuf, running: bool, watcher: WatchThread, @@ -134,11 +140,21 @@ pub enum CheckCommand { impl CheckWatcherState { pub fn new( - shared: Arc>, + check_command: Option, + check_args: Vec, workspace_root: PathBuf, + shared: Arc>, ) -> CheckWatcherState { - let watcher = WatchThread::new(&workspace_root); - CheckWatcherState { workspace_root, running: false, watcher, last_update_req: None, shared } + let watcher = WatchThread::new(check_command.as_ref(), &check_args, &workspace_root); + CheckWatcherState { + check_command, + check_args, + workspace_root, + running: false, + watcher, + last_update_req: None, + shared, + } } pub fn run(&mut self, task_send: &Sender, cmd_recv: &Receiver) { @@ -163,7 +179,11 @@ impl CheckWatcherState { self.shared.write().clear(task_send); self.watcher.cancel(); - self.watcher = WatchThread::new(&self.workspace_root); + self.watcher = WatchThread::new( + self.check_command.as_ref(), + &self.check_args, + &self.workspace_root, + ); } } } @@ -229,13 +249,25 @@ struct WatchThread { } impl WatchThread { - fn new(workspace_root: &PathBuf) -> WatchThread { - let manifest_path = format!("{}/Cargo.toml", workspace_root.to_string_lossy()); + fn new( + check_command: Option<&String>, + check_args: &[String], + workspace_root: &PathBuf, + ) -> WatchThread { + let check_command = check_command.cloned().unwrap_or("check".to_string()); + let mut args: Vec = vec![ + check_command, + "--message-format=json".to_string(), + "--manifest-path".to_string(), + format!("{}/Cargo.toml", workspace_root.to_string_lossy()), + ]; + args.extend(check_args.iter().cloned()); + let (message_send, message_recv) = unbounded(); let (cancel_send, cancel_recv) = unbounded(); std::thread::spawn(move || { let mut command = Command::new("cargo") - .args(&["check", "--message-format=json", "--manifest-path", &manifest_path]) + .args(&args) .stdout(Stdio::piped()) .stderr(Stdio::null()) .spawn() diff --git a/crates/ra_lsp_server/src/config.rs b/crates/ra_lsp_server/src/config.rs index 67942aa41..621f2238c 100644 --- a/crates/ra_lsp_server/src/config.rs +++ b/crates/ra_lsp_server/src/config.rs @@ -32,6 +32,10 @@ pub struct ServerConfig { pub max_inlay_hint_length: Option, + pub cargo_check_enable: bool, + pub cargo_check_command: Option, + pub cargo_check_args: Vec, + /// For internal usage to make integrated tests faster. #[serde(deserialize_with = "nullable_bool_true")] pub with_sysroot: bool, @@ -51,6 +55,9 @@ impl Default for ServerConfig { use_client_watching: false, lru_capacity: None, max_inlay_hint_length: None, + cargo_check_enable: true, + cargo_check_command: None, + cargo_check_args: vec![], with_sysroot: true, feature_flags: FxHashMap::default(), cargo_features: Default::default(), diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 943d38943..1f6175699 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs @@ -127,6 +127,9 @@ pub fn main_loop( .and_then(|it| it.line_folding_only) .unwrap_or(false), max_inlay_hint_length: config.max_inlay_hint_length, + cargo_check_enable: config.cargo_check_enable, + cargo_check_command: config.cargo_check_command, + cargo_check_args: config.cargo_check_args, } }; diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs index 8e9380ca0..235eb199d 100644 --- a/crates/ra_lsp_server/src/world.rs +++ b/crates/ra_lsp_server/src/world.rs @@ -35,6 +35,9 @@ pub struct Options { pub supports_location_link: bool, pub line_folding_only: bool, pub max_inlay_hint_length: Option, + pub cargo_check_enable: bool, + pub cargo_check_command: Option, + pub cargo_check_args: Vec, } /// `WorldState` is the primary mutable state of the language server @@ -131,7 +134,7 @@ impl WorldState { change.set_crate_graph(crate_graph); // FIXME: Figure out the multi-workspace situation - let check_watcher = CheckWatcher::new(folder_roots.first().cloned().unwrap()); + let check_watcher = CheckWatcher::new(&options, folder_roots.first().cloned().unwrap()); let mut analysis_host = AnalysisHost::new(lru_capacity, feature_flags); analysis_host.apply_change(change); -- cgit v1.2.3