Fix font list parser producing garbage entries that corrupted config.font

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>
This commit is contained in:
2026-07-18 01:43:38 +09:00
parent 8afe869b02
commit d7eb6d3459

View File

@@ -229,7 +229,7 @@ local function get_current_fonts()
return nil, nil
end
local block = text:match("config%.font = wezterm%.font_with_fallback%(%{(.-)%}%)")
local block = text:match("config%.font = wezterm%.font_with_fallback%(%{(.-)\n%}%)")
if not block then
return nil, nil
end
@@ -250,7 +250,7 @@ local function set_fonts(window, pane, primary, korean)
local new_block = string.format('\n\t%q, -- 영어/기본 폰트\n\t%q, -- 한글 폰트\n', primary, korean)
local safe_block = new_block:gsub("%%", "%%%%")
local updated, count = text:gsub("(config%.font = wezterm%.font_with_fallback%(%{).-(%}%))", "%1" .. safe_block .. "%2", 1)
local updated, count = text:gsub("(config%.font = wezterm%.font_with_fallback%(%{).-\n(%}%))", "%1" .. safe_block .. "%2", 1)
if count == 0 then
notify(window, "config.font 설정을 찾지 못했습니다")
@@ -308,10 +308,14 @@ local function list_system_fonts()
return nil
end
-- 실제 출력은 `wezterm.font("이름", {weight=...}) -- (AKA: ...) 경로, DirectWrite` 형태의
-- 코드 스니펫이라, 그 안의 family 이름만 뽑아낸다. 이 패턴에 안 맞는 줄은 그대로 버린다
-- (예전에는 안 맞는 줄을 통째로 "이름"으로 취급해서, 그 스니펫 텍스트 안에 있던 "})"가
-- config.font 블록 편집 시 조기 종료를 일으켜 설정 파일이 깨지는 사고가 있었다)
local seen = {}
local fonts = {}
for line in stdout:gmatch("[^\r\n]+") do
local name = line:match('^"([^"]+)"') or line:match("^%s*(.-)%s*$")
local name = line:match('wezterm%.font%("([^"]+)"') or line:match('^"([^"]+)"')
if name and name ~= "" and not seen[name] then
seen[name] = true
table.insert(fonts, name)