aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists/src/lib.rs')
-rw-r--r--crates/ra_assists/src/lib.rs40
1 files changed, 37 insertions, 3 deletions
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs
index 881db6347..fc4e95303 100644
--- a/crates/ra_assists/src/lib.rs
+++ b/crates/ra_assists/src/lib.rs
@@ -8,7 +8,7 @@
8mod assist_ctx; 8mod assist_ctx;
9 9
10use ra_text_edit::TextEdit; 10use ra_text_edit::TextEdit;
11use ra_syntax::{TextUnit, SyntaxNode, Direction}; 11use ra_syntax::{TextRange, TextUnit, SyntaxNode, Direction};
12use ra_db::FileRange; 12use ra_db::FileRange;
13use hir::db::HirDatabase; 13use hir::db::HirDatabase;
14 14
@@ -23,6 +23,7 @@ pub struct AssistLabel {
23pub struct AssistAction { 23pub struct AssistAction {
24 pub edit: TextEdit, 24 pub edit: TextEdit,
25 pub cursor_position: Option<TextUnit>, 25 pub cursor_position: Option<TextUnit>,
26 pub target: Option<TextRange>,
26} 27}
27 28
28/// Return all the assists applicable at the given position. 29/// Return all the assists applicable at the given position.
@@ -53,15 +54,26 @@ pub fn assists<H>(db: &H, range: FileRange) -> Vec<(AssistLabel, AssistAction)>
53where 54where
54 H: HirDatabase + 'static, 55 H: HirDatabase + 'static,
55{ 56{
57 use std::cmp::Ordering;
58
56 AssistCtx::with_ctx(db, range, true, |ctx| { 59 AssistCtx::with_ctx(db, range, true, |ctx| {
57 all_assists() 60 let mut a = all_assists()
58 .iter() 61 .iter()
59 .filter_map(|f| f(ctx.clone())) 62 .filter_map(|f| f(ctx.clone()))
60 .map(|a| match a { 63 .map(|a| match a {
61 Assist::Resolved(label, action) => (label, action), 64 Assist::Resolved(label, action) => (label, action),
62 Assist::Unresolved(..) => unreachable!(), 65 Assist::Unresolved(..) => unreachable!(),
63 }) 66 })
64 .collect() 67 .collect::<Vec<(AssistLabel, AssistAction)>>();
68 a.sort_unstable_by(|a, b| match a {
69 // Some(y) < Some(x) < None for y < x
70 (_, AssistAction { target: Some(a), .. }) => match b {
71 (_, AssistAction { target: Some(b), .. }) => a.len().cmp(&b.len()),
72 _ => Ordering::Less,
73 },
74 _ => Ordering::Greater,
75 });
76 a
65 }) 77 })
66} 78}
67 79
@@ -162,5 +174,27 @@ mod helpers {
162 let assist = AssistCtx::with_ctx(&db, frange, true, assist); 174 let assist = AssistCtx::with_ctx(&db, frange, true, assist);
163 assert!(assist.is_none()); 175 assert!(assist.is_none());
164 } 176 }
177}
178
179#[cfg(test)]
180mod tests {
181 use hir::mock::MockDatabase;
182 use ra_syntax::TextRange;
183 use ra_db::FileRange;
184 use test_utils::extract_offset;
185
186 #[test]
187 fn assist_order() {
188 let before = "struct Foo { <|>bar: u32 }";
189 let (before_cursor_pos, before) = extract_offset(before);
190 let (db, _source_root, file_id) = MockDatabase::with_single_file(&before);
191 let frange =
192 FileRange { file_id, range: TextRange::offset_len(before_cursor_pos, 0.into()) };
193 let assists = super::assists(&db, frange);
194 let mut assists = assists.iter();
195
196 assert_eq!(assists.next().expect("expected assist").0.label, "make pub(crate)");
197 assert_eq!(assists.next().expect("expected assist").0.label, "add `#[derive]`");
198 }
165 199
166} 200}