This commit is contained in:
HuaGu-Dragon 2026-05-31 18:18:06 +10:00 committed by GitHub
commit 6c07f95f8d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 91 additions and 4 deletions

View file

@ -1827,7 +1827,15 @@ impl Editor {
.text_highlights(HighlightKey::PendingInput, cx)
.is_none()
{
self.ime_transaction.take();
let ime_tx = self.ime_transaction.take();
self.buffer().update(cx, |buffer, cx| {
if let Some(transaction) = ime_tx {
buffer.forget_transaction(transaction, cx);
}
if let Some(tx) = transaction {
buffer.forget_transaction(tx, cx);
}
});
}
}

View file

@ -4687,6 +4687,7 @@ impl Window {
}
let mut currently_pending = self.pending_input.take().unwrap_or_default();
let had_pending_input = !currently_pending.keystrokes.is_empty();
if currently_pending.focus.is_some() && currently_pending.focus != self.focus {
currently_pending = PendingInput::default();
}
@ -4697,6 +4698,12 @@ impl Window {
&dispatch_path,
);
let pending_input_was_cleared = had_pending_input && match_result.pending.is_empty();
if pending_input_was_cleared {
// Synchronous binding actions may edit immediately, so clear pending input first.
self.pending_input_changed(cx);
}
if !match_result.to_replay.is_empty() {
self.replay_pending_input(match_result.to_replay, cx);
cx.propagate_event = true;
@ -4781,14 +4788,18 @@ impl Window {
match_result.context_stack,
cx,
);
self.pending_input_changed(cx);
if !pending_input_was_cleared {
self.pending_input_changed(cx);
}
return;
}
}
}
self.finish_dispatch_key_event(event, dispatch_path, match_result.context_stack, cx);
self.pending_input_changed(cx);
if !pending_input_was_cleared {
self.pending_input_changed(cx);
}
}
fn finish_dispatch_key_event(

View file

@ -8,7 +8,7 @@ use collections::HashMap;
use command_palette::CommandPalette;
use editor::{
AnchorRangeExt, DisplayPoint, Editor, EditorMode, MultiBuffer, MultiBufferOffset,
actions::{DeleteLine, WrapSelectionsInTag},
actions::{DeleteLine, HandleInput, WrapSelectionsInTag},
code_context_menus::CodeContextMenu,
display_map::DisplayRow,
test::editor_test_context::EditorTestContext,
@ -1402,6 +1402,74 @@ async fn test_undo(cx: &mut gpui::TestAppContext) {
3"});
}
#[perf]
#[gpui::test]
async fn test_ime_transaction_undo(cx: &mut gpui::TestAppContext) {
let mut cx = VimTestContext::new(cx, true).await;
cx.update(|_, cx| {
cx.bind_keys([KeyBinding::new(
"j k",
NormalBefore,
Some("vim_mode == insert"),
)])
});
cx.set_state("ˇone", Mode::Normal);
cx.simulate_keystrokes("i j");
cx.assert_state("ˇjone", Mode::Insert);
assert_pending_input(&mut cx, "«j»one");
cx.simulate_keystrokes("k");
cx.assert_state("ˇone", Mode::Normal);
cx.simulate_keystrokes("u");
cx.assert_state("ˇ", Mode::Normal);
}
#[perf]
#[gpui::test]
async fn test_pending_input_mapping_output_undo(cx: &mut gpui::TestAppContext) {
let mut cx = VimTestContext::new(cx, true).await;
cx.update(|_, cx| {
cx.bind_keys([KeyBinding::new(
"a b c",
HandleInput("d".to_string()),
Some("vim_mode == insert"),
)])
});
cx.set_state("ˇone", Mode::Normal);
cx.simulate_keystrokes("i a b c");
cx.assert_state("dˇone", Mode::Insert);
cx.simulate_keystrokes("escape u");
cx.assert_state("ˇone", Mode::Normal);
}
#[perf]
#[gpui::test]
async fn test_pending_input_mapping_output_undo_delay(cx: &mut gpui::TestAppContext) {
let mut cx = VimTestContext::new(cx, true).await;
cx.update(|_, cx| {
cx.bind_keys([KeyBinding::new(
"a b c",
HandleInput("d".to_string()),
Some("vim_mode == insert"),
)])
});
cx.set_state("ˇone", Mode::Normal);
cx.simulate_keystrokes("i a b");
cx.executor().advance_clock(Duration::from_millis(1500));
cx.run_until_parked();
cx.assert_state("abˇone", Mode::Insert);
cx.simulate_keystrokes("escape u");
cx.assert_state("ˇone", Mode::Normal);
}
#[perf]
#[gpui::test]
async fn test_lsp_completions_undo(cx: &mut gpui::TestAppContext) {