aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server/src/server_world.rs
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-04-14 18:26:07 +0100
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-04-14 18:26:07 +0100
commit88be6f32172813f53dae60d73c9f5deb0c3fb29f (patch)
tree0b5f8f793929f651dfe332e0f5545b938ff5189f /crates/ra_lsp_server/src/server_world.rs
parent5d35f284f5ac70cde5d758e7c63a38eae0fb0b55 (diff)
parentc2dfc8a229c0a18dff08d5ce7e6836c91648eee5 (diff)
Merge #1137
1137: Adds support for multiple editor workspaces on initialization r=matklad a=jrvidal OK, so this "simple hack" turned out to be way more contrived than I expected :joy: ### What works This patch only handles multi-folder editor workspaces _on initialization_. * I've found that modifying the layout of a workspace in VSCode just reloads the extension, so this hack should be enough for now. * Not sure about how emacs-lsp behaves, but we fallback gracefully to the mono-folder workspace, so it should be fine. ### What doesn't work * [x] `cargo watch` can only watch a single root folder with a `Cargo.toml`. I've left this part untouched but we could either warn that it's not supported or launch _multiple_ `cargo-watch` processes. * [x] The `rust-analyzer/runnables` command is not functional, since we don't send the correct `cwd`. * [x] Should we add some happy path test to `heavy_tests`? * [ ] Going from a single `root` to multiple `roots` leaves us with a couple of `n * m` loops that smell a bit. The number of folders in the editor workspace is probably low though. Co-authored-by: Roberto Vidal <[email protected]>
Diffstat (limited to 'crates/ra_lsp_server/src/server_world.rs')
-rw-r--r--crates/ra_lsp_server/src/server_world.rs27
1 files changed, 17 insertions, 10 deletions
diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs
index 4b1d592bb..b2808b817 100644
--- a/crates/ra_lsp_server/src/server_world.rs
+++ b/crates/ra_lsp_server/src/server_world.rs
@@ -1,5 +1,5 @@
1use std::{ 1use std::{
2 path::PathBuf, 2 path::{Path, PathBuf},
3 sync::Arc, 3 sync::Arc,
4}; 4};
5 5
@@ -24,7 +24,7 @@ use crate::{
24#[derive(Debug)] 24#[derive(Debug)]
25pub struct ServerWorldState { 25pub struct ServerWorldState {
26 pub roots_to_scan: usize, 26 pub roots_to_scan: usize,
27 pub root: PathBuf, 27 pub roots: Vec<PathBuf>,
28 pub workspaces: Arc<Vec<ProjectWorkspace>>, 28 pub workspaces: Arc<Vec<ProjectWorkspace>>,
29 pub analysis_host: AnalysisHost, 29 pub analysis_host: AnalysisHost,
30 pub vfs: Arc<RwLock<Vfs>>, 30 pub vfs: Arc<RwLock<Vfs>>,
@@ -37,19 +37,20 @@ pub struct ServerWorld {
37} 37}
38 38
39impl ServerWorldState { 39impl ServerWorldState {
40 pub fn new(root: PathBuf, workspaces: Vec<ProjectWorkspace>) -> ServerWorldState { 40 pub fn new(folder_roots: Vec<PathBuf>, workspaces: Vec<ProjectWorkspace>) -> ServerWorldState {
41 let mut change = AnalysisChange::new(); 41 let mut change = AnalysisChange::new();
42 42
43 let mut roots = Vec::new(); 43 let mut roots = Vec::new();
44 roots.push(IncludeRustFiles::member(root.clone())); 44 roots.extend(folder_roots.iter().cloned().map(IncludeRustFiles::member));
45 for ws in workspaces.iter() { 45 for ws in workspaces.iter() {
46 roots.extend(IncludeRustFiles::from_roots(ws.to_roots())); 46 roots.extend(IncludeRustFiles::from_roots(ws.to_roots()));
47 } 47 }
48 48
49 let (mut vfs, roots) = Vfs::new(roots); 49 let (mut vfs, vfs_roots) = Vfs::new(roots);
50 let roots_to_scan = roots.len(); 50 let roots_to_scan = vfs_roots.len();
51 for r in roots { 51 for r in vfs_roots {
52 let is_local = vfs.root2path(r).starts_with(&root); 52 let vfs_root_path = vfs.root2path(r);
53 let is_local = folder_roots.iter().any(|it| vfs_root_path.starts_with(it));
53 change.add_root(SourceRootId(r.0.into()), is_local); 54 change.add_root(SourceRootId(r.0.into()), is_local);
54 } 55 }
55 56
@@ -68,7 +69,7 @@ impl ServerWorldState {
68 analysis_host.apply_change(change); 69 analysis_host.apply_change(change);
69 ServerWorldState { 70 ServerWorldState {
70 roots_to_scan, 71 roots_to_scan,
71 root, 72 roots: folder_roots,
72 workspaces: Arc::new(workspaces), 73 workspaces: Arc::new(workspaces),
73 analysis_host, 74 analysis_host,
74 vfs: Arc::new(RwLock::new(vfs)), 75 vfs: Arc::new(RwLock::new(vfs)),
@@ -90,7 +91,8 @@ impl ServerWorldState {
90 match c { 91 match c {
91 VfsChange::AddRoot { root, files } => { 92 VfsChange::AddRoot { root, files } => {
92 let root_path = self.vfs.read().root2path(root); 93 let root_path = self.vfs.read().root2path(root);
93 if root_path.starts_with(&self.root) { 94 let is_local = self.roots.iter().any(|r| root_path.starts_with(r));
95 if is_local {
94 self.roots_to_scan -= 1; 96 self.roots_to_scan -= 1;
95 for (file, path, text) in files { 97 for (file, path, text) in files {
96 change.add_file( 98 change.add_file(
@@ -193,4 +195,9 @@ impl ServerWorld {
193 res.push_str(&self.analysis.status()); 195 res.push_str(&self.analysis.status());
194 res 196 res
195 } 197 }
198
199 pub fn workspace_root_for(&self, file_id: FileId) -> Option<&Path> {
200 let path = self.vfs.read().file2path(VfsFile(file_id.0.into()));
201 self.workspaces.iter().find_map(|ws| ws.workspace_root_for(&path))
202 }
196} 203}