aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_lsp_server/src')
-rw-r--r--crates/ra_lsp_server/src/conv.rs47
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};
5use ra_analysis::{FileId, FileSystemEdit, SourceChange, SourceFileEdit, FilePosition, CompletionItem, CompletionItemKind, InsertText}; 5use ra_analysis::{FileId, FileSystemEdit, SourceChange, SourceFileEdit, FilePosition, CompletionItem, CompletionItemKind, InsertText};
6use ra_editor::{LineCol, LineIndex}; 6use ra_editor::{LineCol, LineIndex, translate_offset_with_edit};
7use ra_text_edit::{AtomTextEdit, TextEdit}; 7use ra_text_edit::{AtomTextEdit, TextEdit};
8use ra_syntax::{SyntaxKind, TextRange, TextUnit}; 8use 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
272fn 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
302impl TryConvWith for SourceFileEdit { 269impl TryConvWith for SourceFileEdit {
303 type Ctx = ServerWorld; 270 type Ctx = ServerWorld;
304 type Output = TextDocumentEdit; 271 type Output = TextDocumentEdit;