diff options
Diffstat (limited to 'crates/rust-analyzer/src/main_loop/handlers.rs')
-rw-r--r-- | crates/rust-analyzer/src/main_loop/handlers.rs | 64 |
1 files changed, 11 insertions, 53 deletions
diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index 121964718..a9703e1d6 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs | |||
@@ -18,7 +18,7 @@ use lsp_types::{ | |||
18 | SemanticTokensResult, SymbolInformation, TextDocumentIdentifier, Url, WorkspaceEdit, | 18 | SemanticTokensResult, SymbolInformation, TextDocumentIdentifier, Url, WorkspaceEdit, |
19 | }; | 19 | }; |
20 | use ra_ide::{ | 20 | use ra_ide::{ |
21 | Assist, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind, SearchScope, | 21 | FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind, SearchScope, |
22 | TextEdit, | 22 | TextEdit, |
23 | }; | 23 | }; |
24 | use ra_prof::profile; | 24 | use ra_prof::profile; |
@@ -720,6 +720,7 @@ pub fn handle_code_action( | |||
720 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 720 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; |
721 | let line_index = world.analysis().file_line_index(file_id)?; | 721 | let line_index = world.analysis().file_line_index(file_id)?; |
722 | let range = from_proto::text_range(&line_index, params.range); | 722 | let range = from_proto::text_range(&line_index, params.range); |
723 | let frange = FileRange { file_id, range }; | ||
723 | 724 | ||
724 | let diagnostics = world.analysis().diagnostics(file_id)?; | 725 | let diagnostics = world.analysis().diagnostics(file_id)?; |
725 | let mut res: Vec<lsp_ext::CodeAction> = Vec::new(); | 726 | let mut res: Vec<lsp_ext::CodeAction> = Vec::new(); |
@@ -730,10 +731,11 @@ pub fn handle_code_action( | |||
730 | .filter(|(diag_range, _fix)| diag_range.intersect(range).is_some()) | 731 | .filter(|(diag_range, _fix)| diag_range.intersect(range).is_some()) |
731 | .map(|(_range, fix)| fix); | 732 | .map(|(_range, fix)| fix); |
732 | 733 | ||
733 | for source_edit in fixes_from_diagnostics { | 734 | for fix in fixes_from_diagnostics { |
734 | let title = source_edit.label.clone(); | 735 | let title = fix.label; |
735 | let edit = to_proto::snippet_workspace_edit(&world, source_edit)?; | 736 | let edit = to_proto::snippet_workspace_edit(&world, fix.source_change)?; |
736 | let action = lsp_ext::CodeAction { title, kind: None, edit: Some(edit), command: None }; | 737 | let action = |
738 | lsp_ext::CodeAction { title, group: None, kind: None, edit: Some(edit), command: None }; | ||
737 | res.push(action); | 739 | res.push(action); |
738 | } | 740 | } |
739 | 741 | ||
@@ -745,53 +747,9 @@ pub fn handle_code_action( | |||
745 | res.push(fix.action.clone()); | 747 | res.push(fix.action.clone()); |
746 | } | 748 | } |
747 | 749 | ||
748 | let mut grouped_assists: FxHashMap<String, (usize, Vec<Assist>)> = FxHashMap::default(); | 750 | for assist in world.analysis().assists(&world.config.assist, frange)?.into_iter() { |
749 | for assist in | 751 | res.push(to_proto::code_action(&world, assist)?.into()); |
750 | world.analysis().assists(&world.config.assist, FileRange { file_id, range })?.into_iter() | ||
751 | { | ||
752 | match &assist.group_label { | ||
753 | Some(label) => grouped_assists | ||
754 | .entry(label.to_owned()) | ||
755 | .or_insert_with(|| { | ||
756 | let idx = res.len(); | ||
757 | let dummy = lsp_ext::CodeAction { | ||
758 | title: String::new(), | ||
759 | kind: None, | ||
760 | command: None, | ||
761 | edit: None, | ||
762 | }; | ||
763 | res.push(dummy); | ||
764 | (idx, Vec::new()) | ||
765 | }) | ||
766 | .1 | ||
767 | .push(assist), | ||
768 | None => { | ||
769 | res.push(to_proto::code_action(&world, assist)?.into()); | ||
770 | } | ||
771 | } | ||
772 | } | ||
773 | |||
774 | for (group_label, (idx, assists)) in grouped_assists { | ||
775 | if assists.len() == 1 { | ||
776 | res[idx] = to_proto::code_action(&world, assists.into_iter().next().unwrap())?.into(); | ||
777 | } else { | ||
778 | let title = group_label; | ||
779 | |||
780 | let mut arguments = Vec::with_capacity(assists.len()); | ||
781 | for assist in assists { | ||
782 | let source_change = to_proto::source_change(&world, assist.source_change)?; | ||
783 | arguments.push(to_value(source_change)?); | ||
784 | } | ||
785 | |||
786 | let command = Some(Command { | ||
787 | title: title.clone(), | ||
788 | command: "rust-analyzer.selectAndApplySourceChange".to_string(), | ||
789 | arguments: Some(vec![serde_json::Value::Array(arguments)]), | ||
790 | }); | ||
791 | res[idx] = lsp_ext::CodeAction { title, kind: None, edit: None, command }; | ||
792 | } | ||
793 | } | 752 | } |
794 | |||
795 | Ok(Some(res)) | 753 | Ok(Some(res)) |
796 | } | 754 | } |
797 | 755 | ||
@@ -986,11 +944,11 @@ pub fn handle_document_highlight( | |||
986 | pub fn handle_ssr( | 944 | pub fn handle_ssr( |
987 | world: WorldSnapshot, | 945 | world: WorldSnapshot, |
988 | params: lsp_ext::SsrParams, | 946 | params: lsp_ext::SsrParams, |
989 | ) -> Result<lsp_ext::SourceChange> { | 947 | ) -> Result<lsp_types::WorkspaceEdit> { |
990 | let _p = profile("handle_ssr"); | 948 | let _p = profile("handle_ssr"); |
991 | let source_change = | 949 | let source_change = |
992 | world.analysis().structural_search_replace(¶ms.query, params.parse_only)??; | 950 | world.analysis().structural_search_replace(¶ms.query, params.parse_only)??; |
993 | to_proto::source_change(&world, source_change) | 951 | to_proto::workspace_edit(&world, source_change) |
994 | } | 952 | } |
995 | 953 | ||
996 | pub fn publish_diagnostics(world: &WorldSnapshot, file_id: FileId) -> Result<DiagnosticTask> { | 954 | pub fn publish_diagnostics(world: &WorldSnapshot, file_id: FileId) -> Result<DiagnosticTask> { |