From 1533409ed710eabc4b3cfa1ed9c1aa99caf29b3f Mon Sep 17 00:00:00 2001 From: Ken Chou Date: Sat, 15 Jun 2024 20:42:00 +0800 Subject: [PATCH] Feature: The search overlay accepts IME composed input (#5564) * Feature: The search overlay accepts IME composed input * use LineEditBuffer Co-authored-by: Wez Furlong --- wezterm-gui/src/overlay/copy.rs | 38 +++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/wezterm-gui/src/overlay/copy.rs b/wezterm-gui/src/overlay/copy.rs index e4de21b8c..00ce46452 100644 --- a/wezterm-gui/src/overlay/copy.rs +++ b/wezterm-gui/src/overlay/copy.rs @@ -13,7 +13,7 @@ use mux::pane::{ use mux::renderable::*; use mux::tab::TabId; use ordered_float::NotNan; -use parking_lot::{MappedMutexGuard, Mutex}; +use parking_lot::{MappedMutexGuard, Mutex, MutexGuard}; use rangeset::RangeSet; use std::collections::HashMap; use std::ops::Range; @@ -40,7 +40,8 @@ const SEARCH_CHUNK_SIZE: StableRowIndex = 1000; pub struct CopyOverlay { delegate: Arc, - render: Mutex, + render: Arc>, + writer: Mutex, } #[derive(Copy, Clone, Debug)] @@ -167,9 +168,15 @@ impl CopyOverlay { render.dirty_results.add(search_row); render.update_search(); + let shared_render = Arc::new(Mutex::new(render)); + let writer = SearchOverlayPatternWriter { + render: Arc::clone(&shared_render), + }; + Ok(Arc::new(CopyOverlay { delegate: Arc::clone(pane), - render: Mutex::new(render), + render: shared_render, + writer: Mutex::new(writer), })) } @@ -1116,7 +1123,10 @@ impl Pane for CopyOverlay { } fn writer(&self) -> MappedMutexGuard { - self.delegate.writer() + MutexGuard::map(self.writer.lock(), |writer| { + let w: &mut dyn std::io::Write = writer; + w + }) } fn resize(&self, size: TerminalSize) -> anyhow::Result<()> { @@ -1587,6 +1597,26 @@ impl Pane for CopyOverlay { } } +pub struct SearchOverlayPatternWriter { + render: Arc>, +} + +impl std::io::Write for SearchOverlayPatternWriter { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + let mut render = self.render.lock(); + let s = std::str::from_utf8(buf).map_err(|err| { + std::io::Error::new(std::io::ErrorKind::Other, format!("invalid UTF-8: {err:#}")) + })?; + render.search_line.insert_text(s); + render.schedule_update_search(); + Ok(buf.len()) + } + + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } +} + fn is_whitespace_word(word: &str) -> bool { if let Some(c) = word.chars().next() { c.is_whitespace()