T40: review round 1: a notification names the session as the output stands at its place: the tap follows OSC 0 and 2, the title stack's CSI 22 t and 23 t and a full reset as alacritty does, and sends each title in order, since alacritty's own title events come after the tap's; one write and split writes post the same
CI / platforms (ubuntu-24.04) (push) Successful in 1m21s
CI / platforms (windows-latest) (push) Successful in 1m48s
CI / macos (push) Canceled after 7m24s

This commit is contained in:
ZacharyZhang-NY committed 2026-10-17 16:06:10 -04:00
1 parent 52576bb8ee
commit 22752a28db
9 files changed
+247 -15

No files matched your search

+56 -6
View File
@@ -17,6 +17,8 @@ struct Ran {
statuses: Vec<Option<Status>>,
/// Notifications and progress programs asked for.
asks: Vec<Ask>,
/// Titles, notifications and full resets, in the output's order.
said: Vec<String>,
text: String,
/// The first line's cells that carry a prompt's link.
prompt: Vec<usize>,
@@ -35,22 +37,37 @@ fn run(script: &str, size: (usize, usize)) -> Ran {
};
let (pty, mut events) =
spawn(&launch, size, (8, 16), config(&Settings::default())).expect("sh starts");
let (folders, marks, statuses, asks, success) = futures::executor::block_on(async {
let (mut folders, mut marks, mut statuses, mut asks, mut success) =
(Vec::new(), Vec::new(), Vec::new(), Vec::new(), false);
let (folders, marks, statuses, asks, said, success) = futures::executor::block_on(async {
let (mut folders, mut marks, mut statuses, mut asks, mut said, mut success) = (
Vec::new(),
Vec::new(),
Vec::new(),
Vec::new(),
Vec::new(),
false,
);
while let Some(event) = events.next().await {
match event {
PtyEvent::Folder(folder) => folders.push(folder),
PtyEvent::Mark(mark) => marks.push(mark),
PtyEvent::Status(status) => statuses.push(Some(status)),
PtyEvent::Reset => statuses.push(None),
PtyEvent::Ask(ask) => asks.push(ask),
PtyEvent::Reset => {
said.push("reset".to_string());
statuses.push(None);
}
PtyEvent::Title(title) => said.push(format!("title {title}")),
PtyEvent::Ask(ask) => {
if let Ask::Show(notice) = &ask {
said.push(format!("show {}", notice.title));
}
asks.push(ask);
}
PtyEvent::Term(Event::ChildExit(status)) => success = status.success(),
PtyEvent::Term(Event::Exit) => break,
PtyEvent::Term(_) | PtyEvent::Mouse(_) => {}
}
}
(folders, marks, statuses, asks, success)
(folders, marks, statuses, asks, said, success)
});
let term = pty.term.lock();
let row = &term.grid()[Line(0)];
@@ -65,6 +82,7 @@ fn run(script: &str, size: (usize, usize)) -> Ran {
marks,
statuses,
asks,
said,
text: text.trim_end().to_string(),
prompt: prompt.collect(),
success,
@@ -161,6 +179,38 @@ fn osc_99_gathers_a_full_encoded_chunk_and_the_lines_base64_carries() {
assert_eq!(ran.text, "x");
}
#[test]
fn titles_reach_the_session_in_their_place_among_notifications() {
let parts = [
"\\033]2;Old\\007",
"\\033[22t",
"\\033]2;New\\007",
"\\033]9;a\\007",
"\\033[23t",
"\\033]9;b\\007",
"\\033c",
"\\033]9;c\\007",
];
let whole = run(&format!("printf '{}x'", parts.concat()), (40, 4));
let split: Vec<String> = parts
.iter()
.map(|part| format!("printf '{part}'; sleep 0.1"))
.collect();
let split = run(&format!("{}; printf x", split.join("; ")), (40, 4));
let said = [
"title Old",
"title New",
"show a",
"title Old",
"show b",
"reset",
"show c",
];
assert_eq!(whole.said, said, "one write");
assert_eq!(split.said, said, "a write a sequence");
assert_eq!((whole.text.as_str(), split.text.as_str()), ("x", "x"));
}
#[test]
fn a_long_escape_of_controls_keeps_the_pty_reading() {
let ran = run(