Fix unhighlighted deleted regions in diffs (#64202)
#63145 exposed a bug in the the `snapshot_with_edits` and `fast_forward` methods that we use to evolve the base text buffer for diffs: we preserved the value of the `tree_sitter_data` field from the old snapshot. That causes any diff whose base text has changed to have stale bracket ranges and now stale syntax highlighting as well, which can manifest as unhighlighted text in the deleted portion of an expanded diff hunk. This PR fixes the issue by clearing the `tree_sitter_data` field in `snapshot_with_edits`. Release Notes: - N/A (problem exists in nightly only)
This commit is contained in:
1 parent
411b31e9a5
commit
d705c7f1ae
2 files changed
+46
No files matched your search
@@ -3551,6 +3551,7 @@ impl Buffer {
|
||||
|
||||
snapshot.text = new_text.snapshot.clone();
|
||||
snapshot.syntax = syntax;
|
||||
snapshot.tree_sitter_data = Arc::new(TreeSitterData::new(&snapshot.text));
|
||||
|
||||
EditedBufferSnapshot {
|
||||
text: new_text,
|
||||
|
||||
@@ -5460,6 +5460,51 @@ fn test_chunk_highlights_follow_edits_and_theme_changes(cx: &mut TestAppContext)
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_snapshot_with_edits_refreshes_chunk_highlights(cx: &mut TestAppContext) {
|
||||
cx.update(|cx| init_settings(cx, |_| {}));
|
||||
|
||||
let language = keyword_and_function_lang();
|
||||
let theme = keyword_and_function_theme();
|
||||
language.set_theme(&theme);
|
||||
|
||||
let keyword = theme_highlight_id(&theme, "keyword");
|
||||
let function = theme_highlight_id(&theme, "function");
|
||||
let row = "fn replacement() {}\n";
|
||||
let text = row.repeat(MAX_ROWS_IN_A_CHUNK as usize + 1);
|
||||
|
||||
for original_text in ["", "fn original() {}"] {
|
||||
let buffer =
|
||||
cx.new(|cx| Buffer::local(original_text, cx).with_language(language.clone(), cx));
|
||||
cx.run_until_parked();
|
||||
let original_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
|
||||
let original_highlights =
|
||||
merged_highlight_runs(&original_snapshot, 0..original_snapshot.len());
|
||||
|
||||
let edited = buffer
|
||||
.update(cx, |buffer, cx| {
|
||||
buffer.snapshot_with_edits([(0..buffer.len(), text.clone())], cx)
|
||||
})
|
||||
.await;
|
||||
let snapshot = edited.snapshot();
|
||||
let expected = vec![
|
||||
("fn".to_string(), keyword),
|
||||
("replacement".to_string(), function),
|
||||
];
|
||||
|
||||
assert_eq!(merged_highlight_runs(snapshot, 0..row.len()), expected);
|
||||
let last_row_start = row.len() * MAX_ROWS_IN_A_CHUNK as usize;
|
||||
assert_eq!(
|
||||
merged_highlight_runs(snapshot, last_row_start..snapshot.len()),
|
||||
expected,
|
||||
);
|
||||
assert_eq!(
|
||||
merged_highlight_runs(&original_snapshot, 0..original_snapshot.len()),
|
||||
original_highlights,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn test_chunk_highlights_across_row_chunk_seeks(cx: &mut TestAppContext) {
|
||||
cx.update(|cx| init_settings(cx, |_| {}));
|
||||
|
||||
Reference in new issue
Block a user