Clip invalid edits from LSP instead of reporting an error
This fixes an issue with the Go language server, which reports invalid formatting ranges when there's a missing newline at the end of the file. Specifically, if the buffer is `N` lines long, it will try to insert the newline at `Point(N + 1, 0)`. I confirmed the behavior is the same in VS Code, and they indeed clip the LSP ranges as well.
This commit is contained in:
parent
9cefeb08e1
commit
45eb0e7889
2 changed files with 6 additions and 8 deletions
|
@ -5764,6 +5764,10 @@ impl Project {
|
||||||
let mut lsp_edits = lsp_edits.into_iter().peekable();
|
let mut lsp_edits = lsp_edits.into_iter().peekable();
|
||||||
let mut edits = Vec::new();
|
let mut edits = Vec::new();
|
||||||
while let Some((mut range, mut new_text)) = lsp_edits.next() {
|
while let Some((mut range, mut new_text)) = lsp_edits.next() {
|
||||||
|
// Clip invalid ranges provided by the language server.
|
||||||
|
range.start = snapshot.clip_point_utf16(range.start, Bias::Left);
|
||||||
|
range.end = snapshot.clip_point_utf16(range.end, Bias::Left);
|
||||||
|
|
||||||
// Combine any LSP edits that are adjacent.
|
// Combine any LSP edits that are adjacent.
|
||||||
//
|
//
|
||||||
// Also, combine LSP edits that are separated from each other by only
|
// Also, combine LSP edits that are separated from each other by only
|
||||||
|
@ -5791,12 +5795,6 @@ impl Project {
|
||||||
lsp_edits.next();
|
lsp_edits.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
if snapshot.clip_point_utf16(range.start, Bias::Left) != range.start
|
|
||||||
|| snapshot.clip_point_utf16(range.end, Bias::Left) != range.end
|
|
||||||
{
|
|
||||||
return Err(anyhow!("invalid edits received from language server"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// For multiline edits, perform a diff of the old and new text so that
|
// For multiline edits, perform a diff of the old and new text so that
|
||||||
// we can identify the changes more precisely, preserving the locations
|
// we can identify the changes more precisely, preserving the locations
|
||||||
// of any anchors positioned in the unchanged regions.
|
// of any anchors positioned in the unchanged regions.
|
||||||
|
|
|
@ -1565,7 +1565,7 @@ async fn test_invalid_edits_from_lsp(cx: &mut gpui::TestAppContext) {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Simulate the language server sending us edits in a non-ordered fashion,
|
// Simulate the language server sending us edits in a non-ordered fashion,
|
||||||
// with ranges sometimes being inverted.
|
// with ranges sometimes being inverted or pointing to invalid locations.
|
||||||
let edits = project
|
let edits = project
|
||||||
.update(cx, |project, cx| {
|
.update(cx, |project, cx| {
|
||||||
project.edits_from_lsp(
|
project.edits_from_lsp(
|
||||||
|
@ -1580,7 +1580,7 @@ async fn test_invalid_edits_from_lsp(cx: &mut gpui::TestAppContext) {
|
||||||
new_text: "a::{b, c}".into(),
|
new_text: "a::{b, c}".into(),
|
||||||
},
|
},
|
||||||
lsp::TextEdit {
|
lsp::TextEdit {
|
||||||
range: lsp::Range::new(lsp::Position::new(1, 0), lsp::Position::new(7, 0)),
|
range: lsp::Range::new(lsp::Position::new(1, 0), lsp::Position::new(99, 0)),
|
||||||
new_text: "".into(),
|
new_text: "".into(),
|
||||||
},
|
},
|
||||||
lsp::TextEdit {
|
lsp::TextEdit {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue