diff options
Diffstat (limited to 'crates/completion/src/completions/mod_.rs')
-rw-r--r-- | crates/completion/src/completions/mod_.rs | 87 |
1 files changed, 40 insertions, 47 deletions
diff --git a/crates/completion/src/completions/mod_.rs b/crates/completion/src/completions/mod_.rs index f77864b77..00e951ca9 100644 --- a/crates/completion/src/completions/mod_.rs +++ b/crates/completion/src/completions/mod_.rs | |||
@@ -1,5 +1,7 @@ | |||
1 | //! Completes mod declarations. | 1 | //! Completes mod declarations. |
2 | 2 | ||
3 | use std::iter; | ||
4 | |||
3 | use hir::{Module, ModuleSource}; | 5 | use hir::{Module, ModuleSource}; |
4 | use ide_db::base_db::{SourceDatabaseExt, VfsPath}; | 6 | use ide_db::base_db::{SourceDatabaseExt, VfsPath}; |
5 | use ide_db::RootDatabase; | 7 | use ide_db::RootDatabase; |
@@ -9,12 +11,11 @@ use crate::{CompletionItem, CompletionItemKind}; | |||
9 | 11 | ||
10 | use crate::{context::CompletionContext, item::CompletionKind, Completions}; | 12 | use crate::{context::CompletionContext, item::CompletionKind, Completions}; |
11 | 13 | ||
12 | /// Complete mod declaration, i.e. `mod <|> ;` | 14 | /// Complete mod declaration, i.e. `mod $0 ;` |
13 | pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { | 15 | pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { |
14 | let mod_under_caret = match &ctx.mod_declaration_under_caret { | 16 | let mod_under_caret = match &ctx.mod_declaration_under_caret { |
15 | Some(mod_under_caret) if mod_under_caret.item_list().is_some() => return None, | 17 | Some(mod_under_caret) if mod_under_caret.item_list().is_none() => mod_under_caret, |
16 | Some(mod_under_caret) => mod_under_caret, | 18 | _ => return None, |
17 | None => return None, | ||
18 | }; | 19 | }; |
19 | 20 | ||
20 | let _p = profile::span("completion::complete_mod"); | 21 | let _p = profile::span("completion::complete_mod"); |
@@ -49,9 +50,13 @@ pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Op | |||
49 | .filter_map(|submodule_file| { | 50 | .filter_map(|submodule_file| { |
50 | let submodule_path = source_root.path_for_file(&submodule_file)?; | 51 | let submodule_path = source_root.path_for_file(&submodule_file)?; |
51 | let directory_with_submodule = submodule_path.parent()?; | 52 | let directory_with_submodule = submodule_path.parent()?; |
52 | match submodule_path.name_and_extension()? { | 53 | let (name, ext) = submodule_path.name_and_extension()?; |
53 | ("lib", Some("rs")) | ("main", Some("rs")) => None, | 54 | if ext != Some("rs") { |
54 | ("mod", Some("rs")) => { | 55 | return None; |
56 | } | ||
57 | match name { | ||
58 | "lib" | "main" => None, | ||
59 | "mod" => { | ||
55 | if directory_with_submodule.parent()? == directory_to_look_for_submodules { | 60 | if directory_with_submodule.parent()? == directory_to_look_for_submodules { |
56 | match directory_with_submodule.name_and_extension()? { | 61 | match directory_with_submodule.name_and_extension()? { |
57 | (directory_name, None) => Some(directory_name.to_owned()), | 62 | (directory_name, None) => Some(directory_name.to_owned()), |
@@ -61,9 +66,7 @@ pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Op | |||
61 | None | 66 | None |
62 | } | 67 | } |
63 | } | 68 | } |
64 | (file_name, Some("rs")) | 69 | file_name if directory_with_submodule == directory_to_look_for_submodules => { |
65 | if directory_with_submodule == directory_to_look_for_submodules => | ||
66 | { | ||
67 | Some(file_name.to_owned()) | 70 | Some(file_name.to_owned()) |
68 | } | 71 | } |
69 | _ => None, | 72 | _ => None, |
@@ -73,7 +76,7 @@ pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Op | |||
73 | .for_each(|submodule_name| { | 76 | .for_each(|submodule_name| { |
74 | let mut label = submodule_name; | 77 | let mut label = submodule_name; |
75 | if mod_under_caret.semicolon_token().is_none() { | 78 | if mod_under_caret.semicolon_token().is_none() { |
76 | label.push(';') | 79 | label.push(';'); |
77 | } | 80 | } |
78 | CompletionItem::new(CompletionKind::Magic, ctx.source_range(), &label) | 81 | CompletionItem::new(CompletionKind::Magic, ctx.source_range(), &label) |
79 | .kind(CompletionItemKind::Module) | 82 | .kind(CompletionItemKind::Module) |
@@ -89,11 +92,13 @@ fn directory_to_look_for_submodules( | |||
89 | module_file_path: &VfsPath, | 92 | module_file_path: &VfsPath, |
90 | ) -> Option<VfsPath> { | 93 | ) -> Option<VfsPath> { |
91 | let directory_with_module_path = module_file_path.parent()?; | 94 | let directory_with_module_path = module_file_path.parent()?; |
92 | let base_directory = match module_file_path.name_and_extension()? { | 95 | let (name, ext) = module_file_path.name_and_extension()?; |
93 | ("mod", Some("rs")) | ("lib", Some("rs")) | ("main", Some("rs")) => { | 96 | if ext != Some("rs") { |
94 | Some(directory_with_module_path) | 97 | return None; |
95 | } | 98 | } |
96 | (regular_rust_file_name, Some("rs")) => { | 99 | let base_directory = match name { |
100 | "mod" | "lib" | "main" => Some(directory_with_module_path), | ||
101 | regular_rust_file_name => { | ||
97 | if matches!( | 102 | if matches!( |
98 | ( | 103 | ( |
99 | directory_with_module_path | 104 | directory_with_module_path |
@@ -110,37 +115,25 @@ fn directory_to_look_for_submodules( | |||
110 | directory_with_module_path.join(regular_rust_file_name) | 115 | directory_with_module_path.join(regular_rust_file_name) |
111 | } | 116 | } |
112 | } | 117 | } |
113 | _ => None, | ||
114 | }?; | 118 | }?; |
115 | 119 | ||
116 | let mut resulting_path = base_directory; | 120 | module_chain_to_containing_module_file(module, db) |
117 | for module in module_chain_to_containing_module_file(module, db) { | 121 | .into_iter() |
118 | if let Some(name) = module.name(db) { | 122 | .filter_map(|module| module.name(db)) |
119 | resulting_path = resulting_path.join(&name.to_string())?; | 123 | .try_fold(base_directory, |path, name| path.join(&name.to_string())) |
120 | } | ||
121 | } | ||
122 | |||
123 | Some(resulting_path) | ||
124 | } | 124 | } |
125 | 125 | ||
126 | fn module_chain_to_containing_module_file( | 126 | fn module_chain_to_containing_module_file( |
127 | current_module: Module, | 127 | current_module: Module, |
128 | db: &RootDatabase, | 128 | db: &RootDatabase, |
129 | ) -> Vec<Module> { | 129 | ) -> Vec<Module> { |
130 | let mut path = Vec::new(); | 130 | let mut path = |
131 | 131 | iter::successors(Some(current_module), |current_module| current_module.parent(db)) | |
132 | let mut current_module = Some(current_module); | 132 | .take_while(|current_module| { |
133 | while let Some(ModuleSource::Module(_)) = | 133 | matches!(current_module.definition_source(db).value, ModuleSource::Module(_)) |
134 | current_module.map(|module| module.definition_source(db).value) | 134 | }) |
135 | { | 135 | .collect::<Vec<_>>(); |
136 | if let Some(module) = current_module { | 136 | path.reverse(); |
137 | path.insert(0, module); | ||
138 | current_module = module.parent(db); | ||
139 | } else { | ||
140 | current_module = None; | ||
141 | } | ||
142 | } | ||
143 | |||
144 | path | 137 | path |
145 | } | 138 | } |
146 | 139 | ||
@@ -159,7 +152,7 @@ mod tests { | |||
159 | check( | 152 | check( |
160 | r#" | 153 | r#" |
161 | //- /lib.rs | 154 | //- /lib.rs |
162 | mod <|> | 155 | mod $0 |
163 | //- /foo.rs | 156 | //- /foo.rs |
164 | fn foo() {} | 157 | fn foo() {} |
165 | //- /foo/ignored_foo.rs | 158 | //- /foo/ignored_foo.rs |
@@ -181,7 +174,7 @@ mod tests { | |||
181 | check( | 174 | check( |
182 | r#" | 175 | r#" |
183 | //- /lib.rs | 176 | //- /lib.rs |
184 | mod <|> { | 177 | mod $0 { |
185 | 178 | ||
186 | } | 179 | } |
187 | //- /foo.rs | 180 | //- /foo.rs |
@@ -196,7 +189,7 @@ mod tests { | |||
196 | check( | 189 | check( |
197 | r#" | 190 | r#" |
198 | //- /main.rs | 191 | //- /main.rs |
199 | mod <|> | 192 | mod $0 |
200 | //- /foo.rs | 193 | //- /foo.rs |
201 | fn foo() {} | 194 | fn foo() {} |
202 | //- /foo/ignored_foo.rs | 195 | //- /foo/ignored_foo.rs |
@@ -219,7 +212,7 @@ mod tests { | |||
219 | r#" | 212 | r#" |
220 | //- /main.rs | 213 | //- /main.rs |
221 | mod tests { | 214 | mod tests { |
222 | mod <|>; | 215 | mod $0; |
223 | } | 216 | } |
224 | //- /tests/foo.rs | 217 | //- /tests/foo.rs |
225 | fn foo() {} | 218 | fn foo() {} |
@@ -237,7 +230,7 @@ mod tests { | |||
237 | //- /lib.rs | 230 | //- /lib.rs |
238 | mod foo; | 231 | mod foo; |
239 | //- /foo.rs | 232 | //- /foo.rs |
240 | mod <|>; | 233 | mod $0; |
241 | //- /foo/bar.rs | 234 | //- /foo/bar.rs |
242 | fn bar() {} | 235 | fn bar() {} |
243 | //- /foo/bar/ignored_bar.rs | 236 | //- /foo/bar/ignored_bar.rs |
@@ -262,7 +255,7 @@ mod tests { | |||
262 | mod foo; | 255 | mod foo; |
263 | //- /foo.rs | 256 | //- /foo.rs |
264 | mod bar { | 257 | mod bar { |
265 | mod <|> | 258 | mod $0 |
266 | } | 259 | } |
267 | //- /foo/bar/baz.rs | 260 | //- /foo/bar/baz.rs |
268 | fn baz() {} | 261 | fn baz() {} |
@@ -288,7 +281,7 @@ mod tests { | |||
288 | // //- /src/bin.rs | 281 | // //- /src/bin.rs |
289 | // fn main() {} | 282 | // fn main() {} |
290 | // //- /src/bin/foo.rs | 283 | // //- /src/bin/foo.rs |
291 | // mod <|> | 284 | // mod $0 |
292 | // //- /src/bin/bar.rs | 285 | // //- /src/bin/bar.rs |
293 | // fn bar() {} | 286 | // fn bar() {} |
294 | // //- /src/bin/bar/bar_ignored.rs | 287 | // //- /src/bin/bar/bar_ignored.rs |
@@ -307,7 +300,7 @@ mod tests { | |||
307 | //- /src/bin.rs crate:main | 300 | //- /src/bin.rs crate:main |
308 | fn main() {} | 301 | fn main() {} |
309 | //- /src/bin/foo.rs | 302 | //- /src/bin/foo.rs |
310 | mod <|> | 303 | mod $0 |
311 | //- /src/bin/bar.rs | 304 | //- /src/bin/bar.rs |
312 | mod foo; | 305 | mod foo; |
313 | fn bar() {} | 306 | fn bar() {} |