diff options
Diffstat (limited to 'crates/ra_assists/src/lib.rs')
-rw-r--r-- | crates/ra_assists/src/lib.rs | 40 |
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 @@ | |||
8 | mod assist_ctx; | 8 | mod assist_ctx; |
9 | 9 | ||
10 | use ra_text_edit::TextEdit; | 10 | use ra_text_edit::TextEdit; |
11 | use ra_syntax::{TextUnit, SyntaxNode, Direction}; | 11 | use ra_syntax::{TextRange, TextUnit, SyntaxNode, Direction}; |
12 | use ra_db::FileRange; | 12 | use ra_db::FileRange; |
13 | use hir::db::HirDatabase; | 13 | use hir::db::HirDatabase; |
14 | 14 | ||
@@ -23,6 +23,7 @@ pub struct AssistLabel { | |||
23 | pub struct AssistAction { | 23 | pub 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)> | |||
53 | where | 54 | where |
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)] | ||
180 | mod 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 | } |