aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server/src
diff options
context:
space:
mode:
authorRoberto Vidal <[email protected]>2019-04-11 07:08:19 +0100
committerRoberto Vidal <[email protected]>2019-04-14 09:04:38 +0100
commit3507bcb97aaaafba10d55c101bd295f3ab4fed4f (patch)
treee4febb3206524a6f07641c884734afef9c153674 /crates/ra_lsp_server/src
parent23b876bc3b00c53ce24b8a99b4f4bf190fc6300e (diff)
Adds support for multiple editor workspaces on initialization
This is a quick, partial fix for #1104
Diffstat (limited to 'crates/ra_lsp_server/src')
-rw-r--r--crates/ra_lsp_server/src/main.rs13
-rw-r--r--crates/ra_lsp_server/src/main_loop.rs31
-rw-r--r--crates/ra_lsp_server/src/server_world.rs20
3 files changed, 40 insertions, 24 deletions
diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs
index eb4091a3d..82f52a6e8 100644
--- a/crates/ra_lsp_server/src/main.rs
+++ b/crates/ra_lsp_server/src/main.rs
@@ -40,12 +40,23 @@ fn main_inner() -> Result<()> {
40 run_server(ra_lsp_server::server_capabilities(), receiver, sender, |params, r, s| { 40 run_server(ra_lsp_server::server_capabilities(), receiver, sender, |params, r, s| {
41 let root = params.root_uri.and_then(|it| it.to_file_path().ok()).unwrap_or(cwd); 41 let root = params.root_uri.and_then(|it| it.to_file_path().ok()).unwrap_or(cwd);
42 42
43 let workspace_roots = params
44 .workspace_folders
45 .map(|workspaces| {
46 workspaces
47 .into_iter()
48 .filter_map(|it| it.uri.to_file_path().ok())
49 .collect::<Vec<_>>()
50 })
51 .filter(|workspaces| !workspaces.is_empty())
52 .unwrap_or_else(|| vec![root]);
53
43 let opts = params 54 let opts = params
44 .initialization_options 55 .initialization_options
45 .and_then(|v| InitializationOptions::deserialize(v).ok()) 56 .and_then(|v| InitializationOptions::deserialize(v).ok())
46 .unwrap_or(InitializationOptions::default()); 57 .unwrap_or(InitializationOptions::default());
47 58
48 ra_lsp_server::main_loop(root, opts, r, s) 59 ra_lsp_server::main_loop(workspace_roots, opts, r, s)
49 })?; 60 })?;
50 log::info!("shutting down IO..."); 61 log::info!("shutting down IO...");
51 threads.join()?; 62 threads.join()?;
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs
index 82410bee3..07ac4917a 100644
--- a/crates/ra_lsp_server/src/main_loop.rs
+++ b/crates/ra_lsp_server/src/main_loop.rs
@@ -48,7 +48,7 @@ enum Task {
48const THREADPOOL_SIZE: usize = 8; 48const THREADPOOL_SIZE: usize = 8;
49 49
50pub fn main_loop( 50pub fn main_loop(
51 ws_root: PathBuf, 51 ws_roots: Vec<PathBuf>,
52 options: InitializationOptions, 52 options: InitializationOptions,
53 msg_receiver: &Receiver<RawMessage>, 53 msg_receiver: &Receiver<RawMessage>,
54 msg_sender: &Sender<RawMessage>, 54 msg_sender: &Sender<RawMessage>,
@@ -59,23 +59,26 @@ pub fn main_loop(
59 // FIXME: support dynamic workspace loading. 59 // FIXME: support dynamic workspace loading.
60 let workspaces = { 60 let workspaces = {
61 let ws_worker = workspace_loader(); 61 let ws_worker = workspace_loader();
62 ws_worker.sender().send(ws_root.clone()).unwrap(); 62 let mut loaded_workspaces = Vec::new();
63 match ws_worker.receiver().recv().unwrap() { 63 for ws_root in &ws_roots {
64 Ok(ws) => vec![ws], 64 ws_worker.sender().send(ws_root.clone()).unwrap();
65 Err(e) => { 65 match ws_worker.receiver().recv().unwrap() {
66 log::error!("loading workspace failed: {}", e); 66 Ok(ws) => loaded_workspaces.push(ws),
67 67 Err(e) => {
68 show_message( 68 log::error!("loading workspace failed: {}", e);
69 req::MessageType::Error, 69
70 format!("rust-analyzer failed to load workspace: {}", e), 70 show_message(
71 msg_sender, 71 req::MessageType::Error,
72 ); 72 format!("rust-analyzer failed to load workspace: {}", e),
73 Vec::new() 73 msg_sender,
74 );
75 }
74 } 76 }
75 } 77 }
78 loaded_workspaces
76 }; 79 };
77 80
78 let mut state = ServerWorldState::new(ws_root.clone(), workspaces); 81 let mut state = ServerWorldState::new(ws_roots, workspaces);
79 82
80 log::info!("server initialized, serving requests"); 83 log::info!("server initialized, serving requests");
81 84
diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs
index 4b1d592bb..45ad8e24e 100644
--- a/crates/ra_lsp_server/src/server_world.rs
+++ b/crates/ra_lsp_server/src/server_world.rs
@@ -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(