mirror of
https://github.com/asciinema/asciinema.git
synced 2026-05-18 05:04:50 +02:00
Support OSC theme responses in any order
This commit is contained in:
107
src/tty.rs
107
src/tty.rs
@@ -224,18 +224,89 @@ fn complete_da_response_len(response: &[u8]) -> Option<usize> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_theme_response(response: &[u8]) -> Option<TtyTheme> {
|
fn parse_theme_response(response: &[u8]) -> Option<TtyTheme> {
|
||||||
|
let mut fg = None;
|
||||||
|
let mut bg = None;
|
||||||
|
let mut palette: [Option<RGB8>; 16] = [None; 16];
|
||||||
let response = String::from_utf8_lossy(response);
|
let response = String::from_utf8_lossy(response);
|
||||||
let mut colors = response.match_indices("rgb:");
|
let mut rest = &response[..];
|
||||||
let (idx, _) = colors.next()?;
|
|
||||||
let fg = parse_color(&response[idx + 4..])?;
|
|
||||||
let (idx, _) = colors.next()?;
|
|
||||||
let bg = parse_color(&response[idx + 4..])?;
|
|
||||||
let mut palette = Vec::new();
|
|
||||||
|
|
||||||
for _ in 0..16 {
|
loop {
|
||||||
let (idx, _) = colors.next()?;
|
let Some(seq_start) = rest.find("\x1b]") else {
|
||||||
let color = parse_color(&response[idx + 4..])?;
|
break;
|
||||||
palette.push(color);
|
};
|
||||||
|
|
||||||
|
let rest_after_start = &rest[seq_start + 2..];
|
||||||
|
let bel_end = rest_after_start.find("\x07");
|
||||||
|
let st_end = rest_after_start.find("\x1b\\");
|
||||||
|
|
||||||
|
let Some(seq_end) = (match (bel_end, st_end) {
|
||||||
|
(Some(bel), Some(st)) => Some(bel.min(st)),
|
||||||
|
(Some(bel), None) => Some(bel),
|
||||||
|
(None, Some(st)) => Some(st),
|
||||||
|
(None, None) => None,
|
||||||
|
}) else {
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
let reply = &rest_after_start[..seq_end];
|
||||||
|
|
||||||
|
if rest_after_start[seq_end..].starts_with("\x07") {
|
||||||
|
rest = &rest_after_start[seq_end + 1..];
|
||||||
|
} else {
|
||||||
|
rest = &rest_after_start[seq_end + 2..];
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut params = reply.split(';');
|
||||||
|
|
||||||
|
let Some(p1) = params.next() else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(p2) = params.next() else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
match p1 {
|
||||||
|
"10" => {
|
||||||
|
if let Some(c) = p2.strip_prefix("rgb:") {
|
||||||
|
fg = parse_color(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"11" => {
|
||||||
|
if let Some(c) = p2.strip_prefix("rgb:") {
|
||||||
|
bg = parse_color(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"4" => {
|
||||||
|
let Some(i) = p2.parse::<u8>().ok() else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(p3) = params.next() else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
if i < 16 {
|
||||||
|
if let Some(c) = p3.strip_prefix("rgb:") {
|
||||||
|
palette[i as usize] = parse_color(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let fg = fg?;
|
||||||
|
let bg = bg?;
|
||||||
|
let palette = palette.into_iter().flatten().collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if palette.len() < 16 {
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(TtyTheme { fg, bg, palette })
|
Some(TtyTheme { fg, bg, palette })
|
||||||
@@ -318,24 +389,24 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn parse_theme_response_ok() {
|
fn parse_theme_response_ok() {
|
||||||
let response = concat!(
|
let response = concat!(
|
||||||
"\x1b]10;rgb:1122/3344/5566\x07",
|
|
||||||
"\x1b]11;rgb:7788/99aa/bbcc\x07",
|
|
||||||
"\x1b]4;0;rgb:0000/1111/2222\x07",
|
|
||||||
"\x1b]4;1;rgb:3333/4444/5555\x07",
|
"\x1b]4;1;rgb:3333/4444/5555\x07",
|
||||||
"\x1b]4;2;rgb:6666/7777/8888\x07",
|
"\x1b]11;rgb:7788/99aa/bbcc\x07",
|
||||||
"\x1b]4;3;rgb:9999/aaaa/bbbb\x07",
|
"\x1b]4;3;rgb:9999/aaaa/bbbb\x07",
|
||||||
|
"\x1b]4;2;rgb:6666/7777/8888\x1b\\",
|
||||||
"\x1b]4;4;rgb:cccc/dddd/eeee\x07",
|
"\x1b]4;4;rgb:cccc/dddd/eeee\x07",
|
||||||
"\x1b]4;5;rgb:ffff/0000/1111\x07",
|
"\x1b]4;0;rgb:0000/1111/2222\x07",
|
||||||
"\x1b]4;6;rgb:2222/3333/4444\x07",
|
"\x1b]4;6;rgb:2222/3333/4444\x07",
|
||||||
|
"\x1b]4;5;rgb:ffff/0000/1111\x07",
|
||||||
"\x1b]4;7;rgb:5555/6666/7777\x07",
|
"\x1b]4;7;rgb:5555/6666/7777\x07",
|
||||||
|
"\x1b]4;10;rgb:eeee/ffff/0000\x07",
|
||||||
"\x1b]4;8;rgb:8888/9999/aaaa\x07",
|
"\x1b]4;8;rgb:8888/9999/aaaa\x07",
|
||||||
"\x1b]4;9;rgb:bbbb/cccc/dddd\x07",
|
"\x1b]4;9;rgb:bbbb/cccc/dddd\x07",
|
||||||
"\x1b]4;10;rgb:eeee/ffff/0000\x07",
|
|
||||||
"\x1b]4;11;rgb:1111/2222/3333\x07",
|
"\x1b]4;11;rgb:1111/2222/3333\x07",
|
||||||
"\x1b]4;12;rgb:4444/5555/6666\x07",
|
|
||||||
"\x1b]4;13;rgb:7777/8888/9999\x07",
|
|
||||||
"\x1b]4;14;rgb:aaaa/bbbb/cccc\x07",
|
"\x1b]4;14;rgb:aaaa/bbbb/cccc\x07",
|
||||||
|
"\x1b]4;13;rgb:7777/8888/9999\x07",
|
||||||
|
"\x1b]10;rgb:1122/3344/5566\x1b\\",
|
||||||
"\x1b]4;15;rgb:dddd/eeee/ffff\x07",
|
"\x1b]4;15;rgb:dddd/eeee/ffff\x07",
|
||||||
|
"\x1b]4;12;rgb:4444/5555/6666\x07",
|
||||||
)
|
)
|
||||||
.as_bytes();
|
.as_bytes();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user