diff options
Diffstat (limited to 'crates/ra_lsp_server')
-rw-r--r-- | crates/ra_lsp_server/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/args.rs | 5 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/cli/load_cargo.rs | 3 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/lib.rs | 1 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 2 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/vfs_glob.rs | 94 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/world.rs | 2 |
7 files changed, 105 insertions, 4 deletions
diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml index be7982b2a..da523ba8a 100644 --- a/crates/ra_lsp_server/Cargo.toml +++ b/crates/ra_lsp_server/Cargo.toml | |||
@@ -12,6 +12,7 @@ anyhow = "1.0" | |||
12 | crossbeam-channel = "0.4" | 12 | crossbeam-channel = "0.4" |
13 | either = "1.5" | 13 | either = "1.5" |
14 | env_logger = { version = "0.7.1", default-features = false } | 14 | env_logger = { version = "0.7.1", default-features = false } |
15 | globset = "0.4.4" | ||
15 | itertools = "0.8.0" | 16 | itertools = "0.8.0" |
16 | jod-thread = "0.1.0" | 17 | jod-thread = "0.1.0" |
17 | log = "0.4.3" | 18 | log = "0.4.3" |
@@ -33,7 +34,6 @@ ra_project_model = { path = "../ra_project_model" } | |||
33 | ra_syntax = { path = "../ra_syntax" } | 34 | ra_syntax = { path = "../ra_syntax" } |
34 | ra_text_edit = { path = "../ra_text_edit" } | 35 | ra_text_edit = { path = "../ra_text_edit" } |
35 | ra_vfs = "0.5.0" | 36 | ra_vfs = "0.5.0" |
36 | ra_vfs_glob = { path = "../ra_vfs_glob" } | ||
37 | 37 | ||
38 | # This should only be used in CLI | 38 | # This should only be used in CLI |
39 | ra_db = { path = "../ra_db" } | 39 | ra_db = { path = "../ra_db" } |
diff --git a/crates/ra_lsp_server/src/args.rs b/crates/ra_lsp_server/src/args.rs index 41959797c..89e2139ce 100644 --- a/crates/ra_lsp_server/src/args.rs +++ b/crates/ra_lsp_server/src/args.rs | |||
@@ -1,3 +1,8 @@ | |||
1 | //! Command like parsing for rust-analyzer. | ||
2 | //! | ||
3 | //! If run started args, we run the LSP server loop. With a subcommand, we do a | ||
4 | //! one-time batch processing. | ||
5 | |||
1 | use anyhow::{bail, Result}; | 6 | use anyhow::{bail, Result}; |
2 | use pico_args::Arguments; | 7 | use pico_args::Arguments; |
3 | use ra_lsp_server::cli::{BenchWhat, Position, Verbosity}; | 8 | use ra_lsp_server::cli::{BenchWhat, Position, Verbosity}; |
diff --git a/crates/ra_lsp_server/src/cli/load_cargo.rs b/crates/ra_lsp_server/src/cli/load_cargo.rs index b9a4e6aba..bb3e1513b 100644 --- a/crates/ra_lsp_server/src/cli/load_cargo.rs +++ b/crates/ra_lsp_server/src/cli/load_cargo.rs | |||
@@ -7,9 +7,10 @@ use ra_db::{CrateGraph, FileId, SourceRootId}; | |||
7 | use ra_ide::{AnalysisChange, AnalysisHost, FeatureFlags}; | 7 | use ra_ide::{AnalysisChange, AnalysisHost, FeatureFlags}; |
8 | use ra_project_model::{get_rustc_cfg_options, PackageRoot, ProjectWorkspace}; | 8 | use ra_project_model::{get_rustc_cfg_options, PackageRoot, ProjectWorkspace}; |
9 | use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch}; | 9 | use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch}; |
10 | use ra_vfs_glob::RustPackageFilterBuilder; | ||
11 | use rustc_hash::FxHashMap; | 10 | use rustc_hash::FxHashMap; |
12 | 11 | ||
12 | use crate::vfs_glob::RustPackageFilterBuilder; | ||
13 | |||
13 | use anyhow::Result; | 14 | use anyhow::Result; |
14 | 15 | ||
15 | fn vfs_file_to_id(f: ra_vfs::VfsFile) -> FileId { | 16 | fn vfs_file_to_id(f: ra_vfs::VfsFile) -> FileId { |
diff --git a/crates/ra_lsp_server/src/lib.rs b/crates/ra_lsp_server/src/lib.rs index 2832b2605..958c70fe5 100644 --- a/crates/ra_lsp_server/src/lib.rs +++ b/crates/ra_lsp_server/src/lib.rs | |||
@@ -23,6 +23,7 @@ macro_rules! print { | |||
23 | }; | 23 | }; |
24 | } | 24 | } |
25 | 25 | ||
26 | mod vfs_glob; | ||
26 | mod caps; | 27 | mod caps; |
27 | mod cargo_target_spec; | 28 | mod cargo_target_spec; |
28 | mod conv; | 29 | mod conv; |
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 7ae2e1e6f..944074118 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -135,7 +135,7 @@ pub fn main_loop( | |||
135 | let globs = config | 135 | let globs = config |
136 | .exclude_globs | 136 | .exclude_globs |
137 | .iter() | 137 | .iter() |
138 | .map(|glob| ra_vfs_glob::Glob::new(glob)) | 138 | .map(|glob| crate::vfs_glob::Glob::new(glob)) |
139 | .collect::<std::result::Result<Vec<_>, _>>()?; | 139 | .collect::<std::result::Result<Vec<_>, _>>()?; |
140 | 140 | ||
141 | if config.use_client_watching { | 141 | if config.use_client_watching { |
diff --git a/crates/ra_lsp_server/src/vfs_glob.rs b/crates/ra_lsp_server/src/vfs_glob.rs new file mode 100644 index 000000000..12401d75a --- /dev/null +++ b/crates/ra_lsp_server/src/vfs_glob.rs | |||
@@ -0,0 +1,94 @@ | |||
1 | //! `ra_vfs_glob` crate implements exclusion rules for vfs. | ||
2 | //! | ||
3 | //! By default, we include only `.rs` files, and skip some know offenders like | ||
4 | //! `/target` or `/node_modules` altogether. | ||
5 | //! | ||
6 | //! It's also possible to add custom exclusion globs. | ||
7 | |||
8 | use globset::{GlobSet, GlobSetBuilder}; | ||
9 | use ra_vfs::{Filter, RelativePath}; | ||
10 | |||
11 | pub use globset::{Glob, GlobBuilder}; | ||
12 | |||
13 | const ALWAYS_IGNORED: &[&str] = &["target/**", "**/node_modules/**", "**/.git/**"]; | ||
14 | const IGNORED_FOR_NON_MEMBERS: &[&str] = &["examples/**", "tests/**", "benches/**"]; | ||
15 | |||
16 | pub struct RustPackageFilterBuilder { | ||
17 | is_member: bool, | ||
18 | exclude: GlobSetBuilder, | ||
19 | } | ||
20 | |||
21 | impl Default for RustPackageFilterBuilder { | ||
22 | fn default() -> RustPackageFilterBuilder { | ||
23 | RustPackageFilterBuilder { is_member: false, exclude: GlobSetBuilder::new() } | ||
24 | } | ||
25 | } | ||
26 | |||
27 | impl RustPackageFilterBuilder { | ||
28 | pub fn set_member(mut self, is_member: bool) -> RustPackageFilterBuilder { | ||
29 | self.is_member = is_member; | ||
30 | self | ||
31 | } | ||
32 | pub fn exclude(mut self, glob: Glob) -> RustPackageFilterBuilder { | ||
33 | self.exclude.add(glob); | ||
34 | self | ||
35 | } | ||
36 | pub fn into_vfs_filter(self) -> Box<dyn Filter> { | ||
37 | let RustPackageFilterBuilder { is_member, mut exclude } = self; | ||
38 | for &glob in ALWAYS_IGNORED { | ||
39 | exclude.add(Glob::new(glob).unwrap()); | ||
40 | } | ||
41 | if !is_member { | ||
42 | for &glob in IGNORED_FOR_NON_MEMBERS { | ||
43 | exclude.add(Glob::new(glob).unwrap()); | ||
44 | } | ||
45 | } | ||
46 | Box::new(RustPackageFilter { exclude: exclude.build().unwrap() }) | ||
47 | } | ||
48 | } | ||
49 | |||
50 | struct RustPackageFilter { | ||
51 | exclude: GlobSet, | ||
52 | } | ||
53 | |||
54 | impl Filter for RustPackageFilter { | ||
55 | fn include_dir(&self, dir_path: &RelativePath) -> bool { | ||
56 | !self.exclude.is_match(dir_path.as_str()) | ||
57 | } | ||
58 | |||
59 | fn include_file(&self, file_path: &RelativePath) -> bool { | ||
60 | file_path.extension() == Some("rs") | ||
61 | } | ||
62 | } | ||
63 | |||
64 | #[test] | ||
65 | fn test_globs() { | ||
66 | let filter = RustPackageFilterBuilder::default().set_member(true).into_vfs_filter(); | ||
67 | |||
68 | assert!(filter.include_dir(RelativePath::new("src/tests"))); | ||
69 | assert!(filter.include_dir(RelativePath::new("src/target"))); | ||
70 | assert!(filter.include_dir(RelativePath::new("tests"))); | ||
71 | assert!(filter.include_dir(RelativePath::new("benches"))); | ||
72 | |||
73 | assert!(!filter.include_dir(RelativePath::new("target"))); | ||
74 | assert!(!filter.include_dir(RelativePath::new("src/foo/.git"))); | ||
75 | assert!(!filter.include_dir(RelativePath::new("foo/node_modules"))); | ||
76 | |||
77 | let filter = RustPackageFilterBuilder::default().set_member(false).into_vfs_filter(); | ||
78 | |||
79 | assert!(filter.include_dir(RelativePath::new("src/tests"))); | ||
80 | assert!(filter.include_dir(RelativePath::new("src/target"))); | ||
81 | |||
82 | assert!(!filter.include_dir(RelativePath::new("target"))); | ||
83 | assert!(!filter.include_dir(RelativePath::new("src/foo/.git"))); | ||
84 | assert!(!filter.include_dir(RelativePath::new("foo/node_modules"))); | ||
85 | assert!(!filter.include_dir(RelativePath::new("tests"))); | ||
86 | assert!(!filter.include_dir(RelativePath::new("benches"))); | ||
87 | |||
88 | let filter = RustPackageFilterBuilder::default() | ||
89 | .set_member(true) | ||
90 | .exclude(Glob::new("src/llvm-project/**").unwrap()) | ||
91 | .into_vfs_filter(); | ||
92 | |||
93 | assert!(!filter.include_dir(RelativePath::new("src/llvm-project/clang"))); | ||
94 | } | ||
diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs index d993c5fc4..71c95d4af 100644 --- a/crates/ra_lsp_server/src/world.rs +++ b/crates/ra_lsp_server/src/world.rs | |||
@@ -19,12 +19,12 @@ use ra_ide::{ | |||
19 | }; | 19 | }; |
20 | use ra_project_model::{get_rustc_cfg_options, ProjectWorkspace}; | 20 | use ra_project_model::{get_rustc_cfg_options, ProjectWorkspace}; |
21 | use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsRoot, VfsTask, Watch}; | 21 | use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsRoot, VfsTask, Watch}; |
22 | use ra_vfs_glob::{Glob, RustPackageFilterBuilder}; | ||
23 | use relative_path::RelativePathBuf; | 22 | use relative_path::RelativePathBuf; |
24 | 23 | ||
25 | use crate::{ | 24 | use crate::{ |
26 | diagnostics::{CheckFixes, DiagnosticCollection}, | 25 | diagnostics::{CheckFixes, DiagnosticCollection}, |
27 | main_loop::pending_requests::{CompletedRequest, LatestRequests}, | 26 | main_loop::pending_requests::{CompletedRequest, LatestRequests}, |
27 | vfs_glob::{Glob, RustPackageFilterBuilder}, | ||
28 | LspError, Result, | 28 | LspError, Result, |
29 | }; | 29 | }; |
30 | 30 | ||