Compare commits

...

1 Commits

Author SHA1 Message Date
Rakan El Khalil
28278224a3 tui: preserve kill buffer across submit and slash-command clears 2026-02-17 09:18:42 -08:00
2 changed files with 87 additions and 1 deletions

View File

@@ -5572,6 +5572,78 @@ mod tests {
assert!(composer.textarea.is_empty(), "composer should be cleared");
}
#[test]
fn kill_buffer_persists_after_submit() {
use crossterm::event::KeyCode;
use crossterm::event::KeyEvent;
use crossterm::event::KeyModifiers;
let (tx, _rx) = unbounded_channel::<AppEvent>();
let sender = AppEventSender::new(tx);
let mut composer = ChatComposer::new(
true,
sender,
false,
"Ask Codex to do anything".to_string(),
false,
);
composer.set_steer_enabled(true);
composer.textarea.insert_str("restore me");
composer.textarea.set_cursor(0);
let (_result, _needs_redraw) =
composer.handle_key_event(KeyEvent::new(KeyCode::Char('k'), KeyModifiers::CONTROL));
assert!(composer.textarea.is_empty());
composer.textarea.insert_str("hello");
let (result, _needs_redraw) =
composer.handle_key_event(KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE));
assert!(matches!(result, InputResult::Submitted { .. }));
assert!(composer.textarea.is_empty());
let (_result, _needs_redraw) =
composer.handle_key_event(KeyEvent::new(KeyCode::Char('y'), KeyModifiers::CONTROL));
assert_eq!(composer.textarea.text(), "restore me");
}
#[test]
fn kill_buffer_persists_after_slash_command_dispatch() {
use crossterm::event::KeyCode;
use crossterm::event::KeyEvent;
use crossterm::event::KeyModifiers;
let (tx, _rx) = unbounded_channel::<AppEvent>();
let sender = AppEventSender::new(tx);
let mut composer = ChatComposer::new(
true,
sender,
false,
"Ask Codex to do anything".to_string(),
false,
);
composer.textarea.insert_str("restore me");
composer.textarea.set_cursor(0);
let (_result, _needs_redraw) =
composer.handle_key_event(KeyEvent::new(KeyCode::Char('k'), KeyModifiers::CONTROL));
assert!(composer.textarea.is_empty());
composer.textarea.insert_str("/diff");
let (result, _needs_redraw) =
composer.handle_key_event(KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE));
match result {
InputResult::Command(cmd) => {
assert_eq!(cmd.command(), "diff");
}
_ => panic!("expected Command result for '/diff'"),
}
assert!(composer.textarea.is_empty());
let (_result, _needs_redraw) =
composer.handle_key_event(KeyEvent::new(KeyCode::Char('y'), KeyModifiers::CONTROL));
assert_eq!(composer.textarea.text(), "restore me");
}
#[test]
fn slash_command_disabled_while_task_running_keeps_text() {
use crossterm::event::KeyCode;

View File

@@ -109,7 +109,6 @@ impl TextArea {
self.cursor_pos = self.clamp_pos_to_nearest_boundary(self.cursor_pos);
self.wrap_cache.replace(None);
self.preferred_col = None;
self.kill_buffer.clear();
}
pub fn text(&self) -> &str {
@@ -1669,6 +1668,21 @@ mod tests {
assert_eq!(t.cursor(), 5);
}
#[test]
fn kill_buffer_persists_across_set_text() {
let mut t = ta_with("restore me");
t.set_cursor(0);
t.kill_to_end_of_line();
assert!(t.text().is_empty());
t.set_text_clearing_elements("/diff");
t.set_text_clearing_elements("");
t.yank();
assert_eq!(t.text(), "restore me");
assert_eq!(t.cursor(), "restore me".len());
}
#[test]
fn cursor_left_and_right_handle_graphemes() {
let mut t = ta_with("a👍b");