Skip to content
This repository has been archived by the owner on Aug 31, 2023. It is now read-only.

Commit

Permalink
fix(rome_lsp): fix the calculation of offsets in the diff to LSP text…
Browse files Browse the repository at this point in the history
… edit conversion (#3350)
  • Loading branch information
leops authored Oct 6, 2022
1 parent c854ce1 commit 68ebe59
Showing 1 changed file with 67 additions and 15 deletions.
82 changes: 67 additions & 15 deletions crates/rome_lsp/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,19 @@ pub(crate) fn text_range(line_index: &LineIndex, range: lsp::Range) -> Result<Te

pub(crate) fn text_edit(line_index: &LineIndex, diff: TextEdit) -> Vec<lsp::TextEdit> {
let mut result: Vec<lsp::TextEdit> = Vec::new();
let mut old_offset = TextSize::from(0);
let mut new_offset = TextSize::from(0);
let mut offset = TextSize::from(0);

for op in diff.iter() {
match op {
CompressedOp::DiffOp(DiffOp::Equal { range }) => {
old_offset += range.len();
new_offset += range.len();
offset += range.len();
}
CompressedOp::DiffOp(DiffOp::Insert { range }) => {
let start = position(line_index, new_offset);
new_offset += range.len();
let start = position(line_index, offset);

// Merge with a previous delete operation if possible
let last_edit = result.last_mut().filter(|text_edit| {
text_edit.range.start == start && text_edit.new_text.is_empty()
text_edit.range.end == start && text_edit.new_text.is_empty()
});

if let Some(last_edit) = last_edit {
Expand All @@ -79,9 +76,9 @@ pub(crate) fn text_edit(line_index: &LineIndex, diff: TextEdit) -> Vec<lsp::Text
}
}
CompressedOp::DiffOp(DiffOp::Delete { range }) => {
let start = position(line_index, old_offset);
old_offset += range.len();
let end = position(line_index, old_offset);
let start = position(line_index, offset);
offset += range.len();
let end = position(line_index, offset);

result.push(lsp::TextEdit {
range: lsp::Range::new(start, end),
Expand All @@ -90,18 +87,17 @@ pub(crate) fn text_edit(line_index: &LineIndex, diff: TextEdit) -> Vec<lsp::Text
}

CompressedOp::EqualLines { line_count } => {
let mut line_col = line_index.line_col(old_offset);
let mut line_col = line_index.line_col(offset);
line_col.line += line_count.get() + 1;
line_col.col = 0;

// SAFETY: This should only happen if `line_index` wasn't built
// from the same string as the old revision of `diff`
let offset = line_index
let new_offset = line_index
.offset(line_col)
.expect("diff length is overflowing the line count in the original file");

new_offset += offset - old_offset;
old_offset = offset;
offset = new_offset;
}
}
}
Expand Down Expand Up @@ -313,7 +309,7 @@ mod tests {
use crate::line_index::LineIndex;

#[test]
fn test_diff() {
fn test_diff_1() {
const OLD: &str = "line 1 old
line 2
line 3
Expand Down Expand Up @@ -367,4 +363,60 @@ line 7 new";
]
);
}

#[test]
fn test_diff_2() {
const OLD: &str = "console.log(\"Variable: \" + variable);";
const NEW: &str = "console.log(`Variable: ${variable}`);";

let line_index = LineIndex::new(OLD);
let diff = TextEdit::from_unicode_words(OLD, NEW);

let text_edit = super::text_edit(&line_index, diff);

assert_eq!(
text_edit.as_slice(),
&[
lsp::TextEdit {
range: lsp::Range {
start: lsp::Position {
line: 0,
character: 12,
},
end: lsp::Position {
line: 0,
character: 13,
},
},
new_text: String::from("`"),
},
lsp::TextEdit {
range: lsp::Range {
start: lsp::Position {
line: 0,
character: 23
},
end: lsp::Position {
line: 0,
character: 27
}
},
new_text: String::from("${"),
},
lsp::TextEdit {
range: lsp::Range {
start: lsp::Position {
line: 0,
character: 35
},
end: lsp::Position {
line: 0,
character: 35
}
},
new_text: String::from("}`"),
},
]
);
}
}

0 comments on commit 68ebe59

Please sign in to comment.