From 34203256bf8f8ea12b233e0fb49b42bd8c423281 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 6 Aug 2019 13:00:37 +0200 Subject: introduce ra_vfs_glob crate It manages exclusion rules for the vfs crate --- crates/ra_batch/Cargo.toml | 1 + crates/ra_batch/src/lib.rs | 20 ++++++-- crates/ra_batch/src/vfs_filter.rs | 54 -------------------- crates/ra_lsp_server/Cargo.toml | 1 + crates/ra_lsp_server/src/lib.rs | 1 - crates/ra_lsp_server/src/vfs_filter.rs | 54 -------------------- crates/ra_lsp_server/src/world.rs | 20 ++++++-- crates/ra_project_model/Cargo.toml | 1 - crates/ra_project_model/src/lib.rs | 23 --------- crates/ra_vfs_glob/Cargo.toml | 9 ++++ crates/ra_vfs_glob/src/lib.rs | 93 ++++++++++++++++++++++++++++++++++ 11 files changed, 135 insertions(+), 142 deletions(-) delete mode 100644 crates/ra_batch/src/vfs_filter.rs delete mode 100644 crates/ra_lsp_server/src/vfs_filter.rs create mode 100644 crates/ra_vfs_glob/Cargo.toml create mode 100644 crates/ra_vfs_glob/src/lib.rs (limited to 'crates') diff --git a/crates/ra_batch/Cargo.toml b/crates/ra_batch/Cargo.toml index 0ee94c445..8e23826a4 100644 --- a/crates/ra_batch/Cargo.toml +++ b/crates/ra_batch/Cargo.toml @@ -9,6 +9,7 @@ log = "0.4.5" rustc-hash = "1.0" ra_vfs = "0.2.0" +ra_vfs_glob = { path = "../ra_vfs_glob" } ra_db = { path = "../ra_db" } ra_ide_api = { path = "../ra_ide_api" } ra_hir = { path = "../ra_hir" } diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs index c01574fbc..0db751465 100644 --- a/crates/ra_batch/src/lib.rs +++ b/crates/ra_batch/src/lib.rs @@ -1,5 +1,3 @@ -mod vfs_filter; - use std::{collections::HashSet, error::Error, path::Path}; use rustc_hash::FxHashMap; @@ -7,8 +5,8 @@ use rustc_hash::FxHashMap; use ra_db::{CrateGraph, FileId, SourceRootId}; use ra_ide_api::{AnalysisChange, AnalysisHost}; use ra_project_model::{PackageRoot, ProjectWorkspace}; -use ra_vfs::{Vfs, VfsChange}; -use vfs_filter::IncludeRustFiles; +use ra_vfs::{RootEntry, Vfs, VfsChange}; +use ra_vfs_glob::RustPackageFilterBuilder; type Result = std::result::Result>; @@ -23,7 +21,19 @@ pub fn load_cargo(root: &Path) -> Result<(AnalysisHost, FxHashMap {:?}", path, vfs_file); diff --git a/crates/ra_batch/src/vfs_filter.rs b/crates/ra_batch/src/vfs_filter.rs deleted file mode 100644 index 63bf77704..000000000 --- a/crates/ra_batch/src/vfs_filter.rs +++ /dev/null @@ -1,54 +0,0 @@ -use ra_project_model::PackageRoot; -use ra_vfs::{Filter, RelativePath, RootEntry}; -use std::path::PathBuf; - -/// `IncludeRustFiles` is used to convert -/// from `PackageRoot` to `RootEntry` for VFS -pub struct IncludeRustFiles { - root: PackageRoot, -} - -impl IncludeRustFiles { - pub fn from_roots(roots: R) -> impl Iterator - where - R: IntoIterator, - { - roots.into_iter().map(IncludeRustFiles::from_root) - } - - pub fn from_root(root: PackageRoot) -> RootEntry { - IncludeRustFiles::from(root).into() - } - - #[allow(unused)] - pub fn external(path: PathBuf) -> RootEntry { - IncludeRustFiles::from_root(PackageRoot::new(path, false)) - } - - pub fn member(path: PathBuf) -> RootEntry { - IncludeRustFiles::from_root(PackageRoot::new(path, true)) - } -} - -impl Filter for IncludeRustFiles { - fn include_dir(&self, dir_path: &RelativePath) -> bool { - self.root.include_dir(dir_path) - } - - fn include_file(&self, file_path: &RelativePath) -> bool { - self.root.include_file(file_path) - } -} - -impl From for IncludeRustFiles { - fn from(v: PackageRoot) -> IncludeRustFiles { - IncludeRustFiles { root: v } - } -} - -impl From for RootEntry { - fn from(v: IncludeRustFiles) -> RootEntry { - let path = v.root.path().clone(); - RootEntry::new(path, Box::new(v)) - } -} diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml index cec360667..c282d6db8 100644 --- a/crates/ra_lsp_server/Cargo.toml +++ b/crates/ra_lsp_server/Cargo.toml @@ -25,6 +25,7 @@ ra_ide_api = { path = "../ra_ide_api" } gen_lsp_server = { path = "../gen_lsp_server" } ra_project_model = { path = "../ra_project_model" } ra_prof = { path = "../ra_prof" } +ra_vfs_glob = { path = "../ra_vfs_glob" } [dev-dependencies] tempfile = "3" diff --git a/crates/ra_lsp_server/src/lib.rs b/crates/ra_lsp_server/src/lib.rs index 56a263aa5..2ae6300c8 100644 --- a/crates/ra_lsp_server/src/lib.rs +++ b/crates/ra_lsp_server/src/lib.rs @@ -4,7 +4,6 @@ mod conv; mod main_loop; mod markdown; mod project_model; -mod vfs_filter; pub mod req; pub mod init; mod world; diff --git a/crates/ra_lsp_server/src/vfs_filter.rs b/crates/ra_lsp_server/src/vfs_filter.rs deleted file mode 100644 index abdc8dbad..000000000 --- a/crates/ra_lsp_server/src/vfs_filter.rs +++ /dev/null @@ -1,54 +0,0 @@ -use ra_project_model::PackageRoot; -use ra_vfs::{Filter, RelativePath, RootEntry}; -use std::path::PathBuf; - -/// `IncludeRustFiles` is used to convert -/// from `PackageRoot` to `RootEntry` for VFS -pub struct IncludeRustFiles { - root: PackageRoot, -} - -impl IncludeRustFiles { - pub fn from_roots(roots: R) -> impl Iterator - where - R: IntoIterator, - { - roots.into_iter().map(IncludeRustFiles::from_root) - } - - pub fn from_root(root: PackageRoot) -> RootEntry { - IncludeRustFiles::from(root).into() - } - - #[allow(unused)] - pub fn external(path: PathBuf) -> RootEntry { - IncludeRustFiles::from_root(PackageRoot::new(path, false)) - } - - pub fn member(path: PathBuf) -> RootEntry { - IncludeRustFiles::from_root(PackageRoot::new(path, true)) - } -} - -impl Filter for IncludeRustFiles { - fn include_dir(&self, dir_path: &RelativePath) -> bool { - self.root.include_dir(dir_path) - } - - fn include_file(&self, file_path: &RelativePath) -> bool { - self.root.include_file(file_path) - } -} - -impl std::convert::From for IncludeRustFiles { - fn from(v: PackageRoot) -> IncludeRustFiles { - IncludeRustFiles { root: v } - } -} - -impl std::convert::From for RootEntry { - fn from(v: IncludeRustFiles) -> RootEntry { - let path = v.root.path().clone(); - RootEntry::new(path, Box::new(v)) - } -} diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs index b57cdf925..a8aafe5cb 100644 --- a/crates/ra_lsp_server/src/world.rs +++ b/crates/ra_lsp_server/src/world.rs @@ -9,13 +9,13 @@ use parking_lot::RwLock; use ra_ide_api::{ Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, SourceRootId, }; -use ra_vfs::{Vfs, VfsChange, VfsFile, VfsRoot}; +use ra_vfs::{RootEntry, Vfs, VfsChange, VfsFile, VfsRoot}; +use ra_vfs_glob::RustPackageFilterBuilder; use relative_path::RelativePathBuf; use crate::{ main_loop::pending_requests::{CompletedRequest, LatestRequests}, project_model::ProjectWorkspace, - vfs_filter::IncludeRustFiles, LspError, Result, }; @@ -61,9 +61,21 @@ impl WorldState { let mut change = AnalysisChange::new(); let mut roots = Vec::new(); - roots.extend(folder_roots.iter().cloned().map(IncludeRustFiles::member)); + roots.extend(folder_roots.iter().map(|path| { + RootEntry::new( + path.clone(), + RustPackageFilterBuilder::default().set_member(true).into_vfs_filter(), + ) + })); for ws in workspaces.iter() { - roots.extend(IncludeRustFiles::from_roots(ws.to_roots())); + roots.extend(ws.to_roots().into_iter().map(|pkg_root| { + RootEntry::new( + pkg_root.path().clone(), + RustPackageFilterBuilder::default() + .set_member(pkg_root.is_member()) + .into_vfs_filter(), + ) + })); } let (mut vfs, vfs_roots) = Vfs::new(roots); diff --git a/crates/ra_project_model/Cargo.toml b/crates/ra_project_model/Cargo.toml index 3545d23c9..4fd6c75ef 100644 --- a/crates/ra_project_model/Cargo.toml +++ b/crates/ra_project_model/Cargo.toml @@ -7,7 +7,6 @@ authors = ["rust-analyzer developers"] [dependencies] log = "0.4.5" rustc-hash = "1.0" -relative-path = "0.4.0" cargo_metadata = "0.8.0" diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index c7167046b..55b94b911 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs @@ -10,7 +10,6 @@ use std::{ }; use ra_db::{CrateGraph, Edition, FileId}; -use relative_path::RelativePath; use rustc_hash::FxHashMap; use serde_json::from_reader; @@ -54,28 +53,6 @@ impl PackageRoot { pub fn is_member(&self) -> bool { self.is_member } - - pub fn include_dir(&self, dir_path: &RelativePath) -> bool { - const COMMON_IGNORED_DIRS: &[&str] = &["node_modules", "target", ".git"]; - const EXTERNAL_IGNORED_DIRS: &[&str] = &["examples", "tests", "benches"]; - - let is_ignored = if self.is_member { - dir_path.components().any(|c| COMMON_IGNORED_DIRS.contains(&c.as_str())) - } else { - dir_path.components().any(|c| { - let path = c.as_str(); - COMMON_IGNORED_DIRS.contains(&path) || EXTERNAL_IGNORED_DIRS.contains(&path) - }) - }; - - let hidden = dir_path.components().any(|c| c.as_str().starts_with('.')); - - !is_ignored && !hidden - } - - pub fn include_file(&self, file_path: &RelativePath) -> bool { - file_path.extension() == Some("rs") - } } impl ProjectWorkspace { diff --git a/crates/ra_vfs_glob/Cargo.toml b/crates/ra_vfs_glob/Cargo.toml new file mode 100644 index 000000000..0390d7da1 --- /dev/null +++ b/crates/ra_vfs_glob/Cargo.toml @@ -0,0 +1,9 @@ +[package] +edition = "2018" +name = "ra_vfs_glob" +version = "0.1.0" +authors = ["rust-analyzer developers"] + +[dependencies] +ra_vfs = "0.2.0" +globset = "0.4.4" diff --git a/crates/ra_vfs_glob/src/lib.rs b/crates/ra_vfs_glob/src/lib.rs new file mode 100644 index 000000000..3e54da5fe --- /dev/null +++ b/crates/ra_vfs_glob/src/lib.rs @@ -0,0 +1,93 @@ +//! `ra_vfs_glob` crate implements exclusion rules for vfs. +//! +//! By default, we include only `.rs` files, and skip some know offenders like +//! `/target` or `/node_modules` altogether. +//! +//! It's also possible to add custom exclusion globs. + +use globset::{Glob, GlobSet, GlobSetBuilder}; +use ra_vfs::{Filter, RelativePath}; + +const ALWAYS_IGNORED: &[&str] = &["target/**", "**/node_modules/**", "**/.git/**"]; +const IGNORED_FOR_NON_MEMBERS: &[&str] = &["examples/**", "tests/**", "benches/**"]; + +pub struct RustPackageFilterBuilder { + is_member: bool, + exclude: GlobSetBuilder, +} + +impl Default for RustPackageFilterBuilder { + fn default() -> RustPackageFilterBuilder { + RustPackageFilterBuilder { is_member: false, exclude: GlobSetBuilder::new() } + } +} + +impl RustPackageFilterBuilder { + pub fn set_member(mut self, is_member: bool) -> RustPackageFilterBuilder { + self.is_member = is_member; + self + } + pub fn exclude(mut self, glob: &str) -> Result { + self.exclude.add(Glob::new(glob)?); + Ok(self) + } + pub fn into_vfs_filter(self) -> Box { + let RustPackageFilterBuilder { is_member, mut exclude } = self; + for &glob in ALWAYS_IGNORED { + exclude.add(Glob::new(glob).unwrap()); + } + if !is_member { + for &glob in IGNORED_FOR_NON_MEMBERS { + exclude.add(Glob::new(glob).unwrap()); + } + } + Box::new(RustPackageFilter { exclude: exclude.build().unwrap() }) + } +} + +struct RustPackageFilter { + exclude: GlobSet, +} + +impl Filter for RustPackageFilter { + fn include_dir(&self, dir_path: &RelativePath) -> bool { + !self.exclude.is_match(dir_path.as_str()) + } + + fn include_file(&self, file_path: &RelativePath) -> bool { + file_path.extension() == Some("rs") + } +} + +#[test] +fn test_globs() { + let filter = RustPackageFilterBuilder::default().set_member(true).into_vfs_filter(); + + assert!(filter.include_dir(RelativePath::new("src/tests"))); + assert!(filter.include_dir(RelativePath::new("src/target"))); + assert!(filter.include_dir(RelativePath::new("tests"))); + assert!(filter.include_dir(RelativePath::new("benches"))); + + assert!(!filter.include_dir(RelativePath::new("target"))); + assert!(!filter.include_dir(RelativePath::new("src/foo/.git"))); + assert!(!filter.include_dir(RelativePath::new("foo/node_modules"))); + + let filter = RustPackageFilterBuilder::default().set_member(false).into_vfs_filter(); + + assert!(filter.include_dir(RelativePath::new("src/tests"))); + assert!(filter.include_dir(RelativePath::new("src/target"))); + + assert!(!filter.include_dir(RelativePath::new("target"))); + assert!(!filter.include_dir(RelativePath::new("src/foo/.git"))); + assert!(!filter.include_dir(RelativePath::new("foo/node_modules"))); + assert!(!filter.include_dir(RelativePath::new("tests"))); + assert!(!filter.include_dir(RelativePath::new("benches"))); + + let filter = RustPackageFilterBuilder::default() + .set_member(true) + .exclude("src/llvm-project/**") + .unwrap() + .into_vfs_filter(); + + assert!(!filter.include_dir(RelativePath::new("src/llvm-project/clang"))); +} -- cgit v1.2.3 From f70b7e1f079e7b4a51ddd6503860eb97f1a6fcbe Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 6 Aug 2019 13:12:58 +0200 Subject: rename config --- crates/ra_lsp_server/src/config.rs | 65 +++++++++++++++++++++++++++++++++ crates/ra_lsp_server/src/init.rs | 69 ----------------------------------- crates/ra_lsp_server/src/lib.rs | 5 +-- crates/ra_lsp_server/src/main.rs | 4 +- crates/ra_lsp_server/src/main_loop.rs | 10 ++--- 5 files changed, 74 insertions(+), 79 deletions(-) create mode 100644 crates/ra_lsp_server/src/config.rs delete mode 100644 crates/ra_lsp_server/src/init.rs (limited to 'crates') diff --git a/crates/ra_lsp_server/src/config.rs b/crates/ra_lsp_server/src/config.rs new file mode 100644 index 000000000..a16cc292e --- /dev/null +++ b/crates/ra_lsp_server/src/config.rs @@ -0,0 +1,65 @@ +use serde::{Deserialize, Deserializer}; + +/// Client provided initialization options +#[derive(Deserialize, Clone, Copy, Debug, PartialEq, Eq)] +#[serde(rename_all = "camelCase", default)] +pub struct ServerConfig { + /// Whether the client supports our custom highlighting publishing decorations. + /// This is different to the highlightingOn setting, which is whether the user + /// wants our custom highlighting to be used. + /// + /// Defaults to `false` + #[serde(deserialize_with = "nullable_bool_false")] + pub publish_decorations: bool, + + /// Whether or not the workspace loaded notification should be sent + /// + /// Defaults to `true` + #[serde(deserialize_with = "nullable_bool_true")] + pub show_workspace_loaded: bool, + + pub lru_capacity: Option, +} + +impl Default for ServerConfig { + fn default() -> ServerConfig { + ServerConfig { publish_decorations: false, show_workspace_loaded: true, lru_capacity: None } + } +} + +/// Deserializes a null value to a bool false by default +fn nullable_bool_false<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let opt = Option::deserialize(deserializer)?; + Ok(opt.unwrap_or(false)) +} + +/// Deserializes a null value to a bool true by default +fn nullable_bool_true<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let opt = Option::deserialize(deserializer)?; + Ok(opt.unwrap_or(true)) +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn deserialize_init_options_defaults() { + // check that null == default for both fields + let default = ServerConfig::default(); + assert_eq!(default, serde_json::from_str(r#"{}"#).unwrap()); + assert_eq!( + default, + serde_json::from_str( + r#"{"publishDecorations":null, "showWorkspaceLoaded":null, "lruCapacity":null}"# + ) + .unwrap() + ); + } +} diff --git a/crates/ra_lsp_server/src/init.rs b/crates/ra_lsp_server/src/init.rs deleted file mode 100644 index b894b449d..000000000 --- a/crates/ra_lsp_server/src/init.rs +++ /dev/null @@ -1,69 +0,0 @@ -use serde::{Deserialize, Deserializer}; - -/// Client provided initialization options -#[derive(Deserialize, Clone, Copy, Debug, PartialEq, Eq)] -#[serde(rename_all = "camelCase", default)] -pub struct InitializationOptions { - /// Whether the client supports our custom highlighting publishing decorations. - /// This is different to the highlightingOn setting, which is whether the user - /// wants our custom highlighting to be used. - /// - /// Defaults to `false` - #[serde(deserialize_with = "nullable_bool_false")] - pub publish_decorations: bool, - - /// Whether or not the workspace loaded notification should be sent - /// - /// Defaults to `true` - #[serde(deserialize_with = "nullable_bool_true")] - pub show_workspace_loaded: bool, - - pub lru_capacity: Option, -} - -impl Default for InitializationOptions { - fn default() -> InitializationOptions { - InitializationOptions { - publish_decorations: false, - show_workspace_loaded: true, - lru_capacity: None, - } - } -} - -/// Deserializes a null value to a bool false by default -fn nullable_bool_false<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - let opt = Option::deserialize(deserializer)?; - Ok(opt.unwrap_or(false)) -} - -/// Deserializes a null value to a bool true by default -fn nullable_bool_true<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - let opt = Option::deserialize(deserializer)?; - Ok(opt.unwrap_or(true)) -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn deserialize_init_options_defaults() { - // check that null == default for both fields - let default = InitializationOptions::default(); - assert_eq!(default, serde_json::from_str(r#"{}"#).unwrap()); - assert_eq!( - default, - serde_json::from_str( - r#"{"publishDecorations":null, "showWorkspaceLoaded":null, "lruCapacity":null}"# - ) - .unwrap() - ); - } -} diff --git a/crates/ra_lsp_server/src/lib.rs b/crates/ra_lsp_server/src/lib.rs index 2ae6300c8..795f86383 100644 --- a/crates/ra_lsp_server/src/lib.rs +++ b/crates/ra_lsp_server/src/lib.rs @@ -5,11 +5,10 @@ mod main_loop; mod markdown; mod project_model; pub mod req; -pub mod init; +pub mod config; mod world; pub type Result = std::result::Result>; pub use crate::{ - caps::server_capabilities, init::InitializationOptions, main_loop::main_loop, - main_loop::LspError, + caps::server_capabilities, config::ServerConfig, main_loop::main_loop, main_loop::LspError, }; diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs index c1f8243be..1a2ab1bc2 100644 --- a/crates/ra_lsp_server/src/main.rs +++ b/crates/ra_lsp_server/src/main.rs @@ -2,7 +2,7 @@ use flexi_logger::{Duplicate, Logger}; use gen_lsp_server::{run_server, stdio_transport}; use serde::Deserialize; -use ra_lsp_server::{InitializationOptions, Result}; +use ra_lsp_server::{Result, ServerConfig}; use ra_prof; fn main() -> Result<()> { @@ -48,7 +48,7 @@ fn main_inner() -> Result<()> { let opts = params .initialization_options - .and_then(|v| InitializationOptions::deserialize(v).ok()) + .and_then(|v| ServerConfig::deserialize(v).ok()) .unwrap_or_default(); ra_lsp_server::main_loop(workspace_roots, params.capabilities, opts, r, s) diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 9a38d43d2..8ab501828 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs @@ -23,7 +23,7 @@ use crate::{ project_model::workspace_loader, req, world::{Options, WorldSnapshot, WorldState}, - InitializationOptions, Result, + Result, ServerConfig, }; const THREADPOOL_SIZE: usize = 8; @@ -52,7 +52,7 @@ impl Error for LspError {} pub fn main_loop( ws_roots: Vec, client_caps: ClientCapabilities, - options: InitializationOptions, + config: ServerConfig, msg_receiver: &Receiver, msg_sender: &Sender, ) -> Result<()> { @@ -81,10 +81,10 @@ pub fn main_loop( let mut state = WorldState::new( ws_roots, workspaces, - options.lru_capacity, + config.lru_capacity, Options { - publish_decorations: options.publish_decorations, - show_workspace_loaded: options.show_workspace_loaded, + publish_decorations: config.publish_decorations, + show_workspace_loaded: config.show_workspace_loaded, supports_location_link: client_caps .text_document .and_then(|it| it.definition) -- cgit v1.2.3 From 058c2daba1b81804d9f803e57c72f5702c124d9e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 6 Aug 2019 13:27:00 +0200 Subject: push glob errors outwards --- crates/ra_vfs_glob/src/lib.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'crates') diff --git a/crates/ra_vfs_glob/src/lib.rs b/crates/ra_vfs_glob/src/lib.rs index 3e54da5fe..12401d75a 100644 --- a/crates/ra_vfs_glob/src/lib.rs +++ b/crates/ra_vfs_glob/src/lib.rs @@ -5,9 +5,11 @@ //! //! It's also possible to add custom exclusion globs. -use globset::{Glob, GlobSet, GlobSetBuilder}; +use globset::{GlobSet, GlobSetBuilder}; use ra_vfs::{Filter, RelativePath}; +pub use globset::{Glob, GlobBuilder}; + const ALWAYS_IGNORED: &[&str] = &["target/**", "**/node_modules/**", "**/.git/**"]; const IGNORED_FOR_NON_MEMBERS: &[&str] = &["examples/**", "tests/**", "benches/**"]; @@ -27,9 +29,9 @@ impl RustPackageFilterBuilder { self.is_member = is_member; self } - pub fn exclude(mut self, glob: &str) -> Result { - self.exclude.add(Glob::new(glob)?); - Ok(self) + pub fn exclude(mut self, glob: Glob) -> RustPackageFilterBuilder { + self.exclude.add(glob); + self } pub fn into_vfs_filter(self) -> Box { let RustPackageFilterBuilder { is_member, mut exclude } = self; @@ -85,8 +87,7 @@ fn test_globs() { let filter = RustPackageFilterBuilder::default() .set_member(true) - .exclude("src/llvm-project/**") - .unwrap() + .exclude(Glob::new("src/llvm-project/**").unwrap()) .into_vfs_filter(); assert!(!filter.include_dir(RelativePath::new("src/llvm-project/clang"))); -- cgit v1.2.3 From deea8f52d9803bb8a93d5dbd935970a20f07a51e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 6 Aug 2019 13:34:28 +0200 Subject: allow to exclude certain files and directories --- crates/ra_lsp_server/src/config.rs | 11 +++++++++-- crates/ra_lsp_server/src/main_loop.rs | 8 +++++++- crates/ra_lsp_server/src/world.rs | 24 +++++++++++++----------- 3 files changed, 29 insertions(+), 14 deletions(-) (limited to 'crates') diff --git a/crates/ra_lsp_server/src/config.rs b/crates/ra_lsp_server/src/config.rs index a16cc292e..6dcdc695a 100644 --- a/crates/ra_lsp_server/src/config.rs +++ b/crates/ra_lsp_server/src/config.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Deserializer}; /// Client provided initialization options -#[derive(Deserialize, Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Deserialize, Clone, Debug, PartialEq, Eq)] #[serde(rename_all = "camelCase", default)] pub struct ServerConfig { /// Whether the client supports our custom highlighting publishing decorations. @@ -18,12 +18,19 @@ pub struct ServerConfig { #[serde(deserialize_with = "nullable_bool_true")] pub show_workspace_loaded: bool, + pub exclude_globs: Vec, + pub lru_capacity: Option, } impl Default for ServerConfig { fn default() -> ServerConfig { - ServerConfig { publish_decorations: false, show_workspace_loaded: true, lru_capacity: None } + ServerConfig { + publish_decorations: false, + show_workspace_loaded: true, + exclude_globs: Vec::new(), + lru_capacity: None, + } } } diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 8ab501828..9d540a87e 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs @@ -56,6 +56,7 @@ pub fn main_loop( msg_receiver: &Receiver, msg_sender: &Sender, ) -> Result<()> { + log::debug!("server_config: {:?}", config); // FIXME: support dynamic workspace loading. let workspaces = { let ws_worker = workspace_loader(); @@ -77,11 +78,16 @@ pub fn main_loop( } loaded_workspaces }; - + let globs = config + .exclude_globs + .iter() + .map(|glob| ra_vfs_glob::Glob::new(glob)) + .collect::, _>>()?; let mut state = WorldState::new( ws_roots, workspaces, config.lru_capacity, + &globs, Options { publish_decorations: config.publish_decorations, show_workspace_loaded: config.show_workspace_loaded, diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs index a8aafe5cb..9990ef62e 100644 --- a/crates/ra_lsp_server/src/world.rs +++ b/crates/ra_lsp_server/src/world.rs @@ -10,7 +10,7 @@ use ra_ide_api::{ Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, SourceRootId, }; use ra_vfs::{RootEntry, Vfs, VfsChange, VfsFile, VfsRoot}; -use ra_vfs_glob::RustPackageFilterBuilder; +use ra_vfs_glob::{Glob, RustPackageFilterBuilder}; use relative_path::RelativePathBuf; use crate::{ @@ -56,25 +56,27 @@ impl WorldState { folder_roots: Vec, workspaces: Vec, lru_capacity: Option, + exclude_globs: &[Glob], options: Options, ) -> WorldState { let mut change = AnalysisChange::new(); let mut roots = Vec::new(); roots.extend(folder_roots.iter().map(|path| { - RootEntry::new( - path.clone(), - RustPackageFilterBuilder::default().set_member(true).into_vfs_filter(), - ) + let mut filter = RustPackageFilterBuilder::default().set_member(true); + for glob in exclude_globs.iter() { + filter = filter.exclude(glob.clone()); + } + RootEntry::new(path.clone(), filter.into_vfs_filter()) })); for ws in workspaces.iter() { roots.extend(ws.to_roots().into_iter().map(|pkg_root| { - RootEntry::new( - pkg_root.path().clone(), - RustPackageFilterBuilder::default() - .set_member(pkg_root.is_member()) - .into_vfs_filter(), - ) + let mut filter = + RustPackageFilterBuilder::default().set_member(pkg_root.is_member()); + for glob in exclude_globs.iter() { + filter = filter.exclude(glob.clone()); + } + RootEntry::new(pkg_root.path().clone(), filter.into_vfs_filter()) })); } -- cgit v1.2.3 From 3d45da9bca7ab772ea483b496a901fc500e22033 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 6 Aug 2019 14:41:22 +0200 Subject: fix tests --- crates/ra_lsp_server/tests/heavy_tests/support.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'crates') diff --git a/crates/ra_lsp_server/tests/heavy_tests/support.rs b/crates/ra_lsp_server/tests/heavy_tests/support.rs index 5dddbbe17..ba8ee8b06 100644 --- a/crates/ra_lsp_server/tests/heavy_tests/support.rs +++ b/crates/ra_lsp_server/tests/heavy_tests/support.rs @@ -22,7 +22,7 @@ use tempfile::TempDir; use test_utils::{find_mismatch, parse_fixture}; use thread_worker::Worker; -use ra_lsp_server::{main_loop, req, InitializationOptions}; +use ra_lsp_server::{main_loop, req, ServerConfig}; pub struct Project<'a> { fixture: &'a str, @@ -107,7 +107,7 @@ impl Server { window: None, experimental: None, }, - InitializationOptions::default(), + ServerConfig::default(), &msg_receiver, &msg_sender, ) -- cgit v1.2.3