mirror of
https://github.com/codewhale-hq/Codewhale.git
synced 2026-11-10 17:10:18 -10:00
fix(tui): clear composer and block paste-burst under model picker
Opening the model picker clears the composer buffer and rejects paste bursts while a modal owns keys so typed/pasted text does not leak in.
This commit is contained in:
1 parent
e8b8522b2c
commit
9b2eeca894
3 files changed
+34
No files matched your search
@@ -1862,6 +1862,11 @@ pub(crate) async fn apply_command_result(
|
||||
}
|
||||
AppAction::OpenModelPicker => {
|
||||
if app.view_stack.top_kind() != Some(ModalKind::ModelPicker) {
|
||||
// Slash `/model` and the picker share one grammar: the
|
||||
// composer must not keep a leftover `/model` buffer
|
||||
// (or a held paste-burst) under the picker query.
|
||||
app.clear_input();
|
||||
app.paste_burst.clear_after_explicit_paste();
|
||||
app.view_stack
|
||||
.push(crate::tui::model_picker::ModelPickerView::new(app, config));
|
||||
}
|
||||
|
||||
@@ -152,6 +152,12 @@ fn handle_focused_transcript_action_char(app: &mut App, ch: char) -> bool {
|
||||
/// transcript action only when the composer is still empty and the last
|
||||
/// rendered owner accepts it; otherwise it remains ordinary input.
|
||||
pub(super) fn flush_paste_burst_before_composer(app: &mut App, now: Instant) -> bool {
|
||||
if !app.view_stack.is_empty() {
|
||||
// One grammar buffer: a modal owns keys. Held burst must not leak
|
||||
// into the composer (leaky `/model` after the picker opens).
|
||||
app.paste_burst.clear_after_explicit_paste();
|
||||
return false;
|
||||
}
|
||||
match app.take_paste_burst_flush_if_enabled(now) {
|
||||
crate::tui::paste_burst::FlushResult::Paste(text) => {
|
||||
app.insert_str(&text);
|
||||
|
||||
@@ -4912,6 +4912,29 @@ fn raw_paste_beginning_with_space_preserves_payload_over_reasoning_action() {
|
||||
assert_eq!(app.input, " x");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn paste_burst_does_not_leak_into_composer_while_a_modal_owns_keys() {
|
||||
// `/model` opens a picker with its own query. A held paste-burst from
|
||||
// typing the slash command must not flush into the composer under it.
|
||||
let mut app = Box::new(create_test_app());
|
||||
app.use_paste_burst_detection = true;
|
||||
app.bracketed_paste_seen = false;
|
||||
let now = Instant::now();
|
||||
let slash = KeyEvent::new(KeyCode::Char('/'), KeyModifiers::NONE);
|
||||
assert!(handle_plain_key_before_composer(&mut app, &slash, now));
|
||||
app.view_stack.push(HelpView::new());
|
||||
let flushed = flush_paste_burst_before_composer(
|
||||
&mut app,
|
||||
now + crate::tui::paste_burst::PasteBurst::recommended_flush_delay(),
|
||||
);
|
||||
assert!(!flushed, "modal-owned keys must not flush into the composer");
|
||||
assert!(
|
||||
app.input.is_empty() || app.input == "/",
|
||||
"composer must not gain leaked burst text under a modal: {:?}",
|
||||
app.input
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn active_raw_paste_keeps_space_as_payload_over_reasoning_action() {
|
||||
let mut app = create_test_app();
|
||||
|
||||
Reference in new issue
Block a user