From 0741d012fcbbff65e2bcb93b5f74f9b4167f2461 Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Thu, 19 Mar 2026 15:25:59 -0700 Subject: fix: remove per-event mouse capture toggling that leaked ANSI to stdout (#3299) The per-event `EnableMouseCapture`/`DisableMouseCapture` in `handle_input` wrote directly to `std::io::stdout()`, causing ANSI escape sequences to leak into captured output when running under command substitution (e.g. `VAR=$(atuin search -i)`). This toggling became redundant when session-level mouse capture was added to `Stdout::new()`/`Stdout::drop()`. Fixes #3298 --- .../atuin/src/command/client/search/interactive.rs | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) (limited to 'crates') diff --git a/crates/atuin/src/command/client/search/interactive.rs b/crates/atuin/src/command/client/search/interactive.rs index 4acf7be1..bba64d78 100644 --- a/crates/atuin/src/command/client/search/interactive.rs +++ b/crates/atuin/src/command/client/search/interactive.rs @@ -37,7 +37,7 @@ use ratatui::{ backend::{CrosstermBackend, FromCrossterm}, crossterm::{ cursor::SetCursorStyle, - event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyEvent, MouseEvent}, + event::{self, Event, KeyEvent, MouseEvent}, execute, queue, terminal, }, layout::{Alignment, Constraint, Direction, Layout}, @@ -174,24 +174,13 @@ impl State { } } - fn handle_input( - &mut self, - settings: &Settings, - input: &Event, - w: &mut W, - ) -> Result - where - W: Write, - { - execute!(w, EnableMouseCapture)?; - let r = match input { + fn handle_input(&mut self, settings: &Settings, input: &Event) -> InputAction { + match input { Event::Key(k) => self.handle_key_input(settings, k), Event::Mouse(m) => self.handle_mouse_input(*m), Event::Paste(d) => self.handle_paste_input(d), _ => InputAction::Continue, - }; - execute!(w, DisableMouseCapture)?; - Ok(r) + } } fn handle_mouse_input(&mut self, input: MouseEvent) -> InputAction { @@ -1768,7 +1757,7 @@ pub async fn history( event_ready = event_ready => { if event_ready?? { loop { - match app.handle_input(settings, &event::read()?, &mut std::io::stdout())? { + match app.handle_input(settings, &event::read()?) { InputAction::Continue => {}, InputAction::Delete(index) => { if results.is_empty() { -- cgit v1.3.1