Skip to content

Instantly share code, notes, and snippets.

@dralletje
Last active November 18, 2023 22:25
Show Gist options
  • Save dralletje/4077954c56d9b594115a0f7fafdb0515 to your computer and use it in GitHub Desktop.
Save dralletje/4077954c56d9b594115a0f7fafdb0515 to your computer and use it in GitHub Desktop.
Colored `with_terminal` for Pluto.jl
### A Pluto.jl notebook ###
# v0.15.1
using Markdown
using InteractiveUtils
# ╔═╡ 2da76520-1615-11ec-1ad7-8f93957b2e6e
import IOCapture
# ╔═╡ 7d63286d-2320-49bf-a8a1-e538f53ba829
import Crayons: Crayons, @crayon_str
# ╔═╡ 0b3b46a3-9b65-4958-8860-b663e1c1204b
import JSON3
# ╔═╡ 1810dc75-f4c1-4d3f-963d-0f881abeee19
import UUIDs: UUID
# ╔═╡ e3975303-9295-489a-b0a5-cb6624eab890
md"## Library"
# ╔═╡ 6124c693-f752-4036-a011-b06300f61a6d
"""
force_color_stdout(f::Function)
Because `IOCapture`, even when specifying `color=true`, still just inherits the color property from the current stdout and stderr, we need to add one layer extra just to force color to true.
I hope nothing gets accidentally written to the streams I make, because they redirect to `devnull` 😅
"""
function force_color_stdout(f)
default_stdout = stdout
default_stderr = stderr
try
redirect_stdout(IOContext(devnull, :color => true))
redirect_stderr(IOContext(devnull, :color => true))
f()
finally
redirect_stdout(default_stdout)
redirect_stderr(default_stderr)
end
end
# ╔═╡ c98e0f1b-c489-48ed-b69e-5cbc06267429
"""
force_color_crayons(f::Function)
It never stops... Crayons also has some other way of determining if it should actually show the colors... I DON'T CARE I JUST WANT COLORS.
So I'm using `Crayons.FORCE_COLOR[] = true` and hope it listens
"""
function force_color_crayons(f)
CRAYONS_PKGID = Base.PkgId(UUID("a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"), "Crayons")
if haskey(Base.loaded_modules, CRAYONS_PKGID)
original_crayons_force_color = Crayons.FORCE_COLOR[]
try
Crayons.FORCE_COLOR[] = true
f()
finally
Crayons.FORCE_COLOR[] = original_crayons_force_color
end
else
f()
end
end
# ╔═╡ bf684e0c-e0f2-452c-b9a4-8452233ff920
Base.@kwdef struct TerminalOutput
value
output
end
# ╔═╡ d416b336-a6ee-4059-93af-08b12d59defd
function Base.show(io::IO, ::MIME"text/html", terminal_output::TerminalOutput)
show(io, MIME("text/html"), HTML("""
<script src="https://cdn.jsdelivr.net/npm/[email protected]/ansi_up.min.js"></script>
<script type="text/javascript">
var txt = $(JSON3.write(terminal_output.output))
var container = html`<pre style="
max-height: 300px;
overflow: auto;
white-space: pre;
color: white;
background-color: black;
border-radius: 3px;
margin-block-end: 8px;
"></pre>`
container.innerHTML = AnsiUp.ansi_to_html(txt);
return container
</script>
"""))
end
# ╔═╡ a0df0558-6b19-471d-b609-df3ee65dadbb
function with_terminal(f; color=true)
if color
force_color_stdout() do
force_color_crayons() do
value, output = IOCapture.capture(color=true) do
f()
end
TerminalOutput(value=value, output=output)
end
end
else
value, output = IOCapture.capture() do
f()
end
TerminalOutput(value=value, output=output)
end
end
# ╔═╡ 3072a9cf-ad45-463c-866e-ed2bba434a95
md"## Examples"
# ╔═╡ 376b7763-dd17-4147-a246-a530ace698ec
with_terminal() do
@info "Hey!"
end
# ╔═╡ 5cd4a175-2290-441a-989d-f26921d090bb
with_terminal(color=false) do
@info "Hey!"
end
# ╔═╡ d501d4fd-975b-4459-b9e0-bfb8947ee538
with_terminal() do
println("$(crayon"red")With Crayons! (in red)")
println("$(crayon"blue")Blue!")
println("$(crayon"reset")$(crayon"bold")Bold!")
end
# ╔═╡ 988d2c53-3f4f-40e8-8069-a24a8e10a8ca
# This command doesn't show colors for me... but maybe for someone else it works idk
with_terminal() do
run(`ls -lh --color`)
end
# ╔═╡ e0d49688-ef83-4607-8747-7e4e4f0003c2
with_terminal() do
@code_llvm [1,2,3,4,1//3] .* [2,3,4,.5]
end
# ╔═╡ 34a131cb-3f79-4fcf-91f2-828ee9115127
md"### Macro version because idk"
# ╔═╡ e8f72c6d-1b48-4b30-acee-4ec519682070
macro with_terminal(expr)
quote
$(with_terminal)() do
$(esc(expr))
end
end
end
# ╔═╡ 329d47a4-7ae1-49fb-9411-55cbc113195b
@with_terminal @info "Hey!"
# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
Crayons = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"
IOCapture = "b5f81e59-6552-4d32-b1f0-c071b021bf89"
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
[compat]
Crayons = "~4.0.4"
IOCapture = "~0.2.2"
JSON3 = "~1.9.1"
"""
# ╔═╡ 00000000-0000-0000-0000-000000000002
PLUTO_MANIFEST_TOML_CONTENTS = """
# This file is machine-generated - editing it directly is not advised
[[Crayons]]
git-tree-sha1 = "3f71217b538d7aaee0b69ab47d9b7724ca8afa0d"
uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"
version = "4.0.4"
[[Dates]]
deps = ["Printf"]
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"
[[IOCapture]]
deps = ["Logging", "Random"]
git-tree-sha1 = "f7be53659ab06ddc986428d3a9dcc95f6fa6705a"
uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89"
version = "0.2.2"
[[JSON3]]
deps = ["Dates", "Mmap", "Parsers", "StructTypes", "UUIDs"]
git-tree-sha1 = "b3e5984da3c6c95bcf6931760387ff2e64f508f3"
uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
version = "1.9.1"
[[Logging]]
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"
[[Mmap]]
uuid = "a63ad114-7e13-5084-954f-fe012c677804"
[[Parsers]]
deps = ["Dates"]
git-tree-sha1 = "438d35d2d95ae2c5e8780b330592b6de8494e779"
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
version = "2.0.3"
[[Printf]]
deps = ["Unicode"]
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
[[Random]]
deps = ["Serialization"]
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
[[SHA]]
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
[[Serialization]]
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
[[StructTypes]]
deps = ["Dates", "UUIDs"]
git-tree-sha1 = "8445bf99a36d703a09c601f9a57e2f83000ef2ae"
uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4"
version = "1.7.3"
[[UUIDs]]
deps = ["Random", "SHA"]
uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
[[Unicode]]
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
"""
# ╔═╡ Cell order:
# ╠═2da76520-1615-11ec-1ad7-8f93957b2e6e
# ╠═7d63286d-2320-49bf-a8a1-e538f53ba829
# ╠═0b3b46a3-9b65-4958-8860-b663e1c1204b
# ╠═1810dc75-f4c1-4d3f-963d-0f881abeee19
# ╟─e3975303-9295-489a-b0a5-cb6624eab890
# ╟─6124c693-f752-4036-a011-b06300f61a6d
# ╟─c98e0f1b-c489-48ed-b69e-5cbc06267429
# ╟─bf684e0c-e0f2-452c-b9a4-8452233ff920
# ╟─d416b336-a6ee-4059-93af-08b12d59defd
# ╠═a0df0558-6b19-471d-b609-df3ee65dadbb
# ╟─3072a9cf-ad45-463c-866e-ed2bba434a95
# ╠═376b7763-dd17-4147-a246-a530ace698ec
# ╠═5cd4a175-2290-441a-989d-f26921d090bb
# ╠═d501d4fd-975b-4459-b9e0-bfb8947ee538
# ╠═988d2c53-3f4f-40e8-8069-a24a8e10a8ca
# ╠═e0d49688-ef83-4607-8747-7e4e4f0003c2
# ╟─34a131cb-3f79-4fcf-91f2-828ee9115127
# ╠═329d47a4-7ae1-49fb-9411-55cbc113195b
# ╠═e8f72c6d-1b48-4b30-acee-4ec519682070
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment