Skip to content

Commit

Permalink
live-preview: Fox off-by-one in Text edit application
Browse files Browse the repository at this point in the history
  • Loading branch information
hunger committed May 22, 2024
1 parent a9c321d commit 86b5686
Showing 1 changed file with 80 additions and 76 deletions.
156 changes: 80 additions & 76 deletions tools/lsp/preview/text_edit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ impl TextOffsetAdjustment {
) -> Self {
let new_text_length = edit.new_text.len() as u32;
let (start_offset, end_offset) = {
let so = source_file
.offset(edit.range.start.line as usize, edit.range.start.character as usize);
let eo =
source_file.offset(edit.range.end.line as usize, edit.range.end.character as usize);
let so = source_file.offset(
edit.range.start.line as usize + 1,
edit.range.start.character as usize + 1,
);
let eo = source_file
.offset(edit.range.end.line as usize + 1, edit.range.end.character as usize + 1);
(std::cmp::min(so, eo) as u32, std::cmp::max(so, eo) as u32)
};

Expand Down Expand Up @@ -173,10 +175,12 @@ impl TextEditor {
let current_offset = {
let start_range = &text_edit.range.start;
let end_range = &text_edit.range.end;
let start_offset =
self.source_file.offset(start_range.line as usize, start_range.character as usize);
let end_offset =
self.source_file.offset(end_range.line as usize, end_range.character as usize);
let start_offset = self
.source_file
.offset(start_range.line as usize + 1, start_range.character as usize + 1);
let end_offset = self
.source_file
.offset(end_range.line as usize + 1, end_range.character as usize + 1);
(start_offset, end_offset)
};

Expand Down Expand Up @@ -325,8 +329,8 @@ fn test_edit_iterator_changes_one_one() {
lsp_types::Url::parse("file://foo/bar.slint").unwrap(),
vec![lsp_types::TextEdit {
range: lsp_types::Range::new(
lsp_types::Position::new(23, 42),
lsp_types::Position::new(42, 23),
lsp_types::Position::new(22, 41),
lsp_types::Position::new(41, 22),
),
new_text: "Replacement".to_string(),
}],
Expand All @@ -340,8 +344,8 @@ fn test_edit_iterator_changes_one_one() {
assert_eq!(&r.0.uri.to_string(), "file://foo/bar.slint");
assert_eq!(r.0.version, None);
assert_eq!(&r.1.new_text, "Replacement");
assert_eq!(&r.1.range.start, &lsp_types::Position::new(23, 42));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(42, 23));
assert_eq!(&r.1.range.start, &lsp_types::Position::new(22, 41));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(41, 22));
assert!(it.next().is_none());
assert!(it.next().is_none());
}
Expand All @@ -354,15 +358,15 @@ fn test_edit_iterator_changes_one_two() {
vec![
lsp_types::TextEdit {
range: lsp_types::Range::new(
lsp_types::Position::new(23, 42),
lsp_types::Position::new(42, 23),
lsp_types::Position::new(22, 41),
lsp_types::Position::new(41, 22),
),
new_text: "Replacement".to_string(),
},
lsp_types::TextEdit {
range: lsp_types::Range::new(
lsp_types::Position::new(44, 12),
lsp_types::Position::new(44, 13),
lsp_types::Position::new(43, 11),
lsp_types::Position::new(43, 12),
),
new_text: "Foo".to_string(),
},
Expand All @@ -378,15 +382,15 @@ fn test_edit_iterator_changes_one_two() {
assert_eq!(&r.0.uri.to_string(), "file://foo/bar.slint");
assert_eq!(r.0.version, None);
assert_eq!(&r.1.new_text, "Replacement");
assert_eq!(&r.1.range.start, &lsp_types::Position::new(23, 42));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(42, 23));
assert_eq!(&r.1.range.start, &lsp_types::Position::new(22, 41));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(41, 22));

let r = it.next().unwrap();
assert_eq!(&r.0.uri.to_string(), "file://foo/bar.slint");
assert_eq!(r.0.version, None);
assert_eq!(&r.1.new_text, "Foo");
assert_eq!(&r.1.range.start, &lsp_types::Position::new(44, 12));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(44, 13));
assert_eq!(&r.1.range.start, &lsp_types::Position::new(43, 11));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(43, 12));

assert!(it.next().is_none());
}
Expand All @@ -399,8 +403,8 @@ fn test_edit_iterator_changes_two() {
lsp_types::Url::parse("file://foo/bar.slint").unwrap(),
vec![lsp_types::TextEdit {
range: lsp_types::Range::new(
lsp_types::Position::new(23, 42),
lsp_types::Position::new(42, 23),
lsp_types::Position::new(22, 41),
lsp_types::Position::new(41, 22),
),
new_text: "Replacement".to_string(),
}],
Expand All @@ -409,8 +413,8 @@ fn test_edit_iterator_changes_two() {
lsp_types::Url::parse("file://foo/baz.slint").unwrap(),
vec![lsp_types::TextEdit {
range: lsp_types::Range::new(
lsp_types::Position::new(44, 12),
lsp_types::Position::new(44, 13),
lsp_types::Position::new(43, 11),
lsp_types::Position::new(43, 12),
),
new_text: "Foo".to_string(),
}],
Expand All @@ -430,16 +434,16 @@ fn test_edit_iterator_changes_two() {
assert_eq!(&r.0.uri.to_string(), "file://foo/bar.slint");
assert_eq!(r.0.version, None);
assert_eq!(&r.1.new_text, "Replacement");
assert_eq!(&r.1.range.start, &lsp_types::Position::new(23, 42));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(42, 23));
assert_eq!(&r.1.range.start, &lsp_types::Position::new(22, 41));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(41, 22));
seen1 = true;
} else {
assert_eq!(seen2, false);
assert_eq!(&r.0.uri.to_string(), "file://foo/baz.slint");
assert_eq!(r.0.version, None);
assert_eq!(&r.1.new_text, "Foo");
assert_eq!(&r.1.range.start, &lsp_types::Position::new(44, 12));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(44, 13));
assert_eq!(&r.1.range.start, &lsp_types::Position::new(43, 11));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(43, 12));
seen2 = true;
}
}
Expand Down Expand Up @@ -501,8 +505,8 @@ fn test_edit_iterator_document_changes_one_one() {
lsp_types::TextDocumentEdit {
edits: vec![lsp_types::OneOf::Left(lsp_types::TextEdit {
range: lsp_types::Range::new(
lsp_types::Position::new(23, 42),
lsp_types::Position::new(42, 23),
lsp_types::Position::new(22, 41),
lsp_types::Position::new(41, 22),
),
new_text: "Replacement".to_string(),
})],
Expand All @@ -520,8 +524,8 @@ fn test_edit_iterator_document_changes_one_one() {
assert_eq!(&r.0.uri.to_string(), "file://foo/bar.slint");
assert_eq!(r.0.version, Some(99));
assert_eq!(&r.1.new_text, "Replacement");
assert_eq!(&r.1.range.start, &lsp_types::Position::new(23, 42));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(42, 23));
assert_eq!(&r.1.range.start, &lsp_types::Position::new(22, 41));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(41, 22));
assert!(it.next().is_none());
assert!(it.next().is_none());
}
Expand All @@ -535,16 +539,16 @@ fn test_edit_iterator_document_changes_one_two() {
edits: vec![
lsp_types::OneOf::Left(lsp_types::TextEdit {
range: lsp_types::Range::new(
lsp_types::Position::new(23, 42),
lsp_types::Position::new(42, 23),
lsp_types::Position::new(22, 41),
lsp_types::Position::new(41, 22),
),
new_text: "Replacement".to_string(),
}),
lsp_types::OneOf::Right(lsp_types::AnnotatedTextEdit {
text_edit: lsp_types::TextEdit {
range: lsp_types::Range::new(
lsp_types::Position::new(44, 12),
lsp_types::Position::new(44, 13),
lsp_types::Position::new(43, 11),
lsp_types::Position::new(43, 12),
),
new_text: "Foo".to_string(),
},
Expand All @@ -565,15 +569,15 @@ fn test_edit_iterator_document_changes_one_two() {
assert_eq!(&r.0.uri.to_string(), "file://foo/bar.slint");
assert_eq!(r.0.version, Some(99));
assert_eq!(&r.1.new_text, "Replacement");
assert_eq!(&r.1.range.start, &lsp_types::Position::new(23, 42));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(42, 23));
assert_eq!(&r.1.range.start, &lsp_types::Position::new(22, 41));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(41, 22));

let r = it.next().unwrap();
assert_eq!(&r.0.uri.to_string(), "file://foo/bar.slint");
assert_eq!(r.0.version, Some(99));
assert_eq!(&r.1.new_text, "Foo");
assert_eq!(&r.1.range.start, &lsp_types::Position::new(44, 12));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(44, 13));
assert_eq!(&r.1.range.start, &lsp_types::Position::new(43, 11));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(43, 12));
assert!(it.next().is_none());
assert!(it.next().is_none());
}
Expand All @@ -586,8 +590,8 @@ fn test_edit_iterator_document_changes_two() {
lsp_types::TextDocumentEdit {
edits: vec![lsp_types::OneOf::Left(lsp_types::TextEdit {
range: lsp_types::Range::new(
lsp_types::Position::new(23, 42),
lsp_types::Position::new(42, 23),
lsp_types::Position::new(22, 41),
lsp_types::Position::new(41, 22),
),
new_text: "Replacement".to_string(),
})],
Expand All @@ -600,8 +604,8 @@ fn test_edit_iterator_document_changes_two() {
edits: vec![lsp_types::OneOf::Right(lsp_types::AnnotatedTextEdit {
text_edit: lsp_types::TextEdit {
range: lsp_types::Range::new(
lsp_types::Position::new(44, 12),
lsp_types::Position::new(44, 13),
lsp_types::Position::new(43, 11),
lsp_types::Position::new(43, 12),
),
new_text: "Foo".to_string(),
},
Expand All @@ -621,15 +625,15 @@ fn test_edit_iterator_document_changes_two() {
assert_eq!(&r.0.uri.to_string(), "file://foo/bar.slint");
assert_eq!(r.0.version, Some(99));
assert_eq!(&r.1.new_text, "Replacement");
assert_eq!(&r.1.range.start, &lsp_types::Position::new(23, 42));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(42, 23));
assert_eq!(&r.1.range.start, &lsp_types::Position::new(22, 41));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(41, 22));

let r = it.next().unwrap();
assert_eq!(&r.0.uri.to_string(), "file://foo/baz.slint");
assert_eq!(r.0.version, Some(98));
assert_eq!(&r.1.new_text, "Foo");
assert_eq!(&r.1.range.start, &lsp_types::Position::new(44, 12));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(44, 13));
assert_eq!(&r.1.range.start, &lsp_types::Position::new(43, 11));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(43, 12));
assert!(it.next().is_none());
assert!(it.next().is_none());
}
Expand All @@ -642,8 +646,8 @@ fn test_edit_iterator_document_mixed() {
lsp_types::Url::parse("file://foo/bar.slint").unwrap(),
vec![lsp_types::TextEdit {
range: lsp_types::Range::new(
lsp_types::Position::new(23, 42),
lsp_types::Position::new(42, 23),
lsp_types::Position::new(22, 41),
lsp_types::Position::new(41, 22),
),
new_text: "Replacement".to_string(),
}],
Expand All @@ -652,8 +656,8 @@ fn test_edit_iterator_document_mixed() {
lsp_types::Url::parse("file://foo/baz.slint").unwrap(),
vec![lsp_types::TextEdit {
range: lsp_types::Range::new(
lsp_types::Position::new(44, 12),
lsp_types::Position::new(44, 13),
lsp_types::Position::new(43, 11),
lsp_types::Position::new(43, 12),
),
new_text: "Foo".to_string(),
}],
Expand All @@ -663,8 +667,8 @@ fn test_edit_iterator_document_mixed() {
lsp_types::TextDocumentEdit {
edits: vec![lsp_types::OneOf::Left(lsp_types::TextEdit {
range: lsp_types::Range::new(
lsp_types::Position::new(23, 42),
lsp_types::Position::new(42, 23),
lsp_types::Position::new(22, 41),
lsp_types::Position::new(41, 22),
),
new_text: "Doc Replacement".to_string(),
})],
Expand All @@ -677,8 +681,8 @@ fn test_edit_iterator_document_mixed() {
edits: vec![lsp_types::OneOf::Right(lsp_types::AnnotatedTextEdit {
text_edit: lsp_types::TextEdit {
range: lsp_types::Range::new(
lsp_types::Position::new(44, 12),
lsp_types::Position::new(44, 13),
lsp_types::Position::new(43, 11),
lsp_types::Position::new(43, 12),
),
new_text: "Doc Foo".to_string(),
},
Expand All @@ -704,8 +708,8 @@ fn test_edit_iterator_document_mixed() {
assert_eq!(&r.0.uri.to_string(), "file://foo/bar.slint");
assert_eq!(r.0.version, None);
assert_eq!(&r.1.new_text, "Replacement");
assert_eq!(&r.1.range.start, &lsp_types::Position::new(23, 42));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(42, 23));
assert_eq!(&r.1.range.start, &lsp_types::Position::new(22, 41));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(41, 22));
seen[0] = true;
} else if r.0.uri.to_string() == "file://foo/baz.slint" {
assert_eq!(seen[1], false);
Expand All @@ -714,8 +718,8 @@ fn test_edit_iterator_document_mixed() {
assert_eq!(&r.0.uri.to_string(), "file://foo/baz.slint");
assert_eq!(r.0.version, None);
assert_eq!(&r.1.new_text, "Foo");
assert_eq!(&r.1.range.start, &lsp_types::Position::new(44, 12));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(44, 13));
assert_eq!(&r.1.range.start, &lsp_types::Position::new(43, 11));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(43, 12));
seen[1] = true;
} else if r.0.uri.to_string() == "file://doc/bar.slint" {
assert_eq!(seen[0], true);
Expand All @@ -725,8 +729,8 @@ fn test_edit_iterator_document_mixed() {
assert_eq!(&r.0.uri.to_string(), "file://doc/bar.slint");
assert_eq!(r.0.version, Some(99));
assert_eq!(&r.1.new_text, "Doc Replacement");
assert_eq!(&r.1.range.start, &lsp_types::Position::new(23, 42));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(42, 23));
assert_eq!(&r.1.range.start, &lsp_types::Position::new(22, 41));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(41, 22));
seen[2] = true;
} else {
assert_eq!(seen[0], true);
Expand All @@ -736,8 +740,8 @@ fn test_edit_iterator_document_mixed() {
assert_eq!(&r.0.uri.to_string(), "file://doc/baz.slint");
assert_eq!(r.0.version, Some(98));
assert_eq!(&r.1.new_text, "Doc Foo");
assert_eq!(&r.1.range.start, &lsp_types::Position::new(44, 12));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(44, 13));
assert_eq!(&r.1.range.start, &lsp_types::Position::new(43, 11));
assert_eq!(&r.1.range.end, &lsp_types::Position::new(43, 12));
seen[3] = true;
}
}
Expand Down Expand Up @@ -766,8 +770,8 @@ fn test_texteditor_version_mismatch() {

let edit = lsp_types::TextEdit {
range: lsp_types::Range::new(
lsp_types::Position::new(1, 1),
lsp_types::Position::new(1, 1),
lsp_types::Position::new(0, 0),
lsp_types::Position::new(0, 0),
),
new_text: "Foobar".to_string(),
};
Expand All @@ -788,8 +792,8 @@ fn test_texteditor_edit_out_of_range() {

let edit = lsp_types::TextEdit {
range: lsp_types::Range::new(
lsp_types::Position::new(2, 3),
lsp_types::Position::new(2, 4),
lsp_types::Position::new(1, 2),
lsp_types::Position::new(1, 3),
),
new_text: "Foobar".to_string(),
};
Expand All @@ -813,8 +817,8 @@ geh"#

let edit = lsp_types::TextEdit {
range: lsp_types::Range::new(
lsp_types::Position::new(1, 1),
lsp_types::Position::new(3, 4),
lsp_types::Position::new(0, 0),
lsp_types::Position::new(2, 3),
),
new_text: "".to_string(),
};
Expand Down Expand Up @@ -844,8 +848,8 @@ geh"#

let edit = lsp_types::TextEdit {
range: lsp_types::Range::new(
lsp_types::Position::new(2, 1),
lsp_types::Position::new(2, 4),
lsp_types::Position::new(1, 0),
lsp_types::Position::new(1, 3),
),
new_text: "REPLACEMENT".to_string(),
};
Expand Down Expand Up @@ -880,16 +884,16 @@ geh"#

let edit = lsp_types::TextEdit {
range: lsp_types::Range::new(
lsp_types::Position::new(1, 1),
lsp_types::Position::new(3, 4),
lsp_types::Position::new(0, 0),
lsp_types::Position::new(2, 3),
),
new_text: "".to_string(),
};
assert!(editor.apply(&edit).is_ok());
let edit = lsp_types::TextEdit {
range: lsp_types::Range::new(
lsp_types::Position::new(1, 1),
lsp_types::Position::new(1, 1),
lsp_types::Position::new(0, 0),
lsp_types::Position::new(0, 0),
),
new_text: "REPLACEMENT".to_string(),
};
Expand Down

0 comments on commit 86b5686

Please sign in to comment.