aboutsummaryrefslogtreecommitdiffstats
path: root/zellij-server
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2026-07-28 12:05:38 +0200
committerGitHub <noreply@github.com>2026-07-28 12:05:38 +0200
commit9969ed10b2cd95cb84ddaf8a783949483e2b038b (patch)
treeb8f6fe9a11e69440b6d9cb8ef56ee71c4d79fe9c /zellij-server
parentNested session handling (#5417) (diff)
downloadsl0ppij-9969ed10b2cd95cb84ddaf8a783949483e2b038b.tar.gz
sl0ppij-9969ed10b2cd95cb84ddaf8a783949483e2b038b.tar.xz
sl0ppij-9969ed10b2cd95cb84ddaf8a783949483e2b038b.zip
Dep upgrades for debian (#5420)
* chore(deps): upgrade base64 0.22, colored 3.1, crossterm 0.29, dialoguer 0.11, directories 6.0, highway 1.2, prost 0.12.6, strip-ansi-escapes 0.2.1, suggest 0.5.1 * chore(deps): upgrade miette 7.6, nix 0.30, notify 8.2, notify-debouncer-full 0.5 * vte 0.15 * clap 4.6 * workspaceify plugin deps * don't send empty fs watch events
Diffstat (limited to 'zellij-server')
-rw-r--r--zellij-server/Cargo.toml8
-rw-r--r--zellij-server/src/os_input_output_unix.rs70
-rw-r--r--zellij-server/src/panes/grid.rs14
-rw-r--r--zellij-server/src/panes/plugin_pane.rs4
-rw-r--r--zellij-server/src/panes/terminal_pane.rs15
-rw-r--r--zellij-server/src/panes/unit/grid_tests.rs675
-rw-r--r--zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__save_layout_invalid_kdl_plugin_command.snap2
-rw-r--r--zellij-server/src/plugins/wasm_bridge.rs4
-rw-r--r--zellij-server/src/plugins/watch_filesystem.rs40
-rw-r--r--zellij-server/src/tab/clipboard.rs8
-rw-r--r--zellij-server/src/tab/unit/tab_integration_tests.rs19
-rw-r--r--zellij-server/src/ui/components/mod.rs4
-rw-r--r--zellij-server/src/unit/screen_tests.rs4
13 files changed, 280 insertions, 587 deletions
diff --git a/zellij-server/Cargo.toml b/zellij-server/Cargo.toml
index 859b7433..3b23631a 100644
--- a/zellij-server/Cargo.toml
+++ b/zellij-server/Cargo.toml
@@ -13,12 +13,12 @@ ansi_term = { workspace = true }
anyhow = { workspace = true }
arrayvec = { version = "0.7.2", default-features = false, features = ["std"] }
async-trait = { version = "0.1.50", default-features = false }
-base64 = { version = "0.13.0", default-features = false, features = ["std"] }
+base64 = { version = "0.22", default-features = false, features = ["std"] }
byteorder = { version = "1.4.3", default-features = false, features = ["std"] }
bytes = { version = "1.6.0", default-features = false, features = ["std"] }
-chrono = { version = "0.4.19", default-features = false, features = ["std", "clock"] }
+chrono = { workspace = true }
crossbeam = { version = "0.8", default-features = false, features = ["crossbeam-channel", "std"] }
-highway = { version = "0.6.4", default-features = false, features = ["std"] }
+highway = { version = "=1.2.0", default-features = false, features = ["std"] }
interprocess = { workspace = true }
isahc = { workspace = true }
kasuari = { version = "0.4.12", default-features = false }
@@ -55,7 +55,7 @@ features = ["std"]
close_fds = "0.3.2"
daemonize = { workspace = true }
libc = { workspace = true }
-nix = { workspace = true }
+nix = { workspace = true, features = ["fs", "process", "signal", "term"] }
signal-hook = { workspace = true }
[target.'cfg(windows)'.dependencies]
diff --git a/zellij-server/src/os_input_output_unix.rs b/zellij-server/src/os_input_output_unix.rs
index 1ce8033b..bfebd7b5 100644
--- a/zellij-server/src/os_input_output_unix.rs
+++ b/zellij-server/src/os_input_output_unix.rs
@@ -20,7 +20,7 @@ use std::{
collections::BTreeMap,
fs::File,
io,
- os::fd::FromRawFd,
+ os::fd::{BorrowedFd, FromRawFd, IntoRawFd},
os::unix::{
io::{AsRawFd, RawFd},
process::CommandExt,
@@ -53,11 +53,13 @@ struct RawFdAsyncReader {
impl RawFdAsyncReader {
fn new(fd: RawFd) -> io::Result<Self> {
// Set O_NONBLOCK so AsyncFd can use epoll correctly
- let flags =
- fcntl(fd, FcntlArg::F_GETFL).map_err(|e| io::Error::from_raw_os_error(e as i32))?;
+ let borrowed_fd = unsafe { BorrowedFd::borrow_raw(fd) };
+ let flags = fcntl(borrowed_fd, FcntlArg::F_GETFL)
+ .map_err(|e| io::Error::from_raw_os_error(e as i32))?;
let mut oflags = OFlag::from_bits_truncate(flags);
oflags.insert(OFlag::O_NONBLOCK);
- fcntl(fd, FcntlArg::F_SETFL(oflags)).map_err(|e| io::Error::from_raw_os_error(e as i32))?;
+ fcntl(borrowed_fd, FcntlArg::F_SETFL(oflags))
+ .map_err(|e| io::Error::from_raw_os_error(e as i32))?;
let file = unsafe { File::from_raw_fd(fd) };
Ok(Self {
@@ -195,8 +197,8 @@ fn handle_openpty(
};
// primary side of pty and child fd
- let pid_primary = open_pty_res.master;
- let pid_secondary = open_pty_res.slave;
+ let pid_primary = open_pty_res.master.into_raw_fd();
+ let pid_secondary = open_pty_res.slave.into_raw_fd();
if !command_exists(&cmd) {
return Err(ZellijError::CommandNotFound {
@@ -291,7 +293,7 @@ pub(crate) struct UnixPtyBackend {
fn try_write_to_fd(fd: RawFd, buf: &[u8]) -> Result<usize> {
let mut written = 0;
while written < buf.len() {
- match unistd::write(fd, &buf[written..]) {
+ match unistd::write(unsafe { BorrowedFd::borrow_raw(fd) }, &buf[written..]) {
Ok(0) => break, // fd returned 0 on non-empty buf; treat like EAGAIN
Ok(n) => written += n,
Err(nix::errno::Errno::EINTR) => continue,
@@ -304,7 +306,7 @@ fn try_write_to_fd(fd: RawFd, buf: &[u8]) -> Result<usize> {
impl UnixPtyBackend {
pub fn new() -> Result<Self, io::Error> {
- let current_termios = termios::tcgetattr(0).ok();
+ let current_termios = termios::tcgetattr(io::stdin()).ok();
if current_termios.is_none() {
log::warn!("Starting a server without a controlling terminal, using the default termios configuration.");
}
@@ -409,14 +411,18 @@ impl UnixPtyBackend {
.with_context(err_context)?
.get(&terminal_id)
{
- Some(Some(fd)) => termios::tcdrain(*fd).with_context(err_context),
+ Some(Some(fd)) => {
+ termios::tcdrain(unsafe { BorrowedFd::borrow_raw(*fd) }).with_context(err_context)
+ },
_ => Err(anyhow!("could not find raw file descriptor")).with_context(err_context),
}
}
pub fn tcgetpgrp(&self, terminal_id: u32) -> Option<i32> {
match self.terminal_id_to_raw_fd.lock().ok()?.get(&terminal_id) {
- Some(Some(fd)) => unistd::tcgetpgrp(*fd).ok().map(|pgid| pgid.as_raw()),
+ Some(Some(fd)) => unistd::tcgetpgrp(unsafe { BorrowedFd::borrow_raw(*fd) })
+ .ok()
+ .map(|pgid| pgid.as_raw()),
_ => None,
}
}
@@ -475,22 +481,27 @@ mod tests {
#[test]
fn try_write_to_fd_returns_partial_on_full_buffer() {
let pty = openpty(None, &None).expect("openpty failed");
+ let master_fd = pty.master.into_raw_fd();
+ let slave_fd = pty.slave.into_raw_fd();
+ let borrowed_master = unsafe { BorrowedFd::borrow_raw(master_fd) };
+ let borrowed_slave = unsafe { BorrowedFd::borrow_raw(slave_fd) };
- let mut attrs = termios::tcgetattr(pty.slave).expect("tcgetattr failed");
+ let mut attrs = termios::tcgetattr(borrowed_slave).expect("tcgetattr failed");
termios::cfmakeraw(&mut attrs);
- termios::tcsetattr(pty.slave, termios::SetArg::TCSANOW, &attrs).expect("tcsetattr failed");
+ termios::tcsetattr(borrowed_slave, termios::SetArg::TCSANOW, &attrs)
+ .expect("tcsetattr failed");
// O_NONBLOCK so write() returns EAGAIN instead of blocking
- let flags = fcntl(pty.master, FcntlArg::F_GETFL).expect("F_GETFL");
+ let flags = fcntl(borrowed_master, FcntlArg::F_GETFL).expect("F_GETFL");
let mut oflags = OFlag::from_bits_truncate(flags);
oflags.insert(OFlag::O_NONBLOCK);
- fcntl(pty.master, FcntlArg::F_SETFL(oflags)).expect("F_SETFL");
+ fcntl(borrowed_master, FcntlArg::F_SETFL(oflags)).expect("F_SETFL");
// Fill most of the buffer, leaving some space
let chunk = vec![0x42u8; 1024];
let mut total_filled = 0;
loop {
- match super::try_write_to_fd(pty.master, &chunk) {
+ match super::try_write_to_fd(master_fd, &chunk) {
Ok(0) => break,
Ok(n) => total_filled += n,
Err(e) => panic!("unexpected error filling buffer: {e}"),
@@ -503,7 +514,7 @@ mod tests {
// Read a small amount from the slave to free partial space
let mut drain = vec![0u8; 512];
- let slave_file = unsafe { std::fs::File::from_raw_fd(pty.slave) };
+ let slave_file = unsafe { std::fs::File::from_raw_fd(slave_fd) };
let mut slave_reader = std::io::BufReader::new(&slave_file);
let drained = slave_reader.read(&mut drain).expect("slave read failed");
assert!(drained > 0, "should have drained some bytes");
@@ -513,7 +524,7 @@ mod tests {
// Now write more than the freed space — should get a partial write
let size = 128 * 1024;
let data: Vec<u8> = (0..size).map(|i| (i % 256) as u8).collect();
- let written = super::try_write_to_fd(pty.master, &data)
+ let written = super::try_write_to_fd(master_fd, &data)
.expect("try_write_to_fd should not error on EAGAIN");
assert!(
@@ -522,8 +533,8 @@ mod tests {
);
unsafe {
- libc::close(pty.master);
- libc::close(pty.slave);
+ libc::close(master_fd);
+ libc::close(slave_fd);
}
}
@@ -532,20 +543,25 @@ mod tests {
#[test]
fn try_write_to_fd_returns_zero_on_stuck_pty() {
let pty = openpty(None, &None).expect("openpty failed");
+ let master_fd = pty.master.into_raw_fd();
+ let slave_fd = pty.slave.into_raw_fd();
+ let borrowed_master = unsafe { BorrowedFd::borrow_raw(master_fd) };
+ let borrowed_slave = unsafe { BorrowedFd::borrow_raw(slave_fd) };
- let mut attrs = termios::tcgetattr(pty.slave).expect("tcgetattr failed");
+ let mut attrs = termios::tcgetattr(borrowed_slave).expect("tcgetattr failed");
termios::cfmakeraw(&mut attrs);
- termios::tcsetattr(pty.slave, termios::SetArg::TCSANOW, &attrs).expect("tcsetattr failed");
+ termios::tcsetattr(borrowed_slave, termios::SetArg::TCSANOW, &attrs)
+ .expect("tcsetattr failed");
- let flags = fcntl(pty.master, FcntlArg::F_GETFL).expect("F_GETFL");
+ let flags = fcntl(borrowed_master, FcntlArg::F_GETFL).expect("F_GETFL");
let mut oflags = OFlag::from_bits_truncate(flags);
oflags.insert(OFlag::O_NONBLOCK);
- fcntl(pty.master, FcntlArg::F_SETFL(oflags)).expect("F_SETFL");
+ fcntl(borrowed_master, FcntlArg::F_SETFL(oflags)).expect("F_SETFL");
// Fill the buffer completely — keep writing until we get Ok(0)
let fill = vec![0x42u8; 1024];
loop {
- match super::try_write_to_fd(pty.master, &fill) {
+ match super::try_write_to_fd(master_fd, &fill) {
Ok(0) => break,
Ok(_) => continue,
Err(e) => panic!("unexpected error filling buffer: {e}"),
@@ -553,14 +569,14 @@ mod tests {
}
// Now the buffer is full — next write should return Ok(0)
- let written = super::try_write_to_fd(pty.master, &[0x01, 0x02, 0x03])
+ let written = super::try_write_to_fd(master_fd, &[0x01, 0x02, 0x03])
.expect("try_write_to_fd should not error on EAGAIN");
assert_eq!(written, 0, "expected zero bytes written on full buffer");
unsafe {
- libc::close(pty.master);
- libc::close(pty.slave);
+ libc::close(master_fd);
+ libc::close(slave_fd);
}
}
}
diff --git a/zellij-server/src/panes/grid.rs b/zellij-server/src/panes/grid.rs
index 7ccd7599..30402973 100644
--- a/zellij-server/src/panes/grid.rs
+++ b/zellij-server/src/panes/grid.rs
@@ -1,4 +1,7 @@
use super::sixel::{PixelRect, SixelGrid, SixelImageStore};
+use base64::alphabet::STANDARD as BASE64_STANDARD_ALPHABET;
+use base64::engine::general_purpose::{GeneralPurpose, GeneralPurposeConfig};
+use base64::engine::{DecodePaddingMode, Engine as _};
use std::borrow::Cow;
use std::cell::RefCell;
use std::collections::BTreeMap;
@@ -30,6 +33,11 @@ use zellij_utils::{
const TABSTOP_WIDTH: usize = 8; // TODO: is this always right?
pub const MAX_TITLE_STACK_SIZE: usize = 1000;
+const BASE64_DECODER: GeneralPurpose = GeneralPurpose::new(
+ &BASE64_STANDARD_ALPHABET,
+ GeneralPurposeConfig::new().with_decode_padding_mode(DecodePaddingMode::Indifferent),
+);
+
/// Rewrites OSC 99 metadata for multiplexer forwarding:
///
/// 1. Namespaces the `i=` value with a pane ID prefix and flags so responses
@@ -3740,7 +3748,7 @@ impl Perform for Grid {
// TBD: paste from own clipboard - currently unsupported
},
base64 => {
- if let Ok(bytes) = base64::decode(base64) {
+ if let Ok(bytes) = BASE64_DECODER.decode(base64) {
if let Ok(string) = String::from_utf8(bytes) {
self.pending_clipboard_update = Some(string);
}
@@ -4544,6 +4552,10 @@ impl Perform for Grid {
},
}
}
+
+ fn terminated(&self) -> bool {
+ !self.pending_forwarded_queries.is_empty()
+ }
}
#[derive(Clone)]
diff --git a/zellij-server/src/panes/plugin_pane.rs b/zellij-server/src/panes/plugin_pane.rs
index 8eec16fc..e1adc89a 100644
--- a/zellij-server/src/panes/plugin_pane.rs
+++ b/zellij-server/src/panes/plugin_pane.rs
@@ -246,9 +246,7 @@ impl Pane for PluginPane {
.entry(client_id)
.or_insert_with(|| vte::Parser::new());
- for &byte in &vte_bytes {
- vte_parser.advance(grid, byte);
- }
+ vte_parser.advance(grid, &vte_bytes);
self.should_render.insert(client_id, true);
}
diff --git a/zellij-server/src/panes/terminal_pane.rs b/zellij-server/src/panes/terminal_pane.rs
index cdf269dd..22d8431a 100644
--- a/zellij-server/src/panes/terminal_pane.rs
+++ b/zellij-server/src/panes/terminal_pane.rs
@@ -229,16 +229,11 @@ impl Pane for TerminalPane {
self.pending_pty_input.extend(bytes);
return;
}
- let mut iter = bytes.into_iter();
- while let Some(byte) = iter.next() {
- self.vte_parser.advance(&mut self.grid, byte);
- if !self.grid.pending_forwarded_queries.is_empty() {
- // Grid produced a forward. Stop feeding; queue the
- // un-fed remainder so Tab can replay it after the
- // reply.
- self.pending_pty_input.extend(iter);
- break;
- }
+ let consumed = self
+ .vte_parser
+ .advance_until_terminated(&mut self.grid, &bytes);
+ if consumed < bytes.len() {
+ self.pending_pty_input.extend(&bytes[consumed..]);
}
}
fn cursor_coordinates(&self, client_id: Option<ClientId>) -> Option<(usize, usize, bool)> {
diff --git a/zellij-server/src/panes/unit/grid_tests.rs b/zellij-server/src/panes/unit/grid_tests.rs
index 2029a4b4..ce78f706 100644
--- a/zellij-server/src/panes/unit/grid_tests.rs
+++ b/zellij-server/src/panes/unit/grid_tests.rs
@@ -51,9 +51,7 @@ fn vttest1_0() {
);
let fixture_name = "vttest1-0";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -84,9 +82,7 @@ fn vttest1_1() {
);
let fixture_name = "vttest1-1";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -117,9 +113,7 @@ fn vttest1_2() {
);
let fixture_name = "vttest1-2";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -150,9 +144,7 @@ fn vttest1_3() {
);
let fixture_name = "vttest1-3";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -183,9 +175,7 @@ fn vttest1_4() {
);
let fixture_name = "vttest1-4";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -216,9 +206,7 @@ fn vttest1_5() {
);
let fixture_name = "vttest1-5";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -249,9 +237,7 @@ fn vttest2_0() {
);
let fixture_name = "vttest2-0";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -282,9 +268,7 @@ fn vttest2_1() {
);
let fixture_name = "vttest2-1";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -315,9 +299,7 @@ fn vttest2_2() {
);
let fixture_name = "vttest2-2";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -348,9 +330,7 @@ fn vttest2_3() {
);
let fixture_name = "vttest2-3";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -381,9 +361,7 @@ fn vttest2_4() {
);
let fixture_name = "vttest2-4";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -414,9 +392,7 @@ fn vttest2_5() {
);
let fixture_name = "vttest2-5";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -447,9 +423,7 @@ fn vttest2_6() {
);
let fixture_name = "vttest2-6";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -480,9 +454,7 @@ fn vttest2_7() {
);
let fixture_name = "vttest2-7";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -513,9 +485,7 @@ fn vttest2_8() {
);
let fixture_name = "vttest2-8";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -546,9 +516,7 @@ fn vttest2_9() {
);
let fixture_name = "vttest2-9";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -579,9 +547,7 @@ fn vttest2_10() {
);
let fixture_name = "vttest2-10";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -612,9 +578,7 @@ fn vttest2_11() {
);
let fixture_name = "vttest2-11";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -645,9 +609,7 @@ fn vttest2_12() {
);
let fixture_name = "vttest2-12";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -678,9 +640,7 @@ fn vttest2_13() {
);
let fixture_name = "vttest2-13";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -711,9 +671,7 @@ fn vttest2_14() {
);
let fixture_name = "vttest2-14";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -744,9 +702,7 @@ fn vttest3_0() {
);
let fixture_name = "vttest3-0";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -777,9 +733,7 @@ fn vttest8_0() {
);
let fixture_name = "vttest8-0";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -810,9 +764,7 @@ fn vttest8_1() {
);
let fixture_name = "vttest8-1";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -843,9 +795,7 @@ fn vttest8_2() {
);
let fixture_name = "vttest8-2";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -876,9 +826,7 @@ fn vttest8_3() {
);
let fixture_name = "vttest8-3";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -909,9 +857,7 @@ fn vttest8_4() {
);
let fixture_name = "vttest8-4";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -942,9 +888,7 @@ fn vttest8_5() {
);
let fixture_name = "vttest8-5";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -975,9 +919,7 @@ fn csi_b() {
);
let fixture_name = "csi-b";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1008,9 +950,7 @@ fn csi_capital_i() {
);
let fixture_name = "csi-capital-i";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1041,9 +981,7 @@ fn csi_capital_z() {
);
let fixture_name = "csi-capital-z";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1074,9 +1012,7 @@ fn terminal_reports() {
);
let fixture_name = "terminal_reports";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid.pending_messages_to_pty));
}
@@ -1107,9 +1043,7 @@ fn wide_characters() {
);
let fixture_name = "wide_characters";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1140,9 +1074,7 @@ fn wide_characters_line_wrap() {
);
let fixture_name = "wide_characters_line_wrap";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1173,9 +1105,7 @@ fn insert_character_in_line_with_wide_character() {
);
let fixture_name = "wide_characters_middle_line_insert";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1206,9 +1136,7 @@ fn delete_char_in_middle_of_line_with_widechar() {
);
let fixture_name = "wide-chars-delete-middle";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1239,9 +1167,7 @@ fn delete_char_in_middle_of_line_with_multiple_widechars() {
);
let fixture_name = "wide-chars-delete-middle-after-multi";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1272,9 +1198,7 @@ fn fish_wide_characters_override_clock() {
);
let fixture_name = "fish_wide_characters_override_clock";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1305,9 +1229,7 @@ fn bash_delete_wide_characters() {
);
let fixture_name = "bash_delete_wide_characters";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1338,9 +1260,7 @@ fn delete_wide_characters_before_cursor() {
);
let fixture_name = "delete_wide_characters_before_cursor";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1371,9 +1291,7 @@ fn delete_wide_characters_before_cursor_when_cursor_is_on_wide_character() {
);
let fixture_name = "delete_wide_characters_before_cursor_when_cursor_is_on_wide_character";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1404,9 +1322,7 @@ fn delete_wide_character_under_cursor() {
);
let fixture_name = "delete_wide_character_under_cursor";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1437,9 +1353,7 @@ fn replace_wide_character_under_cursor() {
);
let fixture_name = "replace_wide_character_under_cursor";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1470,9 +1384,7 @@ fn wrap_wide_characters() {
);
let fixture_name = "wide_characters_full";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1503,9 +1415,7 @@ fn wrap_wide_characters_on_size_change() {
);
let fixture_name = "wide_characters_full";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
grid.change_size(21, 90);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1537,9 +1447,7 @@ fn unwrap_wide_characters_on_size_change() {
);
let fixture_name = "wide_characters_full";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
grid.change_size(21, 90);
grid.change_size(21, 93);
assert_snapshot!(format!("{:?}", grid));
@@ -1572,9 +1480,7 @@ fn wrap_wide_characters_in_the_middle_of_the_line() {
);
let fixture_name = "wide_characters_line_middle";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1605,9 +1511,7 @@ fn wrap_wide_characters_at_the_end_of_the_line() {
);
let fixture_name = "wide_characters_line_end";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1638,9 +1542,7 @@ fn copy_selected_text_from_viewport() {
);
let fixture_name = "grid_copy";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
grid.start_selection(&Position::new(23, 6));
// check for widechar, 📦 occupies columns 34, 35, and gets selected even if only the first column is selected
@@ -1679,9 +1581,7 @@ fn copy_wrapped_selected_text_from_viewport() {
);
let fixture_name = "grid_copy_wrapped";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
grid.start_selection(&Position::new(5, 0));
grid.end_selection(&Position::new(8, 42));
@@ -1719,9 +1619,7 @@ fn copy_selected_text_from_lines_above() {
);
let fixture_name = "grid_copy";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
grid.start_selection(&Position::new(-2, 10));
// check for widechar, 📦 occupies columns 34, 35, and gets selected even if only the first column is selected
@@ -1760,9 +1658,7 @@ fn copy_selected_text_from_lines_below() {
);
let fixture_name = "grid_copy";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
grid.move_viewport_up(40);
@@ -1809,9 +1705,7 @@ fn run_bandwhich_from_fish_shell() {
);
let fixture_name = "fish_and_bandwhich";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1842,9 +1736,7 @@ fn fish_tab_completion_options() {
);
let fixture_name = "fish_tab_completion_options";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1881,9 +1773,7 @@ pub fn fish_select_tab_completion_options() {
);
let fixture_name = "fish_select_tab_completion_options";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1924,9 +1814,7 @@ pub fn vim_scroll_region_down() {
);
let fixture_name = "vim_scroll_region_down";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -1964,9 +1852,7 @@ pub fn vim_ctrl_d() {
);
let fixture_name = "vim_ctrl_d";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -2003,9 +1889,7 @@ pub fn vim_ctrl_u() {
);
let fixture_name = "vim_ctrl_u";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -2036,9 +1920,7 @@ pub fn htop() {
);
let fixture_name = "htop";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -2069,9 +1951,7 @@ pub fn htop_scrolling() {
);
let fixture_name = "htop_scrolling";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -2102,9 +1982,7 @@ pub fn htop_right_scrolling() {
);
let fixture_name = "htop_right_scrolling";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -2145,9 +2023,7 @@ pub fn vim_overwrite() {
);
let fixture_name = "vim_overwrite";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -2180,9 +2056,7 @@ pub fn clear_scroll_region() {
);
let fixture_name = "clear_scroll_region";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -2213,9 +2087,7 @@ pub fn display_tab_characters_properly() {
);
let fixture_name = "tab_characters";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -2246,9 +2118,7 @@ pub fn neovim_insert_mode() {
);
let fixture_name = "nvim_insert";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -2279,9 +2149,7 @@ pub fn bash_cursor_linewrap() {
);
let fixture_name = "bash_cursor_linewrap";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -2314,9 +2182,7 @@ pub fn fish_paste_multiline() {
);
let fixture_name = "fish_paste_multiline";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -2347,9 +2213,7 @@ pub fn git_log() {
);
let fixture_name = "git_log";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -2382,9 +2246,7 @@ pub fn git_diff_scrollup() {
);
let fixture_name = "git_diff_scrollup";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -2415,9 +2277,7 @@ pub fn emacs_longbuf() {
);
let fixture_name = "emacs_longbuf_tutorial";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -2448,9 +2308,7 @@ pub fn top_and_quit() {
);
let fixture_name = "top_and_quit";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -2488,9 +2346,7 @@ pub fn exa_plus_omf_theme() {
);
let fixture_name = "exa_plus_omf_theme";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -2521,9 +2377,7 @@ pub fn scroll_up() {
);
let fixture_name = "scrolling";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
grid.scroll_up_one_line();
assert_snapshot!(format!("{:?}", grid));
}
@@ -2555,9 +2409,7 @@ pub fn scroll_down() {
);
let fixture_name = "scrolling";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
grid.scroll_up_one_line();
grid.scroll_down_one_line();
assert_snapshot!(format!("{:?}", grid));
@@ -2590,9 +2442,7 @@ pub fn scroll_up_with_line_wraps() {
);
let fixture_name = "scrolling";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
grid.scroll_up_one_line();
assert_snapshot!(format!("{:?}", grid));
}
@@ -2624,9 +2474,7 @@ pub fn scroll_down_with_line_wraps() {
);
let fixture_name = "scrolling";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
grid.scroll_up_one_line();
grid.scroll_down_one_line();
assert_snapshot!(format!("{:?}", grid));
@@ -2659,9 +2507,7 @@ pub fn scroll_up_decrease_width_and_scroll_down() {
);
let fixture_name = "scrolling";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
for _ in 0..10 {
grid.scroll_up_one_line();
}
@@ -2699,9 +2545,7 @@ pub fn scroll_up_increase_width_and_scroll_down() {
);
let fixture_name = "scrolling";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
for _ in 0..10 {
grid.scroll_up_one_line();
}
@@ -2738,9 +2582,7 @@ fn saved_cursor_across_resize() {
explicitly_disable_kitty_keyboard_protocol,
);
let mut parse = |s, grid: &mut Grid| {
- for b in Vec::from(s) {
- vte_parser.advance(&mut *grid, b)
- }
+ vte_parser.advance(&mut *grid, &Vec::from(s));
};
let content = "
\rLine 1 >fill to 20_<
@@ -2787,9 +2629,7 @@ fn saved_cursor_across_resize_longline() {
explicitly_disable_kitty_keyboard_protocol,
);
let mut parse = |s, grid: &mut Grid| {
- for b in Vec::from(s) {
- vte_parser.advance(&mut *grid, b)
- }
+ vte_parser.advance(&mut *grid, &Vec::from(s));
};
let content = "
\rLine 1 >fill \u{1b}[sto 20_<";
@@ -2829,9 +2669,7 @@ fn saved_cursor_across_resize_rewrap() {
explicitly_disable_kitty_keyboard_protocol,
);
let mut parse = |s, grid: &mut Grid| {
- for b in Vec::from(s) {
- vte_parser.advance(&mut *grid, b)
- }
+ vte_parser.advance(&mut *grid, &Vec::from(s));
};
let content = "
\r12345678123456781234567\u{1b}[s812345678"; // 4*8 chars
@@ -2872,9 +2710,7 @@ pub fn move_cursor_below_scroll_region() {
);
let fixture_name = "move_cursor_below_scroll_region";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -2905,9 +2741,7 @@ pub fn insert_wide_characters_in_existing_line() {
);
let fixture_name = "chinese_characters_line_middle";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -2944,9 +2778,7 @@ pub fn full_screen_scroll_region_and_scroll_up() {
);
let fixture_name = "scroll_region_full_screen";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
grid.scroll_up_one_line();
grid.scroll_up_one_line();
grid.scroll_up_one_line();
@@ -2980,9 +2812,7 @@ pub fn ring_bell() {
);
let fixture_name = "ring_bell";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert!(grid.ring_bell);
}
@@ -3013,9 +2843,7 @@ pub fn alternate_screen_change_size() {
);
let fixture_name = "alternate_screen_change_size";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
// no scrollback in alternate screen
assert_eq!(grid.scrollback_position_and_length(), (0, 0));
grid.change_size(10, 10);
@@ -3050,9 +2878,7 @@ pub fn fzf_fullscreen() {
);
let fixture_name = "fzf_fullscreen";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -3087,9 +2913,7 @@ pub fn replace_multiple_wide_characters_under_cursor() {
);
let fixture_name = "replace_multiple_wide_characters";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -3124,9 +2948,7 @@ pub fn replace_non_wide_characters_with_wide_characters() {
);
let fixture_name = "replace_non_wide_characters_with_wide_characters";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -3157,9 +2979,7 @@ pub fn scroll_down_ansi() {
);
let fixture_name = "scroll_down";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -3189,9 +3009,7 @@ pub fn ansi_capital_t() {
explicitly_disable_kitty_keyboard_protocol,
);
let content = "foo\u{1b}[14Tbar".as_bytes();
- for byte in content {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -3221,9 +3039,7 @@ pub fn ansi_capital_s() {
explicitly_disable_kitty_keyboard_protocol,
);
let content = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nfoo\u{1b}[14Sbar".as_bytes();
- for byte in content {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -3257,9 +3073,7 @@ fn terminal_pixel_size_reports() {
);
let fixture_name = "terminal_pixel_size_reports";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
// CSI 14t and CSI 16t are forwarded to the host; Zellij no longer
// synthesises local replies from character_cell_size for these.
assert!(grid.pending_messages_to_pty.is_empty());
@@ -3300,9 +3114,7 @@ fn terminal_pixel_size_reports_in_unsupported_terminals() {
);
let fixture_name = "terminal_pixel_size_reports";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
// Forwarding is independent of character_cell_size availability —
// the host terminal is authoritative for these queries regardless
// of what Zellij knows locally.
@@ -3343,9 +3155,7 @@ pub fn ansi_csi_at_sign() {
explicitly_disable_kitty_keyboard_protocol,
);
let content = "foo\u{1b}[2D\u{1b}[2@".as_bytes();
- for byte in content {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -3379,9 +3189,7 @@ pub fn sixel_images_are_reaped_when_scrolled_off() {
explicitly_disable_kitty_keyboard_protocol,
);
let pane_content = read_fixture("sixel-image-500px.six");
- for byte in pane_content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &pane_content);
for _ in 0..10_051 {
// scrollbuffer limit + viewport height
grid.add_canonical_line();
@@ -3424,9 +3232,7 @@ pub fn sixel_images_are_reaped_when_resetting() {
explicitly_disable_kitty_keyboard_protocol,
);
let pane_content = read_fixture("sixel-image-500px.six");
- for byte in pane_content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &pane_content);
grid.reset_terminal_state();
let _ = grid.read_changes(0, 0); // we do this because this is where the images are reaped
assert_eq!(
@@ -3467,20 +3273,14 @@ pub fn sixel_image_in_alternate_buffer() {
);
let move_to_alternate_screen = "\u{1b}[?1049h";
- for byte in move_to_alternate_screen.as_bytes() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, move_to_alternate_screen.as_bytes());
let pane_content = read_fixture("sixel-image-500px.six");
- for byte in pane_content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &pane_content);
assert_snapshot!(format!("{:?}", grid)); // should include the image
//
let move_away_from_alternate_screen = "\u{1b}[?1049l";
- for byte in move_away_from_alternate_screen.as_bytes() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, move_away_from_alternate_screen.as_bytes());
assert_snapshot!(format!("{:?}", grid)); // should note include the image
assert_eq!(
sixel_image_store.borrow().image_count(),
@@ -3521,45 +3321,33 @@ pub fn sixel_with_image_scrolling_decsdm() {
// enter DECSDM
let move_to_decsdm = "\u{1b}[?80h";
- for byte in move_to_decsdm.as_bytes() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, move_to_decsdm.as_bytes());
// write some text
let mut text_to_fill_pane = String::new();
for i in 0..10 {
writeln!(&mut text_to_fill_pane, "\rline {}", i + 1).unwrap();
}
- for byte in text_to_fill_pane.as_bytes() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, text_to_fill_pane.as_bytes());
// render a sixel image (will appear on the top left and partially cover the text)
let pane_content = read_fixture("sixel-image-100px.six");
- for byte in pane_content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &pane_content);
// image should be on the top left corner of the grid
assert_snapshot!(format!("{:?}", grid));
// leave DECSDM
let move_away_from_decsdm = "\u{1b}[?80l";
- for byte in move_away_from_decsdm.as_bytes() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, move_away_from_decsdm.as_bytes());
// Go down to the beginning of the next line
let mut go_down_once = String::new();
writeln!(&mut go_down_once, "\n\r").unwrap();
- for byte in go_down_once.as_bytes() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, go_down_once.as_bytes());
// render another sixel image, should appear under the cursor
let pane_content = read_fixture("sixel-image-100px.six");
- for byte in pane_content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &pane_content);
// image should appear in cursor position
assert_snapshot!(format!("{:?}", grid));
@@ -3591,9 +3379,7 @@ pub fn osc_4_background_query() {
explicitly_disable_kitty_keyboard_protocol,
);
let content = "\u{1b}]10;?\u{1b}\\";
- for byte in content.as_bytes() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, content.as_bytes());
// Post-refactor: OSC 10;? is forwarded to the host, not answered
// from Zellij's cached palette. pending_messages_to_pty must stay
// empty.
@@ -3632,9 +3418,7 @@ pub fn osc_4_foreground_query() {
explicitly_disable_kitty_keyboard_protocol,
);
let content = "\u{1b}]11;?\u{1b}\\";
- for byte in content.as_bytes() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, content.as_bytes());
assert!(grid.pending_messages_to_pty.is_empty());
let forwarded_string: String = grid
.pending_forwarded_queries
@@ -3672,9 +3456,7 @@ pub fn osc_4_color_query() {
explicitly_disable_kitty_keyboard_protocol,
);
let content = "\u{1b}]4;222;?\u{1b}\\";
- for byte in content.as_bytes() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, content.as_bytes());
// OSC 4;N;? is forwarded to the host for the real palette value.
assert!(grid.pending_messages_to_pty.is_empty());
let forwarded_string: String = grid
@@ -3711,9 +3493,7 @@ pub fn xtsmgraphics_color_register_count() {
explicitly_disable_kitty_keyboard_protocol,
);
let content = "\u{1b}[?1;1;S\u{1b}\\";
- for byte in content.as_bytes() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, content.as_bytes());
let message_string = grid
.pending_messages_to_pty
.iter()
@@ -3755,9 +3535,7 @@ pub fn xtsmgraphics_pixel_graphics_geometry() {
explicitly_disable_kitty_keyboard_protocol,
);
let content = "\u{1b}[?2;1;S\u{1b}\\";
- for byte in content.as_bytes() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, content.as_bytes());
let message_string = grid
.pending_messages_to_pty
.iter()
@@ -3800,36 +3578,28 @@ pub fn cursor_hide_persists_through_alternate_screen() {
);
let hide_cursor = "\u{1b}[?25l";
- for byte in hide_cursor.as_bytes() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, hide_cursor.as_bytes());
assert!(
matches!(grid.cursor_coordinates(), Some((_, _, false))),
"Cursor hidden properly"
);
let move_to_alternate_screen = "\u{1b}[?1049h";
- for byte in move_to_alternate_screen.as_bytes() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, move_to_alternate_screen.as_bytes());
assert!(
matches!(grid.cursor_coordinates(), Some((_, _, false))),
"Cursor still hidden in alternate screen"
);
let show_cursor = "\u{1b}[?25h";
- for byte in show_cursor.as_bytes() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, show_cursor.as_bytes());
assert!(
matches!(grid.cursor_coordinates(), Some((_, _, true))),
"Cursor shown"
);
let move_away_from_alternate_screen = "\u{1b}[?1049l";
- for byte in move_away_from_alternate_screen.as_bytes() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, move_away_from_alternate_screen.as_bytes());
assert!(
matches!(grid.cursor_coordinates(), Some((_, _, true))),
"Cursor still shown away from alternate screen"
@@ -3863,9 +3633,7 @@ fn table_ui_component() {
);
let fixture_name = "table-ui-component";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -3896,9 +3664,7 @@ fn table_ui_component_with_coordinates() {
);
let fixture_name = "table-ui-component-with-coordinates";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -3929,9 +3695,7 @@ fn ribbon_ui_component() {
);
let fixture_name = "ribbon-ui-component";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -3962,9 +3726,7 @@ fn ribbon_ui_component_with_coordinates() {
);
let fixture_name = "ribbon-ui-component-with-coordinates";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -3995,9 +3757,7 @@ fn nested_list_ui_component() {
);
let fixture_name = "nested-list-ui-component";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -4028,9 +3788,7 @@ fn nested_list_ui_component_with_coordinates() {
);
let fixture_name = "nested-list-ui-component-with-coordinates";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -4061,9 +3819,7 @@ fn text_ui_component() {
);
let fixture_name = "text-ui-component";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -4094,9 +3850,7 @@ fn text_ui_component_with_coordinates() {
);
let fixture_name = "text-ui-component-with-coordinates";
let content = read_fixture(fixture_name);
- for byte in content {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -4134,9 +3888,7 @@ fn cannot_escape_scroll_region() {
explicitly_disable_kitty_keyboard_protocol,
);
let content = "\u{1b}[1;42r\u{1b}[42;1HHi there!".as_bytes();
- for byte in content {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, &content);
assert_snapshot!(format!("{:?}", grid));
}
@@ -4169,9 +3921,7 @@ fn preserve_background_color_on_resize() {
);
let mut parse = |s, grid: &mut Grid| {
- for b in Vec::from(s) {
- vte_parser.advance(&mut *grid, b)
- }
+ vte_parser.advance(&mut *grid, &Vec::from(s));
};
// Write text with red background that extends to end of line
@@ -4250,9 +4000,7 @@ fn create_grid_with_content(content: &str) -> Grid {
true,
false,
);
- for byte in content.as_bytes() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, content.as_bytes());
grid
}
@@ -4426,9 +4174,7 @@ fn osc_11_set_and_query_pane_default_bg() {
// Set background via OSC 11
let set_bg = b"\x1b]11;#001a3a\x07";
- for byte in set_bg.iter() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, set_bg);
assert_eq!(grid.pane_default_bg, Some((0, 26, 58)));
@@ -4439,9 +4185,7 @@ fn osc_11_set_and_query_pane_default_bg() {
// `rgb:RRRR/GGGG/BBBB` form with each 8-bit channel widened by
// repetition (0x00 → 0x0000, 0x1a → 0x1a1a, 0x3a → 0x3a3a).
let query_bg = b"\x1b]11;?\x07";
- for byte in query_bg.iter() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, query_bg);
assert!(
grid.pending_forwarded_queries.is_empty(),
@@ -4477,9 +4221,7 @@ fn osc_10_set_and_query_pane_default_fg() {
// Set foreground via OSC 10
let set_fg = b"\x1b]10;#00e000\x07";
- for byte in set_fg.iter() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, set_fg);
assert_eq!(grid.pane_default_fg, Some((0, 224, 0)));
@@ -4487,9 +4229,7 @@ fn osc_10_set_and_query_pane_default_fg() {
// so the query is answered locally (see OSC 11 equivalent test for
// the short-circuit rationale).
let query_fg = b"\x1b]10;?\x07";
- for byte in query_fg.iter() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, query_fg);
assert!(
grid.pending_forwarded_queries.is_empty(),
@@ -4525,30 +4265,22 @@ fn osc_110_111_reset_pane_default_colors() {
// Set both fg and bg
let set_fg = b"\x1b]10;#00e000\x07";
- for byte in set_fg.iter() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, set_fg);
let set_bg = b"\x1b]11;#001a3a\x07";
- for byte in set_bg.iter() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, set_bg);
assert_eq!(grid.pane_default_fg, Some((0, 224, 0)));
assert_eq!(grid.pane_default_bg, Some((0, 26, 58)));
// Reset foreground via OSC 110
let reset_fg = b"\x1b]110\x07";
- for byte in reset_fg.iter() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, reset_fg);
assert_eq!(grid.pane_default_fg, None);
assert_eq!(grid.pane_default_bg, Some((0, 26, 58)));
// Reset background via OSC 111
let reset_bg = b"\x1b]111\x07";
- for byte in reset_bg.iter() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, reset_bg);
assert_eq!(grid.pane_default_fg, None);
assert_eq!(grid.pane_default_bg, None);
}
@@ -4578,9 +4310,7 @@ fn osc_11_set_bg_produces_ansi_in_render_output() {
// Set background via OSC 11
let set_bg = b"\x1b]11;#001a3a\x07";
- for byte in set_bg.iter() {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, set_bg);
assert_eq!(grid.pane_default_bg, Some((0, 26, 58)));
@@ -4844,9 +4574,7 @@ fn plugin_highlight_at_wrapped_line() {
// Feed a long string that wraps: "abcdefghij" fills row 0, "klmnopqrst" fills row 1
let content = "abcdefghijklmnopqrst";
let mut vte_parser = vte::Parser::new();
- for &byte in content.as_bytes() {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, content.as_bytes());
// Set a highlight for "jklm" which spans the wrap boundary
let highlights = vec![create_highlight(
@@ -5003,9 +4731,7 @@ fn create_grid_with_scrollback() -> Grid {
let mut parser = vte::Parser::new();
for i in 0..25 {
let line = format!("scrollback line {}\r\n", i);
- for byte in line.as_bytes() {
- parser.advance(&mut grid, *byte);
- }
+ parser.advance(&mut grid, line.as_bytes());
}
grid
}
@@ -5095,9 +4821,7 @@ fn create_grid_with_colored_scrollback() -> Grid {
let mut parser = vte::Parser::new();
for i in 0..25 {
let line = format!("\x1b[31mred line {}\x1b[0m\r\n", i);
- for byte in line.as_bytes() {
- parser.advance(&mut grid, *byte);
- }
+ parser.advance(&mut grid, line.as_bytes());
}
grid
}
@@ -5447,17 +5171,13 @@ fn create_grid_with_size_and_raw(rows: usize, cols: usize, content: &[u8]) -> Gr
true,
false,
);
- for byte in content {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, &content);
grid
}
fn feed_bytes(grid: &mut Grid, bytes: &[u8]) {
let mut vte_parser = vte::Parser::new();
- for byte in bytes {
- vte_parser.advance(grid, *byte);
- }
+ vte_parser.advance(grid, bytes);
}
// All tests below use a 10-row, 40-col grid with scroll region 1;8
@@ -5919,9 +5639,7 @@ fn csi_14t_forwards_to_host_not_local() {
// the terminal's real window pixel dimensions.
let mut parser = vte::Parser::new();
let mut grid = new_grid_for_forwarding_test();
- for byte in b"\x1b[14t" {
- parser.advance(&mut grid, *byte);
- }
+ parser.advance(&mut grid, b"\x1b[14t");
assert!(
grid.pending_messages_to_pty.is_empty(),
"local reply path must not fire for 14t"
@@ -5938,9 +5656,7 @@ fn csi_14t_forwards_to_host_not_local() {
fn csi_16t_forwards_to_host_not_local() {
let mut parser = vte::Parser::new();
let mut grid = new_grid_for_forwarding_test();
- for byte in b"\x1b[16t" {
- parser.advance(&mut grid, *byte);
- }
+ parser.advance(&mut grid, b"\x1b[16t");
assert!(grid.pending_messages_to_pty.is_empty());
assert_eq!(grid.pending_forwarded_queries.len(), 1);
assert_eq!(
@@ -5955,9 +5671,7 @@ fn csi_18t_still_answered_locally() {
// authoritative for this, do NOT forward.
let mut parser = vte::Parser::new();
let mut grid = new_grid_for_forwarding_test();
- for byte in b"\x1b[18t" {
- parser.advance(&mut grid, *byte);
- }
+ parser.advance(&mut grid, b"\x1b[18t");
assert_eq!(grid.pending_messages_to_pty.len(), 1);
assert!(grid.pending_forwarded_queries.is_empty());
}
@@ -5968,9 +5682,7 @@ fn osc_11_set_stays_local() {
// to track it for its own rendering.
let mut parser = vte::Parser::new();
let mut grid = new_grid_for_forwarding_test();
- for byte in b"\x1b]11;rgb:ffff/ffff/ffff\x07" {
- parser.advance(&mut grid, *byte);
- }
+ parser.advance(&mut grid, b"\x1b]11;rgb:ffff/ffff/ffff\x07");
assert!(grid.pending_messages_to_pty.is_empty());
assert!(
grid.pending_forwarded_queries.is_empty(),
@@ -5986,9 +5698,7 @@ fn osc_11_query_without_override_forwards_to_host() {
let mut parser = vte::Parser::new();
let mut grid = new_grid_for_forwarding_test();
assert!(grid.pane_default_bg.is_none());
- for byte in b"\x1b]11;?\x07" {
- parser.advance(&mut grid, *byte);
- }
+ parser.advance(&mut grid, b"\x1b]11;?\x07");
assert!(
grid.pending_messages_to_pty.is_empty(),
"no override → no local reply"
@@ -6005,9 +5715,7 @@ fn osc_10_query_without_override_forwards_to_host() {
let mut parser = vte::Parser::new();
let mut grid = new_grid_for_forwarding_test();
assert!(grid.pane_default_fg.is_none());
- for byte in b"\x1b]10;?\x07" {
- parser.advance(&mut grid, *byte);
- }
+ parser.advance(&mut grid, b"\x1b]10;?\x07");
assert!(grid.pending_messages_to_pty.is_empty());
assert_eq!(grid.pending_forwarded_queries.len(), 1);
assert!(matches!(
@@ -6027,12 +5735,8 @@ fn set_pane_default_colors_short_circuits_osc_queries() {
let mut grid = new_grid_for_forwarding_test();
grid.set_pane_default_colors(Some("#ff8040".to_string()), Some("#102030".to_string()));
- for byte in b"\x1b]10;?\x07" {
- parser.advance(&mut grid, *byte);
- }
- for byte in b"\x1b]11;?\x07" {
- parser.advance(&mut grid, *byte);
- }
+ parser.advance(&mut grid, b"\x1b]10;?\x07");
+ parser.advance(&mut grid, b"\x1b]11;?\x07");
assert!(
grid.pending_forwarded_queries.is_empty(),
@@ -6052,15 +5756,11 @@ fn osc_11_override_short_circuits_only_the_overridden_channel() {
// populated, an OSC 10 query (fg) still goes to the host.
let mut parser = vte::Parser::new();
let mut grid = new_grid_for_forwarding_test();
- for byte in b"\x1b]11;rgb:1010/2020/3030\x07" {
- parser.advance(&mut grid, *byte);
- }
+ parser.advance(&mut grid, b"\x1b]11;rgb:1010/2020/3030\x07");
assert!(grid.pane_default_bg.is_some());
assert!(grid.pane_default_fg.is_none());
- for byte in b"\x1b]10;?\x07" {
- parser.advance(&mut grid, *byte);
- }
+ parser.advance(&mut grid, b"\x1b]10;?\x07");
assert!(
grid.pending_messages_to_pty.is_empty(),
"fg has no override → must forward"
@@ -6076,9 +5776,7 @@ fn csi_2026_dollar_p_stays_local() {
// own frames, so individual panes are treated as "not enabled").
let mut parser = vte::Parser::new();
let mut grid = new_grid_for_forwarding_test();
- for byte in b"\x1b[?2026$p" {
- parser.advance(&mut grid, *byte);
- }
+ parser.advance(&mut grid, b"\x1b[?2026$p");
assert!(
grid.pending_forwarded_queries.is_empty(),
"CSI ?2026$p is emulated locally, must not forward"
@@ -6097,9 +5795,7 @@ fn csi_2031_dollar_p_when_disabled_replies_reset() {
// is reset, so the DECRPM reply must report value=2.
let mut parser = vte::Parser::new();
let mut grid = new_grid_for_forwarding_test();
- for byte in b"\x1b[?2031$p" {
- parser.advance(&mut grid, *byte);
- }
+ parser.advance(&mut grid, b"\x1b[?2031$p");
assert!(
grid.pending_forwarded_queries.is_empty(),
"CSI ?2031$p is answered locally, must not forward"
@@ -6117,9 +5813,7 @@ fn csi_2031_dollar_p_when_enabled_replies_set() {
// pane, a DECRQM probe must report value=1 (set).
let mut parser = vte::Parser::new();
let mut grid = new_grid_for_forwarding_test();
- for byte in b"\x1b[?2031h\x1b[?2031$p" {
- parser.advance(&mut grid, *byte);
- }
+ parser.advance(&mut grid, b"\x1b[?2031h\x1b[?2031$p");
assert!(
grid.pending_forwarded_queries.is_empty(),
"CSI ?2031$p is answered locally, must not forward"
@@ -6141,9 +5835,7 @@ fn csi_22t_and_23t_stay_local() {
let mut grid = new_grid_for_forwarding_test();
grid.set_title("hello".to_string());
- for byte in b"\x1b[22;0t" {
- parser.advance(&mut grid, *byte);
- }
+ parser.advance(&mut grid, b"\x1b[22;0t");
assert!(
grid.pending_forwarded_queries.is_empty(),
"22t is a stack op, not a query"
@@ -6155,9 +5847,7 @@ fn csi_22t_and_23t_stay_local() {
// The push actually landed on Zellij's per-pane stack: restore it.
grid.set_title("different".to_string());
- for byte in b"\x1b[23;0t" {
- parser.advance(&mut grid, *byte);
- }
+ parser.advance(&mut grid, b"\x1b[23;0t");
assert!(
grid.pending_forwarded_queries.is_empty(),
"23t is a stack op, not a query"
@@ -6179,9 +5869,7 @@ fn osc_4_set_stays_local() {
// the query form (`OSC 4;N;?`) ever forwards to the host.
let mut parser = vte::Parser::new();
let mut grid = new_grid_for_forwarding_test();
- for byte in b"\x1b]4;5;rgb:ffff/0000/0000\x07" {
- parser.advance(&mut grid, *byte);
- }
+ parser.advance(&mut grid, b"\x1b]4;5;rgb:ffff/0000/0000\x07");
assert!(
grid.pending_forwarded_queries.is_empty(),
"OSC 4 set must not forward"
@@ -6204,16 +5892,12 @@ fn decset_2031_enables_color_palette_notification() {
!grid.color_palette_notification_enabled,
"default state must be disabled"
);
- for byte in b"\x1b[?2031h" {
- parser.advance(&mut grid, *byte);
- }
+ parser.advance(&mut grid, b"\x1b[?2031h");
assert!(
grid.color_palette_notification_enabled,
"DECSET 2031 must enable the flag"
);
- for byte in b"\x1b[?2031l" {
- parser.advance(&mut grid, *byte);
- }
+ parser.advance(&mut grid, b"\x1b[?2031l");
assert!(
!grid.color_palette_notification_enabled,
"DECRST 2031 must disable the flag"
@@ -6256,9 +5940,7 @@ fn csi_996n_pushes_color_palette_mode_query_to_forwarded_queries() {
use crate::host_query::HostQuery;
let mut parser = vte::Parser::new();
let mut grid = new_grid_for_forwarding_test();
- for byte in b"\x1b[?996n" {
- parser.advance(&mut grid, *byte);
- }
+ parser.advance(&mut grid, b"\x1b[?996n");
assert_eq!(
grid.pending_forwarded_queries,
vec![HostQuery::ColorPaletteMode],
@@ -6276,9 +5958,7 @@ fn csi_5n_status_query_still_handled_locally() {
let mut grid = new_grid_for_forwarding_test();
// Plain DSR 5 (no `?` intermediate) is not the new theme query and
// must continue to receive its `\e[0n` "all good" reply locally.
- for byte in b"\x1b[5n" {
- parser.advance(&mut grid, *byte);
- }
+ parser.advance(&mut grid, b"\x1b[5n");
assert!(
grid.pending_forwarded_queries.is_empty(),
"DSR 5 is not a forwarded query"
@@ -6322,9 +6002,10 @@ fn nested_session_frame_is_staged_for_dispatch() {
let mut vte_parser = vte::Parser::new();
let mut grid = new_grid_for_nested_frames();
let message = nested_announce_message();
- for byte in zellij_utils::nested_session::encode_frame(&message) {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(
+ &mut grid,
+ &zellij_utils::nested_session::encode_frame(&message),
+ );
assert_eq!(grid.pending_nested_session_messages, vec![message]);
}
@@ -6335,13 +6016,9 @@ fn nested_session_frame_split_across_feeds_is_staged() {
let message = nested_announce_message();
let frame = zellij_utils::nested_session::encode_frame(&message);
let (first_half, second_half) = frame.split_at(frame.len() / 2);
- for byte in first_half {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, first_half);
assert!(grid.pending_nested_session_messages.is_empty());
- for byte in second_half {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, second_half);
assert_eq!(grid.pending_nested_session_messages, vec![message]);
}
@@ -6349,9 +6026,7 @@ fn nested_session_frame_split_across_feeds_is_staged() {
fn dcs_with_wrong_magic_param_is_not_staged() {
let mut vte_parser = vte::Parser::new();
let mut grid = new_grid_for_nested_frames();
- for byte in b"\x1bP26662nAAAA\x1b\\" {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, b"\x1bP26662nAAAA\x1b\\");
assert!(grid.pending_nested_session_messages.is_empty());
}
@@ -6359,9 +6034,7 @@ fn dcs_with_wrong_magic_param_is_not_staged() {
fn dcs_with_intermediates_is_not_staged() {
let mut vte_parser = vte::Parser::new();
let mut grid = new_grid_for_nested_frames();
- for byte in b"\x1bP26661$nAAAA\x1b\\" {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, b"\x1bP26661$nAAAA\x1b\\");
assert!(grid.pending_nested_session_messages.is_empty());
}
@@ -6369,9 +6042,7 @@ fn dcs_with_intermediates_is_not_staged() {
fn dcs_n_without_params_is_not_staged() {
let mut vte_parser = vte::Parser::new();
let mut grid = new_grid_for_nested_frames();
- for byte in b"\x1bPnAAAA\x1b\\" {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, b"\x1bPnAAAA\x1b\\");
assert!(grid.pending_nested_session_messages.is_empty());
}
@@ -6379,9 +6050,7 @@ fn dcs_n_without_params_is_not_staged() {
fn nested_session_frame_with_garbage_payload_is_dropped() {
let mut vte_parser = vte::Parser::new();
let mut grid = new_grid_for_nested_frames();
- for byte in b"\x1bP26661n!!!not-base64!!!\x1b\\" {
- vte_parser.advance(&mut grid, *byte);
- }
+ vte_parser.advance(&mut grid, b"\x1bP26661n!!!not-base64!!!\x1b\\");
assert!(grid.pending_nested_session_messages.is_empty());
}
@@ -6397,9 +6066,7 @@ fn render_ui_component(component_name: &str, serialized_params: &str) -> Grid {
let mut vte_parser = vte::Parser::new();
let mut grid = new_grid_for_nested_frames();
let dcs = format!("\u{1b}Pz{};{}\u{1b}\\", component_name, serialized_params);
- for byte in dcs.bytes() {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, dcs.as_bytes());
grid
}
diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__save_layout_invalid_kdl_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__save_layout_invalid_kdl_plugin_command.snap
index 0e02eefd..c16e36ad 100644
--- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__save_layout_invalid_kdl_plugin_command.snap
+++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__save_layout_invalid_kdl_plugin_command.snap
@@ -3,5 +3,5 @@ source: zellij-server/src/plugins/./unit/plugin_tests.rs
expression: "format!(\"{:#?}\", plugin_bytes_event)"
---
Some(
- "Save invalid layout error: Invalid layout KDL: KdlError(KdlError { error_message: \"Failed to deserialize KDL node. \\nPossible reasons:\\n- Missing `;` after a node name, eg. { node; another_node; }\\n- Missing quotations (\\\") around an argument node eg. { first_node \\\"argument_node\\\"; }\\n- Missing an equal sign (=) between node arguments on a title line. eg. argument=\\\"value\\\"\\n- Found an extraneous equal sign (=) between node child arguments and their values. eg. { argument=\\\"value\\\" }\", src: Some(NamedSource { name: \"invalid_layout.kdl\", source: \"<redacted>\"), offset: Some(0), len: Some(4), help_message: None })\n\r",
+ "Save invalid layout error: Invalid layout KDL: KdlError(KdlError { error_message: \"Failed to deserialize KDL node. \\nPossible reasons:\\n- Missing `;` after a node name, eg. { node; another_node; }\\n- Missing quotations (\\\") around an argument node eg. { first_node \\\"argument_node\\\"; }\\n- Missing an equal sign (=) between node arguments on a title line. eg. argument=\\\"value\\\"\\n- Found an extraneous equal sign (=) between node child arguments and their values. eg. { argument=\\\"value\\\" }\", src: Some(NamedSource { name: \"invalid_layout.kdl\", source: \"<redacted>\", language: None), offset: Some(0), len: Some(4), help_message: None })\n\r",
)
diff --git a/zellij-server/src/plugins/wasm_bridge.rs b/zellij-server/src/plugins/wasm_bridge.rs
index 4121684b..bbf1f00c 100644
--- a/zellij-server/src/plugins/wasm_bridge.rs
+++ b/zellij-server/src/plugins/wasm_bridge.rs
@@ -11,7 +11,7 @@ use crate::plugins::watch_filesystem::watch_filesystem;
use crate::plugins::zellij_exports::{wasi_read_string, wasi_write_object};
use highway::{HighwayHash, PortableHash};
use log::info;
-use notify_debouncer_full::{notify::RecommendedWatcher, Debouncer, FileIdMap};
+use notify_debouncer_full::{notify::RecommendedWatcher, Debouncer, RecommendedCache};
use std::{
collections::{BTreeMap, HashMap, HashSet},
path::PathBuf,
@@ -185,7 +185,7 @@ pub struct WasmBridge {
loading_plugins: HashSet<(PluginId, RunPlugin)>, // tracks loading plugins without handles
pending_plugin_reloads: HashSet<RunPlugin>,
path_to_default_shell: PathBuf,
- watcher: Option<Debouncer<RecommendedWatcher, FileIdMap>>,
+ watcher: Option<Debouncer<RecommendedWatcher, RecommendedCache>>,
zellij_cwd: PathBuf,
session_env_vars: std::collections::BTreeMap<String, String>,
default_shell: Option<TerminalAction>,
diff --git a/zellij-server/src/plugins/watch_filesystem.rs b/zellij-server/src/plugins/watch_filesystem.rs
index 8cb01af2..5630c9a7 100644
--- a/zellij-server/src/plugins/watch_filesystem.rs
+++ b/zellij-server/src/plugins/watch_filesystem.rs
@@ -7,8 +7,8 @@ use std::time::Duration;
use notify_debouncer_full::{
new_debouncer,
- notify::{EventKind, RecommendedWatcher, RecursiveMode, Watcher},
- DebounceEventResult, Debouncer, FileIdMap,
+ notify::{EventKind, RecommendedWatcher, RecursiveMode},
+ DebounceEventResult, Debouncer, RecommendedCache,
};
use zellij_utils::{data::Event, errors::prelude::Result};
@@ -17,7 +17,7 @@ const DEBOUNCE_DURATION_MS: u64 = 400;
pub fn watch_filesystem(
senders: ThreadSenders,
zellij_cwd: &Path,
-) -> Result<Debouncer<RecommendedWatcher, FileIdMap>> {
+) -> Result<Debouncer<RecommendedWatcher, RecommendedCache>> {
let path_prefix_in_plugins = PathBuf::from("/host");
let current_dir = PathBuf::from(zellij_cwd);
let mut debouncer = new_debouncer(
@@ -93,34 +93,44 @@ pub fn watch_filesystem(
// TODO: at some point we might want to add FileMetadata to these, but right now
// the API is a bit unstable, so let's not rock the boat too much by adding another
// expensive syscall
- let _ = senders.send_to_plugin(PluginInstruction::Update(vec![
- (
+ let mut updates = vec![];
+ if !read_paths.is_empty() {
+ updates.push((
None,
None,
Event::FileSystemRead(read_paths.into_iter().map(|p| (p, None)).collect()),
- ),
- (
+ ));
+ }
+ if !create_paths.is_empty() {
+ updates.push((
None,
None,
Event::FileSystemCreate(
create_paths.into_iter().map(|p| (p, None)).collect(),
),
- ),
- (
+ ));
+ }
+ if !update_paths.is_empty() {
+ updates.push((
None,
None,
Event::FileSystemUpdate(
update_paths.into_iter().map(|p| (p, None)).collect(),
),
- ),
- (
+ ));
+ }
+ if !delete_paths.is_empty() {
+ updates.push((
None,
None,
Event::FileSystemDelete(
delete_paths.into_iter().map(|p| (p, None)).collect(),
),
- ),
- ]));
+ ));
+ }
+ if !updates.is_empty() {
+ let _ = senders.send_to_plugin(PluginInstruction::Update(updates));
+ }
},
Err(errors) => errors
.iter()
@@ -128,8 +138,6 @@ pub fn watch_filesystem(
},
)?;
- debouncer
- .watcher()
- .watch(zellij_cwd, RecursiveMode::Recursive)?;
+ debouncer.watch(zellij_cwd, RecursiveMode::Recursive)?;
Ok(debouncer)
}
diff --git a/zellij-server/src/tab/clipboard.rs b/zellij-server/src/tab/clipboard.rs
index d954b1c7..7820388e 100644
--- a/zellij-server/src/tab/clipboard.rs
+++ b/zellij-server/src/tab/clipboard.rs
@@ -1,4 +1,6 @@
use anyhow::Result;
+use base64::engine::general_purpose::STANDARD as BASE64_STANDARD;
+use base64::engine::Engine as _;
use zellij_utils::{data::CopyDestination, input::options::Clipboard};
use crate::ClientId;
@@ -31,7 +33,11 @@ impl ClipboardProvider {
};
output.add_pre_vte_instruction_to_multiple_clients(
client_ids,
- &format!("\u{1b}]52;{};{}\u{1b}\\", dest, base64::encode(content)),
+ &format!(
+ "\u{1b}]52;{};{}\u{1b}\\",
+ dest,
+ BASE64_STANDARD.encode(content)
+ ),
);
},
};
diff --git a/zellij-server/src/tab/unit/tab_integration_tests.rs b/zellij-server/src/tab/unit/tab_integration_tests.rs
index 3e778b16..9fcb36f5 100644
--- a/zellij-server/src/tab/unit/tab_integration_tests.rs
+++ b/zellij-server/src/tab/unit/tab_integration_tests.rs
@@ -1044,9 +1044,7 @@ fn take_snapshot(ansi_instructions: &str, rows: usize, columns: usize, palette:
explicitly_disable_kitty_keyboard_protocol,
);
let mut vte_parser = vte::Parser::new();
- for &byte in ansi_instructions.as_bytes() {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, ansi_instructions.as_bytes());
format!("{:?}", grid)
}
@@ -1083,9 +1081,7 @@ fn take_snapshot_with_sixel(
explicitly_disable_kitty_keyboard_protocol,
);
let mut vte_parser = vte::Parser::new();
- for &byte in ansi_instructions.as_bytes() {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, ansi_instructions.as_bytes());
format!("{:?}", grid)
}
@@ -1119,9 +1115,7 @@ fn take_snapshot_and_cursor_position(
explicitly_disable_kitty_keyboard_protocol,
);
let mut vte_parser = vte::Parser::new();
- for &byte in ansi_instructions.as_bytes() {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(&mut grid, ansi_instructions.as_bytes());
let coords = grid
.cursor_coordinates()
.and_then(|(x, y, visible)| if visible { Some((x, y)) } else { None });
@@ -15364,9 +15358,10 @@ fn osc99_grid_parses_and_stores_notification() {
// Feed OSC 99 through vte parser
let mut vte_parser = vte::Parser::new();
- for &byte in b"\x1b]99;i=gridtest:p=title;Grid notification\x07" {
- vte_parser.advance(&mut grid, byte);
- }
+ vte_parser.advance(
+ &mut grid,
+ b"\x1b]99;i=gridtest:p=title;Grid notification\x07",
+ );
assert_eq!(
grid.pending_desktop_notifications.len(),
diff --git a/zellij-server/src/ui/components/mod.rs b/zellij-server/src/ui/components/mod.rs
index ad927f0e..f47f97c4 100644
--- a/zellij-server/src/ui/components/mod.rs
+++ b/zellij-server/src/ui/components/mod.rs
@@ -28,9 +28,7 @@ macro_rules! parse_next_param {
macro_rules! parse_vte_bytes {
($self:expr, $encoded_component:expr) => {{
let mut vte_parser = vte::Parser::new();
- for &byte in &$encoded_component {
- vte_parser.advance($self.grid, byte);
- }
+ vte_parser.advance($self.grid, &$encoded_component);
}};
}
diff --git a/zellij-server/src/unit/screen_tests.rs b/zellij-server/src/unit/screen_tests.rs
index 9d839d30..d7f0f63f 100644
--- a/zellij-server/src/unit/screen_tests.rs
+++ b/zellij-server/src/unit/screen_tests.rs
@@ -57,9 +57,7 @@ fn take_snapshot_and_cursor_coordinates(
grid: &mut Grid,
) -> (Option<(usize, usize)>, String) {
let mut vte_parser = vte::Parser::new();
- for &byte in ansi_instructions.as_bytes() {
- vte_parser.advance(grid, byte);
- }
+ vte_parser.advance(grid, ansi_instructions.as_bytes());
let coords = grid
.cursor_coordinates()
.and_then(|(x, y, visible)| if visible { Some((x, y)) } else { None });