Files
ghostty-rs/crates/ghostty-terminal/src/search/test_util.rs
T
ddidderr db1d4fe41d feat(terminal): port terminal search and the tmux control-mode viewer
search/: sliding-window matcher over pages, active-area, page list,
viewport and screen searches, and the background search thread (std
thread + crossbeam-channel mailbox, 24 ms refresh, terminal behind
Arc<Mutex<_>>). Searches take &mut Screen explicitly; ScreenSearch::deinit
must be called to untrack pins. The sliding window uses a VecDeque
instead of CircBuf (same results; two layout-only assertions dropped).

tmux/: layout parsing, output formatting and the control-mode viewer
state machine, reusing ghostty_vt::tmux::control for parsing. The viewer
is not wired into termio yet; steps are in the notes.

The renderer must set terminal.flags.search_viewport_dirty for the
search thread to re-search the viewport.

Test Plan:
- cargo test -p ghostty-terminal --lib search (54; 51/53 Zig tests,
  2 allocator-failure tests skipped)
- cargo test -p ghostty-terminal --lib tmux (96; all Zig tests)
2026-10-11 22:51:36 +02:00

51 lines
1.3 KiB
Rust

//! Shared helpers for search tests.
use crate::page_list::{NodeId, PageList};
use crate::point::{Coordinate, Point, Tag};
use crate::screen::{Options, Screen};
use crate::terminal::{self, Terminal};
pub fn screen(cols: u16, rows: u16, max_scrollback: usize) -> Screen {
Screen::new(Options::new(cols, rows, max_scrollback)).unwrap()
}
pub fn terminal(cols: u16, rows: u16) -> Terminal {
Terminal::new(terminal::Options::new(cols, rows)).unwrap()
}
pub fn terminal_scrollback(cols: u16, rows: u16, max_scrollback: usize) -> Terminal {
let mut o = terminal::Options::new(cols, rows);
o.max_scrollback = max_scrollback;
Terminal::new(o).unwrap()
}
pub fn feed(t: &mut Terminal, bytes: &[u8]) {
let mut s = t.vt_stream();
s.next_slice(bytes).unwrap();
}
/// Point constructor with a tag.
pub fn pt(tag: Tag, x: u16, y: u32) -> Point {
Point::new(tag, Coordinate { x, y })
}
pub fn active(x: u16, y: u32) -> Point {
pt(Tag::Active, x, y)
}
pub fn first(list: &PageList) -> NodeId {
list.first.unwrap()
}
pub fn last(list: &PageList) -> NodeId {
list.last.unwrap()
}
pub fn next(list: &PageList, id: NodeId) -> NodeId {
list.node(id).unwrap().next.unwrap()
}
pub fn screen_pt(x: u16, y: u32) -> Point {
pt(Tag::Screen, x, y)
}