Restore scroll after undo edit prediction (#31162)
Closes #29652 Release Notes: - Fixed an issue where the scroll and cursor position would not be restored after undoing an inline completion
This commit is contained in:
parent
ab017129d8
commit
0d7f4842f3
3 changed files with 111 additions and 3 deletions
|
@ -6523,6 +6523,10 @@ impl Editor {
|
||||||
provider.accept(cx);
|
provider.accept(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Store the transaction ID and selections before applying the edit
|
||||||
|
let transaction_id_prev =
|
||||||
|
self.buffer.read_with(cx, |b, cx| b.last_transaction_id(cx));
|
||||||
|
|
||||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||||
let last_edit_end = edits.last().unwrap().0.end.bias_right(&snapshot);
|
let last_edit_end = edits.last().unwrap().0.end.bias_right(&snapshot);
|
||||||
|
|
||||||
|
@ -6531,9 +6535,20 @@ impl Editor {
|
||||||
});
|
});
|
||||||
|
|
||||||
self.change_selections(None, window, cx, |s| {
|
self.change_selections(None, window, cx, |s| {
|
||||||
s.select_anchor_ranges([last_edit_end..last_edit_end])
|
s.select_anchor_ranges([last_edit_end..last_edit_end]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let selections = self.selections.disjoint_anchors();
|
||||||
|
if let Some(transaction_id_now) =
|
||||||
|
self.buffer.read_with(cx, |b, cx| b.last_transaction_id(cx))
|
||||||
|
{
|
||||||
|
let has_new_transaction = transaction_id_prev != Some(transaction_id_now);
|
||||||
|
if has_new_transaction {
|
||||||
|
self.selection_history
|
||||||
|
.insert_transaction(transaction_id_now, selections);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.update_visible_inline_completion(window, cx);
|
self.update_visible_inline_completion(window, cx);
|
||||||
if self.active_inline_completion.is_none() {
|
if self.active_inline_completion.is_none() {
|
||||||
self.refresh_inline_completion(true, true, window, cx);
|
self.refresh_inline_completion(true, true, window, cx);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
JoinLines,
|
JoinLines,
|
||||||
|
inline_completion_tests::FakeInlineCompletionProvider,
|
||||||
linked_editing_ranges::LinkedEditingRanges,
|
linked_editing_ranges::LinkedEditingRanges,
|
||||||
scroll::scroll_amount::ScrollAmount,
|
scroll::scroll_amount::ScrollAmount,
|
||||||
test::{
|
test::{
|
||||||
|
@ -6380,6 +6381,98 @@ async fn test_undo_format_scrolls_to_last_edit_pos(cx: &mut TestAppContext) {
|
||||||
"});
|
"});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
async fn test_undo_inline_completion_scrolls_to_edit_pos(cx: &mut TestAppContext) {
|
||||||
|
init_test(cx, |_| {});
|
||||||
|
|
||||||
|
let mut cx = EditorTestContext::new(cx).await;
|
||||||
|
|
||||||
|
let provider = cx.new(|_| FakeInlineCompletionProvider::default());
|
||||||
|
cx.update_editor(|editor, window, cx| {
|
||||||
|
editor.set_edit_prediction_provider(Some(provider.clone()), window, cx);
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.set_state(indoc! {"
|
||||||
|
line 1
|
||||||
|
line 2
|
||||||
|
linˇe 3
|
||||||
|
line 4
|
||||||
|
line 5
|
||||||
|
line 6
|
||||||
|
line 7
|
||||||
|
line 8
|
||||||
|
line 9
|
||||||
|
line 10
|
||||||
|
"});
|
||||||
|
|
||||||
|
let snapshot = cx.buffer_snapshot();
|
||||||
|
let edit_position = snapshot.anchor_after(Point::new(2, 4));
|
||||||
|
|
||||||
|
cx.update(|_, cx| {
|
||||||
|
provider.update(cx, |provider, _| {
|
||||||
|
provider.set_inline_completion(Some(inline_completion::InlineCompletion {
|
||||||
|
id: None,
|
||||||
|
edits: vec![(edit_position..edit_position, "X".into())],
|
||||||
|
edit_preview: None,
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.update_editor(|editor, window, cx| editor.update_visible_inline_completion(window, cx));
|
||||||
|
cx.update_editor(|editor, window, cx| {
|
||||||
|
editor.accept_edit_prediction(&crate::AcceptEditPrediction, window, cx)
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.assert_editor_state(indoc! {"
|
||||||
|
line 1
|
||||||
|
line 2
|
||||||
|
lineXˇ 3
|
||||||
|
line 4
|
||||||
|
line 5
|
||||||
|
line 6
|
||||||
|
line 7
|
||||||
|
line 8
|
||||||
|
line 9
|
||||||
|
line 10
|
||||||
|
"});
|
||||||
|
|
||||||
|
cx.update_editor(|editor, window, cx| {
|
||||||
|
editor.change_selections(None, window, cx, |s| {
|
||||||
|
s.select_ranges([Point::new(9, 2)..Point::new(9, 2)]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.assert_editor_state(indoc! {"
|
||||||
|
line 1
|
||||||
|
line 2
|
||||||
|
lineX 3
|
||||||
|
line 4
|
||||||
|
line 5
|
||||||
|
line 6
|
||||||
|
line 7
|
||||||
|
line 8
|
||||||
|
line 9
|
||||||
|
liˇne 10
|
||||||
|
"});
|
||||||
|
|
||||||
|
cx.update_editor(|editor, window, cx| {
|
||||||
|
editor.undo(&Default::default(), window, cx);
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.assert_editor_state(indoc! {"
|
||||||
|
line 1
|
||||||
|
line 2
|
||||||
|
lineˇ 3
|
||||||
|
line 4
|
||||||
|
line 5
|
||||||
|
line 6
|
||||||
|
line 7
|
||||||
|
line 8
|
||||||
|
line 9
|
||||||
|
line 10
|
||||||
|
"});
|
||||||
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_select_next_with_multiple_carets(cx: &mut TestAppContext) {
|
async fn test_select_next_with_multiple_carets(cx: &mut TestAppContext) {
|
||||||
init_test(cx, |_| {});
|
init_test(cx, |_| {});
|
||||||
|
|
|
@ -302,8 +302,8 @@ fn assign_editor_completion_provider(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
struct FakeInlineCompletionProvider {
|
pub struct FakeInlineCompletionProvider {
|
||||||
completion: Option<inline_completion::InlineCompletion>,
|
pub completion: Option<inline_completion::InlineCompletion>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FakeInlineCompletionProvider {
|
impl FakeInlineCompletionProvider {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue