Skip to content

Commit

Permalink
Use more compact RGB color notation for snapshots
Browse files Browse the repository at this point in the history
ku1ik committed Oct 17, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 0c8f301 commit f08ab26
Showing 4 changed files with 33 additions and 11 deletions.
16 changes: 13 additions & 3 deletions lib/asciinema/recordings/snapshot.ex
Original file line number Diff line number Diff line change
@@ -180,11 +180,13 @@ defmodule Asciinema.Recordings.Snapshot do
case {k, v} do
{"fg", c} when is_number(c) and c < 8 -> "3#{c}"
{"fg", c} when is_number(c) -> "38;5;#{c}"
{"fg", "rgb(" <> _} -> "38;2;#{parse_rgb(v)}"
{"fg", "#" <> _} -> "38;2;#{parse_hex_color(v)}"
{"fg", "rgb(" <> _} -> "38;2;#{parse_rgb_color(v)}"
{"fg", [r, g, b]} -> "38;2;#{r};#{g};#{b}"
{"bg", c} when is_number(c) and c < 8 -> "4#{c}"
{"bg", c} when is_number(c) -> "48;5;#{c}"
{"bg", "rgb(" <> _} -> "48;2;#{parse_rgb(v)}"
{"bg", "#" <> _} -> "48;2;#{parse_hex_color(v)}"
{"bg", "rgb(" <> _} -> "48;2;#{parse_rgb_color(v)}"
{"bg", [r, g, b]} -> "48;2;#{r};#{g};#{b}"
{"bold", true} -> "1"
{"faint", true} -> "2"
@@ -200,7 +202,15 @@ defmodule Asciinema.Recordings.Snapshot do

defp sgr_params([]), do: []

defp parse_rgb("rgb(" <> c) do
defp parse_hex_color(<<"#", r::binary-size(2), g::binary-size(2), b::binary-size(2)>>) do
r = String.to_integer(r, 16)
g = String.to_integer(g, 16)
b = String.to_integer(b, 16)

"#{r};#{g};#{b}"
end

defp parse_rgb_color("rgb(" <> c) do
c
|> String.slice(0, String.length(c) - 1)
|> String.split(",")
4 changes: 2 additions & 2 deletions native/vt_nif/src/lib.rs
Original file line number Diff line number Diff line change
@@ -129,7 +129,7 @@ fn chunk_to_term(cells: Vec<avt::Cell>, env: Env) -> Term {
}

Some(avt::Color::RGB(c)) => {
let c = format!("rgb({},{},{})", c.r, c.g, c.b);
let c = format!("#{:02x}{:02x}{:02x}", c.r, c.g, c.b);
pairs.push(("fg".to_owned(), c.encode(env)));
}

@@ -142,7 +142,7 @@ fn chunk_to_term(cells: Vec<avt::Cell>, env: Env) -> Term {
}

Some(avt::Color::RGB(c)) => {
let c = format!("rgb({},{},{})", c.r, c.g, c.b);
let c = format!("#{:02x}{:02x}{:02x}", c.r, c.g, c.b);
pairs.push(("bg".to_owned(), c.encode(env)));
}

17 changes: 14 additions & 3 deletions test/asciinema/recordings/snapshot_test.exs
Original file line number Diff line number Diff line change
@@ -180,7 +180,7 @@ defmodule Asciinema.Recordings.SnapshotTest do

@lines [
[[" foo bar baz", %{"bg" => 2}, 1], ["!", %{"fg" => 1}, 1]],
[["qux", %{"bg" => 2}, 1], ["连", %{}, 2], ["接", %{}, 2]]
[["qux", %{"bg" => "#102030"}, 1], ["连", %{}, 2], ["接", %{}, 2]]
]

describe "fg_coords/1" do
@@ -202,7 +202,7 @@ defmodule Asciinema.Recordings.SnapshotTest do
%{
y: 1,
segments: [
%{text: "qux", attrs: %{"bg" => 2}, x: 0, width: 3},
%{text: "qux", attrs: %{"bg" => "#102030"}, x: 0, width: 3},
%{text: "连", attrs: %{}, x: 3, width: 2},
%{text: "接", attrs: %{}, x: 5, width: 2}
]
@@ -228,10 +228,21 @@ defmodule Asciinema.Recordings.SnapshotTest do
%{
y: 1,
segments: [
%{attrs: %{"bg" => 2}, x: 0, width: 3}
%{attrs: %{"bg" => "#102030"}, x: 0, width: 3}
]
}
]
end
end

describe "seq/1" do
test "dumps snapshot as an ANSI sequence" do
seq =
@lines
|> Snapshot.new()
|> Snapshot.seq()

assert seq == "\e[42m foo bar baz\e[0m\e[31m!\e[0m\r\n\e[48;2;16;32;48mqux\e[0m连接\e[?25l"
end
end
end
7 changes: 4 additions & 3 deletions test/asciinema/vt_test.exs
Original file line number Diff line number Diff line change
@@ -10,16 +10,17 @@ defmodule Asciinema.VtTest do
Vt.with_vt(8, 3, fn vt ->
Vt.feed(vt, "foobar\r\n")
Vt.feed(vt, "baz")
Vt.feed(vt, "全")
Vt.feed(vt, "全\r\n")
Vt.feed(vt, "\x1b[1;38:2:16:32:48mqux")
Vt.dump_screen(vt)
end)

assert {:ok,
{[
[{"foobar ", %{}, 1}],
[{"baz", %{}, 1}, {"全", %{}, 2}, {" ", %{}, 1}],
[{" ", %{}, 1}]
], {4, 1}}} = result
[{"qux", %{"bold" => true, "fg" => "#102030"}, 1}, {" ", %{}, 1}]
], {3, 2}}} = result
end

test "feeding it a lot of data" do

0 comments on commit f08ab26

Please sign in to comment.