wezterm ls-fonts --list-system's real output is a ready-to-paste code
snippet per font (`wezterm.font("Name", {weight=...}) -- (AKA: ...)
path, DirectWrite`), not a bare quoted family name. The picker's
fallback branch treated any non-matching line as a literal font name,
so selecting one of these snippet entries wrote its full text --
including a literal "})" substring from the embedded example call --
into config.font, corrupting the file (confirmed against a user's
actual .wezterm.lua that failed to parse after picking a Korean font
this way).
Fixed the parser to only accept `wezterm.font("Name"` lines (or a
bare quoted string) and extract just the family name, dropping
anything else instead of guessing. Also anchored get_current_fonts and
set_fonts's block-matching patterns to require the closing "})" be on
its own line, so a stray "})" embedded inside a font value can no
longer be mistaken for the block's real end.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
wezterm ls-fonts --list-system runs synchronously and blocks the UI
thread while it walks every installed font, which happens right after
the previous menu overlay closes -- during that gap the underlying
shell was briefly visible before the font picker rendered. Caching the
parsed result means the blocking call only happens once; gui-startup
also warms the cache immediately so even the first font settings visit
in a session is instant.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
show_font_picker runs `wezterm ls-fonts --list-system` via
wezterm.run_child_process, parses out unique font family names, and
presents them through the existing fuzzy InputSelector so English/
Korean font menu entries no longer require typing an exact,
correctly-spelled font name. A "직접 입력..." choice at the top falls
back to the previous free-text prompt_font flow, also used
automatically if the font list can't be retrieved.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
window_decorations = "INTEGRATED_BUTTONS | RESIZE" drops the separate
OS title bar and draws minimize/maximize/close directly in the fancy
tab bar strip instead, now that use_fancy_tab_bar is enabled.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Alt+Left-click never reached our show-main-menu binding because
WezTerm's own default mouse bindings already claim ALT+drag on a
pane as the start of rectangular/block text selection, swallowing
the click before our handler saw it. Rebound the menu trigger to
Ctrl+Shift+Left-click, which isn't claimed by any default gesture,
and updated the status bar hint text to match.
- use_fancy_tab_bar = true: the retro (lightweight) tab bar has no
per-tab close button at all; the native/OS-style bar shows a
hover close (x) button per tab and supports dragging a tab out of
the strip to pop it into its own window (the closest native
equivalent to an explicit "open in new window" button).
- format-tab-title now renders just the terminal/process name instead
of "index: name [domain]" -- shorter titles leave the native tab
bar's close button room to render, and per-host color-coding already
conveys the domain without needing it spelled out in text.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
notify() now accepts an optional duration override; the SSH domain
save/update toasts use it to stay up 10s (vs the default 4s) and lead
with a bold warning that connecting immediately will fail and
wezterm-gui.exe needs a full restart (Task Manager End Task, not just
reload) before the new/edited domain is usable.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
config.font is set via wezterm.font_with_fallback({ primary, korean }),
a multi-line block that the existing single-line set_config_value
can't touch. Added get_current_fonts (reads both font names straight
out of the config file text, for display) and set_fonts (replaces the
whole font_with_fallback body in one shot, lazy-matched between the
"{" and the closing "})"), plus two new font settings menu entries
("영어 폰트" / "한글 폰트") that prompt for one name at a time while
keeping the other font unchanged.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Without it, WezTerm tries to run its own mux protocol over the SSH
session (spawning `wezterm cli --prefer-mux proxy` on the remote),
which fails with "Please install the same version of wezterm on both
the client and server" whenever the remote host doesn't have wezterm
installed -- the case for a plain SSH target. multiplexing = "None"
makes the domain behave like a normal SSH terminal instead.
update_ssh_domain's match pattern is now a lazy "match to the next
closing brace" instead of assuming an exact 3-field shape, so it can
still find and replace entries saved before this change (without the
multiplexing field) as well as ones saved after.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- SSH domain add flow gains a 4th, optional "port" step; a non-empty
port is appended to remote_address as "host:port" (WezTerm's native
way to specify a non-default SSH port), matching how existing
entries are parsed back out via the new split_remote_address helper.
- New "SSH 도메인 수정" entry in connection settings lists existing
config.ssh_domains entries; picking one re-prompts each field
(name/address/port/username) with the current value shown in the
description, where leaving a field blank keeps the old value instead
of cancelling (unlike the add flow, where blank cancels).
- update_ssh_domain locates the exact entry block by its original name
(pattern built from append_ssh_domain's fixed write format, escaped
for Lua pattern safety) and replaces it wholesale, so a rename is
just "old name matched, new block written".
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
config.ssh_domains is only registered into wezterm's mux domain list
at process startup; ReloadConfiguration picks up simple value changes
(font, colors, etc.) but does not re-register newly added ssh domains.
Selecting a freshly-saved domain from the main menu before a full
restart fails with "domain name ... is invalid" since it's absent
from the mux's domain list. Updated the save notification to tell the
user a restart (not just reload) is required.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Main menu now lists each registered config.ssh_domains entry as a
choice (selecting one spawns a tab attached to that SSH domain via
SpawnTab), with a single "설정" entry below them that opens what used
to be the main menu (font/connection/other settings, launcher,
reload) -- renamed to show_settings_menu.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The real bug was the invalid initial_value field (fixed previously),
not Enter bleed-through from InputSelector. The defer-via-status-tick
workaround left a gap (up to the status update interval) between the
InputSelector closing and the PromptInputLine actually capturing
keyboard input -- during that gap the underlying shell was visible
(the reported flash) and any keystrokes typed during it went to the
shell instead of the field. This is especially damaging for the
3-step SSH domain flow, where hitting the gap on any step submits an
empty line and the whole entry is silently cancelled without saving.
Calling perform_action synchronously, as before the call_after/defer
detour, removes the gap entirely.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The user's WezTerm build (20240203-110809) rejects `initial_value` as a
PromptInputLine field (only `action`/`description` are valid on that
version), so constructing the action errored out immediately and the
whole callback died silently -- the prompt never appeared and the
underlying shell showed through. Current values are now shown inline
in the description text instead.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Deferring the PromptInputLine open by one tick via wezterm.time.call_after
did not fix the InputSelector -> PromptInputLine chaining issue on the
user's WezTerm build (the box never appeared at all, straight back to the
shell) — consistent with call_after being unavailable/erroring and silently
aborting the callback. Replaced it with a pending_action flag drained on the
next update-right-status tick, an event hook already confirmed working via
the existing status bar, removing the dependency on wezterm.time entirely.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Selecting a settings item from an InputSelector menu (font size, line height,
color scheme, opacity, scrollback lines, max FPS, SSH domain add) would open
a PromptInputLine that closed instantly, dumping back to the shell — the
Enter that confirmed the InputSelector choice was bleeding into the newly
opened PromptInputLine. Deferring the PromptInputLine open by one tick via
wezterm.time.call_after fixes it. SSH domain registration now asks for name,
address, and username one at a time instead of a single comma-separated line.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>