fix(tui): input stays in box during/after turn
- mark input bar turn-in-progress on submit - re-enable input after turn resumes - clear input area before redraw - clear completion popup before redraw - resume re-enters alternate screen and clears cleanly This prevents typed text from overwriting itself and stops redraws from spilling word-wrapped text outside the input box.
This commit is contained in:
parent
f6597f1935
commit
1b0d237de6
|
|
@ -7301,6 +7301,7 @@ fn run_tui_repl(mut cli: LiveCli) -> Result<(), Box<dyn std::error::Error>> {
|
|||
let result = cli.run_turn_to(&trimmed, &mut buf, false);
|
||||
drop(stdout);
|
||||
app.resume()?;
|
||||
app.set_turn_in_progress(false);
|
||||
|
||||
{
|
||||
let messages = &cli.runtime.session().messages;
|
||||
|
|
|
|||
|
|
@ -107,10 +107,14 @@ impl TuiApp {
|
|||
|
||||
/// Resume TUI after suspend.
|
||||
pub fn resume(&mut self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
crossterm::execute!(
|
||||
io::stdout(),
|
||||
crossterm::terminal::EnterAlternateScreen,
|
||||
Clear(ClearType::All),
|
||||
crossterm::cursor::Hide
|
||||
)?;
|
||||
enable_raw_mode()?;
|
||||
let _ = crossterm::execute!(io::stdout(), Clear(ClearType::All), crossterm::cursor::MoveTo(0, 0));
|
||||
let _ = io::stdout().flush();
|
||||
self.terminal.hide_cursor()?;
|
||||
self.terminal.clear()?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -226,6 +230,10 @@ impl TuiApp {
|
|||
self.keymap.set_preset(preset);
|
||||
}
|
||||
|
||||
pub fn set_turn_in_progress(&mut self, in_progress: bool) {
|
||||
self.input_bar.set_turn_in_progress(in_progress);
|
||||
}
|
||||
|
||||
pub fn key_preset_name(&self) -> &'static str {
|
||||
match self.keymap.preset() {
|
||||
KeyPreset::Emacs => "Emacs",
|
||||
|
|
@ -284,6 +292,7 @@ impl TuiApp {
|
|||
match outcome {
|
||||
InputOutcome::Submit(text) => {
|
||||
self.input_bar.push_history(&text);
|
||||
self.set_turn_in_progress(true);
|
||||
Ok(TuiReadOutcome::Submit(text))
|
||||
}
|
||||
InputOutcome::Cancel => Ok(TuiReadOutcome::Cancel),
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ impl InputBar {
|
|||
|
||||
pub fn set_turn_in_progress(&mut self, in_progress: bool) {
|
||||
self.turn_in_progress = in_progress;
|
||||
self.dirty = true;
|
||||
}
|
||||
|
||||
/// Push text to history.
|
||||
|
|
@ -293,23 +294,17 @@ impl InputBar {
|
|||
width: area.width.min(40),
|
||||
height: (matches.len() as u16 + 2).min(10),
|
||||
};
|
||||
frame.render_widget(ratatui::widgets::Clear, popup);
|
||||
frame.render_widget(list, popup);
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for InputBar {
|
||||
fn render(&self, area: Rect, frame: &mut Frame, theme: &TuiTheme) {
|
||||
frame.render_widget(ratatui::widgets::Clear, area);
|
||||
let widget = self.textarea.clone();
|
||||
frame.render_widget(&widget, area);
|
||||
|
||||
// Render completions popup above the input area
|
||||
if self.showing_completions {
|
||||
// Note: can't call self.render_completions() from &self here
|
||||
// because we need mutable access to check state but render is &self.
|
||||
// Workaround: render completions in the draw_frame function directly.
|
||||
// This is acceptable for Phase 1 — will be refined later.
|
||||
let _ = (area, frame, theme);
|
||||
}
|
||||
self.render_completions(area, frame, theme);
|
||||
}
|
||||
|
||||
fn is_dirty(&self) -> bool {
|
||||
|
|
|
|||
Loading…
Reference in New Issue