Skip to content

Commit 7e83ed9

Browse files
author
Jonas Schievink
committed
Respect casing when searching for imports
1 parent ed2817e commit 7e83ed9

File tree

3 files changed

+81
-6
lines changed

3 files changed

+81
-6
lines changed

crates/ra_assists/src/handlers/auto_import.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,31 @@ impl fmt::Display for S {}
914914
fn main() {
915915
Cheese;
916916
}
917+
",
918+
);
919+
}
920+
921+
#[test]
922+
fn casing() {
923+
// Tests that differently cased names don't interfere and we only suggest the matching one.
924+
check_assist(
925+
auto_import,
926+
r"
927+
//- /lib.rs crate:dep
928+
929+
pub struct FMT;
930+
pub struct fmt;
931+
932+
//- /main.rs crate:main deps:dep
933+
934+
fn main() {
935+
FMT<|>;
936+
}",
937+
r"use dep::FMT;
938+
939+
fn main() {
940+
FMT;
941+
}
917942
",
918943
);
919944
}

crates/ra_hir/src/code_model.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl Crate {
107107
import_map::search_dependencies(
108108
db,
109109
self.into(),
110-
import_map::Query::new(query).anchor_end().limit(40),
110+
import_map::Query::new(query).anchor_end().case_sensitive().limit(40),
111111
)
112112
.into_iter()
113113
.map(|item| match item {

crates/ra_hir_def/src/import_map.rs

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,21 @@ fn cmp((_, lhs): &(&ItemInNs, &ModPath), (_, rhs): &(&ItemInNs, &ModPath)) -> Or
177177
#[derive(Debug)]
178178
pub struct Query {
179179
query: String,
180+
lowercased: String,
180181
anchor_end: bool,
182+
case_sensitive: bool,
181183
limit: usize,
182184
}
183185

184186
impl Query {
185187
pub fn new(query: &str) -> Self {
186-
Self { query: query.to_lowercase(), anchor_end: false, limit: usize::max_value() }
188+
Self {
189+
lowercased: query.to_lowercase(),
190+
query: query.to_string(),
191+
anchor_end: false,
192+
case_sensitive: false,
193+
limit: usize::max_value(),
194+
}
187195
}
188196

189197
/// Only returns items whose paths end with the (case-insensitive) query string as their last
@@ -196,6 +204,11 @@ impl Query {
196204
pub fn limit(self, limit: usize) -> Self {
197205
Self { limit, ..self }
198206
}
207+
208+
/// Respect casing of the query string when matching.
209+
pub fn case_sensitive(self) -> Self {
210+
Self { case_sensitive: true, ..self }
211+
}
199212
}
200213

201214
/// Searches dependencies of `krate` for an importable path matching `query`.
@@ -212,7 +225,7 @@ pub fn search_dependencies<'a>(
212225
let import_maps: Vec<_> =
213226
graph[krate].dependencies.iter().map(|dep| db.import_map(dep.crate_id)).collect();
214227

215-
let automaton = fst::automaton::Subsequence::new(&query.query);
228+
let automaton = fst::automaton::Subsequence::new(&query.lowercased);
216229

217230
let mut op = fst::map::OpBuilder::new();
218231
for map in &import_maps {
@@ -232,17 +245,27 @@ pub fn search_dependencies<'a>(
232245
if query.anchor_end {
233246
// Last segment must match query.
234247
let last = path.segments.last().unwrap().to_string();
235-
if last.to_lowercase() != query.query {
248+
if last.to_lowercase() != query.lowercased {
236249
continue;
237250
}
238251
}
239252

240253
// Add the items from this `ModPath` group. Those are all subsequent items in
241254
// `importables` whose paths match `path`.
242-
res.extend(importables.iter().copied().take_while(|item| {
255+
let iter = importables.iter().copied().take_while(|item| {
243256
let item_path = &import_map.map[item];
244257
fst_path(item_path) == fst_path(path)
245-
}));
258+
});
259+
260+
if query.case_sensitive {
261+
// FIXME: This does not do a subsequence match.
262+
res.extend(iter.filter(|item| {
263+
let item_path = &import_map.map[item];
264+
item_path.to_string().contains(&query.query)
265+
}));
266+
} else {
267+
res.extend(iter);
268+
}
246269

247270
if res.len() >= query.limit {
248271
res.truncate(query.limit);
@@ -582,6 +605,33 @@ mod tests {
582605
"###);
583606
}
584607

608+
#[test]
609+
fn search_casing() {
610+
let ra_fixture = r#"
611+
//- /main.rs crate:main deps:dep
612+
//- /dep.rs crate:dep
613+
614+
pub struct fmt;
615+
pub struct FMT;
616+
"#;
617+
618+
let res = search_dependencies_of(ra_fixture, "main", Query::new("FMT"));
619+
620+
assert_snapshot!(res, @r###"
621+
dep::FMT (v)
622+
dep::FMT (t)
623+
dep::fmt (t)
624+
dep::fmt (v)
625+
"###);
626+
627+
let res = search_dependencies_of(ra_fixture, "main", Query::new("FMT").case_sensitive());
628+
629+
assert_snapshot!(res, @r###"
630+
dep::FMT (v)
631+
dep::FMT (t)
632+
"###);
633+
}
634+
585635
#[test]
586636
fn search_limit() {
587637
let res = search_dependencies_of(

0 commit comments

Comments
 (0)