mirror of
https://github.com/wez/wezterm.git
synced 2024-12-27 07:18:13 +03:00
b904ed7677
Previously we'd return the Url string. Now we provide a Url object that provides access to the various elements of the Url. This will cause slightly breakage for folks that were treating it as a string in their status event handlers, for example. The docs have been updated to show how to run with both this new Url object and also continue to run on older versions of wezterm. They now also show how to manually percent decode the url for older versions of wezterm. refs: https://github.com/wez/wezterm/discussions/4157 refs: https://github.com/wez/wezterm/issues/4000
502 lines
16 KiB
Python
502 lines
16 KiB
Python
#!/usr/bin/env python3
|
|
import base64
|
|
import glob
|
|
import json
|
|
import os
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
|
|
|
|
class Page(object):
|
|
def __init__(self, title, filename, children=None):
|
|
self.title = title
|
|
self.filename = filename
|
|
self.children = children or []
|
|
|
|
def render(self, output, depth=0, mode="mdbook"):
|
|
indent = " " * depth
|
|
bullet = "- " if depth > 0 else ""
|
|
if mode == "mdbook":
|
|
if self.filename:
|
|
output.write(f"{indent}{bullet}[{self.title}]({self.filename})\n")
|
|
elif mode == "mkdocs":
|
|
if depth > 0:
|
|
if len(self.children) == 0:
|
|
output.write(f'{indent}{bullet}"{self.title}": {self.filename}\n')
|
|
else:
|
|
output.write(f'{indent}{bullet}"{self.title}":\n')
|
|
if self.filename:
|
|
output.write(
|
|
f'{indent} {bullet}"{self.title}": {self.filename}\n'
|
|
)
|
|
for kid in self.children:
|
|
kid.render(output, depth + 1, mode)
|
|
|
|
|
|
# autogenerate an index page from the contents of a directory
|
|
class Gen(object):
|
|
def __init__(self, title, dirname, index=None, extract_title=False):
|
|
self.title = title
|
|
self.dirname = dirname
|
|
self.index = index
|
|
self.extract_title = extract_title
|
|
|
|
def render(self, output, depth=0, mode="mdbook"):
|
|
names = sorted(glob.glob(f"{self.dirname}/*.md"))
|
|
children = []
|
|
for filename in names:
|
|
title = os.path.basename(filename).rsplit(".", 1)[0]
|
|
if title == "index":
|
|
continue
|
|
|
|
if self.extract_title:
|
|
with open(filename, "r") as f:
|
|
title = f.readline().strip("#").strip()
|
|
|
|
children.append(Page(title, filename))
|
|
|
|
index_filename = f"{self.dirname}/index.md"
|
|
index_page = Page(self.title, index_filename, children=children)
|
|
index_page.render(output, depth, mode)
|
|
with open(f"{self.dirname}/index.md", "w") as idx:
|
|
if self.index:
|
|
idx.write(self.index)
|
|
idx.write("\n\n")
|
|
else:
|
|
try:
|
|
with open(f"{self.dirname}/index.markdown", "r") as f:
|
|
idx.write(f.read())
|
|
idx.write("\n\n")
|
|
except FileNotFoundError:
|
|
pass
|
|
for page in children:
|
|
idx.write(f" - [{page.title}]({os.path.basename(page.filename)})\n")
|
|
|
|
|
|
def load_scheme(scheme):
|
|
ident = re.sub(
|
|
"[^a-z0-9_]", "_", scheme["metadata"]["name"].lower().replace("+", "plus")
|
|
)
|
|
|
|
colors = scheme["colors"]["ansi"] + scheme["colors"]["brights"]
|
|
|
|
data = {
|
|
"name": scheme["metadata"]["name"],
|
|
"prefix": scheme["metadata"]["prefix"],
|
|
"ident": ident,
|
|
"fg": scheme["colors"]["foreground"],
|
|
"bg": scheme["colors"]["background"],
|
|
"metadata": scheme["metadata"],
|
|
}
|
|
|
|
# <https://github.com/asciinema/asciinema-player/wiki/Custom-terminal-themes>
|
|
css = f"""
|
|
.asciinema-theme-{ident} .asciinema-terminal {{
|
|
color: {data["fg"]};
|
|
background-color: {data["bg"]};
|
|
border-color: {data["bg"]};
|
|
}}
|
|
|
|
.asciinema-theme-{ident} .fg-bg {{
|
|
color: {data["bg"]};
|
|
}}
|
|
|
|
.asciinema-theme-{ident} .bg-fg {{
|
|
background-color: {data["fg"]};
|
|
}}
|
|
"""
|
|
|
|
if "cursor_border" in scheme["colors"]:
|
|
data["cursor"] = scheme["colors"]["cursor_border"]
|
|
|
|
css += f"""
|
|
.asciinema-theme-{ident} .cursor-b {{
|
|
background-color: {data["cursor"]} !important;
|
|
}}
|
|
"""
|
|
|
|
if "selection_fg" in scheme["colors"] and "selection_bg" in scheme["colors"]:
|
|
selection_bg = scheme["colors"]["selection_bg"]
|
|
selection_fg = scheme["colors"]["selection_fg"]
|
|
|
|
css += f"""
|
|
.asciinema-theme-{ident} .asciinema-terminal ::selection {{
|
|
color: {selection_fg};
|
|
background-color: {selection_bg};
|
|
}}
|
|
"""
|
|
|
|
for idx, color in enumerate(colors):
|
|
css += f"""
|
|
.asciinema-theme-{ident} .fg-{idx} {{
|
|
color: {color};
|
|
}}
|
|
.asciinema-theme-{ident} .bg-{idx} {{
|
|
background-color: {color};
|
|
}}
|
|
"""
|
|
|
|
data["css"] = css
|
|
return data
|
|
|
|
|
|
def screen_shot_table(scheme):
|
|
T = "gYw"
|
|
lines = [
|
|
scheme["name"],
|
|
"",
|
|
" def 40m 41m 42m 43m 44m 45m 46m 47m",
|
|
]
|
|
for fg_space in [
|
|
" m",
|
|
" 1m",
|
|
" 30m",
|
|
"1;30m",
|
|
" 31m",
|
|
"1;31m",
|
|
" 32m",
|
|
"1;32m",
|
|
" 33m",
|
|
"1;33m",
|
|
" 34m",
|
|
"1;34m",
|
|
" 35m",
|
|
"1;35m",
|
|
" 36m",
|
|
"1;36m",
|
|
" 37m",
|
|
"1;37m",
|
|
]:
|
|
fg = fg_space.strip()
|
|
line = f" {fg_space} \033[{fg} {T} "
|
|
|
|
for bg in ["40m", "41m", "42m", "43m", "44m", "45m", "46m", "47m"]:
|
|
line += f" \033[{fg}\033[{bg} {T} \033[0m"
|
|
lines.append(line)
|
|
|
|
lines.append("")
|
|
lines.append("")
|
|
|
|
screen = "\r\n".join(lines)
|
|
|
|
header = {
|
|
"version": 2,
|
|
"width": 80,
|
|
"height": 24,
|
|
"title": scheme["name"],
|
|
}
|
|
header = json.dumps(header, sort_keys=True)
|
|
data = json.dumps([0.0, "o", screen])
|
|
|
|
return base64.b64encode(f"{header}\n{data}\n".encode("UTF-8")).decode("UTF-8")
|
|
|
|
|
|
class GenColorScheme(object):
|
|
def __init__(self, title, dirname, index=None):
|
|
self.title = title
|
|
self.dirname = dirname
|
|
self.index = index
|
|
|
|
def render(self, output, depth=0, mode="mdbook"):
|
|
with open("colorschemes/data.json") as f:
|
|
scheme_data = json.load(f)
|
|
by_prefix = {}
|
|
by_name = {}
|
|
for scheme in scheme_data:
|
|
scheme = load_scheme(scheme)
|
|
prefix = scheme["prefix"]
|
|
if prefix not in by_prefix:
|
|
by_prefix[prefix] = []
|
|
by_prefix[prefix].append(scheme)
|
|
by_name[scheme["name"]] = scheme
|
|
|
|
style_filename = f"{self.dirname}/scheme.css"
|
|
with open(style_filename, "w") as style_file:
|
|
for scheme in by_name.values():
|
|
style_file.write(scheme["css"])
|
|
style_file.write("\n")
|
|
js_filename = f"{self.dirname}/scheme.js"
|
|
with open(js_filename, "w") as js_file:
|
|
data_by_scheme = {}
|
|
for scheme in by_name.values():
|
|
ident = scheme["ident"]
|
|
data = screen_shot_table(scheme)
|
|
data_by_scheme[ident] = data
|
|
|
|
js_file.write(f"SCHEME_DATA = {json.dumps(data_by_scheme)};\n")
|
|
js_file.write(
|
|
f"""
|
|
function load_scheme_player(ident) {{
|
|
var data = SCHEME_DATA[ident];
|
|
AsciinemaPlayer.create(
|
|
'data:text/plain;base64,' + data,
|
|
document.getElementById(ident + '-player'), {{
|
|
theme: ident,
|
|
autoPlay: true,
|
|
}});
|
|
}}
|
|
"""
|
|
)
|
|
|
|
children = []
|
|
for scheme_prefix in sorted(by_prefix.keys()):
|
|
scheme_filename = f"{self.dirname}/{scheme_prefix}/index.md"
|
|
os.makedirs(os.path.dirname(scheme_filename), exist_ok=True)
|
|
children.append(Page(scheme_prefix, scheme_filename))
|
|
|
|
with open(scheme_filename, "w") as idx:
|
|
idents_to_load = []
|
|
|
|
idx.write(
|
|
f"""---
|
|
title: Color Schemes with first letter "{scheme_prefix}"
|
|
---
|
|
|
|
"""
|
|
)
|
|
|
|
for scheme in by_prefix[scheme_prefix]:
|
|
title = scheme["name"]
|
|
idx.write(f"## {title}\n")
|
|
|
|
data = screen_shot_table(scheme)
|
|
ident = scheme["ident"]
|
|
idents_to_load.append(ident)
|
|
|
|
idx.write(
|
|
f"""
|
|
<div id="{ident}-player"></div>
|
|
"""
|
|
)
|
|
|
|
author = scheme["metadata"].get("author", None)
|
|
if author:
|
|
idx.write(f"Author: `{author}`<br/>\n")
|
|
origin_url = scheme["metadata"].get("origin_url", None)
|
|
if origin_url:
|
|
idx.write(f"Source: <{origin_url}><br/>\n")
|
|
version = scheme["metadata"].get("wezterm_version", None)
|
|
if version and version != "Always":
|
|
idx.write(f"{{{{since('{version}')}}}}<br/>\n")
|
|
|
|
aliases = scheme["metadata"]["aliases"]
|
|
if len(aliases) > 0:
|
|
alias_list = []
|
|
for a in aliases:
|
|
alias_list.append(f"`{a}`")
|
|
aliases = ", ".join(alias_list)
|
|
idx.write(f"This scheme is also known as {aliases}.<br/>\n")
|
|
|
|
idx.write("\nTo use this scheme, add this to your config:\n")
|
|
idx.write(
|
|
f"""
|
|
```lua
|
|
config.color_scheme = '{title}'
|
|
```
|
|
|
|
"""
|
|
)
|
|
|
|
idents_to_load = json.dumps(idents_to_load)
|
|
idx.write(
|
|
f"""
|
|
<script>
|
|
document.addEventListener("DOMContentLoaded", function() {{
|
|
{idents_to_load}.forEach(ident => load_scheme_player(ident));
|
|
}});
|
|
</script>
|
|
"""
|
|
)
|
|
|
|
index_filename = f"{self.dirname}/index.md"
|
|
index_page = Page(self.title, index_filename, children=children)
|
|
index_page.render(output, depth, mode)
|
|
|
|
with open(f"{self.dirname}/index.md", "w") as idx:
|
|
idx.write(f"{len(scheme_data)} Color schemes listed by first letter\n\n")
|
|
for page in children:
|
|
upper = page.title.upper()
|
|
idx.write(f" - [{upper}]({page.title}/index.md)\n")
|
|
|
|
|
|
TOC = [
|
|
Page(
|
|
"WezTerm",
|
|
"index.md",
|
|
children=[
|
|
Page("Features", "features.md"),
|
|
Page("Scrollback", "scrollback.md"),
|
|
Page("Quick Select Mode", "quickselect.md"),
|
|
Page("Copy Mode", "copymode.md"),
|
|
Page("Hyperlinks", "hyperlinks.md"),
|
|
Page("Shell Integration", "shell-integration.md"),
|
|
Page("iTerm Image Protocol", "imgcat.md"),
|
|
Page("SSH", "ssh.md"),
|
|
Page("Serial Ports & Arduino", "serial.md"),
|
|
Page("Multiplexing", "multiplexing.md"),
|
|
],
|
|
),
|
|
Page(
|
|
"Download",
|
|
"installation.md",
|
|
children=[
|
|
Page("Windows", "install/windows.md"),
|
|
Page("macOS", "install/macos.md"),
|
|
Page("Linux", "install/linux.md"),
|
|
Page("FreeBSD", "install/freebsd.md"),
|
|
Page("Build from source", "install/source.md"),
|
|
],
|
|
),
|
|
Page(
|
|
"Configuration",
|
|
"config/files.md",
|
|
children=[
|
|
Page("Colors & Appearance", "config/appearance.md"),
|
|
Page("Launching Programs", "config/launch.md"),
|
|
Page("Fonts", "config/fonts.md"),
|
|
Page("Font Shaping", "config/font-shaping.md"),
|
|
Page("Keyboard Concepts", "config/keyboard-concepts.md"),
|
|
Page("Key Binding", "config/keys.md"),
|
|
Page("Key Tables", "config/key-tables.md"),
|
|
Page("Default Key Assignments", "config/default-keys.md"),
|
|
Page("Keyboard Encoding", "config/key-encoding.md"),
|
|
Page("Mouse Binding", "config/mouse.md"),
|
|
GenColorScheme("Color Schemes", "colorschemes"),
|
|
Gen("Recipes", "recipes", extract_title=True),
|
|
],
|
|
),
|
|
Page(
|
|
"Full Config & Lua Reference",
|
|
"config/lua/general.md",
|
|
children=[
|
|
Gen(
|
|
"Config Options",
|
|
"config/lua/config",
|
|
),
|
|
Gen(
|
|
"module: wezterm",
|
|
"config/lua/wezterm",
|
|
),
|
|
Gen(
|
|
"module: wezterm.color",
|
|
"config/lua/wezterm.color",
|
|
),
|
|
Gen(
|
|
"module: wezterm.gui",
|
|
"config/lua/wezterm.gui",
|
|
),
|
|
Gen(
|
|
"module: wezterm.mux",
|
|
"config/lua/wezterm.mux",
|
|
),
|
|
Gen(
|
|
"module: wezterm.procinfo",
|
|
"config/lua/wezterm.procinfo",
|
|
),
|
|
Gen(
|
|
"module: wezterm.time",
|
|
"config/lua/wezterm.time",
|
|
),
|
|
Gen(
|
|
"module: wezterm.url",
|
|
"config/lua/wezterm.url",
|
|
),
|
|
Gen(
|
|
"enum: KeyAssignment",
|
|
"config/lua/keyassignment",
|
|
),
|
|
Gen(
|
|
"enum: CopyModeAssignment",
|
|
"config/lua/keyassignment/CopyMode",
|
|
),
|
|
Gen("object: Color", "config/lua/color"),
|
|
Page("object: ExecDomain", "config/lua/ExecDomain.md"),
|
|
Page("object: LocalProcessInfo", "config/lua/LocalProcessInfo.md"),
|
|
Gen("object: MuxDomain", "config/lua/MuxDomain"),
|
|
Gen("object: MuxWindow", "config/lua/mux-window"),
|
|
Gen("object: MuxTab", "config/lua/MuxTab"),
|
|
Page("object: PaneInformation", "config/lua/PaneInformation.md"),
|
|
Page("object: TabInformation", "config/lua/TabInformation.md"),
|
|
Page("object: SshDomain", "config/lua/SshDomain.md"),
|
|
Page("object: SpawnCommand", "config/lua/SpawnCommand.md"),
|
|
Gen("object: Time", "config/lua/wezterm.time/Time"),
|
|
Page("object: TlsDomainClient", "config/lua/TlsDomainClient.md"),
|
|
Page("object: TlsDomainServer", "config/lua/TlsDomainServer.md"),
|
|
Gen(
|
|
"object: Pane",
|
|
"config/lua/pane",
|
|
),
|
|
Gen(
|
|
"object: Window",
|
|
"config/lua/window",
|
|
),
|
|
Page("object: WslDomain", "config/lua/WslDomain.md"),
|
|
Gen(
|
|
"events: Gui",
|
|
"config/lua/gui-events",
|
|
),
|
|
Gen(
|
|
"events: Multiplexer",
|
|
"config/lua/mux-events",
|
|
),
|
|
Gen(
|
|
"events: Window",
|
|
"config/lua/window-events",
|
|
),
|
|
],
|
|
),
|
|
Page(
|
|
"CLI Reference",
|
|
"cli/general.md",
|
|
children=[
|
|
Gen("wezterm cli", "cli/cli"),
|
|
Page("wezterm connect", "cli/connect.md"),
|
|
Page("wezterm imgcat", "cli/imgcat.md"),
|
|
Page("wezterm ls-fonts", "cli/ls-fonts.md"),
|
|
Page("wezterm record", "cli/record.md"),
|
|
Page("wezterm replay", "cli/replay.md"),
|
|
Page("wezterm serial", "cli/serial.md"),
|
|
Page("wezterm set-working-directory", "cli/set-working-directory.md"),
|
|
Page("wezterm show-keys", "cli/show-keys.md"),
|
|
Page("wezterm ssh", "cli/ssh.md"),
|
|
Page("wezterm start", "cli/start.md"),
|
|
],
|
|
),
|
|
Page(
|
|
"Reference",
|
|
None,
|
|
children=[
|
|
Page("Escape Sequences", "escape-sequences.md"),
|
|
Page("What is a Terminal?", "what-is-a-terminal.md"),
|
|
],
|
|
),
|
|
Page(
|
|
"Get Help",
|
|
None,
|
|
children=[
|
|
Page("Troubleshooting", "troubleshooting.md"),
|
|
Page("F.A.Q.", "faq.md"),
|
|
Page("Getting Help", "help.md"),
|
|
Page("Contributing", "contributing.md"),
|
|
],
|
|
),
|
|
Page("Change Log", "changelog.md"),
|
|
Page("Sponsor", "sponsor.md"),
|
|
]
|
|
|
|
os.chdir("docs")
|
|
|
|
with open("../mkdocs.yml", "w") as f:
|
|
f.write("# this is auto-generated by docs/generate-toc.py, do not edit\n")
|
|
f.write("INHERIT: docs/mkdocs-base.yml\n")
|
|
f.write("nav:\n")
|
|
for page in TOC:
|
|
page.render(f, depth=1, mode="mkdocs")
|
|
|
|
|
|
with open("SUMMARY.md", "w") as f:
|
|
f.write("[root](index.md)\n")
|
|
for page in TOC:
|
|
page.render(f, depth=1, mode="mdbook")
|