diff options
author | gfreezy <[email protected]> | 2019-01-19 16:38:34 +0000 |
---|---|---|
committer | gfreezy <[email protected]> | 2019-01-19 16:38:34 +0000 |
commit | 94d96b60f334e662f516bd0f04cc4191d7a804e6 (patch) | |
tree | 34ed5b9da22c938a5f7a3cac7a09de5812fa819f /crates/ra_ide_api/src/completion/completion_item.rs | |
parent | 64342599ca43fb72d0db8e79802a1018f480b5f5 (diff) |
refactor to use `remove_range` and `replace_range` instead of TextEdit
Diffstat (limited to 'crates/ra_ide_api/src/completion/completion_item.rs')
-rw-r--r-- | crates/ra_ide_api/src/completion/completion_item.rs | 110 |
1 files changed, 36 insertions, 74 deletions
diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide_api/src/completion/completion_item.rs index f9a266524..da8da94d1 100644 --- a/crates/ra_ide_api/src/completion/completion_item.rs +++ b/crates/ra_ide_api/src/completion/completion_item.rs | |||
@@ -1,10 +1,7 @@ | |||
1 | use hir::PerNs; | 1 | use hir::PerNs; |
2 | use ra_text_edit::{ | ||
3 | AtomTextEdit, | ||
4 | TextEdit, | ||
5 | }; | ||
6 | 2 | ||
7 | use crate::completion::completion_context::CompletionContext; | 3 | use crate::completion::completion_context::CompletionContext; |
4 | use ra_syntax::TextRange; | ||
8 | 5 | ||
9 | /// `CompletionItem` describes a single completion variant in the editor pop-up. | 6 | /// `CompletionItem` describes a single completion variant in the editor pop-up. |
10 | /// It is basically a POD with various properties. To construct a | 7 | /// It is basically a POD with various properties. To construct a |
@@ -18,26 +15,10 @@ pub struct CompletionItem { | |||
18 | kind: Option<CompletionItemKind>, | 15 | kind: Option<CompletionItemKind>, |
19 | detail: Option<String>, | 16 | detail: Option<String>, |
20 | lookup: Option<String>, | 17 | lookup: Option<String>, |
21 | /// The format of the insert text. The format applies to both the `insert_text` property | 18 | insert_text: Option<String>, |
22 | /// and the `insert` property of a provided `text_edit`. | ||
23 | insert_text_format: InsertTextFormat, | 19 | insert_text_format: InsertTextFormat, |
24 | /// An edit which is applied to a document when selecting this completion. When an edit is | 20 | replace_range: TextRange, |
25 | /// provided the value of `insert_text` is ignored. | 21 | delete_range: Option<TextRange>, |
26 | /// | ||
27 | /// *Note:* The range of the edit must be a single line range and it must contain the position | ||
28 | /// at which completion has been requested. | ||
29 | /// | ||
30 | /// *Note:* If sending a range that overlaps a string, the string should match the relevant | ||
31 | /// part of the replacement text, or be filtered out. | ||
32 | text_edit: Option<AtomTextEdit>, | ||
33 | /// An optional array of additional text edits that are applied when | ||
34 | /// selecting this completion. Edits must not overlap (including the same insert position) | ||
35 | /// with the main edit nor with themselves. | ||
36 | /// | ||
37 | /// Additional text edits should be used to change text unrelated to the current cursor position | ||
38 | /// (for example adding an import statement at the top of the file if the completion item will | ||
39 | /// insert an unqualified type). | ||
40 | additional_text_edits: Option<TextEdit>, | ||
41 | } | 22 | } |
42 | 23 | ||
43 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 24 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
@@ -76,14 +57,14 @@ pub enum InsertTextFormat { | |||
76 | } | 57 | } |
77 | 58 | ||
78 | impl CompletionItem { | 59 | impl CompletionItem { |
79 | pub(crate) fn new<'a>( | 60 | pub(crate) fn new( |
80 | completion_kind: CompletionKind, | 61 | completion_kind: CompletionKind, |
81 | ctx: &'a CompletionContext, | 62 | replace_range: TextRange, |
82 | label: impl Into<String>, | 63 | label: impl Into<String>, |
83 | ) -> Builder<'a> { | 64 | ) -> Builder { |
84 | let label = label.into(); | 65 | let label = label.into(); |
85 | Builder { | 66 | Builder { |
86 | ctx, | 67 | replace_range, |
87 | completion_kind, | 68 | completion_kind, |
88 | label, | 69 | label, |
89 | insert_text: None, | 70 | insert_text: None, |
@@ -91,8 +72,7 @@ impl CompletionItem { | |||
91 | detail: None, | 72 | detail: None, |
92 | lookup: None, | 73 | lookup: None, |
93 | kind: None, | 74 | kind: None, |
94 | text_edit: None, | 75 | delete_range: None, |
95 | additional_text_edits: None, | ||
96 | } | 76 | } |
97 | } | 77 | } |
98 | /// What user sees in pop-up in the UI. | 78 | /// What user sees in pop-up in the UI. |
@@ -114,22 +94,27 @@ impl CompletionItem { | |||
114 | pub fn insert_text_format(&self) -> InsertTextFormat { | 94 | pub fn insert_text_format(&self) -> InsertTextFormat { |
115 | self.insert_text_format.clone() | 95 | self.insert_text_format.clone() |
116 | } | 96 | } |
117 | 97 | pub fn insert_text(&self) -> String { | |
98 | match &self.insert_text { | ||
99 | Some(t) => t.clone(), | ||
100 | None => self.label.clone(), | ||
101 | } | ||
102 | } | ||
118 | pub fn kind(&self) -> Option<CompletionItemKind> { | 103 | pub fn kind(&self) -> Option<CompletionItemKind> { |
119 | self.kind | 104 | self.kind |
120 | } | 105 | } |
121 | pub fn text_edit(&mut self) -> Option<&AtomTextEdit> { | 106 | pub fn delete_range(&self) -> Option<TextRange> { |
122 | self.text_edit.as_ref() | 107 | self.delete_range |
123 | } | 108 | } |
124 | pub fn take_additional_text_edits(&mut self) -> Option<TextEdit> { | 109 | pub fn replace_range(&self) -> TextRange { |
125 | self.additional_text_edits.take() | 110 | self.replace_range |
126 | } | 111 | } |
127 | } | 112 | } |
128 | 113 | ||
129 | /// A helper to make `CompletionItem`s. | 114 | /// A helper to make `CompletionItem`s. |
130 | #[must_use] | 115 | #[must_use] |
131 | pub(crate) struct Builder<'a> { | 116 | pub(crate) struct Builder { |
132 | ctx: &'a CompletionContext<'a>, | 117 | replace_range: TextRange, |
133 | completion_kind: CompletionKind, | 118 | completion_kind: CompletionKind, |
134 | label: String, | 119 | label: String, |
135 | insert_text: Option<String>, | 120 | insert_text: Option<String>, |
@@ -137,76 +122,53 @@ pub(crate) struct Builder<'a> { | |||
137 | detail: Option<String>, | 122 | detail: Option<String>, |
138 | lookup: Option<String>, | 123 | lookup: Option<String>, |
139 | kind: Option<CompletionItemKind>, | 124 | kind: Option<CompletionItemKind>, |
140 | text_edit: Option<AtomTextEdit>, | 125 | delete_range: Option<TextRange>, |
141 | additional_text_edits: Option<TextEdit>, | ||
142 | } | 126 | } |
143 | 127 | ||
144 | impl<'a> Builder<'a> { | 128 | impl Builder { |
145 | pub(crate) fn add_to(self, acc: &mut Completions) { | 129 | pub(crate) fn add_to(self, acc: &mut Completions) { |
146 | acc.add(self.build()) | 130 | acc.add(self.build()) |
147 | } | 131 | } |
148 | 132 | ||
149 | pub(crate) fn build(self) -> CompletionItem { | 133 | pub(crate) fn build(self) -> CompletionItem { |
150 | let self_text_edit = self.text_edit; | ||
151 | let self_insert_text = self.insert_text; | ||
152 | let text_edit = match (self_text_edit, self_insert_text) { | ||
153 | (Some(text_edit), ..) => Some(text_edit), | ||
154 | (None, Some(insert_text)) => { | ||
155 | Some(AtomTextEdit::replace(self.ctx.leaf_range(), insert_text)) | ||
156 | } | ||
157 | _ => None, | ||
158 | }; | ||
159 | |||
160 | CompletionItem { | 134 | CompletionItem { |
135 | replace_range: self.replace_range, | ||
161 | label: self.label, | 136 | label: self.label, |
162 | detail: self.detail, | 137 | detail: self.detail, |
163 | insert_text_format: self.insert_text_format, | 138 | insert_text_format: self.insert_text_format, |
164 | lookup: self.lookup, | 139 | lookup: self.lookup, |
165 | kind: self.kind, | 140 | kind: self.kind, |
166 | completion_kind: self.completion_kind, | 141 | completion_kind: self.completion_kind, |
167 | text_edit, | 142 | delete_range: self.delete_range, |
168 | additional_text_edits: self.additional_text_edits, | 143 | insert_text: self.insert_text, |
169 | } | 144 | } |
170 | } | 145 | } |
171 | pub(crate) fn lookup_by(mut self, lookup: impl Into<String>) -> Builder<'a> { | 146 | pub(crate) fn lookup_by(mut self, lookup: impl Into<String>) -> Builder { |
172 | self.lookup = Some(lookup.into()); | 147 | self.lookup = Some(lookup.into()); |
173 | self | 148 | self |
174 | } | 149 | } |
175 | pub(crate) fn insert_text(mut self, insert_text: impl Into<String>) -> Builder<'a> { | 150 | pub(crate) fn insert_text(mut self, insert_text: impl Into<String>) -> Builder { |
176 | self.insert_text = Some(insert_text.into()); | 151 | self.insert_text = Some(insert_text.into()); |
177 | self | 152 | self |
178 | } | 153 | } |
179 | #[allow(unused)] | 154 | #[allow(unused)] |
180 | pub(crate) fn insert_text_format( | 155 | pub(crate) fn insert_text_format(mut self, insert_text_format: InsertTextFormat) -> Builder { |
181 | mut self, | ||
182 | insert_text_format: InsertTextFormat, | ||
183 | ) -> Builder<'a> { | ||
184 | self.insert_text_format = insert_text_format; | 156 | self.insert_text_format = insert_text_format; |
185 | self | 157 | self |
186 | } | 158 | } |
187 | pub(crate) fn snippet(mut self, snippet: impl Into<String>) -> Builder<'a> { | 159 | pub(crate) fn snippet(mut self, snippet: impl Into<String>) -> Builder { |
188 | self.insert_text_format = InsertTextFormat::Snippet; | 160 | self.insert_text_format = InsertTextFormat::Snippet; |
189 | self.insert_text(snippet) | 161 | self.insert_text(snippet) |
190 | } | 162 | } |
191 | pub(crate) fn kind(mut self, kind: CompletionItemKind) -> Builder<'a> { | 163 | pub(crate) fn kind(mut self, kind: CompletionItemKind) -> Builder { |
192 | self.kind = Some(kind); | 164 | self.kind = Some(kind); |
193 | self | 165 | self |
194 | } | 166 | } |
195 | #[allow(unused)] | 167 | #[allow(unused)] |
196 | pub(crate) fn text_edit(mut self, text_edit: AtomTextEdit) -> Builder<'a> { | 168 | pub(crate) fn detail(self, detail: impl Into<String>) -> Builder { |
197 | self.text_edit = Some(text_edit); | ||
198 | self | ||
199 | } | ||
200 | #[allow(unused)] | ||
201 | pub(crate) fn additional_text_edits(mut self, additional_text_edits: TextEdit) -> Builder<'a> { | ||
202 | self.additional_text_edits = Some(additional_text_edits); | ||
203 | self | ||
204 | } | ||
205 | #[allow(unused)] | ||
206 | pub(crate) fn detail(self, detail: impl Into<String>) -> Builder<'a> { | ||
207 | self.set_detail(Some(detail)) | 169 | self.set_detail(Some(detail)) |
208 | } | 170 | } |
209 | pub(crate) fn set_detail(mut self, detail: Option<impl Into<String>>) -> Builder<'a> { | 171 | pub(crate) fn set_detail(mut self, detail: Option<impl Into<String>>) -> Builder { |
210 | self.detail = detail.map(Into::into); | 172 | self.detail = detail.map(Into::into); |
211 | self | 173 | self |
212 | } | 174 | } |
@@ -214,7 +176,7 @@ impl<'a> Builder<'a> { | |||
214 | mut self, | 176 | mut self, |
215 | ctx: &CompletionContext, | 177 | ctx: &CompletionContext, |
216 | resolution: &hir::Resolution, | 178 | resolution: &hir::Resolution, |
217 | ) -> Builder<'a> { | 179 | ) -> Builder { |
218 | let resolved = resolution.def_id.map(|d| d.resolve(ctx.db)); | 180 | let resolved = resolution.def_id.map(|d| d.resolve(ctx.db)); |
219 | let kind = match resolved { | 181 | let kind = match resolved { |
220 | PerNs { | 182 | PerNs { |
@@ -259,7 +221,7 @@ impl<'a> Builder<'a> { | |||
259 | mut self, | 221 | mut self, |
260 | ctx: &CompletionContext, | 222 | ctx: &CompletionContext, |
261 | function: hir::Function, | 223 | function: hir::Function, |
262 | ) -> Builder<'a> { | 224 | ) -> Builder { |
263 | // If not an import, add parenthesis automatically. | 225 | // If not an import, add parenthesis automatically. |
264 | if ctx.use_item_syntax.is_none() && !ctx.is_call { | 226 | if ctx.use_item_syntax.is_none() && !ctx.is_call { |
265 | if function.signature(ctx.db).params().is_empty() { | 227 | if function.signature(ctx.db).params().is_empty() { |
@@ -274,7 +236,7 @@ impl<'a> Builder<'a> { | |||
274 | } | 236 | } |
275 | } | 237 | } |
276 | 238 | ||
277 | impl<'a> Into<CompletionItem> for Builder<'a> { | 239 | impl<'a> Into<CompletionItem> for Builder { |
278 | fn into(self) -> CompletionItem { | 240 | fn into(self) -> CompletionItem { |
279 | self.build() | 241 | self.build() |
280 | } | 242 | } |