Show tab queue hint in footer (#9138)

- show the Tab queue hint in the footer when a task is running with
Steer enabled
- drop the history queue hint and add footer snapshots
This commit is contained in:
Ahmed Ibrahim 2026-01-13 00:32:53 -08:00 committed by GitHub
parent 3c8fb90bf0
commit 17ab5f6a52
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 184 additions and 32 deletions

View file

@ -1641,6 +1641,7 @@ impl ChatComposer {
esc_backtrack_hint: self.esc_backtrack_hint,
use_shift_enter_hint: self.use_shift_enter_hint,
is_task_running: self.is_task_running,
steer_enabled: self.steer_enabled,
context_window_percent: self.context_window_percent,
context_window_used_tokens: self.context_window_used_tokens,
}

View file

@ -20,6 +20,7 @@ pub(crate) struct FooterProps {
pub(crate) esc_backtrack_hint: bool,
pub(crate) use_shift_enter_hint: bool,
pub(crate) is_task_running: bool,
pub(crate) steer_enabled: bool,
pub(crate) context_window_percent: Option<i64>,
pub(crate) context_window_used_tokens: Option<i64>,
}
@ -110,10 +111,18 @@ fn footer_lines(props: FooterProps) -> Vec<Line<'static>> {
shortcut_overlay_lines(state)
}
FooterMode::EscHint => vec![esc_hint_line(props.esc_backtrack_hint)],
FooterMode::ContextOnly => vec![context_window_line(
props.context_window_percent,
props.context_window_used_tokens,
)],
FooterMode::ContextOnly => {
let mut line = context_window_line(
props.context_window_percent,
props.context_window_used_tokens,
);
if props.is_task_running && props.steer_enabled {
line.push_span(" · ".dim());
line.push_span(key_hint::plain(KeyCode::Tab));
line.push_span(" to queue message".dim());
}
vec![line]
}
}
}
@ -477,6 +486,7 @@ mod tests {
esc_backtrack_hint: false,
use_shift_enter_hint: false,
is_task_running: false,
steer_enabled: false,
context_window_percent: None,
context_window_used_tokens: None,
},
@ -489,6 +499,7 @@ mod tests {
esc_backtrack_hint: true,
use_shift_enter_hint: true,
is_task_running: false,
steer_enabled: false,
context_window_percent: None,
context_window_used_tokens: None,
},
@ -501,6 +512,7 @@ mod tests {
esc_backtrack_hint: false,
use_shift_enter_hint: false,
is_task_running: false,
steer_enabled: false,
context_window_percent: None,
context_window_used_tokens: None,
},
@ -513,6 +525,7 @@ mod tests {
esc_backtrack_hint: false,
use_shift_enter_hint: false,
is_task_running: true,
steer_enabled: false,
context_window_percent: None,
context_window_used_tokens: None,
},
@ -525,6 +538,7 @@ mod tests {
esc_backtrack_hint: false,
use_shift_enter_hint: false,
is_task_running: false,
steer_enabled: false,
context_window_percent: None,
context_window_used_tokens: None,
},
@ -537,6 +551,7 @@ mod tests {
esc_backtrack_hint: true,
use_shift_enter_hint: false,
is_task_running: false,
steer_enabled: false,
context_window_percent: None,
context_window_used_tokens: None,
},
@ -549,6 +564,7 @@ mod tests {
esc_backtrack_hint: false,
use_shift_enter_hint: false,
is_task_running: true,
steer_enabled: false,
context_window_percent: Some(72),
context_window_used_tokens: None,
},
@ -561,9 +577,36 @@ mod tests {
esc_backtrack_hint: false,
use_shift_enter_hint: false,
is_task_running: false,
steer_enabled: false,
context_window_percent: None,
context_window_used_tokens: Some(123_456),
},
);
snapshot_footer(
"footer_context_only_queue_hint_disabled",
FooterProps {
mode: FooterMode::ContextOnly,
esc_backtrack_hint: false,
use_shift_enter_hint: false,
is_task_running: true,
steer_enabled: false,
context_window_percent: None,
context_window_used_tokens: None,
},
);
snapshot_footer(
"footer_context_only_queue_hint_enabled",
FooterProps {
mode: FooterMode::ContextOnly,
esc_backtrack_hint: false,
use_shift_enter_hint: false,
is_task_running: true,
steer_enabled: true,
context_window_percent: None,
context_window_used_tokens: None,
},
);
}
}

View file

@ -0,0 +1,5 @@
---
source: tui/src/bottom_pane/footer.rs
expression: terminal.backend()
---
" 100% context left "

View file

@ -0,0 +1,5 @@
---
source: tui/src/bottom_pane/footer.rs
expression: terminal.backend()
---
" 100% context left · tab to queue message "

View file

@ -2152,17 +2152,6 @@ impl ChatWidget {
self.add_to_history(history_cell::new_user_prompt(text));
}
// If steer is enabled and a task is running, show hint about queuing with Tab
if self.config.features.enabled(Feature::Steer) && self.bottom_pane.is_task_running() {
use crate::key_hint;
use ratatui::text::Line;
let hint_line = Line::from(vec![
"You can queue messages by pressing ".dim(),
key_hint::plain(KeyCode::Tab).into(),
]);
self.add_to_history(history_cell::PlainHistoryCell::new(vec![hint_line]));
}
self.needs_final_message_separator = false;
}

View file

@ -2,6 +2,33 @@
source: tui/src/chatwidget/tests.rs
expression: term.backend().vt100().screen().contents()
---
• Im going to search the repo for where “Change Approved” is rendered to update
that view.
@ -14,4 +41,4 @@ expression: term.backend().vt100().screen().contents()
Summarize recent commits
100% context left
100% context left · tab to queue message

View file

@ -1583,6 +1583,7 @@ impl ChatComposer {
esc_backtrack_hint: self.esc_backtrack_hint,
use_shift_enter_hint: self.use_shift_enter_hint,
is_task_running: self.is_task_running,
steer_enabled: self.steer_enabled,
context_window_percent: self.context_window_percent,
context_window_used_tokens: self.context_window_used_tokens,
transcript_scrolled: self.transcript_scrolled,

View file

@ -21,6 +21,7 @@ pub(crate) struct FooterProps {
pub(crate) esc_backtrack_hint: bool,
pub(crate) use_shift_enter_hint: bool,
pub(crate) is_task_running: bool,
pub(crate) steer_enabled: bool,
pub(crate) context_window_percent: Option<i64>,
pub(crate) context_window_used_tokens: Option<i64>,
pub(crate) transcript_scrolled: bool,
@ -152,10 +153,18 @@ fn footer_lines(props: FooterProps) -> Vec<Line<'static>> {
shortcut_overlay_lines(state)
}
FooterMode::EscHint => vec![esc_hint_line(props.esc_backtrack_hint)],
FooterMode::ContextOnly => vec![context_window_line(
props.context_window_percent,
props.context_window_used_tokens,
)],
FooterMode::ContextOnly => {
let mut line = context_window_line(
props.context_window_percent,
props.context_window_used_tokens,
);
if props.is_task_running && props.steer_enabled {
line.push_span(" · ".dim());
line.push_span(key_hint::plain(KeyCode::Tab));
line.push_span(" to queue message".dim());
}
vec![line]
}
};
apply_copy_feedback(&mut lines, props.transcript_copy_feedback);
lines
@ -508,6 +517,7 @@ mod tests {
esc_backtrack_hint: false,
use_shift_enter_hint: false,
is_task_running: false,
steer_enabled: false,
context_window_percent: None,
context_window_used_tokens: None,
transcript_scrolled: false,
@ -525,6 +535,7 @@ mod tests {
esc_backtrack_hint: false,
use_shift_enter_hint: false,
is_task_running: false,
steer_enabled: false,
context_window_percent: None,
context_window_used_tokens: None,
transcript_scrolled: true,
@ -542,6 +553,7 @@ mod tests {
esc_backtrack_hint: true,
use_shift_enter_hint: true,
is_task_running: false,
steer_enabled: false,
context_window_percent: None,
context_window_used_tokens: None,
transcript_scrolled: false,
@ -559,6 +571,7 @@ mod tests {
esc_backtrack_hint: false,
use_shift_enter_hint: false,
is_task_running: false,
steer_enabled: false,
context_window_percent: None,
context_window_used_tokens: None,
transcript_scrolled: false,
@ -576,6 +589,7 @@ mod tests {
esc_backtrack_hint: false,
use_shift_enter_hint: false,
is_task_running: true,
steer_enabled: false,
context_window_percent: None,
context_window_used_tokens: None,
transcript_scrolled: false,
@ -593,6 +607,7 @@ mod tests {
esc_backtrack_hint: false,
use_shift_enter_hint: false,
is_task_running: false,
steer_enabled: false,
context_window_percent: None,
context_window_used_tokens: None,
transcript_scrolled: false,
@ -610,6 +625,7 @@ mod tests {
esc_backtrack_hint: true,
use_shift_enter_hint: false,
is_task_running: false,
steer_enabled: false,
context_window_percent: None,
context_window_used_tokens: None,
transcript_scrolled: false,
@ -627,6 +643,7 @@ mod tests {
esc_backtrack_hint: false,
use_shift_enter_hint: false,
is_task_running: true,
steer_enabled: false,
context_window_percent: Some(72),
context_window_used_tokens: None,
transcript_scrolled: false,
@ -644,6 +661,7 @@ mod tests {
esc_backtrack_hint: false,
use_shift_enter_hint: false,
is_task_running: false,
steer_enabled: false,
context_window_percent: None,
context_window_used_tokens: Some(123_456),
transcript_scrolled: false,
@ -654,6 +672,42 @@ mod tests {
},
);
snapshot_footer(
"footer_context_only_queue_hint_disabled",
FooterProps {
mode: FooterMode::ContextOnly,
esc_backtrack_hint: false,
use_shift_enter_hint: false,
is_task_running: true,
steer_enabled: false,
context_window_percent: None,
context_window_used_tokens: None,
transcript_scrolled: false,
transcript_selection_active: false,
transcript_scroll_position: None,
transcript_copy_selection_key: key_hint::ctrl_shift(KeyCode::Char('c')),
transcript_copy_feedback: None,
},
);
snapshot_footer(
"footer_context_only_queue_hint_enabled",
FooterProps {
mode: FooterMode::ContextOnly,
esc_backtrack_hint: false,
use_shift_enter_hint: false,
is_task_running: true,
steer_enabled: true,
context_window_percent: None,
context_window_used_tokens: None,
transcript_scrolled: false,
transcript_selection_active: false,
transcript_scroll_position: None,
transcript_copy_selection_key: key_hint::ctrl_shift(KeyCode::Char('c')),
transcript_copy_feedback: None,
},
);
snapshot_footer(
"footer_copy_feedback_copied",
FooterProps {
@ -661,6 +715,7 @@ mod tests {
esc_backtrack_hint: false,
use_shift_enter_hint: false,
is_task_running: false,
steer_enabled: false,
context_window_percent: None,
context_window_used_tokens: None,
transcript_scrolled: false,

View file

@ -0,0 +1,5 @@
---
source: tui2/src/bottom_pane/footer.rs
expression: terminal.backend()
---
" 100% context left "

View file

@ -0,0 +1,5 @@
---
source: tui2/src/bottom_pane/footer.rs
expression: terminal.backend()
---
" 100% context left · tab to queue message "

View file

@ -2135,17 +2135,6 @@ impl ChatWidget {
self.add_to_history(history_cell::new_user_prompt(message.to_string()));
}
// If steer is enabled and a task is running, show hint about queuing with Tab
if self.config.features.enabled(Feature::Steer) && self.bottom_pane.is_task_running() {
use crate::key_hint;
use ratatui::text::Line;
let hint_line = Line::from(vec![
"You can queue messages by pressing ".dim(),
key_hint::plain(KeyCode::Tab).into(),
]);
self.add_to_history(history_cell::PlainHistoryCell::new(vec![hint_line]));
}
self.needs_final_message_separator = false;
}

View file

@ -2,6 +2,33 @@
source: tui2/src/chatwidget/tests.rs
expression: term.backend().vt100().screen().contents()
---
• Im going to search the repo for where “Change Approved” is rendered to update
that view.
@ -14,4 +41,4 @@ expression: term.backend().vt100().screen().contents()
Summarize recent commits
100% context left
100% context left · tab to queue message