diff options
-rw-r--r-- | crates/rust-analyzer/src/global_state.rs | 21 | ||||
-rw-r--r-- | crates/rust-analyzer/src/main_loop.rs | 5 | ||||
-rw-r--r-- | crates/rust-analyzer/src/reload.rs | 41 | ||||
-rw-r--r-- | crates/vfs/src/lib.rs | 2 |
4 files changed, 58 insertions, 11 deletions
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index c8d34e15a..728dc9962 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs | |||
@@ -122,6 +122,9 @@ impl GlobalState { | |||
122 | } | 122 | } |
123 | 123 | ||
124 | pub(crate) fn process_changes(&mut self) -> bool { | 124 | pub(crate) fn process_changes(&mut self) -> bool { |
125 | let mut fs_changes = Vec::new(); | ||
126 | let mut has_fs_changes = false; | ||
127 | |||
125 | let change = { | 128 | let change = { |
126 | let mut change = AnalysisChange::new(); | 129 | let mut change = AnalysisChange::new(); |
127 | let (vfs, line_endings_map) = &mut *self.vfs.write(); | 130 | let (vfs, line_endings_map) = &mut *self.vfs.write(); |
@@ -130,13 +133,14 @@ impl GlobalState { | |||
130 | return false; | 133 | return false; |
131 | } | 134 | } |
132 | 135 | ||
133 | let fs_op = changed_files.iter().any(|it| it.is_created_or_deleted()); | ||
134 | if fs_op { | ||
135 | let roots = self.source_root_config.partition(&vfs); | ||
136 | change.set_roots(roots) | ||
137 | } | ||
138 | |||
139 | for file in changed_files { | 136 | for file in changed_files { |
137 | if file.is_created_or_deleted() { | ||
138 | if let Some(path) = vfs.file_path(file.file_id).as_path() { | ||
139 | fs_changes.push((path.to_path_buf(), file.change_kind)); | ||
140 | has_fs_changes = true; | ||
141 | } | ||
142 | } | ||
143 | |||
140 | let text = if file.exists() { | 144 | let text = if file.exists() { |
141 | let bytes = vfs.file_contents(file.file_id).to_vec(); | 145 | let bytes = vfs.file_contents(file.file_id).to_vec(); |
142 | match String::from_utf8(bytes).ok() { | 146 | match String::from_utf8(bytes).ok() { |
@@ -152,10 +156,15 @@ impl GlobalState { | |||
152 | }; | 156 | }; |
153 | change.change_file(file.file_id, text); | 157 | change.change_file(file.file_id, text); |
154 | } | 158 | } |
159 | if has_fs_changes { | ||
160 | let roots = self.source_root_config.partition(&vfs); | ||
161 | change.set_roots(roots); | ||
162 | } | ||
155 | change | 163 | change |
156 | }; | 164 | }; |
157 | 165 | ||
158 | self.analysis_host.apply_change(change); | 166 | self.analysis_host.apply_change(change); |
167 | self.maybe_refresh(&fs_changes); | ||
159 | true | 168 | true |
160 | } | 169 | } |
161 | 170 | ||
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 96e2399ce..cea03fb6b 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs | |||
@@ -22,6 +22,7 @@ use crate::{ | |||
22 | Result, | 22 | Result, |
23 | }; | 23 | }; |
24 | use ra_project_model::ProjectWorkspace; | 24 | use ra_project_model::ProjectWorkspace; |
25 | use vfs::ChangeKind; | ||
25 | 26 | ||
26 | pub fn main_loop(config: Config, connection: Connection) -> Result<()> { | 27 | pub fn main_loop(config: Config, connection: Connection) -> Result<()> { |
27 | log::info!("initial config: {:#?}", config); | 28 | log::info!("initial config: {:#?}", config); |
@@ -428,7 +429,9 @@ impl GlobalState { | |||
428 | if let Some(flycheck) = &this.flycheck { | 429 | if let Some(flycheck) = &this.flycheck { |
429 | flycheck.handle.update(); | 430 | flycheck.handle.update(); |
430 | } | 431 | } |
431 | this.maybe_refresh(params.text_document.uri.as_str()); | 432 | if let Ok(abs_path) = from_proto::abs_path(¶ms.text_document.uri) { |
433 | this.maybe_refresh(&[(abs_path, ChangeKind::Modify)]); | ||
434 | } | ||
432 | Ok(()) | 435 | Ok(()) |
433 | })? | 436 | })? |
434 | .on::<lsp_types::notification::DidChangeConfiguration>(|this, _params| { | 437 | .on::<lsp_types::notification::DidChangeConfiguration>(|this, _params| { |
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index 0a201fceb..a425320f6 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs | |||
@@ -6,7 +6,7 @@ use flycheck::FlycheckHandle; | |||
6 | use ra_db::{CrateGraph, SourceRoot, VfsPath}; | 6 | use ra_db::{CrateGraph, SourceRoot, VfsPath}; |
7 | use ra_ide::AnalysisChange; | 7 | use ra_ide::AnalysisChange; |
8 | use ra_project_model::{PackageRoot, ProcMacroClient, ProjectWorkspace}; | 8 | use ra_project_model::{PackageRoot, ProcMacroClient, ProjectWorkspace}; |
9 | use vfs::{file_set::FileSetConfig, AbsPath}; | 9 | use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind}; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | config::{Config, FilesWatcher, LinkedProject}, | 12 | config::{Config, FilesWatcher, LinkedProject}, |
@@ -27,8 +27,8 @@ impl GlobalState { | |||
27 | self.reload_flycheck(); | 27 | self.reload_flycheck(); |
28 | } | 28 | } |
29 | } | 29 | } |
30 | pub(crate) fn maybe_refresh(&mut self, saved_doc_url: &str) { | 30 | pub(crate) fn maybe_refresh(&mut self, changes: &[(AbsPathBuf, ChangeKind)]) { |
31 | if !(saved_doc_url.ends_with("Cargo.toml") || saved_doc_url.ends_with("Cargo.lock")) { | 31 | if !changes.iter().any(|(path, kind)| is_interesting(path, *kind)) { |
32 | return; | 32 | return; |
33 | } | 33 | } |
34 | match self.status { | 34 | match self.status { |
@@ -40,6 +40,41 @@ impl GlobalState { | |||
40 | } else { | 40 | } else { |
41 | self.transition(Status::NeedsReload); | 41 | self.transition(Status::NeedsReload); |
42 | } | 42 | } |
43 | |||
44 | fn is_interesting(path: &AbsPath, change_kind: ChangeKind) -> bool { | ||
45 | const IMPLICIT_TARGET_FILES: &[&str] = &["build.rs", "src/main.rs", "src/lib.rs"]; | ||
46 | const IMPLICIT_TARGET_DIRS: &[&str] = &["src/bin", "examples", "tests", "benches"]; | ||
47 | |||
48 | if path.ends_with("Cargo.toml") || path.ends_with("Cargo.lock") { | ||
49 | return true; | ||
50 | } | ||
51 | if change_kind == ChangeKind::Modify { | ||
52 | return false; | ||
53 | } | ||
54 | if path.extension().map(|it| it.to_str()) != Some("rs".into()) { | ||
55 | return false; | ||
56 | } | ||
57 | if IMPLICIT_TARGET_FILES.iter().any(|it| path.ends_with(it)) { | ||
58 | return true; | ||
59 | } | ||
60 | let parent = match path.parent() { | ||
61 | Some(it) => it, | ||
62 | None => return false, | ||
63 | }; | ||
64 | if IMPLICIT_TARGET_DIRS.iter().any(|it| parent.ends_with(it)) { | ||
65 | return true; | ||
66 | } | ||
67 | if path.ends_with("main.rs") { | ||
68 | let grand_parent = match parent.parent() { | ||
69 | Some(it) => it, | ||
70 | None => return false, | ||
71 | }; | ||
72 | if IMPLICIT_TARGET_DIRS.iter().any(|it| grand_parent.ends_with(it)) { | ||
73 | return true; | ||
74 | } | ||
75 | } | ||
76 | false | ||
77 | } | ||
43 | } | 78 | } |
44 | pub(crate) fn transition(&mut self, new_status: Status) { | 79 | pub(crate) fn transition(&mut self, new_status: Status) { |
45 | self.status = new_status; | 80 | self.status = new_status; |
diff --git a/crates/vfs/src/lib.rs b/crates/vfs/src/lib.rs index 024e58018..569da8a1c 100644 --- a/crates/vfs/src/lib.rs +++ b/crates/vfs/src/lib.rs | |||
@@ -70,7 +70,7 @@ impl ChangedFile { | |||
70 | } | 70 | } |
71 | } | 71 | } |
72 | 72 | ||
73 | #[derive(Eq, PartialEq)] | 73 | #[derive(Eq, PartialEq, Copy, Clone)] |
74 | pub enum ChangeKind { | 74 | pub enum ChangeKind { |
75 | Create, | 75 | Create, |
76 | Modify, | 76 | Modify, |