diff options
-rw-r--r-- | crates/ra_assists/src/add_derive.rs | 4 | ||||
-rw-r--r-- | crates/ra_assists/src/add_impl.rs | 4 | ||||
-rw-r--r-- | crates/ra_assists/src/assist_ctx.rs | 5 | ||||
-rw-r--r-- | crates/ra_assists/src/auto_import.rs | 16 | ||||
-rw-r--r-- | crates/ra_assists/src/change_visibility.rs | 8 | ||||
-rw-r--r-- | crates/ra_assists/src/fill_match_arms.rs | 4 | ||||
-rw-r--r-- | crates/ra_assists/src/flip_comma.rs | 4 | ||||
-rw-r--r-- | crates/ra_assists/src/introduce_variable.rs | 4 | ||||
-rw-r--r-- | crates/ra_assists/src/lib.rs | 6 | ||||
-rw-r--r-- | crates/ra_assists/src/remove_dbg.rs | 4 | ||||
-rw-r--r-- | crates/ra_assists/src/replace_if_let_with_match.rs | 4 | ||||
-rw-r--r-- | crates/ra_assists/src/split_import.rs | 4 | ||||
-rw-r--r-- | crates/ra_ide_api/src/assists.rs | 16 | ||||
-rw-r--r-- | crates/ra_ide_api/src/lib.rs | 3 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 48 | ||||
-rw-r--r-- | crates/ra_lsp_server/tests/heavy_tests/main.rs | 11 |
16 files changed, 102 insertions, 43 deletions
diff --git a/crates/ra_assists/src/add_derive.rs b/crates/ra_assists/src/add_derive.rs index 0556dd69c..e91b5eb8d 100644 --- a/crates/ra_assists/src/add_derive.rs +++ b/crates/ra_assists/src/add_derive.rs | |||
@@ -5,12 +5,12 @@ use ra_syntax::{ | |||
5 | TextUnit, | 5 | TextUnit, |
6 | }; | 6 | }; |
7 | 7 | ||
8 | use crate::{AssistCtx, Assist}; | 8 | use crate::{AssistCtx, Assist, AssistId}; |
9 | 9 | ||
10 | pub(crate) fn add_derive(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 10 | pub(crate) fn add_derive(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
11 | let nominal = ctx.node_at_offset::<ast::NominalDef>()?; | 11 | let nominal = ctx.node_at_offset::<ast::NominalDef>()?; |
12 | let node_start = derive_insertion_offset(nominal)?; | 12 | let node_start = derive_insertion_offset(nominal)?; |
13 | ctx.add_action("add `#[derive]`", |edit| { | 13 | ctx.add_action(AssistId("add_derive"), "add `#[derive]`", |edit| { |
14 | let derive_attr = nominal | 14 | let derive_attr = nominal |
15 | .attrs() | 15 | .attrs() |
16 | .filter_map(|x| x.as_call()) | 16 | .filter_map(|x| x.as_call()) |
diff --git a/crates/ra_assists/src/add_impl.rs b/crates/ra_assists/src/add_impl.rs index b40b9cc0c..b292f188d 100644 --- a/crates/ra_assists/src/add_impl.rs +++ b/crates/ra_assists/src/add_impl.rs | |||
@@ -5,12 +5,12 @@ use ra_syntax::{ | |||
5 | TextUnit, | 5 | TextUnit, |
6 | }; | 6 | }; |
7 | 7 | ||
8 | use crate::{AssistCtx, Assist}; | 8 | use crate::{AssistCtx, Assist, AssistId}; |
9 | 9 | ||
10 | pub(crate) fn add_impl(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 10 | pub(crate) fn add_impl(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
11 | let nominal = ctx.node_at_offset::<ast::NominalDef>()?; | 11 | let nominal = ctx.node_at_offset::<ast::NominalDef>()?; |
12 | let name = nominal.name()?; | 12 | let name = nominal.name()?; |
13 | ctx.add_action("add impl", |edit| { | 13 | ctx.add_action(AssistId("add_impl"), "add impl", |edit| { |
14 | edit.target(nominal.syntax().range()); | 14 | edit.target(nominal.syntax().range()); |
15 | let type_params = nominal.type_param_list(); | 15 | let type_params = nominal.type_param_list(); |
16 | let start_offset = nominal.syntax().range().end(); | 16 | let start_offset = nominal.syntax().range().end(); |
diff --git a/crates/ra_assists/src/assist_ctx.rs b/crates/ra_assists/src/assist_ctx.rs index e9c4f0a23..4ad21c74b 100644 --- a/crates/ra_assists/src/assist_ctx.rs +++ b/crates/ra_assists/src/assist_ctx.rs | |||
@@ -7,7 +7,7 @@ use ra_syntax::{ | |||
7 | }; | 7 | }; |
8 | use ra_fmt::{leading_indent, reindent}; | 8 | use ra_fmt::{leading_indent, reindent}; |
9 | 9 | ||
10 | use crate::{AssistLabel, AssistAction}; | 10 | use crate::{AssistLabel, AssistAction, AssistId}; |
11 | 11 | ||
12 | #[derive(Clone, Debug)] | 12 | #[derive(Clone, Debug)] |
13 | pub(crate) enum Assist { | 13 | pub(crate) enum Assist { |
@@ -81,10 +81,11 @@ impl<'a, DB: HirDatabase> AssistCtx<'a, DB> { | |||
81 | 81 | ||
82 | pub(crate) fn add_action( | 82 | pub(crate) fn add_action( |
83 | &mut self, | 83 | &mut self, |
84 | id: AssistId, | ||
84 | label: impl Into<String>, | 85 | label: impl Into<String>, |
85 | f: impl FnOnce(&mut AssistBuilder), | 86 | f: impl FnOnce(&mut AssistBuilder), |
86 | ) -> &mut Self { | 87 | ) -> &mut Self { |
87 | let label = AssistLabel { label: label.into() }; | 88 | let label = AssistLabel { label: label.into(), id }; |
88 | match &mut self.assist { | 89 | match &mut self.assist { |
89 | Assist::Unresolved(labels) => labels.push(label), | 90 | Assist::Unresolved(labels) => labels.push(label), |
90 | Assist::Resolved(labels_actions) => { | 91 | Assist::Resolved(labels_actions) => { |
diff --git a/crates/ra_assists/src/auto_import.rs b/crates/ra_assists/src/auto_import.rs index 105c888d5..685dbed06 100644 --- a/crates/ra_assists/src/auto_import.rs +++ b/crates/ra_assists/src/auto_import.rs | |||
@@ -4,7 +4,10 @@ use ra_syntax::{ | |||
4 | ast::{ self, NameOwner }, AstNode, SyntaxNode, Direction, TextRange, | 4 | ast::{ self, NameOwner }, AstNode, SyntaxNode, Direction, TextRange, |
5 | SyntaxKind::{ PATH, PATH_SEGMENT, COLONCOLON, COMMA } | 5 | SyntaxKind::{ PATH, PATH_SEGMENT, COLONCOLON, COMMA } |
6 | }; | 6 | }; |
7 | use crate::assist_ctx::{AssistCtx, Assist, AssistBuilder}; | 7 | use crate::{ |
8 | AssistId, | ||
9 | assist_ctx::{AssistCtx, Assist, AssistBuilder}, | ||
10 | }; | ||
8 | 11 | ||
9 | fn collect_path_segments(path: &ast::Path) -> Option<Vec<&ast::PathSegment>> { | 12 | fn collect_path_segments(path: &ast::Path) -> Option<Vec<&ast::PathSegment>> { |
10 | let mut v = Vec::new(); | 13 | let mut v = Vec::new(); |
@@ -526,6 +529,7 @@ pub(crate) fn auto_import(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist | |||
526 | if let Some(module) = path.syntax().ancestors().find_map(ast::Module::cast) { | 529 | if let Some(module) = path.syntax().ancestors().find_map(ast::Module::cast) { |
527 | if let (Some(item_list), Some(name)) = (module.item_list(), module.name()) { | 530 | if let (Some(item_list), Some(name)) = (module.item_list(), module.name()) { |
528 | ctx.add_action( | 531 | ctx.add_action( |
532 | AssistId("auto_import"), | ||
529 | format!("import {} in mod {}", fmt_segments(&segments), name.text()), | 533 | format!("import {} in mod {}", fmt_segments(&segments), name.text()), |
530 | |edit| { | 534 | |edit| { |
531 | apply_auto_import(item_list.syntax(), path, &segments, edit); | 535 | apply_auto_import(item_list.syntax(), path, &segments, edit); |
@@ -534,9 +538,13 @@ pub(crate) fn auto_import(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist | |||
534 | } | 538 | } |
535 | } else { | 539 | } else { |
536 | let current_file = node.ancestors().find_map(ast::SourceFile::cast)?; | 540 | let current_file = node.ancestors().find_map(ast::SourceFile::cast)?; |
537 | ctx.add_action(format!("import {} in the current file", fmt_segments(&segments)), |edit| { | 541 | ctx.add_action( |
538 | apply_auto_import(current_file.syntax(), path, &segments, edit); | 542 | AssistId("auto_import"), |
539 | }); | 543 | format!("import {} in the current file", fmt_segments(&segments)), |
544 | |edit| { | ||
545 | apply_auto_import(current_file.syntax(), path, &segments, edit); | ||
546 | }, | ||
547 | ); | ||
540 | } | 548 | } |
541 | 549 | ||
542 | ctx.build() | 550 | ctx.build() |
diff --git a/crates/ra_assists/src/change_visibility.rs b/crates/ra_assists/src/change_visibility.rs index c2ba897a4..50c1be5ae 100644 --- a/crates/ra_assists/src/change_visibility.rs +++ b/crates/ra_assists/src/change_visibility.rs | |||
@@ -5,7 +5,7 @@ use ra_syntax::{ | |||
5 | SyntaxKind::{VISIBILITY, FN_KW, MOD_KW, STRUCT_KW, ENUM_KW, TRAIT_KW, FN_DEF, MODULE, STRUCT_DEF, ENUM_DEF, TRAIT_DEF, IDENT, WHITESPACE, COMMENT, ATTR}, | 5 | SyntaxKind::{VISIBILITY, FN_KW, MOD_KW, STRUCT_KW, ENUM_KW, TRAIT_KW, FN_DEF, MODULE, STRUCT_DEF, ENUM_DEF, TRAIT_DEF, IDENT, WHITESPACE, COMMENT, ATTR}, |
6 | }; | 6 | }; |
7 | 7 | ||
8 | use crate::{AssistCtx, Assist}; | 8 | use crate::{AssistCtx, Assist, AssistId}; |
9 | 9 | ||
10 | pub(crate) fn change_visibility(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 10 | pub(crate) fn change_visibility(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
11 | if let Some(vis) = ctx.node_at_offset::<ast::Visibility>() { | 11 | if let Some(vis) = ctx.node_at_offset::<ast::Visibility>() { |
@@ -41,7 +41,7 @@ fn add_vis(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | |||
41 | (vis_offset(field.syntax()), ident.range()) | 41 | (vis_offset(field.syntax()), ident.range()) |
42 | }; | 42 | }; |
43 | 43 | ||
44 | ctx.add_action("make pub(crate)", |edit| { | 44 | ctx.add_action(AssistId("change_visibility"), "make pub(crate)", |edit| { |
45 | edit.target(target); | 45 | edit.target(target); |
46 | edit.insert(offset, "pub(crate) "); | 46 | edit.insert(offset, "pub(crate) "); |
47 | edit.set_cursor(offset); | 47 | edit.set_cursor(offset); |
@@ -63,7 +63,7 @@ fn vis_offset(node: &SyntaxNode) -> TextUnit { | |||
63 | 63 | ||
64 | fn change_vis(mut ctx: AssistCtx<impl HirDatabase>, vis: &ast::Visibility) -> Option<Assist> { | 64 | fn change_vis(mut ctx: AssistCtx<impl HirDatabase>, vis: &ast::Visibility) -> Option<Assist> { |
65 | if vis.syntax().text() == "pub" { | 65 | if vis.syntax().text() == "pub" { |
66 | ctx.add_action("change to pub(crate)", |edit| { | 66 | ctx.add_action(AssistId("change_visibility"), "change to pub(crate)", |edit| { |
67 | edit.target(vis.syntax().range()); | 67 | edit.target(vis.syntax().range()); |
68 | edit.replace(vis.syntax().range(), "pub(crate)"); | 68 | edit.replace(vis.syntax().range(), "pub(crate)"); |
69 | edit.set_cursor(vis.syntax().range().start()) | 69 | edit.set_cursor(vis.syntax().range().start()) |
@@ -72,7 +72,7 @@ fn change_vis(mut ctx: AssistCtx<impl HirDatabase>, vis: &ast::Visibility) -> Op | |||
72 | return ctx.build(); | 72 | return ctx.build(); |
73 | } | 73 | } |
74 | if vis.syntax().text() == "pub(crate)" { | 74 | if vis.syntax().text() == "pub(crate)" { |
75 | ctx.add_action("change to pub", |edit| { | 75 | ctx.add_action(AssistId("change_visibility"), "change to pub", |edit| { |
76 | edit.target(vis.syntax().range()); | 76 | edit.target(vis.syntax().range()); |
77 | edit.replace(vis.syntax().range(), "pub"); | 77 | edit.replace(vis.syntax().range(), "pub"); |
78 | edit.set_cursor(vis.syntax().range().start()); | 78 | edit.set_cursor(vis.syntax().range().start()); |
diff --git a/crates/ra_assists/src/fill_match_arms.rs b/crates/ra_assists/src/fill_match_arms.rs index 6bf6e7332..30020b56e 100644 --- a/crates/ra_assists/src/fill_match_arms.rs +++ b/crates/ra_assists/src/fill_match_arms.rs | |||
@@ -6,7 +6,7 @@ use hir::{ | |||
6 | }; | 6 | }; |
7 | use ra_syntax::ast::{self, AstNode}; | 7 | use ra_syntax::ast::{self, AstNode}; |
8 | 8 | ||
9 | use crate::{AssistCtx, Assist}; | 9 | use crate::{AssistCtx, Assist, AssistId}; |
10 | 10 | ||
11 | pub(crate) fn fill_match_arms(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 11 | pub(crate) fn fill_match_arms(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
12 | let match_expr = ctx.node_at_offset::<ast::MatchExpr>()?; | 12 | let match_expr = ctx.node_at_offset::<ast::MatchExpr>()?; |
@@ -37,7 +37,7 @@ pub(crate) fn fill_match_arms(mut ctx: AssistCtx<impl HirDatabase>) -> Option<As | |||
37 | let enum_name = enum_def.name(ctx.db)?; | 37 | let enum_name = enum_def.name(ctx.db)?; |
38 | let db = ctx.db; | 38 | let db = ctx.db; |
39 | 39 | ||
40 | ctx.add_action("fill match arms", |edit| { | 40 | ctx.add_action(AssistId("fill_match_arms"), "fill match arms", |edit| { |
41 | let mut buf = format!("match {} {{\n", expr.syntax().text().to_string()); | 41 | let mut buf = format!("match {} {{\n", expr.syntax().text().to_string()); |
42 | let variants = enum_def.variants(db); | 42 | let variants = enum_def.variants(db); |
43 | for variant in variants { | 43 | for variant in variants { |
diff --git a/crates/ra_assists/src/flip_comma.rs b/crates/ra_assists/src/flip_comma.rs index 0d4a789fc..6b98cac68 100644 --- a/crates/ra_assists/src/flip_comma.rs +++ b/crates/ra_assists/src/flip_comma.rs | |||
@@ -5,13 +5,13 @@ use ra_syntax::{ | |||
5 | algo::non_trivia_sibling, | 5 | algo::non_trivia_sibling, |
6 | }; | 6 | }; |
7 | 7 | ||
8 | use crate::{AssistCtx, Assist}; | 8 | use crate::{AssistCtx, Assist, AssistId}; |
9 | 9 | ||
10 | pub(crate) fn flip_comma(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 10 | pub(crate) fn flip_comma(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
11 | let comma = ctx.leaf_at_offset().find(|leaf| leaf.kind() == COMMA)?; | 11 | let comma = ctx.leaf_at_offset().find(|leaf| leaf.kind() == COMMA)?; |
12 | let prev = non_trivia_sibling(comma, Direction::Prev)?; | 12 | let prev = non_trivia_sibling(comma, Direction::Prev)?; |
13 | let next = non_trivia_sibling(comma, Direction::Next)?; | 13 | let next = non_trivia_sibling(comma, Direction::Next)?; |
14 | ctx.add_action("flip comma", |edit| { | 14 | ctx.add_action(AssistId("flip_comma"), "flip comma", |edit| { |
15 | edit.target(comma.range()); | 15 | edit.target(comma.range()); |
16 | edit.replace(prev.range(), next.text()); | 16 | edit.replace(prev.range(), next.text()); |
17 | edit.replace(next.range(), prev.text()); | 17 | edit.replace(next.range(), prev.text()); |
diff --git a/crates/ra_assists/src/introduce_variable.rs b/crates/ra_assists/src/introduce_variable.rs index f0e012105..3d708ebb2 100644 --- a/crates/ra_assists/src/introduce_variable.rs +++ b/crates/ra_assists/src/introduce_variable.rs | |||
@@ -6,7 +6,7 @@ use ra_syntax::{ | |||
6 | }, SyntaxNode, TextUnit, | 6 | }, SyntaxNode, TextUnit, |
7 | }; | 7 | }; |
8 | 8 | ||
9 | use crate::{AssistCtx, Assist}; | 9 | use crate::{AssistCtx, Assist, AssistId}; |
10 | 10 | ||
11 | pub(crate) fn introduce_variable(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 11 | pub(crate) fn introduce_variable(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
12 | let node = ctx.covering_node(); | 12 | let node = ctx.covering_node(); |
@@ -19,7 +19,7 @@ pub(crate) fn introduce_variable(mut ctx: AssistCtx<impl HirDatabase>) -> Option | |||
19 | if indent.kind() != WHITESPACE { | 19 | if indent.kind() != WHITESPACE { |
20 | return None; | 20 | return None; |
21 | } | 21 | } |
22 | ctx.add_action("introduce variable", move |edit| { | 22 | ctx.add_action(AssistId("introduce_variable"), "introduce variable", move |edit| { |
23 | let mut buf = String::new(); | 23 | let mut buf = String::new(); |
24 | 24 | ||
25 | let cursor_offset = if wrap_in_block { | 25 | let cursor_offset = if wrap_in_block { |
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs index e1e899edc..56d276867 100644 --- a/crates/ra_assists/src/lib.rs +++ b/crates/ra_assists/src/lib.rs | |||
@@ -16,10 +16,16 @@ use hir::db::HirDatabase; | |||
16 | 16 | ||
17 | pub(crate) use crate::assist_ctx::{AssistCtx, Assist}; | 17 | pub(crate) use crate::assist_ctx::{AssistCtx, Assist}; |
18 | 18 | ||
19 | /// Unique identifier of the assist, should not be shown to the user | ||
20 | /// directly. | ||
21 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
22 | pub struct AssistId(pub &'static str); | ||
23 | |||
19 | #[derive(Debug, Clone)] | 24 | #[derive(Debug, Clone)] |
20 | pub struct AssistLabel { | 25 | pub struct AssistLabel { |
21 | /// Short description of the assist, as shown in the UI. | 26 | /// Short description of the assist, as shown in the UI. |
22 | pub label: String, | 27 | pub label: String, |
28 | pub id: AssistId, | ||
23 | } | 29 | } |
24 | 30 | ||
25 | #[derive(Debug, Clone)] | 31 | #[derive(Debug, Clone)] |
diff --git a/crates/ra_assists/src/remove_dbg.rs b/crates/ra_assists/src/remove_dbg.rs index 2bed270a1..6ea48d909 100644 --- a/crates/ra_assists/src/remove_dbg.rs +++ b/crates/ra_assists/src/remove_dbg.rs | |||
@@ -6,7 +6,7 @@ use ra_syntax::{ | |||
6 | L_PAREN, R_PAREN, L_CURLY, R_CURLY, L_BRACK, R_BRACK, EXCL | 6 | L_PAREN, R_PAREN, L_CURLY, R_CURLY, L_BRACK, R_BRACK, EXCL |
7 | }, | 7 | }, |
8 | }; | 8 | }; |
9 | use crate::{AssistCtx, Assist}; | 9 | use crate::{AssistCtx, Assist, AssistId}; |
10 | 10 | ||
11 | pub(crate) fn remove_dbg(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 11 | pub(crate) fn remove_dbg(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
12 | let macro_call = ctx.node_at_offset::<ast::MacroCall>()?; | 12 | let macro_call = ctx.node_at_offset::<ast::MacroCall>()?; |
@@ -46,7 +46,7 @@ pub(crate) fn remove_dbg(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> | |||
46 | macro_args.text().slice(start..end).to_string() | 46 | macro_args.text().slice(start..end).to_string() |
47 | }; | 47 | }; |
48 | 48 | ||
49 | ctx.add_action("remove dbg!()", |edit| { | 49 | ctx.add_action(AssistId("remove_dbg"), "remove dbg!()", |edit| { |
50 | edit.target(macro_call.syntax().range()); | 50 | edit.target(macro_call.syntax().range()); |
51 | edit.replace(macro_range, macro_content); | 51 | edit.replace(macro_range, macro_content); |
52 | edit.set_cursor(cursor_pos); | 52 | edit.set_cursor(cursor_pos); |
diff --git a/crates/ra_assists/src/replace_if_let_with_match.rs b/crates/ra_assists/src/replace_if_let_with_match.rs index 87a2c1185..230573499 100644 --- a/crates/ra_assists/src/replace_if_let_with_match.rs +++ b/crates/ra_assists/src/replace_if_let_with_match.rs | |||
@@ -2,7 +2,7 @@ use ra_syntax::{AstNode, ast}; | |||
2 | use ra_fmt::extract_trivial_expression; | 2 | use ra_fmt::extract_trivial_expression; |
3 | use hir::db::HirDatabase; | 3 | use hir::db::HirDatabase; |
4 | 4 | ||
5 | use crate::{AssistCtx, Assist}; | 5 | use crate::{AssistCtx, Assist, AssistId}; |
6 | 6 | ||
7 | pub(crate) fn replace_if_let_with_match(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 7 | pub(crate) fn replace_if_let_with_match(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
8 | let if_expr: &ast::IfExpr = ctx.node_at_offset()?; | 8 | let if_expr: &ast::IfExpr = ctx.node_at_offset()?; |
@@ -15,7 +15,7 @@ pub(crate) fn replace_if_let_with_match(mut ctx: AssistCtx<impl HirDatabase>) -> | |||
15 | ast::ElseBranchFlavor::IfExpr(_) => return None, | 15 | ast::ElseBranchFlavor::IfExpr(_) => return None, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | ctx.add_action("replace with match", |edit| { | 18 | ctx.add_action(AssistId("replace_if_let_with_match"), "replace with match", |edit| { |
19 | let match_expr = build_match_expr(expr, pat, then_block, else_block); | 19 | let match_expr = build_match_expr(expr, pat, then_block, else_block); |
20 | edit.target(if_expr.syntax().range()); | 20 | edit.target(if_expr.syntax().range()); |
21 | edit.replace_node_and_indent(if_expr.syntax(), match_expr); | 21 | edit.replace_node_and_indent(if_expr.syntax(), match_expr); |
diff --git a/crates/ra_assists/src/split_import.rs b/crates/ra_assists/src/split_import.rs index f043be636..dd5be4e91 100644 --- a/crates/ra_assists/src/split_import.rs +++ b/crates/ra_assists/src/split_import.rs | |||
@@ -5,7 +5,7 @@ use ra_syntax::{ | |||
5 | algo::generate, | 5 | algo::generate, |
6 | }; | 6 | }; |
7 | 7 | ||
8 | use crate::{AssistCtx, Assist}; | 8 | use crate::{AssistCtx, Assist, AssistId}; |
9 | 9 | ||
10 | pub(crate) fn split_import(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 10 | pub(crate) fn split_import(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
11 | let colon_colon = ctx.leaf_at_offset().find(|leaf| leaf.kind() == COLONCOLON)?; | 11 | let colon_colon = ctx.leaf_at_offset().find(|leaf| leaf.kind() == COLONCOLON)?; |
@@ -23,7 +23,7 @@ pub(crate) fn split_import(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assis | |||
23 | None => top_path.syntax().range().end(), | 23 | None => top_path.syntax().range().end(), |
24 | }; | 24 | }; |
25 | 25 | ||
26 | ctx.add_action("split import", |edit| { | 26 | ctx.add_action(AssistId("split_import"), "split import", |edit| { |
27 | edit.target(colon_colon.range()); | 27 | edit.target(colon_colon.range()); |
28 | edit.insert(l_curly, "{"); | 28 | edit.insert(l_curly, "{"); |
29 | edit.insert(r_curly, "}"); | 29 | edit.insert(r_curly, "}"); |
diff --git a/crates/ra_ide_api/src/assists.rs b/crates/ra_ide_api/src/assists.rs index 7a9c66681..3c0475a51 100644 --- a/crates/ra_ide_api/src/assists.rs +++ b/crates/ra_ide_api/src/assists.rs | |||
@@ -2,20 +2,30 @@ use ra_db::{FileRange, FilePosition}; | |||
2 | 2 | ||
3 | use crate::{SourceFileEdit, SourceChange, db::RootDatabase}; | 3 | use crate::{SourceFileEdit, SourceChange, db::RootDatabase}; |
4 | 4 | ||
5 | pub(crate) fn assists(db: &RootDatabase, frange: FileRange) -> Vec<SourceChange> { | 5 | pub use ra_assists::AssistId; |
6 | |||
7 | #[derive(Debug)] | ||
8 | pub struct Assist { | ||
9 | pub id: AssistId, | ||
10 | pub change: SourceChange, | ||
11 | } | ||
12 | |||
13 | pub(crate) fn assists(db: &RootDatabase, frange: FileRange) -> Vec<Assist> { | ||
6 | ra_assists::assists(db, frange) | 14 | ra_assists::assists(db, frange) |
7 | .into_iter() | 15 | .into_iter() |
8 | .map(|(label, action)| { | 16 | .map(|(label, action)| { |
9 | let file_id = frange.file_id; | 17 | let file_id = frange.file_id; |
10 | let file_edit = SourceFileEdit { file_id, edit: action.edit }; | 18 | let file_edit = SourceFileEdit { file_id, edit: action.edit }; |
11 | SourceChange { | 19 | let id = label.id; |
20 | let change = SourceChange { | ||
12 | label: label.label, | 21 | label: label.label, |
13 | source_file_edits: vec![file_edit], | 22 | source_file_edits: vec![file_edit], |
14 | file_system_edits: vec![], | 23 | file_system_edits: vec![], |
15 | cursor_position: action | 24 | cursor_position: action |
16 | .cursor_position | 25 | .cursor_position |
17 | .map(|offset| FilePosition { offset, file_id }), | 26 | .map(|offset| FilePosition { offset, file_id }), |
18 | } | 27 | }; |
28 | Assist { id, change } | ||
19 | }) | 29 | }) |
20 | .collect() | 30 | .collect() |
21 | } | 31 | } |
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 4b9fc9372..076a8396c 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs | |||
@@ -57,6 +57,7 @@ pub use crate::{ | |||
57 | runnables::{Runnable, RunnableKind}, | 57 | runnables::{Runnable, RunnableKind}, |
58 | navigation_target::NavigationTarget, | 58 | navigation_target::NavigationTarget, |
59 | references::ReferenceSearchResult, | 59 | references::ReferenceSearchResult, |
60 | assists::{Assist, AssistId}, | ||
60 | }; | 61 | }; |
61 | pub use ra_ide_api_light::{ | 62 | pub use ra_ide_api_light::{ |
62 | Fold, FoldKind, HighlightedRange, Severity, StructureNode, LocalEdit, | 63 | Fold, FoldKind, HighlightedRange, Severity, StructureNode, LocalEdit, |
@@ -368,7 +369,7 @@ impl Analysis { | |||
368 | 369 | ||
369 | /// Computes assists (aks code actons aka intentions) for the given | 370 | /// Computes assists (aks code actons aka intentions) for the given |
370 | /// position. | 371 | /// position. |
371 | pub fn assists(&self, frange: FileRange) -> Cancelable<Vec<SourceChange>> { | 372 | pub fn assists(&self, frange: FileRange) -> Cancelable<Vec<Assist>> { |
372 | self.with_db(|db| assists::assists(db, frange)) | 373 | self.with_db(|db| assists::assists(db, frange)) |
373 | } | 374 | } |
374 | 375 | ||
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 9abd4054e..5da731801 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use gen_lsp_server::ErrorCode; | 1 | use gen_lsp_server::ErrorCode; |
2 | use lsp_types::{ | 2 | use lsp_types::{ |
3 | CodeActionResponse, CodeLens, Command, Diagnostic, DiagnosticSeverity, | 3 | CodeActionResponse, CodeLens, Command, Diagnostic, DiagnosticSeverity, CodeAction, |
4 | DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange, | 4 | DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange, |
5 | FoldingRangeKind, FoldingRangeParams, Hover, HoverContents, Location, MarkupContent, | 5 | FoldingRangeKind, FoldingRangeParams, Hover, HoverContents, Location, MarkupContent, |
6 | MarkupKind, ParameterInformation, ParameterLabel, Position, PrepareRenameResponse, Range, | 6 | MarkupKind, ParameterInformation, ParameterLabel, Position, PrepareRenameResponse, Range, |
@@ -9,6 +9,7 @@ use lsp_types::{ | |||
9 | }; | 9 | }; |
10 | use ra_ide_api::{ | 10 | use ra_ide_api::{ |
11 | FileId, FilePosition, FileRange, FoldKind, Query, RangeInfo, RunnableKind, Severity, Cancelable, | 11 | FileId, FilePosition, FileRange, FoldKind, Query, RangeInfo, RunnableKind, Severity, Cancelable, |
12 | AssistId, | ||
12 | }; | 13 | }; |
13 | use ra_syntax::{AstNode, SyntaxKind, TextUnit}; | 14 | use ra_syntax::{AstNode, SyntaxKind, TextUnit}; |
14 | use rustc_hash::FxHashMap; | 15 | use rustc_hash::FxHashMap; |
@@ -576,28 +577,57 @@ pub fn handle_code_action( | |||
576 | let range = params.range.conv_with(&line_index); | 577 | let range = params.range.conv_with(&line_index); |
577 | 578 | ||
578 | let assists = world.analysis().assists(FileRange { file_id, range })?.into_iter(); | 579 | let assists = world.analysis().assists(FileRange { file_id, range })?.into_iter(); |
579 | let fixes = world | 580 | let diagnostics = world.analysis().diagnostics(file_id)?; |
580 | .analysis() | 581 | let mut res: Vec<CodeAction> = Vec::new(); |
581 | .diagnostics(file_id)? | 582 | |
583 | let fixes_from_diagnostics = diagnostics | ||
582 | .into_iter() | 584 | .into_iter() |
583 | .filter_map(|d| Some((d.range, d.fix?))) | 585 | .filter_map(|d| Some((d.range, d.fix?))) |
584 | .filter(|(diag_range, _fix)| diag_range.intersection(&range).is_some()) | 586 | .filter(|(diag_range, _fix)| diag_range.intersection(&range).is_some()) |
585 | .map(|(_range, fix)| fix); | 587 | .map(|(_range, fix)| fix); |
586 | 588 | ||
587 | let mut res = Vec::new(); | 589 | for source_edit in fixes_from_diagnostics { |
588 | for source_edit in assists.chain(fixes) { | ||
589 | let title = source_edit.label.clone(); | 590 | let title = source_edit.label.clone(); |
590 | let edit = source_edit.try_conv_with(&world)?; | 591 | let edit = source_edit.try_conv_with(&world)?; |
591 | 592 | ||
592 | let cmd = Command { | 593 | let command = Command { |
594 | title, | ||
595 | command: "rust-analyzer.applySourceChange".to_string(), | ||
596 | arguments: Some(vec![to_value(edit).unwrap()]), | ||
597 | }; | ||
598 | let action = CodeAction { | ||
599 | title: command.title.clone(), | ||
600 | kind: None, | ||
601 | diagnostics: None, | ||
602 | edit: None, | ||
603 | command: Some(command), | ||
604 | }; | ||
605 | res.push(action); | ||
606 | } | ||
607 | |||
608 | for assist in assists { | ||
609 | let title = assist.change.label.clone(); | ||
610 | let edit = assist.change.try_conv_with(&world)?; | ||
611 | |||
612 | let command = Command { | ||
593 | title, | 613 | title, |
594 | command: "rust-analyzer.applySourceChange".to_string(), | 614 | command: "rust-analyzer.applySourceChange".to_string(), |
595 | arguments: Some(vec![to_value(edit).unwrap()]), | 615 | arguments: Some(vec![to_value(edit).unwrap()]), |
596 | }; | 616 | }; |
597 | res.push(cmd); | 617 | let action = CodeAction { |
618 | title: command.title.clone(), | ||
619 | kind: match assist.id { | ||
620 | AssistId("introduce_variable") => Some("refactor.extract.variable".to_string()), | ||
621 | _ => None, | ||
622 | }, | ||
623 | diagnostics: None, | ||
624 | edit: None, | ||
625 | command: Some(command), | ||
626 | }; | ||
627 | res.push(action); | ||
598 | } | 628 | } |
599 | 629 | ||
600 | Ok(Some(CodeActionResponse::Commands(res))) | 630 | Ok(Some(CodeActionResponse::Actions(res))) |
601 | } | 631 | } |
602 | 632 | ||
603 | pub fn handle_code_lens( | 633 | pub fn handle_code_lens( |
diff --git a/crates/ra_lsp_server/tests/heavy_tests/main.rs b/crates/ra_lsp_server/tests/heavy_tests/main.rs index e49c87169..996bf8e01 100644 --- a/crates/ra_lsp_server/tests/heavy_tests/main.rs +++ b/crates/ra_lsp_server/tests/heavy_tests/main.rs | |||
@@ -225,10 +225,12 @@ fn main() {} | |||
225 | context: empty_context(), | 225 | context: empty_context(), |
226 | }, | 226 | }, |
227 | json!([ | 227 | json!([ |
228 | { | 228 | { |
229 | "command": { | ||
229 | "arguments": [ | 230 | "arguments": [ |
230 | { | 231 | { |
231 | "cursorPosition": null, | 232 | "cursorPosition": null, |
233 | "label": "create module", | ||
232 | "workspaceEdit": { | 234 | "workspaceEdit": { |
233 | "documentChanges": [ | 235 | "documentChanges": [ |
234 | { | 236 | { |
@@ -236,13 +238,14 @@ fn main() {} | |||
236 | "uri": "file:///[..]/src/bar.rs" | 238 | "uri": "file:///[..]/src/bar.rs" |
237 | } | 239 | } |
238 | ] | 240 | ] |
239 | }, | 241 | } |
240 | "label": "create module" | ||
241 | } | 242 | } |
242 | ], | 243 | ], |
243 | "command": "rust-analyzer.applySourceChange", | 244 | "command": "rust-analyzer.applySourceChange", |
244 | "title": "create module" | 245 | "title": "create module" |
245 | } | 246 | }, |
247 | "title": "create module" | ||
248 | } | ||
246 | ]), | 249 | ]), |
247 | ); | 250 | ); |
248 | 251 | ||