Deduplicate loaded projects

This commit is contained in:
Lukas Wirth 2023-04-18 14:27:01 +02:00
parent f5f68e4dc7
commit 9c408970ea
3 changed files with 29 additions and 22 deletions

View File

@ -535,7 +535,7 @@ fn default() -> Self {
#[derive(Debug, Clone)]
pub struct Config {
discovered_projects: Option<Vec<ProjectManifest>>,
discovered_projects: Vec<ProjectManifest>,
/// The workspace roots as registered by the LSP client
workspace_roots: Vec<AbsPathBuf>,
caps: lsp_types::ClientCapabilities,
@ -743,7 +743,7 @@ pub fn new(
caps,
data: ConfigData::default(),
detached_files: Vec::new(),
discovered_projects: None,
discovered_projects: Vec::new(),
root_path,
snippets: Default::default(),
workspace_roots,
@ -756,7 +756,7 @@ pub fn rediscover_workspaces(&mut self) {
if discovered.is_empty() {
tracing::error!("failed to find any projects in {:?}", &self.workspace_roots);
}
self.discovered_projects = Some(discovered);
self.discovered_projects = discovered;
}
pub fn remove_workspace(&mut self, path: &AbsPath) {
@ -871,25 +871,19 @@ pub fn has_linked_projects(&self) -> bool {
pub fn linked_projects(&self) -> Vec<LinkedProject> {
match self.data.linkedProjects.as_slice() {
[] => {
match self.discovered_projects.as_ref() {
Some(discovered_projects) => {
let exclude_dirs: Vec<_> = self
.data
.files_excludeDirs
.iter()
.map(|p| self.root_path.join(p))
.collect();
discovered_projects
.iter()
.filter(|(ProjectManifest::ProjectJson(path) | ProjectManifest::CargoToml(path))| {
let exclude_dirs: Vec<_> =
self.data.files_excludeDirs.iter().map(|p| self.root_path.join(p)).collect();
self.discovered_projects
.iter()
.filter(
|(ProjectManifest::ProjectJson(path)
| ProjectManifest::CargoToml(path))| {
!exclude_dirs.iter().any(|p| path.starts_with(p))
})
.cloned()
.map(LinkedProject::from)
.collect()
}
None => Vec::new(),
}
},
)
.cloned()
.map(LinkedProject::from)
.collect()
}
linked_projects => linked_projects
.iter()

View File

@ -212,6 +212,20 @@ pub(crate) fn fetch_workspaces(&mut self, cause: Cause) {
})
.collect::<Vec<_>>();
let mut i = 0;
while i < workspaces.len() {
if let Ok(w) = &workspaces[i] {
if let Some(dupe) = workspaces[i + 1..]
.iter()
.filter_map(|it| it.as_ref().ok())
.position(|ws| ws.eq_ignore_build_data(w))
{
_ = workspaces.remove(dupe);
}
}
i += 1;
}
if !detached_files.is_empty() {
workspaces.push(project_model::ProjectWorkspace::load_detached_files(
detached_files,

View File

@ -9,7 +9,6 @@
use crossbeam_channel::{after, select, Receiver};
use lsp_server::{Connection, Message, Notification, Request};
use lsp_types::{notification::Exit, request::Shutdown, TextDocumentIdentifier, Url};
use project_model::ProjectManifest;
use rust_analyzer::{config::Config, lsp_ext, main_loop};
use serde::Serialize;
use serde_json::{json, to_string_pretty, Value};