Mouse selection, copy/paste, yield_to_user fixes

- Mouse text selection with highlight rendering in panes
- OSC 52 clipboard copy on selection, middle-click paste via tmux buffer
- Bracketed paste support (Event::Paste)
- yield_to_user: no tool result appended, ends turn immediately
- yield_to_user: no parameters, just a control signal
- Drop arboard dependency, use crossterm OSC 52 + tmux for clipboard

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
ProofOfConcept 2026-04-09 18:08:07 -04:00 committed by Kent Overstreet
parent 7dd9daa2b9
commit a596e007b2
9 changed files with 246 additions and 22 deletions

View file

@ -19,7 +19,7 @@ use crate::user::{self as tui};
// --- TUI infrastructure (moved from tui/mod.rs) ---
use ratatui::crossterm::{
event::{EnableMouseCapture, DisableMouseCapture},
event::{EnableMouseCapture, DisableMouseCapture, EnableBracketedPaste, DisableBracketedPaste},
terminal::{self, EnterAlternateScreen, LeaveAlternateScreen},
ExecutableCommand,
};
@ -98,6 +98,7 @@ struct ChannelStatus {
struct App {
status: StatusInfo,
activity: String,
activity_started: Option<std::time::Instant>,
running_processes: u32,
reasoning_effort: String,
temperature: f32,
@ -125,6 +126,7 @@ impl App {
turn_tools: 0, context_budget: String::new(),
},
activity: String::new(),
activity_started: None,
running_processes: 0,
reasoning_effort: "none".to_string(),
temperature: 0.6,
@ -164,12 +166,14 @@ fn init_terminal() -> io::Result<ratatui::Terminal<CrosstermBackend<io::Stdout>>
let mut stdout = io::stdout();
stdout.execute(EnterAlternateScreen)?;
stdout.execute(EnableMouseCapture)?;
stdout.execute(EnableBracketedPaste)?;
let backend = CrosstermBackend::new(stdout);
ratatui::Terminal::new(backend)
}
fn restore_terminal(terminal: &mut ratatui::Terminal<CrosstermBackend<io::Stdout>>) -> io::Result<()> {
terminal::disable_raw_mode()?;
terminal.backend_mut().execute(DisableBracketedPaste)?;
terminal.backend_mut().execute(DisableMouseCapture)?;
terminal.backend_mut().execute(LeaveAlternateScreen)?;
terminal.show_cursor()
@ -319,7 +323,7 @@ async fn run(
let (event_tx, mut event_rx) = tokio::sync::mpsc::unbounded_channel();
std::thread::spawn(move || {
loop {
match crossterm::event::read() {
match ratatui::crossterm::event::read() {
Ok(event) => { if event_tx.send(event).is_err() { break; } }
Err(_) => break,
}