e2b746dd64
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
84 lines
2.2 KiB
Rust
84 lines
2.2 KiB
Rust
use alacritty_terminal::event::VoidListener;
|
|
use alacritty_terminal::grid::Dimensions;
|
|
use alacritty_terminal::index::{Column, Line, Point};
|
|
use alacritty_terminal::term::{Config, Term};
|
|
use alacritty_terminal::vte::ansi::Processor;
|
|
|
|
/// Fixed-size terminal dimensions for the daemon-side grid.
|
|
#[derive(Clone, Copy)]
|
|
pub struct GridSize {
|
|
pub cols: usize,
|
|
pub lines: usize,
|
|
}
|
|
|
|
impl Dimensions for GridSize {
|
|
fn total_lines(&self) -> usize {
|
|
self.lines
|
|
}
|
|
fn screen_lines(&self) -> usize {
|
|
self.lines
|
|
}
|
|
fn columns(&self) -> usize {
|
|
self.cols
|
|
}
|
|
}
|
|
|
|
/// Owns an alacritty terminal model and feeds raw PTY bytes into it.
|
|
pub struct GridSurface {
|
|
term: Term<VoidListener>,
|
|
parser: Processor,
|
|
size: GridSize,
|
|
}
|
|
|
|
impl GridSurface {
|
|
pub fn new(cols: u16, rows: u16) -> Self {
|
|
let size = GridSize { cols: cols as usize, lines: rows as usize };
|
|
let term = Term::new(Config::default(), &size, VoidListener);
|
|
Self { term, parser: Processor::new(), size }
|
|
}
|
|
|
|
pub fn feed(&mut self, bytes: &[u8]) {
|
|
self.parser.advance(&mut self.term, bytes);
|
|
}
|
|
|
|
pub fn resize(&mut self, cols: u16, rows: u16) {
|
|
self.size = GridSize { cols: cols as usize, lines: rows as usize };
|
|
self.term.resize(self.size);
|
|
}
|
|
|
|
pub fn size(&self) -> GridSize {
|
|
self.size
|
|
}
|
|
|
|
/// Read the visible character at (line, col) — used by tests and the snapshot writer.
|
|
pub fn char_at(&self, line: usize, col: usize) -> char {
|
|
let point = Point::new(Line(line as i32), Column(col));
|
|
self.term.grid()[point].c
|
|
}
|
|
|
|
pub fn term(&self) -> &Term<VoidListener> {
|
|
&self.term
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn feeding_plain_text_lands_in_the_grid() {
|
|
let mut g = GridSurface::new(20, 5);
|
|
g.feed(b"hello");
|
|
assert_eq!(g.char_at(0, 0), 'h');
|
|
assert_eq!(g.char_at(0, 4), 'o');
|
|
}
|
|
|
|
#[test]
|
|
fn carriage_return_and_newline_move_the_cursor() {
|
|
let mut g = GridSurface::new(20, 5);
|
|
g.feed(b"ab\r\ncd");
|
|
assert_eq!(g.char_at(0, 0), 'a');
|
|
assert_eq!(g.char_at(1, 0), 'c');
|
|
}
|
|
}
|