aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-09-06 15:22:00 +0100
committerGitHub <[email protected]>2019-09-06 15:22:00 +0100
commit1acd9d5540bf755e87173fe16a803cfe8b2bb500 (patch)
treea5fb9afa541a4e6ab5818530b3fd19d5e461ef9e
parent007737a0e7dd2866e02a6398d8ee4aa7d5051d8c (diff)
parent28df377759ee5625b0dad4c797be306c8d2624e3 (diff)
Merge #1780
1780: add option to disable notify r=matklad a=matklad This should help if notify uses 100% of CPU. Put ``` { "rust-analyzer.useClientWatching": true, } ``` into `.vscode/settings.json` (or appropriate config of your editor) to use editor's file watching capabilites instead of notify Co-authored-by: Aleksey Kladov <[email protected]>
-rw-r--r--Cargo.lock10
-rw-r--r--crates/ra_batch/Cargo.toml2
-rw-r--r--crates/ra_batch/src/lib.rs3
-rw-r--r--crates/ra_lsp_server/Cargo.toml2
-rw-r--r--crates/ra_lsp_server/src/config.rs3
-rw-r--r--crates/ra_lsp_server/src/main_loop.rs174
-rw-r--r--crates/ra_lsp_server/src/req.rs9
-rw-r--r--crates/ra_lsp_server/src/world.rs5
-rw-r--r--crates/ra_vfs_glob/Cargo.toml2
-rw-r--r--docs/user/README.md2
-rw-r--r--editors/code/package.json5
-rw-r--r--editors/code/src/config.ts4
-rw-r--r--editors/code/src/server.ts1
13 files changed, 151 insertions, 71 deletions
diff --git a/Cargo.lock b/Cargo.lock
index c6fbe8ed0..f93f11a82 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -958,7 +958,7 @@ dependencies = [
958 "ra_hir 0.1.0", 958 "ra_hir 0.1.0",
959 "ra_ide_api 0.1.0", 959 "ra_ide_api 0.1.0",
960 "ra_project_model 0.1.0", 960 "ra_project_model 0.1.0",
961 "ra_vfs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 961 "ra_vfs 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
962 "ra_vfs_glob 0.1.0", 962 "ra_vfs_glob 0.1.0",
963 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 963 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
964] 964]
@@ -1065,7 +1065,7 @@ dependencies = [
1065 "ra_project_model 0.1.0", 1065 "ra_project_model 0.1.0",
1066 "ra_syntax 0.1.0", 1066 "ra_syntax 0.1.0",
1067 "ra_text_edit 0.1.0", 1067 "ra_text_edit 0.1.0",
1068 "ra_vfs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1068 "ra_vfs 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
1069 "ra_vfs_glob 0.1.0", 1069 "ra_vfs_glob 0.1.0",
1070 "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1070 "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
1071 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1071 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1165,7 +1165,7 @@ dependencies = [
1165 1165
1166[[package]] 1166[[package]]
1167name = "ra_vfs" 1167name = "ra_vfs"
1168version = "0.3.0" 1168version = "0.4.0"
1169source = "registry+https://github.com/rust-lang/crates.io-index" 1169source = "registry+https://github.com/rust-lang/crates.io-index"
1170dependencies = [ 1170dependencies = [
1171 "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 1171 "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1183,7 +1183,7 @@ name = "ra_vfs_glob"
1183version = "0.1.0" 1183version = "0.1.0"
1184dependencies = [ 1184dependencies = [
1185 "globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 1185 "globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
1186 "ra_vfs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1186 "ra_vfs 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
1187] 1187]
1188 1188
1189[[package]] 1189[[package]]
@@ -1945,7 +1945,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1945"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" 1945"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
1946"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" 1946"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
1947"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" 1947"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
1948"checksum ra_vfs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ccc8b709e0b7ceec822513451b610df1b9370b01953a8bc545a041a6b3bfef01" 1948"checksum ra_vfs 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdf6a0926414eb0c00866eb9274894182302f879cd06b5459c1d8ee7f1234aed"
1949"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" 1949"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
1950"checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c" 1950"checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c"
1951"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" 1951"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
diff --git a/crates/ra_batch/Cargo.toml b/crates/ra_batch/Cargo.toml
index 5fc2703ee..62850746f 100644
--- a/crates/ra_batch/Cargo.toml
+++ b/crates/ra_batch/Cargo.toml
@@ -9,7 +9,7 @@ log = "0.4.5"
9rustc-hash = "1.0" 9rustc-hash = "1.0"
10crossbeam-channel = "0.3.5" 10crossbeam-channel = "0.3.5"
11 11
12ra_vfs = "0.3.0" 12ra_vfs = "0.4.0"
13ra_vfs_glob = { path = "../ra_vfs_glob" } 13ra_vfs_glob = { path = "../ra_vfs_glob" }
14ra_db = { path = "../ra_db" } 14ra_db = { path = "../ra_db" }
15ra_ide_api = { path = "../ra_ide_api" } 15ra_ide_api = { path = "../ra_ide_api" }
diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs
index 4e5bad044..07a7e0c86 100644
--- a/crates/ra_batch/src/lib.rs
+++ b/crates/ra_batch/src/lib.rs
@@ -6,7 +6,7 @@ use crossbeam_channel::{unbounded, Receiver};
6use ra_db::{CrateGraph, FileId, SourceRootId}; 6use ra_db::{CrateGraph, FileId, SourceRootId};
7use ra_ide_api::{AnalysisChange, AnalysisHost, FeatureFlags}; 7use ra_ide_api::{AnalysisChange, AnalysisHost, FeatureFlags};
8use ra_project_model::{PackageRoot, ProjectWorkspace}; 8use ra_project_model::{PackageRoot, ProjectWorkspace};
9use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask}; 9use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch};
10use ra_vfs_glob::RustPackageFilterBuilder; 10use ra_vfs_glob::RustPackageFilterBuilder;
11 11
12type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>; 12type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>;
@@ -37,6 +37,7 @@ pub fn load_cargo(root: &Path) -> Result<(AnalysisHost, FxHashMap<SourceRootId,
37 }) 37 })
38 .collect(), 38 .collect(),
39 sender, 39 sender,
40 Watch(false),
40 ); 41 );
41 let crate_graph = ws.to_crate_graph(&mut |path: &Path| { 42 let crate_graph = ws.to_crate_graph(&mut |path: &Path| {
42 let vfs_file = vfs.load(path); 43 let vfs_file = vfs.load(path);
diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml
index 07cc2dd32..46a0f958c 100644
--- a/crates/ra_lsp_server/Cargo.toml
+++ b/crates/ra_lsp_server/Cargo.toml
@@ -16,7 +16,7 @@ lsp-types = { version = "0.61.0", features = ["proposed"] }
16rustc-hash = "1.0" 16rustc-hash = "1.0"
17parking_lot = "0.9.0" 17parking_lot = "0.9.0"
18jod-thread = "0.1.0" 18jod-thread = "0.1.0"
19ra_vfs = "0.3.0" 19ra_vfs = "0.4.0"
20ra_syntax = { path = "../ra_syntax" } 20ra_syntax = { path = "../ra_syntax" }
21ra_text_edit = { path = "../ra_text_edit" } 21ra_text_edit = { path = "../ra_text_edit" }
22ra_ide_api = { path = "../ra_ide_api" } 22ra_ide_api = { path = "../ra_ide_api" }
diff --git a/crates/ra_lsp_server/src/config.rs b/crates/ra_lsp_server/src/config.rs
index 5c5ae3e18..cf53e7c4c 100644
--- a/crates/ra_lsp_server/src/config.rs
+++ b/crates/ra_lsp_server/src/config.rs
@@ -15,6 +15,8 @@ pub struct ServerConfig {
15 pub publish_decorations: bool, 15 pub publish_decorations: bool,
16 16
17 pub exclude_globs: Vec<String>, 17 pub exclude_globs: Vec<String>,
18 #[serde(deserialize_with = "nullable_bool_false")]
19 pub use_client_watching: bool,
18 20
19 pub lru_capacity: Option<usize>, 21 pub lru_capacity: Option<usize>,
20 22
@@ -31,6 +33,7 @@ impl Default for ServerConfig {
31 ServerConfig { 33 ServerConfig {
32 publish_decorations: false, 34 publish_decorations: false,
33 exclude_globs: Vec::new(), 35 exclude_globs: Vec::new(),
36 use_client_watching: false,
34 lru_capacity: None, 37 lru_capacity: None,
35 with_sysroot: true, 38 with_sysroot: true,
36 feature_flags: FxHashMap::default(), 39 feature_flags: FxHashMap::default(),
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs
index 80f0216e8..25fa51b8a 100644
--- a/crates/ra_lsp_server/src/main_loop.rs
+++ b/crates/ra_lsp_server/src/main_loop.rs
@@ -9,8 +9,9 @@ use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestI
9use lsp_types::{ClientCapabilities, NumberOrString}; 9use lsp_types::{ClientCapabilities, NumberOrString};
10use ra_ide_api::{Canceled, FeatureFlags, FileId, LibraryData, SourceRootId}; 10use ra_ide_api::{Canceled, FeatureFlags, FileId, LibraryData, SourceRootId};
11use ra_prof::profile; 11use ra_prof::profile;
12use ra_vfs::VfsTask; 12use ra_vfs::{VfsTask, Watch};
13use relative_path::RelativePathBuf; 13use relative_path::RelativePathBuf;
14use rustc_hash::FxHashSet;
14use serde::{de::DeserializeOwned, Serialize}; 15use serde::{de::DeserializeOwned, Serialize};
15use threadpool::ThreadPool; 16use threadpool::ThreadPool;
16 17
@@ -55,72 +56,96 @@ pub fn main_loop(
55) -> Result<()> { 56) -> Result<()> {
56 log::info!("server_config: {:#?}", config); 57 log::info!("server_config: {:#?}", config);
57 58
58 // FIXME: support dynamic workspace loading. 59 let mut loop_state = LoopState::default();
59 let workspaces = { 60 let mut world_state = {
60 let mut loaded_workspaces = Vec::new(); 61 // FIXME: support dynamic workspace loading.
61 for ws_root in &ws_roots { 62 let workspaces = {
62 let workspace = ra_project_model::ProjectWorkspace::discover_with_sysroot( 63 let mut loaded_workspaces = Vec::new();
63 ws_root.as_path(), 64 for ws_root in &ws_roots {
64 config.with_sysroot, 65 let workspace = ra_project_model::ProjectWorkspace::discover_with_sysroot(
65 ); 66 ws_root.as_path(),
66 match workspace { 67 config.with_sysroot,
67 Ok(workspace) => loaded_workspaces.push(workspace), 68 );
68 Err(e) => { 69 match workspace {
69 log::error!("loading workspace failed: {}", e); 70 Ok(workspace) => loaded_workspaces.push(workspace),
71 Err(e) => {
72 log::error!("loading workspace failed: {}", e);
73
74 show_message(
75 req::MessageType::Error,
76 format!("rust-analyzer failed to load workspace: {}", e),
77 &connection.sender,
78 );
79 }
80 }
81 }
82 loaded_workspaces
83 };
70 84
85 let globs = config
86 .exclude_globs
87 .iter()
88 .map(|glob| ra_vfs_glob::Glob::new(glob))
89 .collect::<std::result::Result<Vec<_>, _>>()?;
90
91 if config.use_client_watching {
92 let registration_options = req::DidChangeWatchedFilesRegistrationOptions {
93 watchers: workspaces
94 .iter()
95 .flat_map(|ws| ws.to_roots())
96 .filter(|root| root.is_member())
97 .map(|root| format!("{}/**/*.rs", root.path().display()))
98 .map(|glob_pattern| req::FileSystemWatcher { glob_pattern, kind: None })
99 .collect(),
100 };
101 let registration = req::Registration {
102 id: "file-watcher".to_string(),
103 method: "workspace/didChangeWatchedFiles".to_string(),
104 register_options: Some(serde_json::to_value(registration_options).unwrap()),
105 };
106 let params = req::RegistrationParams { registrations: vec![registration] };
107 let request =
108 request_new::<req::RegisterCapability>(loop_state.next_request_id(), params);
109 connection.sender.send(request.into()).unwrap();
110 }
111
112 let feature_flags = {
113 let mut ff = FeatureFlags::default();
114 for (flag, value) in config.feature_flags {
115 if let Err(_) = ff.set(flag.as_str(), value) {
116 log::error!("unknown feature flag: {:?}", flag);
71 show_message( 117 show_message(
72 req::MessageType::Error, 118 req::MessageType::Error,
73 format!("rust-analyzer failed to load workspace: {}", e), 119 format!("unknown feature flag: {:?}", flag),
74 &connection.sender, 120 &connection.sender,
75 ); 121 );
76 } 122 }
77 } 123 }
78 } 124 ff
79 loaded_workspaces 125 };
80 }; 126 log::info!("feature_flags: {:#?}", feature_flags);
81 127
82 let globs = config 128 WorldState::new(
83 .exclude_globs 129 ws_roots,
84 .iter() 130 workspaces,
85 .map(|glob| ra_vfs_glob::Glob::new(glob)) 131 config.lru_capacity,
86 .collect::<std::result::Result<Vec<_>, _>>()?; 132 &globs,
87 133 Watch(!config.use_client_watching),
88 let feature_flags = { 134 Options {
89 let mut ff = FeatureFlags::default(); 135 publish_decorations: config.publish_decorations,
90 for (flag, value) in config.feature_flags { 136 supports_location_link: client_caps
91 if let Err(_) = ff.set(flag.as_str(), value) { 137 .text_document
92 log::error!("unknown feature flag: {:?}", flag); 138 .and_then(|it| it.definition)
93 show_message( 139 .and_then(|it| it.link_support)
94 req::MessageType::Error, 140 .unwrap_or(false),
95 format!("unknown feature flag: {:?}", flag), 141 },
96 &connection.sender, 142 feature_flags,
97 ); 143 )
98 }
99 }
100 ff
101 }; 144 };
102 log::info!("feature_flags: {:#?}", feature_flags);
103
104 let mut world_state = WorldState::new(
105 ws_roots,
106 workspaces,
107 config.lru_capacity,
108 &globs,
109 Options {
110 publish_decorations: config.publish_decorations,
111 supports_location_link: client_caps
112 .text_document
113 .and_then(|it| it.definition)
114 .and_then(|it| it.link_support)
115 .unwrap_or(false),
116 },
117 feature_flags,
118 );
119 145
120 let pool = ThreadPool::new(THREADPOOL_SIZE); 146 let pool = ThreadPool::new(THREADPOOL_SIZE);
121 let (task_sender, task_receiver) = unbounded::<Task>(); 147 let (task_sender, task_receiver) = unbounded::<Task>();
122 let (libdata_sender, libdata_receiver) = unbounded::<LibraryData>(); 148 let (libdata_sender, libdata_receiver) = unbounded::<LibraryData>();
123 let mut loop_state = LoopState::default();
124 149
125 log::info!("server initialized, serving requests"); 150 log::info!("server initialized, serving requests");
126 { 151 {
@@ -227,6 +252,8 @@ impl fmt::Debug for Event {
227 252
228#[derive(Debug, Default)] 253#[derive(Debug, Default)]
229struct LoopState { 254struct LoopState {
255 next_request_id: u64,
256 pending_responses: FxHashSet<RequestId>,
230 pending_requests: PendingRequests, 257 pending_requests: PendingRequests,
231 subscriptions: Subscriptions, 258 subscriptions: Subscriptions,
232 // We try not to index more than MAX_IN_FLIGHT_LIBS libraries at the same 259 // We try not to index more than MAX_IN_FLIGHT_LIBS libraries at the same
@@ -236,6 +263,16 @@ struct LoopState {
236 workspace_loaded: bool, 263 workspace_loaded: bool,
237} 264}
238 265
266impl LoopState {
267 fn next_request_id(&mut self) -> RequestId {
268 self.next_request_id += 1;
269 let res: RequestId = self.next_request_id.into();
270 let inserted = self.pending_responses.insert(res.clone());
271 assert!(inserted);
272 res
273 }
274}
275
239fn loop_turn( 276fn loop_turn(
240 pool: &ThreadPool, 277 pool: &ThreadPool,
241 task_sender: &Sender<Task>, 278 task_sender: &Sender<Task>,
@@ -290,7 +327,12 @@ fn loop_turn(
290 )?; 327 )?;
291 state_changed = true; 328 state_changed = true;
292 } 329 }
293 Message::Response(resp) => log::error!("unexpected response: {:?}", resp), 330 Message::Response(resp) => {
331 let removed = loop_state.pending_responses.remove(&resp.id);
332 if !removed {
333 log::error!("unexpected response: {:?}", resp)
334 }
335 }
294 }, 336 },
295 }; 337 };
296 338
@@ -479,6 +521,18 @@ fn on_notification(
479 } 521 }
480 Err(not) => not, 522 Err(not) => not,
481 }; 523 };
524 let not = match notification_cast::<req::DidChangeWatchedFiles>(not) {
525 Ok(params) => {
526 let mut vfs = state.vfs.write();
527 for change in params.changes {
528 let uri = change.uri;
529 let path = uri.to_file_path().map_err(|()| format!("invalid uri: {}", uri))?;
530 vfs.notify_changed(path)
531 }
532 return Ok(());
533 }
534 Err(not) => not,
535 };
482 log::error!("unhandled notification: {:?}", not); 536 log::error!("unhandled notification: {:?}", not);
483 Ok(()) 537 Ok(())
484} 538}
@@ -682,3 +736,11 @@ where
682{ 736{
683 Notification::new(N::METHOD.to_string(), params) 737 Notification::new(N::METHOD.to_string(), params)
684} 738}
739
740fn request_new<R>(id: RequestId, params: R::Params) -> Request
741where
742 R: lsp_types::request::Request,
743 R::Params: Serialize,
744{
745 Request::new(id, R::METHOD.to_string(), params)
746}
diff --git a/crates/ra_lsp_server/src/req.rs b/crates/ra_lsp_server/src/req.rs
index 1b23f0c3d..0540f166e 100644
--- a/crates/ra_lsp_server/src/req.rs
+++ b/crates/ra_lsp_server/src/req.rs
@@ -5,10 +5,11 @@ use serde::{Deserialize, Serialize};
5pub use lsp_types::{ 5pub use lsp_types::{
6 notification::*, request::*, ApplyWorkspaceEditParams, CodeActionParams, CodeLens, 6 notification::*, request::*, ApplyWorkspaceEditParams, CodeActionParams, CodeLens,
7 CodeLensParams, CompletionParams, CompletionResponse, DidChangeConfigurationParams, 7 CodeLensParams, CompletionParams, CompletionResponse, DidChangeConfigurationParams,
8 DocumentOnTypeFormattingParams, DocumentSymbolParams, DocumentSymbolResponse, Hover, 8 DidChangeWatchedFilesParams, DidChangeWatchedFilesRegistrationOptions,
9 InitializeResult, MessageType, PublishDiagnosticsParams, ReferenceParams, ShowMessageParams, 9 DocumentOnTypeFormattingParams, DocumentSymbolParams, DocumentSymbolResponse,
10 SignatureHelp, TextDocumentEdit, TextDocumentPositionParams, TextEdit, WorkspaceEdit, 10 FileSystemWatcher, Hover, InitializeResult, MessageType, PublishDiagnosticsParams,
11 WorkspaceSymbolParams, 11 ReferenceParams, Registration, RegistrationParams, ShowMessageParams, SignatureHelp,
12 TextDocumentEdit, TextDocumentPositionParams, TextEdit, WorkspaceEdit, WorkspaceSymbolParams,
12}; 13};
13 14
14pub enum AnalyzerStatus {} 15pub enum AnalyzerStatus {}
diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs
index e1c5c3343..086ecd587 100644
--- a/crates/ra_lsp_server/src/world.rs
+++ b/crates/ra_lsp_server/src/world.rs
@@ -12,7 +12,7 @@ use ra_ide_api::{
12 SourceRootId, 12 SourceRootId,
13}; 13};
14use ra_project_model::ProjectWorkspace; 14use ra_project_model::ProjectWorkspace;
15use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsRoot, VfsTask}; 15use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsRoot, VfsTask, Watch};
16use ra_vfs_glob::{Glob, RustPackageFilterBuilder}; 16use ra_vfs_glob::{Glob, RustPackageFilterBuilder};
17use relative_path::RelativePathBuf; 17use relative_path::RelativePathBuf;
18 18
@@ -60,6 +60,7 @@ impl WorldState {
60 workspaces: Vec<ProjectWorkspace>, 60 workspaces: Vec<ProjectWorkspace>,
61 lru_capacity: Option<usize>, 61 lru_capacity: Option<usize>,
62 exclude_globs: &[Glob], 62 exclude_globs: &[Glob],
63 watch: Watch,
63 options: Options, 64 options: Options,
64 feature_flags: FeatureFlags, 65 feature_flags: FeatureFlags,
65 ) -> WorldState { 66 ) -> WorldState {
@@ -85,7 +86,7 @@ impl WorldState {
85 } 86 }
86 let (task_sender, task_receiver) = unbounded(); 87 let (task_sender, task_receiver) = unbounded();
87 let task_sender = Box::new(move |t| task_sender.send(t).unwrap()); 88 let task_sender = Box::new(move |t| task_sender.send(t).unwrap());
88 let (mut vfs, vfs_roots) = Vfs::new(roots, task_sender); 89 let (mut vfs, vfs_roots) = Vfs::new(roots, task_sender, watch);
89 let roots_to_scan = vfs_roots.len(); 90 let roots_to_scan = vfs_roots.len();
90 for r in vfs_roots { 91 for r in vfs_roots {
91 let vfs_root_path = vfs.root2path(r); 92 let vfs_root_path = vfs.root2path(r);
diff --git a/crates/ra_vfs_glob/Cargo.toml b/crates/ra_vfs_glob/Cargo.toml
index 09ba3d3bf..d1073b2be 100644
--- a/crates/ra_vfs_glob/Cargo.toml
+++ b/crates/ra_vfs_glob/Cargo.toml
@@ -5,5 +5,5 @@ version = "0.1.0"
5authors = ["rust-analyzer developers"] 5authors = ["rust-analyzer developers"]
6 6
7[dependencies] 7[dependencies]
8ra_vfs = "0.3.0" 8ra_vfs = "0.4.0"
9globset = "0.4.4" 9globset = "0.4.4"
diff --git a/docs/user/README.md b/docs/user/README.md
index 453e8e273..56c2d9eb5 100644
--- a/docs/user/README.md
+++ b/docs/user/README.md
@@ -74,6 +74,8 @@ See https://github.com/microsoft/vscode/issues/72308[microsoft/vscode#72308] for
74* `rust-analyzer.excludeGlobs`: a list of glob-patterns for exclusion (see globset [docs](https://docs.rs/globset) for syntax). 74* `rust-analyzer.excludeGlobs`: a list of glob-patterns for exclusion (see globset [docs](https://docs.rs/globset) for syntax).
75 Note: glob patterns are applied to all Cargo packages and a rooted at a package root. 75 Note: glob patterns are applied to all Cargo packages and a rooted at a package root.
76 This is not very intuitive and a limitation of a current implementation. 76 This is not very intuitive and a limitation of a current implementation.
77* `rust-analyzer.useClientWatching`: use client provided file watching instead
78 of notify watching.
77* `rust-analyzer.cargo-watch.check-arguments`: cargo-watch check arguments. 79* `rust-analyzer.cargo-watch.check-arguments`: cargo-watch check arguments.
78 (e.g: `--features="shumway,pdf"` will run as `cargo watch -x "check --features="shumway,pdf""` ) 80 (e.g: `--features="shumway,pdf"` will run as `cargo watch -x "check --features="shumway,pdf""` )
79* `rust-analyzer.trace.server`: enables internal logging 81* `rust-analyzer.trace.server`: enables internal logging
diff --git a/editors/code/package.json b/editors/code/package.json
index e2bc72f32..7a48d6794 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -205,6 +205,11 @@
205 "default": [], 205 "default": [],
206 "description": "Paths to exclude from analysis" 206 "description": "Paths to exclude from analysis"
207 }, 207 },
208 "rust-analyzer.useClientWatching": {
209 "type": "boolean",
210 "default": false,
211 "description": "client provided file watching instead of notify watching."
212 },
208 "rust-analyzer.cargo-watch.arguments": { 213 "rust-analyzer.cargo-watch.arguments": {
209 "type": "string", 214 "type": "string",
210 "description": "`cargo-watch` arguments. (e.g: `--features=\"shumway,pdf\"` will run as `cargo watch -x \"check --features=\"shumway,pdf\"\"` )", 215 "description": "`cargo-watch` arguments. (e.g: `--features=\"shumway,pdf\"` will run as `cargo watch -x \"check --features=\"shumway,pdf\"\"` )",
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts
index 570ddca46..a4581485c 100644
--- a/editors/code/src/config.ts
+++ b/editors/code/src/config.ts
@@ -23,6 +23,7 @@ export class Config {
23 public lruCapacity: null | number = null; 23 public lruCapacity: null | number = null;
24 public displayInlayHints = true; 24 public displayInlayHints = true;
25 public excludeGlobs = []; 25 public excludeGlobs = [];
26 public useClientWatching = false;
26 public featureFlags = {}; 27 public featureFlags = {};
27 public cargoWatchOptions: CargoWatchOptions = { 28 public cargoWatchOptions: CargoWatchOptions = {
28 enableOnStartup: 'ask', 29 enableOnStartup: 'ask',
@@ -133,6 +134,9 @@ export class Config {
133 if (config.has('excludeGlobs')) { 134 if (config.has('excludeGlobs')) {
134 this.excludeGlobs = config.get('excludeGlobs') || []; 135 this.excludeGlobs = config.get('excludeGlobs') || [];
135 } 136 }
137 if (config.has('useClientWatching')) {
138 this.useClientWatching = config.get('useClientWatching') || false;
139 }
136 if (config.has('featureFlags')) { 140 if (config.has('featureFlags')) {
137 this.featureFlags = config.get('featureFlags') || {}; 141 this.featureFlags = config.get('featureFlags') || {};
138 } 142 }
diff --git a/editors/code/src/server.ts b/editors/code/src/server.ts
index 0d2a99c70..ff50fcd99 100644
--- a/editors/code/src/server.ts
+++ b/editors/code/src/server.ts
@@ -46,6 +46,7 @@ export class Server {
46 Server.config.showWorkspaceLoadedNotification, 46 Server.config.showWorkspaceLoadedNotification,
47 lruCapacity: Server.config.lruCapacity, 47 lruCapacity: Server.config.lruCapacity,
48 excludeGlobs: Server.config.excludeGlobs, 48 excludeGlobs: Server.config.excludeGlobs,
49 useClientWatching: Server.config.useClientWatching,
49 featureFlags: Server.config.featureFlags 50 featureFlags: Server.config.featureFlags
50 }, 51 },
51 traceOutputChannel 52 traceOutputChannel