diff options
Diffstat (limited to 'crates/ra_lsp_server/src')
-rw-r--r-- | crates/ra_lsp_server/src/conv.rs | 47 |
1 files changed, 7 insertions, 40 deletions
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index c0e4e3a36..d3670104e 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs | |||
@@ -3,7 +3,7 @@ use languageserver_types::{ | |||
3 | TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, InsertTextFormat, | 3 | TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, InsertTextFormat, |
4 | }; | 4 | }; |
5 | use ra_analysis::{FileId, FileSystemEdit, SourceChange, SourceFileEdit, FilePosition, CompletionItem, CompletionItemKind, InsertText}; | 5 | use ra_analysis::{FileId, FileSystemEdit, SourceChange, SourceFileEdit, FilePosition, CompletionItem, CompletionItemKind, InsertText}; |
6 | use ra_editor::{LineCol, LineIndex}; | 6 | use ra_editor::{LineCol, LineIndex, translate_offset_with_edit}; |
7 | use ra_text_edit::{AtomTextEdit, TextEdit}; | 7 | use ra_text_edit::{AtomTextEdit, TextEdit}; |
8 | use ra_syntax::{SyntaxKind, TextRange, TextUnit}; | 8 | use ra_syntax::{SyntaxKind, TextRange, TextUnit}; |
9 | 9 | ||
@@ -238,13 +238,15 @@ impl TryConvWith for SourceChange { | |||
238 | None => None, | 238 | None => None, |
239 | Some(pos) => { | 239 | Some(pos) => { |
240 | let line_index = world.analysis().file_line_index(pos.file_id); | 240 | let line_index = world.analysis().file_line_index(pos.file_id); |
241 | let edits = self | 241 | let edit = self |
242 | .source_file_edits | 242 | .source_file_edits |
243 | .iter() | 243 | .iter() |
244 | .find(|it| it.file_id == pos.file_id) | 244 | .find(|it| it.file_id == pos.file_id) |
245 | .map(|it| it.edit.as_atoms()) | 245 | .map(|it| &it.edit); |
246 | .unwrap_or(&[]); | 246 | let line_col = match edit { |
247 | let line_col = translate_offset_with_edit(&*line_index, pos.offset, edits); | 247 | Some(edit) => translate_offset_with_edit(&*line_index, pos.offset, edit), |
248 | None => line_index.line_col(pos.offset), | ||
249 | }; | ||
248 | let position = | 250 | let position = |
249 | Position::new(u64::from(line_col.line), u64::from(line_col.col_utf16)); | 251 | Position::new(u64::from(line_col.line), u64::from(line_col.col_utf16)); |
250 | Some(TextDocumentPositionParams { | 252 | Some(TextDocumentPositionParams { |
@@ -264,41 +266,6 @@ impl TryConvWith for SourceChange { | |||
264 | } | 266 | } |
265 | } | 267 | } |
266 | 268 | ||
267 | // HACK: we should translate offset to line/column using linde_index *with edits applied*. | ||
268 | // A naive version of this function would be to apply `edits` to the original text, | ||
269 | // construct a new line index and use that, but it would be slow. | ||
270 | // | ||
271 | // Writing fast & correct version is issue #105, let's use a quick hack in the meantime | ||
272 | fn translate_offset_with_edit( | ||
273 | pre_edit_index: &LineIndex, | ||
274 | offset: TextUnit, | ||
275 | edits: &[AtomTextEdit], | ||
276 | ) -> LineCol { | ||
277 | let fallback = pre_edit_index.line_col(offset); | ||
278 | let edit = match edits.first() { | ||
279 | None => return fallback, | ||
280 | Some(edit) => edit, | ||
281 | }; | ||
282 | let end_offset = edit.delete.start() + TextUnit::of_str(&edit.insert); | ||
283 | if !(edit.delete.start() <= offset && offset <= end_offset) { | ||
284 | return fallback; | ||
285 | } | ||
286 | let rel_offset = offset - edit.delete.start(); | ||
287 | let in_edit_line_col = LineIndex::new(&edit.insert).line_col(rel_offset); | ||
288 | let edit_line_col = pre_edit_index.line_col(edit.delete.start()); | ||
289 | if in_edit_line_col.line == 0 { | ||
290 | LineCol { | ||
291 | line: edit_line_col.line, | ||
292 | col_utf16: edit_line_col.col_utf16 + in_edit_line_col.col_utf16, | ||
293 | } | ||
294 | } else { | ||
295 | LineCol { | ||
296 | line: edit_line_col.line + in_edit_line_col.line, | ||
297 | col_utf16: in_edit_line_col.col_utf16, | ||
298 | } | ||
299 | } | ||
300 | } | ||
301 | |||
302 | impl TryConvWith for SourceFileEdit { | 269 | impl TryConvWith for SourceFileEdit { |
303 | type Ctx = ServerWorld; | 270 | type Ctx = ServerWorld; |
304 | type Output = TextDocumentEdit; | 271 | type Output = TextDocumentEdit; |