aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/assist_ctx.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists/src/assist_ctx.rs')
-rw-r--r--crates/ra_assists/src/assist_ctx.rs45
1 files changed, 39 insertions, 6 deletions
diff --git a/crates/ra_assists/src/assist_ctx.rs b/crates/ra_assists/src/assist_ctx.rs
index 1a65b5dc0..879216a36 100644
--- a/crates/ra_assists/src/assist_ctx.rs
+++ b/crates/ra_assists/src/assist_ctx.rs
@@ -14,7 +14,7 @@ use crate::{AssistAction, AssistId, AssistLabel};
14#[derive(Clone, Debug)] 14#[derive(Clone, Debug)]
15pub(crate) enum Assist { 15pub(crate) enum Assist {
16 Unresolved { label: AssistLabel }, 16 Unresolved { label: AssistLabel },
17 Resolved { label: AssistLabel, action: AssistAction }, 17 Resolved { label: AssistLabel, action: AssistAction, alternative_actions: Vec<AssistAction> },
18} 18}
19 19
20/// `AssistCtx` allows to apply an assist or check if it could be applied. 20/// `AssistCtx` allows to apply an assist or check if it could be applied.
@@ -81,18 +81,43 @@ impl<'a, DB: HirDatabase> AssistCtx<'a, DB> {
81 self, 81 self,
82 id: AssistId, 82 id: AssistId,
83 label: impl Into<String>, 83 label: impl Into<String>,
84 f: impl FnOnce(&mut AssistBuilder), 84 f: impl FnOnce(&mut ActionBuilder),
85 ) -> Option<Assist> { 85 ) -> Option<Assist> {
86 let label = AssistLabel { label: label.into(), id }; 86 let label = AssistLabel { label: label.into(), id };
87 assert!(label.label.chars().nth(0).unwrap().is_uppercase()); 87 assert!(label.label.chars().nth(0).unwrap().is_uppercase());
88 88
89 let assist = if self.should_compute_edit { 89 let assist = if self.should_compute_edit {
90 let action = { 90 let action = {
91 let mut edit = AssistBuilder::default(); 91 let mut edit = ActionBuilder::default();
92 f(&mut edit); 92 f(&mut edit);
93 edit.build() 93 edit.build()
94 }; 94 };
95 Assist::Resolved { label, action } 95 Assist::Resolved { label, action, alternative_actions: Vec::default() }
96 } else {
97 Assist::Unresolved { label }
98 };
99
100 Some(assist)
101 }
102
103 #[allow(dead_code)] // will be used for auto import assist with multiple actions
104 pub(crate) fn add_assist_group(
105 self,
106 id: AssistId,
107 label: impl Into<String>,
108 f: impl FnOnce() -> (ActionBuilder, Vec<ActionBuilder>),
109 ) -> Option<Assist> {
110 let label = AssistLabel { label: label.into(), id };
111 let assist = if self.should_compute_edit {
112 let (action, alternative_actions) = f();
113 Assist::Resolved {
114 label,
115 action: action.build(),
116 alternative_actions: alternative_actions
117 .into_iter()
118 .map(ActionBuilder::build)
119 .collect(),
120 }
96 } else { 121 } else {
97 Assist::Unresolved { label } 122 Assist::Unresolved { label }
98 }; 123 };
@@ -128,13 +153,20 @@ impl<'a, DB: HirDatabase> AssistCtx<'a, DB> {
128} 153}
129 154
130#[derive(Default)] 155#[derive(Default)]
131pub(crate) struct AssistBuilder { 156pub(crate) struct ActionBuilder {
132 edit: TextEditBuilder, 157 edit: TextEditBuilder,
133 cursor_position: Option<TextUnit>, 158 cursor_position: Option<TextUnit>,
134 target: Option<TextRange>, 159 target: Option<TextRange>,
160 label: Option<String>,
135} 161}
136 162
137impl AssistBuilder { 163impl ActionBuilder {
164 #[allow(dead_code)]
165 /// Adds a custom label to the action, if it needs to be different from the assist label
166 pub fn label(&mut self, label: impl Into<String>) {
167 self.label = Some(label.into())
168 }
169
138 /// Replaces specified `range` of text with a given string. 170 /// Replaces specified `range` of text with a given string.
139 pub(crate) fn replace(&mut self, range: TextRange, replace_with: impl Into<String>) { 171 pub(crate) fn replace(&mut self, range: TextRange, replace_with: impl Into<String>) {
140 self.edit.replace(range, replace_with.into()) 172 self.edit.replace(range, replace_with.into())
@@ -193,6 +225,7 @@ impl AssistBuilder {
193 edit: self.edit.finish(), 225 edit: self.edit.finish(),
194 cursor_position: self.cursor_position, 226 cursor_position: self.cursor_position,
195 target: self.target, 227 target: self.target,
228 label: self.label,
196 } 229 }
197 } 230 }
198} 231}