Skip to content

Commit 4883966

Browse files
authored
Merge pull request #18998 from ChayimFriedman2/exclude
fix: Make `rust-analyzer.files.excludeDirs` work, actually
2 parents 5373014 + c7e331b commit 4883966

File tree

15 files changed

+262
-131
lines changed

15 files changed

+262
-131
lines changed

src/tools/rust-analyzer/crates/load-cargo/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,9 @@ pub fn load_workspace(
9494
let contents = loader.load_sync(path);
9595
let path = vfs::VfsPath::from(path.to_path_buf());
9696
vfs.set_file_contents(path.clone(), contents);
97-
vfs.file_id(&path)
97+
vfs.file_id(&path).and_then(|(file_id, excluded)| {
98+
(excluded == vfs::FileExcluded::No).then_some(file_id)
99+
})
98100
},
99101
extra_env,
100102
);

src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,10 @@ config_data! {
8484
completion_snippets_custom: FxHashMap<String, SnippetDef> = Config::completion_snippets_default(),
8585

8686

87-
/// These directories will be ignored by rust-analyzer. They are
87+
/// These paths (file/directories) will be ignored by rust-analyzer. They are
8888
/// relative to the workspace root, and globs are not supported. You may
8989
/// also need to add the folders to Code's `files.watcherExclude`.
90-
files_excludeDirs: Vec<Utf8PathBuf> = vec![],
90+
files_exclude | files_excludeDirs: Vec<Utf8PathBuf> = vec![],
9191

9292

9393

@@ -1792,7 +1792,7 @@ impl Config {
17921792

17931793
fn discovered_projects(&self) -> Vec<ManifestOrProjectJson> {
17941794
let exclude_dirs: Vec<_> =
1795-
self.files_excludeDirs().iter().map(|p| self.root_path.join(p)).collect();
1795+
self.files_exclude().iter().map(|p| self.root_path.join(p)).collect();
17961796

17971797
let mut projects = vec![];
17981798
for fs_proj in &self.discovered_projects_from_filesystem {
@@ -1914,10 +1914,14 @@ impl Config {
19141914
}
19151915
_ => FilesWatcher::Server,
19161916
},
1917-
exclude: self.files_excludeDirs().iter().map(|it| self.root_path.join(it)).collect(),
1917+
exclude: self.excluded().collect(),
19181918
}
19191919
}
19201920

1921+
pub fn excluded(&self) -> impl Iterator<Item = AbsPathBuf> + use<'_> {
1922+
self.files_exclude().iter().map(|it| self.root_path.join(it))
1923+
}
1924+
19211925
pub fn notifications(&self) -> NotificationsConfig {
19221926
NotificationsConfig {
19231927
cargo_toml_not_found: self.notifications_cargoTomlNotFound().to_owned(),

src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -650,15 +650,17 @@ impl GlobalStateSnapshot {
650650
RwLockReadGuard::map(self.vfs.read(), |(it, _)| it)
651651
}
652652

653-
pub(crate) fn url_to_file_id(&self, url: &Url) -> anyhow::Result<FileId> {
653+
/// Returns `None` if the file was excluded.
654+
pub(crate) fn url_to_file_id(&self, url: &Url) -> anyhow::Result<Option<FileId>> {
654655
url_to_file_id(&self.vfs_read(), url)
655656
}
656657

657658
pub(crate) fn file_id_to_url(&self, id: FileId) -> Url {
658659
file_id_to_url(&self.vfs_read(), id)
659660
}
660661

661-
pub(crate) fn vfs_path_to_file_id(&self, vfs_path: &VfsPath) -> anyhow::Result<FileId> {
662+
/// Returns `None` if the file was excluded.
663+
pub(crate) fn vfs_path_to_file_id(&self, vfs_path: &VfsPath) -> anyhow::Result<Option<FileId>> {
662664
vfs_path_to_file_id(&self.vfs_read(), vfs_path)
663665
}
664666

@@ -750,14 +752,21 @@ pub(crate) fn file_id_to_url(vfs: &vfs::Vfs, id: FileId) -> Url {
750752
url_from_abs_path(path)
751753
}
752754

753-
pub(crate) fn url_to_file_id(vfs: &vfs::Vfs, url: &Url) -> anyhow::Result<FileId> {
755+
/// Returns `None` if the file was excluded.
756+
pub(crate) fn url_to_file_id(vfs: &vfs::Vfs, url: &Url) -> anyhow::Result<Option<FileId>> {
754757
let path = from_proto::vfs_path(url)?;
755-
let res = vfs.file_id(&path).ok_or_else(|| anyhow::format_err!("file not found: {path}"))?;
756-
Ok(res)
758+
vfs_path_to_file_id(vfs, &path)
757759
}
758760

759-
pub(crate) fn vfs_path_to_file_id(vfs: &vfs::Vfs, vfs_path: &VfsPath) -> anyhow::Result<FileId> {
760-
let res =
761+
/// Returns `None` if the file was excluded.
762+
pub(crate) fn vfs_path_to_file_id(
763+
vfs: &vfs::Vfs,
764+
vfs_path: &VfsPath,
765+
) -> anyhow::Result<Option<FileId>> {
766+
let (file_id, excluded) =
761767
vfs.file_id(vfs_path).ok_or_else(|| anyhow::format_err!("file not found: {vfs_path}"))?;
762-
Ok(res)
768+
match excluded {
769+
vfs::FileExcluded::Yes => Ok(None),
770+
vfs::FileExcluded::No => Ok(Some(file_id)),
771+
}
763772
}

src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use crate::{
2222
mem_docs::DocumentData,
2323
reload,
2424
target_spec::TargetSpec,
25+
try_default,
2526
};
2627

2728
pub(crate) fn handle_cancel(state: &mut GlobalState, params: CancelParams) -> anyhow::Result<()> {
@@ -74,6 +75,14 @@ pub(crate) fn handle_did_open_text_document(
7475
tracing::error!("duplicate DidOpenTextDocument: {}", path);
7576
}
7677

78+
if let Some(abs_path) = path.as_path() {
79+
if state.config.excluded().any(|excluded| abs_path.starts_with(&excluded)) {
80+
tracing::trace!("opened excluded file {abs_path}");
81+
state.vfs.write().0.insert_excluded_file(path);
82+
return Ok(());
83+
}
84+
}
85+
7786
let contents = params.text_document.text.into_bytes();
7887
state.vfs.write().0.set_file_contents(path, Some(contents));
7988
if state.config.discover_workspace_config().is_some() {
@@ -127,7 +136,8 @@ pub(crate) fn handle_did_close_text_document(
127136
tracing::error!("orphan DidCloseTextDocument: {}", path);
128137
}
129138

130-
if let Some(file_id) = state.vfs.read().0.file_id(&path) {
139+
// Clear diagnostics also for excluded files, just in case.
140+
if let Some((file_id, _)) = state.vfs.read().0.file_id(&path) {
131141
state.diagnostics.clear_native_for(file_id);
132142
}
133143

@@ -146,7 +156,7 @@ pub(crate) fn handle_did_save_text_document(
146156
) -> anyhow::Result<()> {
147157
if let Ok(vfs_path) = from_proto::vfs_path(&params.text_document.uri) {
148158
let snap = state.snapshot();
149-
let file_id = snap.vfs_path_to_file_id(&vfs_path)?;
159+
let file_id = try_default!(snap.vfs_path_to_file_id(&vfs_path)?);
150160
let sr = snap.analysis.source_root_id(file_id)?;
151161

152162
if state.config.script_rebuild_on_save(Some(sr)) && state.build_deps_changed {
@@ -290,7 +300,7 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
290300
let _p = tracing::info_span!("run_flycheck").entered();
291301

292302
let file_id = state.vfs.read().0.file_id(&vfs_path);
293-
if let Some(file_id) = file_id {
303+
if let Some((file_id, vfs::FileExcluded::No)) = file_id {
294304
let world = state.snapshot();
295305
let invocation_strategy_once = state.config.flycheck(None).invocation_strategy_once();
296306
let may_flycheck_workspace = state.config.flycheck_workspace(None);

0 commit comments

Comments
 (0)