-- =========================================================
-- WezTerm Configuration (v2 - 검증본)
-- Windows / macOS / Linux 공통 | 한국어 + 영어 최적화
--
-- 설치 위치 (세 OS 모두 홈 디렉토리):
-- Windows : %USERPROFILE%\.wezterm.lua
-- macOS : /Users/<사용자명>/.wezterm.lua
-- Linux : /home/<사용자명>/.wezterm.lua
--
-- 검증 기준: wezterm.org 공식 문서 (config/default-keys, fonts,
-- keys, window_decorations, files)
-- =========================================================
local wezterm = require 'wezterm'
local act = wezterm.action
local config = wezterm.config_builder()
-- ---------------------------------------------------------
-- 1. 플랫폼 판별
-- ---------------------------------------------------------
local triple = wezterm.target_triple
local is_windows = triple:find('windows') ~= nil
local is_mac = triple:find('darwin') ~= nil
local is_linux = triple:find('linux') ~= nil
-- 파일 존재 확인.
-- [주의] wezterm.run_child_process 는 프로그램이 없을 때 false 를 반환하지 않고
-- Lua 에러를 던진다("No such file or directory"). 설정 최상위에서
-- 이를 쓰면 창 대신 Configuration Error 가 뜬다. 따라서 사용하지 않는다.
-- io.open 은 실패 시 nil 을 돌려주므로 안전하고 프로세스도 띄우지 않는다.
local function file_exists(path)
local ok, f = pcall(io.open, path, 'r')
if ok and f then f:close(); return true end
return false
end
-- WezTerm 빌드 날짜 비교 (예: '20240203-110809-...' -> 20240203)
-- 신버전 전용 옵션을 구버전에서 켜면 설정 전체가 로드 실패하므로 게이트가 필요하다.
local BUILD = tonumber(tostring(wezterm.version):match('^(%d%d%d%d%d%d%d%d)') or '0') or 0
local function build_at_least(d) return BUILD >= d end
-- 여러 후보 경로 중 처음 존재하는 것을 반환 (없으면 nil)
local function first_existing(paths)
for _, p in ipairs(paths) do
if file_exists(p) then return p end
end
return nil
end
-- ---------------------------------------------------------
-- 2. 폰트 : 영문 주폰트 + 한글 폴백
-- WezTerm은 지정한 목록 뒤에 Nerd Font Symbols 등
-- 자체 기본 폴백을 자동 추가하므로 따로 나열할 필요 없음
-- ---------------------------------------------------------
local cjk_font
if is_windows then
cjk_font = 'Malgun Gothic' -- 윈도우 기본 탑재
elseif is_mac then
cjk_font = 'Apple SD Gothic Neo' -- macOS 기본 탑재
else
cjk_font = 'Noto Sans Mono CJK KR'
end
-- [정정] 이전 버전에서 CJK 폰트에 scale=1.33 을 넣었으나 이는 잘못이었다.
-- 한글 x_adv 가 셀폭보다 작은 것은 결함이 아니라 폰트의 의도된 좌우 여백이다.
-- 1.33 배로 강제 확대하면 글리프가 픽셀 격자에서 벗어나 힌팅이 깨지고
-- 화면이 뿌옇게 흐려진다. 크기 조절은 scale 이 아니라 font_size 로 해야 한다.
config.font = wezterm.font_with_fallback {
-- 'JetBrains Mono' 는 WezTerm 내장 폰트라 설치가 필요 없고,
-- Nerd Font 아이콘은 내장 'Symbols Nerd Font Mono' 가 자동 폴백된다.
{ family = 'JetBrains Mono' },
{ family = 'D2Coding' }, -- 한글 고정폭. 설치돼 있으면 우선 사용
{ family = cjk_font }, -- OS 기본 한글 폰트
'Noto Color Emoji',
}
-- 크기: 기본 12 에서 한 단계 낮춘 11 을 기본값으로 둔다.
-- 크게 쓰고 싶으면 이 값만 12~13 으로 올릴 것 (scale 은 건드리지 말 것)
config.font_size = is_mac and 13.0 or 11.0
-- [중요] 탭바·명령팔레트 같은 UI 요소는 config.font 가 아니라 각자 폰트를 쓴다.
-- 단일 폰트만 지정하면 한글 탭 이름이 두부(□)로 렌더된다.
-- UI 전용 폴백 체인을 만들어 모든 UI 폰트에 공통으로 넘긴다.
local function ui_font(weight)
return wezterm.font_with_fallback {
{ family = 'JetBrains Mono', weight = weight or 'Regular' },
{ family = 'D2Coding' },
{ family = cjk_font },
'Noto Color Emoji',
}
end
config.line_height = 1.1
config.cell_width = 1.0
-- CJK 폰트는 cap-height 지표가 부정확하므로 자동 스케일링을 끈다
config.use_cap_height_to_scale_fallback_fonts = false
config.warn_about_missing_glyphs = false
-- 글자 선명도.
-- Windows/Linux LCD 모니터에서는 서브픽셀 렌더링(HorizontalLcd)이 가장 또렷하다.
-- 색 번짐(빨강/파랑 테두리)이 보이면 'Normal' 로 바꿀 것.
-- macOS 는 Retina 라 Normal 이 자연스럽다.
if is_mac then
config.freetype_load_target = 'Normal'
config.freetype_render_target = 'Normal'
else
config.freetype_load_target = 'Light'
config.freetype_render_target = 'HorizontalLcd'
end
config.adjust_window_size_when_changing_font_size = false
-- ---------------------------------------------------------
-- 3. 한국어 처리 (★ 핵심)
-- ---------------------------------------------------------
-- 한글 입력기(IME) 활성화
config.use_ime = true
-- macOS 는 한글 파일명을 NFD(자모 분리)로 저장한다.
-- 이 옵션이 없으면 ls 결과가 "ㅎㅏㄴㄱㅡㄹ" 처럼 분리되어 보인다.
config.normalize_output_to_unicode_nfc = true
-- 동아시아 애매폭 문자(─ │ ┌ ● ★ 등)를 2칸으로 처리할지 여부.
-- tree / htop / 박스 그리기가 어긋나면 true 로 바꿔 볼 것.
-- 반대로 이미 잘 나오는데 true 로 두면 오히려 어긋나므로 기본은 false.
config.treat_east_asian_ambiguous_width_as_wide = false
-- ---------------------------------------------------------
-- 4. 외관
-- ---------------------------------------------------------
-- =========================================================
-- 밝은 테마 (눈에 편한 따뜻한 오프화이트)
--
-- [배경 선택 근거]
-- 순백(#ffffff, 휘도 255)은 눈부심이 크다. 여기서는 휘도 238의
-- 따뜻한 미색을 쓴다. 밝지만 눈이 덜 피로하다.
--
-- [ANSI 색을 직접 정의한 이유]
-- 내장 밝은 테마 20종을 전수 측정한 결과 ANSI 색 최저 대비가
-- 최고 2.11, 대부분 1.0~1.6 으로 WCAG AA(4.5)에 한참 못 미쳤다.
-- (밝은 배경 위에 밝은 색을 올리니 구조적으로 안 나온다)
-- 그래서 Gruvbox Light 색상을 기준으로 색조·채도는 유지한 채
-- 명도만 낮춰 모든 색이 4.5 이상이 되도록 재계산했다.
-- bright 계열은 7.0 이상으로 맞춰 굵은 글씨가 8/8 구분된다.
-- =========================================================
local P = {
bg = '#f6eeda', -- 배경 (휘도 238)
fg = '#3c3836', -- 전경 (대비 10.03)
accent = '#1d69ce', -- 파랑 강조 (4.58)
warn = '#8e6516', -- 주황 강조 (4.51)
tab_bar = '#e7e0cd', -- 탭바 배경
tab_ina = '#6d6258', -- 비활성 탭 글자 (4.51)
popup_bg = '#fbf7ee', -- 팝업 배경 (글자 대비 10.84)
thumb = '#b1ab9d', -- 스크롤바
sel_bg = '#c6d1d7', -- 선택 영역 (글자 대비 7.46)
dim = '#5a5048', -- 보조 텍스트 (탭바 위 대비 5.96)
chip = '#b5a98c', -- 상태줄 칩 (탭바와 구분 1.77 / 글자 대비 4.98)
}
config.color_schemes = {
['Warm Light AA'] = {
background = P.bg,
foreground = P.fg,
cursor_bg = P.accent,
cursor_fg = P.bg,
cursor_border = P.accent,
selection_bg = P.sel_bg,
selection_fg = P.fg,
-- 검정 빨강 초록 노랑 파랑 자홍 청록 흰색
ansi = { '#282828','#cc241d','#707013','#8e6516','#3d7578','#9c5676','#4e7650','#5f5750' },
brights = { '#6d6258','#9b1b16','#52520e','#684a10','#2d5558','#723f56','#39563a','#3c3836' },
},
}
config.color_scheme = 'Warm Light AA'
-- 투명도는 밝은 테마에서 특히 대비를 크게 깎는다. 불투명 유지.
config.window_background_opacity = 1.0
-- 세 OS 모두 TITLE|RESIZE 로 통일한다.
-- RESIZE 단독 -> 타이틀바 없음. 탭 1개면 탭바도 숨겨져 창 이동 불가
-- INTEGRATED_BUTTONS 단독 -> 창 버튼이 탭바에 들어가므로 위와 같은 문제 발생
config.window_decorations = 'TITLE|RESIZE'
-- [렌더링] 화면 찢김(가로 흰줄)과 랙의 주원인은 GPU 어댑터 선택 실패다.
-- 노트북처럼 GPU 가 여러 개인 환경에서 WezTerm 이 소프트웨어 렌더러나
-- 엉뚱한 어댑터를 잡으면 프레임이 밀리고 가로줄이 생긴다.
-- 우선순위: Dx12/Metal > Vulkan > OpenGL, 외장 > 내장 (Cpu 는 제외)
local function pick_gpu()
local ok, gpus = pcall(function() return wezterm.gui.enumerate_gpus() end)
if not ok or type(gpus) ~= 'table' then return nil end
local backend_rank = { Dx12 = 40, Metal = 40, Vulkan = 30, Gl = 10 }
local device_rank = { DiscreteGpu = 3, IntegratedGpu = 2, Other = 1, Cpu = 0 }
local best, best_score = nil, 0
for _, g in ipairs(gpus) do
local d = device_rank[tostring(g.device_type)] or 0
if d > 0 then
local score = (backend_rank[tostring(g.backend)] or 0) + d
if score > best_score then best, best_score = g, score end
end
end
return best
end
local gpu = pick_gpu()
if gpu then
config.front_end = 'WebGpu'
config.webgpu_preferred_adapter = gpu
config.webgpu_power_preference = 'HighPerformance'
else
config.front_end = 'OpenGL'
end
config.max_fps = 120
config.enable_kitty_keyboard = false
if is_mac then
config.macos_window_background_blur = 0
end
config.window_padding = { left = 12, right = 12, top = 10, bottom = 8 }
config.window_close_confirmation = 'AlwaysPrompt'
-- 스크롤백은 패널마다 따로 잡힌다. 분할을 자주 하면 그만큼 메모리와
-- 초기화 비용이 늘어난다. 10000 줄이면 실사용에 충분하다.
config.scrollback_lines = 10000
config.enable_scroll_bar = true
config.default_cursor_style = 'SteadyBar'
config.cursor_blink_rate = 0
config.cursor_blink_ease_in = 'Constant'
config.cursor_blink_ease_out = 'Constant'
config.audible_bell = 'Disabled'
-- 밝은 테마에서는 밝기를 낮추면 오히려 대비가 살짝 올라간다(10.03 -> 8.95).
-- 채도만 조금 빼서 비활성 패널을 '바래 보이게' 하는 편이 자연스럽다.
config.inactive_pane_hsb = { saturation = 0.75, brightness = 0.97 }
config.hide_mouse_cursor_when_typing = true
-- ---- 사용 편의 ----
-- 탭바 위에서 마우스 휠 -> 탭 전환
config.mouse_wheel_scrolls_tabs = true
-- 다른 창에서 넘어오며 클릭할 때, 그 클릭이 터미널로 전달되지 않게 한다
config.swallow_mouse_click_on_window_focus = true
-- 셸만 돌고 있으면 탭/창을 닫을 때 확인창을 띄우지 않는다.
-- 실행 중인 작업(vim, ssh 등)이 있을 때만 물어본다.
config.skip_close_confirmation_for_processes_named = {
'bash', 'sh', 'zsh', 'fish', 'tmux',
'cmd.exe', 'pwsh.exe', 'powershell.exe',
}
-- 비밀번호 입력 중이면 커서 모양으로 알려준다
config.detect_password_input = true
-- 키를 누르면 스크롤 위치를 맨 아래로 되돌린다
config.scroll_to_bottom_on_input = true
-- 파일을 창에 끌어다 놓으면 경로에 따옴표를 씌워준다 (공백/한글 경로 대응)
config.quote_dropped_files = is_windows and 'Windows' or 'Posix'
-- 팝업 UI 도 테마에 맞춘다. 지정 안 하면 밝은 회색 창이 튀어나온다.
config.command_palette_bg_color = P.popup_bg
config.command_palette_fg_color = P.fg
config.command_palette_font_size = is_mac and 13.0 or 11.0
config.command_palette_rows = 14
config.char_select_bg_color = P.popup_bg
config.char_select_fg_color = P.fg
config.char_select_font_size = is_mac and 13.0 or 11.0
-- [주의] *_font_size 는 구버전에도 있지만 *_font 는 신버전 전용이다.
-- 구버전(20240203)에 지정하면 설정 전체가 로드 실패한다 — 실측으로 확인했다.
-- 지원하는 빌드에서만 한글 폴백 폰트를 넘긴다.
if build_at_least(20240301) then
config.command_palette_font = ui_font()
config.char_select_font = ui_font()
config.pane_select_font = ui_font('Bold')
end
-- 패널 전환 시 확대 상태 자동 해제 (확대된 채 이동하면 혼란)
config.unzoom_on_switch_pane = true
-- 상태 표시줄 갱신 주기(ms)
config.status_update_interval = 1000
-- 패키지 매니저로 설치했다면 앱 내부 업데이트 알림은 방해다
config.check_for_updates = false
config.show_update_window = false
-- 탭바
-- [중요] 탭별 닫기(x) 버튼은 fancy 탭바에서만 그려진다.
-- use_fancy_tab_bar = false(레트로)로 두면 닫기 버튼이 아예 없다.
-- show_close_tab_button_in_tabs 는 기본값이 true 라 따로 켤 필요는 없다.
config.use_fancy_tab_bar = true
config.tab_bar_at_bottom = false -- 탭바를 창 위쪽에
config.hide_tab_bar_if_only_one_tab = false -- 탭 1개여도 계속 표시
-- 탭 제목이 폭을 다 먹으면 오른쪽 닫기(x) 버튼이 잘려 안 보인다.
-- 제목은 짧게 자르고 탭 폭은 넉넉히 준다.
config.tab_max_width = 36
-- 닫기 버튼은 기본값이 true 지만, 구버전에는 이 옵션 자체가 없어
-- 그냥 쓰면 설정 로드가 통째로 실패한다. 지원하는 빌드에서만 명시한다.
if build_at_least(20240301) then
config.show_close_tab_button_in_tabs = true
end
config.show_new_tab_button_in_tab_bar = true -- + 버튼 (동작은 아래에서 분할로 바꿈)
config.show_tab_index_in_tab_bar = true
config.switch_to_last_active_tab_when_closing_tab = true -- 탭 닫으면 직전 탭으로
-- fancy 탭바는 탭 '바깥' 영역을 window_frame 으로 그린다.
-- 여기를 안 맞추면 탭바만 회색으로 떠 보인다.
config.window_frame = {
font = ui_font('Bold'), -- 한글 탭 이름 대응
font_size = is_mac and 12.0 or 10.0,
active_titlebar_bg = P.tab_bar,
inactive_titlebar_bg = P.tab_bar,
active_titlebar_fg = P.fg,
inactive_titlebar_fg = P.dim,
button_bg = P.tab_bar,
button_fg = P.fg,
button_hover_bg = P.accent,
button_hover_fg = P.bg,
}
-- use_fancy_tab_bar = false 일 때 탭바는 테마 색을 따라가지 않으므로
-- ayu 팔레트에 맞춰 직접 지정한다 (지정하지 않으면 회색 기본값과 충돌)
config.colors = {
-- 스크롤바 손잡이 (배경 대비 1.98 — 은은하게 보이는 정도)
scrollbar_thumb = P.thumb,
-- 패널 분할선. 지정 안 하면 밝은 배경에 묻혀 화면이 나뉜 게 안 보인다.
split = P.accent,
-- 한글 IME 조합 중 커서 색 (조합 중/확정 구분)
compose_cursor = P.warn,
-- 복사 모드 선택 강조
copy_mode_active_highlight_bg = { Color = P.accent },
copy_mode_active_highlight_fg = { Color = P.bg },
copy_mode_inactive_highlight_bg = { Color = P.sel_bg },
copy_mode_inactive_highlight_fg = { Color = P.fg },
-- 퀵셀렉트(LEADER+e) 라벨
quick_select_label_bg = { Color = P.warn },
quick_select_label_fg = { Color = P.bg },
quick_select_match_bg = { Color = P.sel_bg },
quick_select_match_fg = { Color = P.fg },
tab_bar = {
-- [실측] 활성탭 글자 4.58 / 비활성탭 글자 4.51 / 배경 구분 4.02
background = P.tab_bar,
active_tab = {
bg_color = P.accent,
fg_color = P.bg,
intensity = 'Bold',
},
inactive_tab = {
bg_color = P.tab_bar,
fg_color = P.tab_ina,
},
inactive_tab_hover = {
bg_color = P.sel_bg,
fg_color = P.fg,
italic = false,
},
new_tab = {
bg_color = P.tab_bar,
fg_color = P.tab_ina,
},
new_tab_hover = {
bg_color = P.accent,
fg_color = P.bg,
intensity = 'Bold',
},
},
}
-- ---------------------------------------------------------
-- 5. 기본 셸 / 실행 메뉴
-- ---------------------------------------------------------
if is_windows then
-- PowerShell 7(pwsh)은 별도 설치 항목이다. 설치돼 있을 때만 기본 셸로 쓰고,
-- 없으면 윈도우에 항상 있는 powershell.exe 로 폴백한다.
local pwsh = first_existing {
'C:\\Program Files\\PowerShell\\7\\pwsh.exe',
'C:\\Program Files (x86)\\PowerShell\\7\\pwsh.exe',
(os.getenv('LOCALAPPDATA') or '') .. '\\Microsoft\\WindowsApps\\pwsh.exe',
(os.getenv('ProgramFiles') or '') .. '\\PowerShell\\7\\pwsh.exe',
}
if pwsh then
config.default_prog = { pwsh, '-NoLogo' }
else
config.default_prog = { 'powershell.exe', '-NoLogo' }
end
config.launch_menu = {
{ label = 'PowerShell 7', args = { 'pwsh.exe', '-NoLogo' } },
{ label = 'Windows PowerShell', args = { 'powershell.exe', '-NoLogo' } },
{ label = 'Command Prompt', args = { 'cmd.exe' } },
{ label = 'WSL', args = { 'wsl.exe', '~' } },
}
elseif is_linux then
config.launch_menu = {
{ label = 'bash', args = { 'bash', '-l' } },
{ label = 'zsh', args = { 'zsh', '-l' } },
}
end
-- ---------------------------------------------------------
-- 6. 키 바인딩
--
-- 설계 원칙:
-- (1) 창/탭/패널 조작은 전부 LEADER(Ctrl+A) 아래로 모은다.
-- -> 기본 키와 절대 충돌하지 않는 안전 지대
-- (2) 기본 키로 이미 되는 것은 다시 정의하지 않는다.
-- Ctrl+- / Ctrl+= / Ctrl+0 : 폰트 크기
-- Alt+Enter : 전체화면
-- Ctrl+Shift+C / V : 복사 / 붙여넣기
-- Ctrl+Shift+L : 디버그 오버레이 (문제 해결용, 덮지 말 것)
-- Ctrl+Shift+P : 명령 팔레트
-- Ctrl+Shift+Tab / Ctrl+Tab : 탭 이동
-- (3) ALT+문자 는 쓰지 않는다. 셸의 readline / vim 이 Meta 로 사용
-- ---------------------------------------------------------
config.leader = { key = 'a', mods = 'CTRL', timeout_milliseconds = 1000 }
config.keys = {
---------------- 패널 분할 ----------------
{ key = '\\', mods = 'LEADER', action = act.SplitHorizontal { domain = 'CurrentPaneDomain' } },
{ key = '-', mods = 'LEADER', action = act.SplitVertical { domain = 'CurrentPaneDomain' } },
---------------- 패널 이동 (vim 키) ----------------
{ key = 'h', mods = 'LEADER', action = act.ActivatePaneDirection 'Left' },
{ key = 'j', mods = 'LEADER', action = act.ActivatePaneDirection 'Down' },
{ key = 'k', mods = 'LEADER', action = act.ActivatePaneDirection 'Up' },
{ key = 'l', mods = 'LEADER', action = act.ActivatePaneDirection 'Right' },
---------------- 패널 크기 조정 ----------------
{ key = 'LeftArrow', mods = 'LEADER', action = act.AdjustPaneSize { 'Left', 5 } },
{ key = 'DownArrow', mods = 'LEADER', action = act.AdjustPaneSize { 'Down', 5 } },
{ key = 'UpArrow', mods = 'LEADER', action = act.AdjustPaneSize { 'Up', 5 } },
{ key = 'RightArrow', mods = 'LEADER', action = act.AdjustPaneSize { 'Right', 5 } },
---------------- 패널 제어 ----------------
{ key = 'z', mods = 'LEADER', action = act.TogglePaneZoomState },
{ key = 'x', mods = 'LEADER', action = act.CloseCurrentPane { confirm = true } },
{ key = 'q', mods = 'LEADER', action = act.PaneSelect { alphabet = 'asdfghjkl' } },
{ key = 'o', mods = 'LEADER', action = act.RotatePanes 'Clockwise' },
---------------- 탭 ----------------
{ key = 'c', mods = 'LEADER', action = act.SpawnTab 'CurrentPaneDomain' },
{ key = 'n', mods = 'LEADER', action = act.ActivateTabRelative(1) },
{ key = 'p', mods = 'LEADER', action = act.ActivateTabRelative(-1) },
-- '&' 같은 시프트 문자는 키보드 레이아웃에 따라 인식이 불안정하므로 'w' 사용
{ key = 'w', mods = 'LEADER', action = act.CloseCurrentTab { confirm = true } },
-- 탭 이름 변경. 빈 값으로 확인하면 자동 제목(디렉토리명)으로 되돌아간다.
{ key = ',', mods = 'LEADER', action = act.PromptInputLine {
description = '탭 이름 (빈 값 = 자동 제목으로 복귀):',
action = wezterm.action_callback(function(window, _, line)
if line == nil then return end -- Esc 로 취소한 경우
window:active_tab():set_title(line)
end),
},
},
---------------- 검색 / 복사 / 선택 ----------------
{ key = '[', mods = 'LEADER', action = act.ActivateCopyMode },
{ key = ']', mods = 'LEADER', action = act.PasteFrom 'Clipboard' },
{ key = 'f', mods = 'LEADER', action = act.Search { CaseInSensitiveString = '' } },
{ key = 'e', mods = 'LEADER', action = act.QuickSelect },
{ key = 'u', mods = 'LEADER', action = act.CharSelect },
---------------- 유틸 ----------------
{ key = 'm', mods = 'LEADER', action = act.ShowLauncher },
-- ---- 작업공간(세션) ----
-- 탭보다 상위 단위. 프로젝트별로 탭 묶음을 따로 둘 수 있다.
-- 목록에서 골라 전환 (퍼지 검색 지원)
{ key = 's', mods = 'LEADER', action = act.ShowLauncherArgs {
flags = 'FUZZY|WORKSPACES', title = '작업공간 선택' } },
-- 이름을 입력해 새로 만들거나 기존 것으로 전환
{ key = 'S', mods = 'LEADER|SHIFT', action = act.PromptInputLine {
description = '작업공간 이름 (없으면 새로 생성):',
action = wezterm.action_callback(function(window, pane, line)
if line and #line > 0 then
window:perform_action(act.SwitchToWorkspace { name = line }, pane)
end
end),
},
},
-- 현재 작업공간 이름 변경
-- ';' 사용: '$' 같은 시프트 문자는 키보드 레이아웃에 따라 인식이 불안정하다
{ key = ';', mods = 'LEADER', action = act.PromptInputLine {
description = '현재 작업공간의 새 이름:',
action = wezterm.action_callback(function(window, pane, line)
if line and #line > 0 then
wezterm.mux.rename_workspace(wezterm.mux.get_active_workspace(), line)
end
end),
},
},
-- ---- 탭 관리 ----
-- 탭이 많아지면 제목만으로 찾기 어렵다. 목록에서 골라 이동한다.
{ key = 't', mods = 'LEADER', action = act.ShowTabNavigator },
-- 탭 순서 바꾸기 ('<' '>' 같은 시프트 문자는 레이아웃 의존이라 화살표 사용)
{ key = 'LeftArrow', mods = 'LEADER|SHIFT', action = act.MoveTabRelative(-1) },
{ key = 'RightArrow', mods = 'LEADER|SHIFT', action = act.MoveTabRelative(1) },
-- [의도적으로 제거] LEADER+X 로 '확인 없이 탭 닫기'를 두었으나 삭제했다.
-- LEADER+x 는 패널을 '확인 후' 닫는다. 쉬프트 하나 차이로 탭 전체가
-- 확인 없이 사라지면 오조작 한 번에 작업을 잃는다.
-- 탭 닫기는 LEADER+w 하나로 통일한다. 셸만 떠 있을 때는
-- skip_close_confirmation_for_processes_named 덕분에 확인창이 뜨지 않는다.
-- [UX] 크기 조절 모드. LEADER 는 1초 뒤 풀리므로 반복 조절이 불편하다.
-- LEADER+r 로 모드에 들어가면 화살표/hjkl 을 계속 눌러 조절할 수 있고
-- Esc 또는 Enter 로 빠져나온다. 진행 중에는 상태줄에 모드가 표시된다.
-- until_unknown=true : 크기조절과 무관한 키를 누르면 모드가 자동으로 풀린다.
-- 이게 없으면 모드에 있는 줄 모르고 명령을 치다가 엉뚱하게 동작한다.
{ key = 'r', mods = 'LEADER', action = act.ActivateKeyTable {
name = 'resize_pane', one_shot = false,
timeout_milliseconds = 3000, until_unknown = true } },
{ key = 'K', mods = 'LEADER|SHIFT', action = act.ClearScrollback 'ScrollbackAndViewport' },
{ key = 'R', mods = 'LEADER|SHIFT', action = act.ReloadConfiguration },
{ key = 'd', mods = 'LEADER', action = act.ShowDebugOverlay },
---------------- Ctrl+A 원본을 셸로 전달 ----------------
-- Ctrl+A 를 두 번 누르면 '줄 맨 앞으로 이동'이 정상 동작
{ key = 'a', mods = 'LEADER|CTRL', action = act.SendKey { key = 'a', mods = 'CTRL' } },
}
-- LEADER + 1~9 로 탭 직접 이동
for i = 1, 9 do
table.insert(config.keys, {
key = tostring(i),
mods = 'LEADER',
action = act.ActivateTab(i - 1),
})
end
-- ---------------------------------------------------------
-- 7. 마우스 : Ctrl(mac은 Cmd) + 클릭으로 링크 열기
-- ---------------------------------------------------------
local link_mod = is_mac and 'CMD' or 'CTRL'
config.mouse_bindings = {
{
event = { Up = { streak = 1, button = 'Left' } },
mods = link_mod,
action = act.OpenLinkAtMouseCursor,
},
-- 누를 때의 클릭 이벤트가 셸로 새어나가지 않도록 차단
{
event = { Down = { streak = 1, button = 'Left' } },
mods = link_mod,
action = act.Nop,
},
}
-- ---------------------------------------------------------
-- 6-2. 모달 키 테이블 : 크기 조절 모드
-- LEADER+r 로 진입. 화살표 또는 hjkl 을 반복해서 누를 수 있다.
-- Esc / Enter / q 로 빠져나오며, 3초간 입력이 없어도 자동 해제된다.
-- ---------------------------------------------------------
config.key_tables = {
resize_pane = {
{ key = 'LeftArrow', action = act.AdjustPaneSize { 'Left', 3 } },
{ key = 'h', action = act.AdjustPaneSize { 'Left', 3 } },
{ key = 'DownArrow', action = act.AdjustPaneSize { 'Down', 3 } },
{ key = 'j', action = act.AdjustPaneSize { 'Down', 3 } },
{ key = 'UpArrow', action = act.AdjustPaneSize { 'Up', 3 } },
{ key = 'k', action = act.AdjustPaneSize { 'Up', 3 } },
{ key = 'RightArrow', action = act.AdjustPaneSize { 'Right', 3 } },
{ key = 'l', action = act.AdjustPaneSize { 'Right', 3 } },
{ key = 'Escape', action = 'PopKeyTable' },
{ key = 'Enter', action = 'PopKeyTable' },
{ key = 'q', action = 'PopKeyTable' },
},
}
-- ---------------------------------------------------------
-- 7-1. 상태 표시줄
-- [문제] LEADER(Ctrl+A)를 눌러도 화면에 아무 변화가 없어서
-- 눌렸는지 알 수 없고, 모드에 들어가 있는지도 보이지 않는다.
-- [해결] 왼쪽에 LEADER/모드 상태를, 오른쪽에 작업공간과 시간을 표시한다.
-- ---------------------------------------------------------
wezterm.on('update-status', function(window, pane)
local ok = pcall(function()
---------------- 왼쪽: 모드 표시 ----------------
local left = {}
local mode = window:active_key_table()
if mode == 'resize_pane' then
-- 크기 조절 모드: 주황색으로 강하게
left = {
{ Background = { Color = P.warn } },
{ Foreground = { Color = P.bg } },
{ Attribute = { Intensity = 'Bold' } },
{ Text = ' 크기조절 hjkl/화살표 Esc 종료 ' },
}
elseif window:leader_is_active() then
-- LEADER 대기 중: 청색
left = {
{ Background = { Color = P.accent } },
{ Foreground = { Color = P.bg } },
{ Attribute = { Intensity = 'Bold' } },
{ Text = ' LEADER ' },
}
else
left = { { Text = '' } }
end
window:set_left_status(wezterm.format(left))
---------------- 오른쪽: 작업공간 + 시간 ----------------
local right = {}
local ws = window:active_workspace()
if type(ws) == 'string' and #ws > 0 and ws ~= 'default' then
-- 이름이 길면 상태줄이 밀려 시간이 화면 밖으로 나간다. 폭 기준으로 자른다.
if wezterm.column_width(ws) > 16 then
ws = wezterm.truncate_right(ws, 15) .. '…'
end
right[#right + 1] = { Foreground = { Color = P.accent } }
right[#right + 1] = { Attribute = { Intensity = 'Bold' } }
right[#right + 1] = { Text = ' ' .. ws .. ' ' }
end
-- 확대된 패널이 있으면 알려준다 (확대 중인 걸 모르고 헤매는 일 방지)
local tab = window:active_tab()
for _, p in ipairs(tab:panes_with_info()) do
if p.is_zoomed then
right[#right + 1] = { Foreground = { Color = P.warn } }
right[#right + 1] = { Attribute = { Intensity = 'Bold' } }
right[#right + 1] = { Text = ' 확대중 ' }
break
end
end
-- [시인성] 이전에는 흐린 회색(#8a7f74)이라 탭바 위에서 대비 2.97 로
-- 거의 읽히지 않았다. 진한 글자(대비 8.80)에 배경 칩을 깔아 분리한다.
right[#right + 1] = { Background = { Color = P.chip } }
right[#right + 1] = { Foreground = { Color = P.fg } }
right[#right + 1] = { Attribute = { Intensity = 'Bold' } }
right[#right + 1] = { Text = wezterm.strftime(' %m/%d (%a) %H:%M ') }
window:set_right_status(wezterm.format(right))
end)
if not ok then
window:set_left_status('')
window:set_right_status('')
end
end)
-- ---------------------------------------------------------
-- 7-2. 탭바의 [+] 버튼을 "화면 분할" 버튼으로 바꾼다
--
-- 패널 1개일 때 좌클릭 : 좌우 반반으로 2분할
-- 패널 2개일 때 좌클릭 : 새 탭 생성 (더 쪼개지 않는다)
-- 우클릭 : 기본 동작(런처 메뉴) 유지
--
-- 3분할까지 가면 패널 하나의 폭이 좁아 코드와 로그가 접혀 읽기 어렵다.
-- 가로 분할은 2개까지만 하고 그 이상은 탭으로 넘긴다.
-- ---------------------------------------------------------
wezterm.on('new-tab-button-click', function(window, pane, button, default_action)
-- 좌클릭이 아니면 WezTerm 기본 동작에 맡긴다 (우클릭 = 런처 메뉴)
if button ~= 'Left' then return end
-- [성능 메모] 분할이 느리게 느껴지는 주된 원인은 이 핸들러가 아니라
-- 새 패널마다 셸 프로세스가 새로 뜨는 비용이다(측정: 핸들러 1회 0.004ms).
-- Windows PowerShell 은 프로필 로딩 때문에 특히 느리다.
-- 본인 환경 측정: Measure-Command { pwsh -NoLogo -Command exit }
-- 500ms 를 넘으면 프로필($PROFILE)을 정리하는 게 가장 효과적이다.
-- 아래 FAST_SPLIT 을 true 로 하면 분할된 패널은 프로필 없이 띄운다.
local FAST_SPLIT = false
local ok, err = pcall(function()
local tab = window:active_tab()
local count = #tab:panes()
local spawn = nil
if FAST_SPLIT and is_windows then
spawn = { args = { config.default_prog[1], '-NoLogo', '-NoProfile' } }
end
-- 확대(zoom) 상태에서는 분할이 어색하므로 먼저 해제
tab:set_zoomed(false)
if count == 1 then
-- 좌우 반반. 한 화면을 셋으로 쪼개면 각 폭이 좁아 코드/로그가 접힌다.
pane:split { direction = 'Right', size = 0.5, args = spawn and spawn.args or nil }
else
-- 3분할 이상이면 새 탭
if default_action then
window:perform_action(default_action, pane)
else
window:perform_action(act.SpawnTab 'CurrentPaneDomain', pane)
end
end
end)
if not ok then
wezterm.log_error('new-tab-button-click 실패: ' .. tostring(err))
end
-- 처리했음을 알려 기본 동작이 중복 실행되지 않게 한다
return false
end)
-- ---------------------------------------------------------
-- 8. 탭 제목 : 현재 디렉토리명 표시
-- current_working_dir 은 버전에 따라 Url 객체(userdata) 또는
-- 문자열을 반환하므로 양쪽 모두 처리한다
-- ---------------------------------------------------------
wezterm.on('format-tab-title', function(tab)
-- 이 핸들러는 매 렌더마다 호출된다. 여기서 예외가 나면 탭바 전체가
-- 그려지지 않으므로 전부 pcall 로 감싸고, 실패 시 최소 제목을 반환한다.
local ok, items = pcall(function()
local pane = tab.active_pane
---------------- 1. 제목 결정 ----------------
-- 우선순위: 사용자가 직접 지정한 이름 > 현재 디렉토리명 > 프로세스명
-- (tab_title 을 보지 않으면 이름을 바꿔도 즉시 덮어써진다)
local title
local manual = tab.tab_title
if manual and #manual > 0 then
title = manual
else
title = pane.title or 'shell'
local cwd = pane.current_working_dir
if cwd then
local path
if type(cwd) == 'string' then path = cwd else path = cwd.file_path or tostring(cwd) end
local name = path:gsub('[/\\]+$', ''):match('([^/\\]+)$')
if name and #name > 0 then title = name end
end
end
---------------- 2. 상태 수집 ----------------
-- 수동 이름을 쓰든 자동 제목을 쓰든 상태 표시는 동일하게 붙는다
local panes, zoomed, unseen = 1, false, false
if tab.panes then
panes = #tab.panes
for _, p in ipairs(tab.panes) do
if p.is_zoomed then zoomed = true end
if p.has_unseen_output and not tab.is_active then unseen = true end
end
end
local suffix = ''
if panes > 1 then suffix = suffix .. ' ' .. panes end
if zoomed then suffix = suffix .. ' Z' end
---------------- 3. 길이 제한 ----------------
-- 한글은 화면에서 2칸을 차지하므로 열 폭 기준으로 자른다.
-- 접미사와 여백을 뺀 만큼만 제목에 허용해 닫기(x) 버튼이 잘리지 않게 한다.
local budget = 22 - wezterm.column_width(suffix)
if wezterm.column_width(title) > budget then
title = wezterm.truncate_right(title, budget - 1) .. '…'
end
---------------- 4. 렌더 ----------------
local out = {}
if unseen then
out[#out + 1] = { Foreground = { Color = P.warn } }
out[#out + 1] = { Text = ' •' }
else
out[#out + 1] = { Text = ' ' }
end
out[#out + 1] = { Attribute = { Intensity = tab.is_active and 'Bold' or 'Normal' } }
out[#out + 1] = { Text = string.format(' %d: %s%s ', tab.tab_index + 1, title, suffix) }
return out
end)
if ok and items then return items end
-- 예외가 나도 탭바가 사라지지 않도록 최소한의 제목을 돌려준다
return { { Text = string.format(' %d ', (tab.tab_index or 0) + 1) } }
end)
-- ---------------------------------------------------------
-- 9. 시작 시 창 최대화
-- ---------------------------------------------------------
-- [주의] 이 핸들러가 등록되면 WezTerm 은 기본 창을 스스로 만들지 않고
-- 이 함수에 위임한다. 여기서 예외가 나면 창이 아예 안 뜨거나
-- 기본 창과 겹쳐 두 개가 뜰 수 있으므로 전부 pcall 로 감싼다.
wezterm.on('gui-startup', function(cmd)
local ok, err = pcall(function()
-- 이미 창이 있으면 새로 만들지 않는다 (중복 창 방지)
local existing = wezterm.mux.all_windows()
if existing and #existing > 0 then
local gw = existing[1]:gui_window()
if gw then gw:maximize() end
return
end
local _, _, window = wezterm.mux.spawn_window(cmd or {})
local gw = window:gui_window()
if gw then gw:maximize() end
end)
if not ok then
wezterm.log_error('gui-startup 실패: ' .. tostring(err))
end
end)
return configㅇㅇㅇ
2026. 8. 7. 00:21
ㄹㄹㄹ
2026. 8. 6. 15:41
-- =========================================================
-- WezTerm Configuration (v2 - 검증본)
-- Windows / macOS / Linux 공통 | 한국어 + 영어 최적화
--
-- 설치 위치 (세 OS 모두 홈 디렉토리):
-- Windows : %USERPROFILE%\.wezterm.lua
-- macOS : /Users/<사용자명>/.wezterm.lua
-- Linux : /home/<사용자명>/.wezterm.lua
--
-- 검증 기준: wezterm.org 공식 문서 (config/default-keys, fonts,
-- keys, window_decorations, files)
-- =========================================================
local wezterm = require 'wezterm'
local act = wezterm.action
local config = wezterm.config_builder()
-- ---------------------------------------------------------
-- 1. 플랫폼 판별
-- ---------------------------------------------------------
local triple = wezterm.target_triple
local is_windows = triple:find('windows') ~= nil
local is_mac = triple:find('darwin') ~= nil
local is_linux = triple:find('linux') ~= nil
-- 파일 존재 확인.
-- [주의] wezterm.run_child_process 는 프로그램이 없을 때 false 를 반환하지 않고
-- Lua 에러를 던진다("No such file or directory"). 설정 최상위에서
-- 이를 쓰면 창 대신 Configuration Error 가 뜬다. 따라서 사용하지 않는다.
-- io.open 은 실패 시 nil 을 돌려주므로 안전하고 프로세스도 띄우지 않는다.
local function file_exists(path)
local ok, f = pcall(io.open, path, 'r')
if ok and f then f:close(); return true end
return false
end
-- WezTerm 빌드 날짜 비교 (예: '20240203-110809-...' -> 20240203)
-- 신버전 전용 옵션을 구버전에서 켜면 설정 전체가 로드 실패하므로 게이트가 필요하다.
local BUILD = tonumber(tostring(wezterm.version):match('^(%d%d%d%d%d%d%d%d)') or '0') or 0
local function build_at_least(d) return BUILD >= d end
-- 여러 후보 경로 중 처음 존재하는 것을 반환 (없으면 nil)
local function first_existing(paths)
for _, p in ipairs(paths) do
if file_exists(p) then return p end
end
return nil
end
-- ---------------------------------------------------------
-- 2. 폰트 : 영문 주폰트 + 한글 폴백
-- WezTerm은 지정한 목록 뒤에 Nerd Font Symbols 등
-- 자체 기본 폴백을 자동 추가하므로 따로 나열할 필요 없음
-- ---------------------------------------------------------
local cjk_font
if is_windows then
cjk_font = 'Malgun Gothic' -- 윈도우 기본 탑재
elseif is_mac then
cjk_font = 'Apple SD Gothic Neo' -- macOS 기본 탑재
else
cjk_font = 'Noto Sans Mono CJK KR'
end
-- [정정] 이전 버전에서 CJK 폰트에 scale=1.33 을 넣었으나 이는 잘못이었다.
-- 한글 x_adv 가 셀폭보다 작은 것은 결함이 아니라 폰트의 의도된 좌우 여백이다.
-- 1.33 배로 강제 확대하면 글리프가 픽셀 격자에서 벗어나 힌팅이 깨지고
-- 화면이 뿌옇게 흐려진다. 크기 조절은 scale 이 아니라 font_size 로 해야 한다.
config.font = wezterm.font_with_fallback {
-- 'JetBrains Mono' 는 WezTerm 내장 폰트라 설치가 필요 없고,
-- Nerd Font 아이콘은 내장 'Symbols Nerd Font Mono' 가 자동 폴백된다.
{ family = 'JetBrains Mono' },
{ family = 'D2Coding' }, -- 한글 고정폭. 설치돼 있으면 우선 사용
{ family = cjk_font }, -- OS 기본 한글 폰트
'Noto Color Emoji',
}
-- 크기: 기본 12 에서 한 단계 낮춘 11 을 기본값으로 둔다.
-- 크게 쓰고 싶으면 이 값만 12~13 으로 올릴 것 (scale 은 건드리지 말 것)
config.font_size = is_mac and 13.0 or 11.0
config.line_height = 1.1
config.cell_width = 1.0
-- CJK 폰트는 cap-height 지표가 부정확하므로 자동 스케일링을 끈다
config.use_cap_height_to_scale_fallback_fonts = false
config.warn_about_missing_glyphs = false
-- 글자 선명도.
-- Windows/Linux LCD 모니터에서는 서브픽셀 렌더링(HorizontalLcd)이 가장 또렷하다.
-- 색 번짐(빨강/파랑 테두리)이 보이면 'Normal' 로 바꿀 것.
-- macOS 는 Retina 라 Normal 이 자연스럽다.
if is_mac then
config.freetype_load_target = 'Normal'
config.freetype_render_target = 'Normal'
else
config.freetype_load_target = 'Light'
config.freetype_render_target = 'HorizontalLcd'
end
config.adjust_window_size_when_changing_font_size = false
-- ---------------------------------------------------------
-- 3. 한국어 처리 (★ 핵심)
-- ---------------------------------------------------------
-- 한글 입력기(IME) 활성화
config.use_ime = true
-- macOS 는 한글 파일명을 NFD(자모 분리)로 저장한다.
-- 이 옵션이 없으면 ls 결과가 "ㅎㅏㄴㄱㅡㄹ" 처럼 분리되어 보인다.
config.normalize_output_to_unicode_nfc = true
-- 동아시아 애매폭 문자(─ │ ┌ ● ★ 등)를 2칸으로 처리할지 여부.
-- tree / htop / 박스 그리기가 어긋나면 true 로 바꿔 볼 것.
-- 반대로 이미 잘 나오는데 true 로 두면 오히려 어긋나므로 기본은 false.
config.treat_east_asian_ambiguous_width_as_wide = false
-- ---------------------------------------------------------
-- 4. 외관
-- ---------------------------------------------------------
-- =========================================================
-- 밝은 테마 (눈에 편한 따뜻한 오프화이트)
--
-- [배경 선택 근거]
-- 순백(#ffffff, 휘도 255)은 눈부심이 크다. 여기서는 휘도 238의
-- 따뜻한 미색을 쓴다. 밝지만 눈이 덜 피로하다.
--
-- [ANSI 색을 직접 정의한 이유]
-- 내장 밝은 테마 20종을 전수 측정한 결과 ANSI 색 최저 대비가
-- 최고 2.11, 대부분 1.0~1.6 으로 WCAG AA(4.5)에 한참 못 미쳤다.
-- (밝은 배경 위에 밝은 색을 올리니 구조적으로 안 나온다)
-- 그래서 Gruvbox Light 색상을 기준으로 색조·채도는 유지한 채
-- 명도만 낮춰 모든 색이 4.5 이상이 되도록 재계산했다.
-- bright 계열은 7.0 이상으로 맞춰 굵은 글씨가 8/8 구분된다.
-- =========================================================
local P = {
bg = '#f6eeda', -- 배경 (휘도 238)
fg = '#3c3836', -- 전경 (대비 10.03)
accent = '#1d69ce', -- 파랑 강조 (4.58)
warn = '#8e6516', -- 주황 강조 (4.51)
tab_bar = '#e7e0cd', -- 탭바 배경
tab_ina = '#6d6258', -- 비활성 탭 글자 (4.51)
popup_bg = '#fbf7ee', -- 팝업 배경 (글자 대비 10.84)
thumb = '#b1ab9d', -- 스크롤바
sel_bg = '#c6d1d7', -- 선택 영역 (글자 대비 7.46)
dim = '#5a5048', -- 보조 텍스트 (탭바 위 대비 5.96)
chip = '#b5a98c', -- 상태줄 칩 (탭바와 구분 1.77 / 글자 대비 4.98)
}
config.color_schemes = {
['Warm Light AA'] = {
background = P.bg,
foreground = P.fg,
cursor_bg = P.accent,
cursor_fg = P.bg,
cursor_border = P.accent,
selection_bg = P.sel_bg,
selection_fg = P.fg,
-- 검정 빨강 초록 노랑 파랑 자홍 청록 흰색
ansi = { '#282828','#cc241d','#707013','#8e6516','#3d7578','#9c5676','#4e7650','#5f5750' },
brights = { '#6d6258','#9b1b16','#52520e','#684a10','#2d5558','#723f56','#39563a','#3c3836' },
},
}
config.color_scheme = 'Warm Light AA'
-- 투명도는 밝은 테마에서 특히 대비를 크게 깎는다. 불투명 유지.
config.window_background_opacity = 1.0
-- 세 OS 모두 TITLE|RESIZE 로 통일한다.
-- RESIZE 단독 -> 타이틀바 없음. 탭 1개면 탭바도 숨겨져 창 이동 불가
-- INTEGRATED_BUTTONS 단독 -> 창 버튼이 탭바에 들어가므로 위와 같은 문제 발생
config.window_decorations = 'TITLE|RESIZE'
-- [렌더링] 화면 찢김(가로 흰줄)과 랙의 주원인은 GPU 어댑터 선택 실패다.
-- 노트북처럼 GPU 가 여러 개인 환경에서 WezTerm 이 소프트웨어 렌더러나
-- 엉뚱한 어댑터를 잡으면 프레임이 밀리고 가로줄이 생긴다.
-- 우선순위: Dx12/Metal > Vulkan > OpenGL, 외장 > 내장 (Cpu 는 제외)
local function pick_gpu()
local ok, gpus = pcall(function() return wezterm.gui.enumerate_gpus() end)
if not ok or type(gpus) ~= 'table' then return nil end
local backend_rank = { Dx12 = 40, Metal = 40, Vulkan = 30, Gl = 10 }
local device_rank = { DiscreteGpu = 3, IntegratedGpu = 2, Other = 1, Cpu = 0 }
local best, best_score = nil, 0
for _, g in ipairs(gpus) do
local d = device_rank[tostring(g.device_type)] or 0
if d > 0 then
local score = (backend_rank[tostring(g.backend)] or 0) + d
if score > best_score then best, best_score = g, score end
end
end
return best
end
local gpu = pick_gpu()
if gpu then
config.front_end = 'WebGpu'
config.webgpu_preferred_adapter = gpu
config.webgpu_power_preference = 'HighPerformance'
else
config.front_end = 'OpenGL'
end
config.max_fps = 120
config.enable_kitty_keyboard = false
if is_mac then
config.macos_window_background_blur = 0
end
config.window_padding = { left = 12, right = 12, top = 10, bottom = 8 }
config.window_close_confirmation = 'AlwaysPrompt'
-- 스크롤백은 패널마다 따로 잡힌다. 분할을 자주 하면 그만큼 메모리와
-- 초기화 비용이 늘어난다. 10000 줄이면 실사용에 충분하다.
config.scrollback_lines = 10000
config.enable_scroll_bar = true
config.default_cursor_style = 'SteadyBar'
config.cursor_blink_rate = 0
config.cursor_blink_ease_in = 'Constant'
config.cursor_blink_ease_out = 'Constant'
config.audible_bell = 'Disabled'
-- 밝은 테마에서는 밝기를 낮추면 오히려 대비가 살짝 올라간다(10.03 -> 8.95).
-- 채도만 조금 빼서 비활성 패널을 '바래 보이게' 하는 편이 자연스럽다.
config.inactive_pane_hsb = { saturation = 0.75, brightness = 0.97 }
config.hide_mouse_cursor_when_typing = true
-- ---- 사용 편의 ----
-- 탭바 위에서 마우스 휠 -> 탭 전환
config.mouse_wheel_scrolls_tabs = true
-- 다른 창에서 넘어오며 클릭할 때, 그 클릭이 터미널로 전달되지 않게 한다
config.swallow_mouse_click_on_window_focus = true
-- 셸만 돌고 있으면 탭/창을 닫을 때 확인창을 띄우지 않는다.
-- 실행 중인 작업(vim, ssh 등)이 있을 때만 물어본다.
config.skip_close_confirmation_for_processes_named = {
'bash', 'sh', 'zsh', 'fish', 'tmux',
'cmd.exe', 'pwsh.exe', 'powershell.exe',
}
-- 비밀번호 입력 중이면 커서 모양으로 알려준다
config.detect_password_input = true
-- 키를 누르면 스크롤 위치를 맨 아래로 되돌린다
config.scroll_to_bottom_on_input = true
-- 파일을 창에 끌어다 놓으면 경로에 따옴표를 씌워준다 (공백/한글 경로 대응)
config.quote_dropped_files = is_windows and 'Windows' or 'Posix'
-- 팝업 UI 도 테마에 맞춘다. 지정 안 하면 밝은 회색 창이 튀어나온다.
config.command_palette_bg_color = P.popup_bg
config.command_palette_fg_color = P.fg
config.command_palette_font_size = is_mac and 13.0 or 11.0
config.command_palette_rows = 14
config.char_select_bg_color = P.popup_bg
config.char_select_fg_color = P.fg
config.char_select_font_size = is_mac and 13.0 or 11.0
-- 패널 전환 시 확대 상태 자동 해제 (확대된 채 이동하면 혼란)
config.unzoom_on_switch_pane = true
-- 상태 표시줄 갱신 주기(ms)
config.status_update_interval = 1000
-- 패키지 매니저로 설치했다면 앱 내부 업데이트 알림은 방해다
config.check_for_updates = false
config.show_update_window = false
-- 탭바
-- [중요] 탭별 닫기(x) 버튼은 fancy 탭바에서만 그려진다.
-- use_fancy_tab_bar = false(레트로)로 두면 닫기 버튼이 아예 없다.
-- show_close_tab_button_in_tabs 는 기본값이 true 라 따로 켤 필요는 없다.
config.use_fancy_tab_bar = true
config.tab_bar_at_bottom = false -- 탭바를 창 위쪽에
config.hide_tab_bar_if_only_one_tab = false -- 탭 1개여도 계속 표시
-- 탭 제목이 폭을 다 먹으면 오른쪽 닫기(x) 버튼이 잘려 안 보인다.
-- 제목은 짧게 자르고 탭 폭은 넉넉히 준다.
config.tab_max_width = 36
-- 닫기 버튼은 기본값이 true 지만, 구버전에는 이 옵션 자체가 없어
-- 그냥 쓰면 설정 로드가 통째로 실패한다. 지원하는 빌드에서만 명시한다.
if build_at_least(20240301) then
config.show_close_tab_button_in_tabs = true
end
config.show_new_tab_button_in_tab_bar = true -- + 버튼 (동작은 아래에서 분할로 바꿈)
config.show_tab_index_in_tab_bar = true
config.switch_to_last_active_tab_when_closing_tab = true -- 탭 닫으면 직전 탭으로
-- fancy 탭바는 탭 '바깥' 영역을 window_frame 으로 그린다.
-- 여기를 안 맞추면 탭바만 회색으로 떠 보인다.
config.window_frame = {
font = wezterm.font { family = 'JetBrains Mono', weight = 'Bold' },
font_size = is_mac and 12.0 or 10.0,
active_titlebar_bg = P.tab_bar,
inactive_titlebar_bg = P.tab_bar,
active_titlebar_fg = P.fg,
inactive_titlebar_fg = P.dim,
button_bg = P.tab_bar,
button_fg = P.fg,
button_hover_bg = P.accent,
button_hover_fg = P.bg,
}
-- use_fancy_tab_bar = false 일 때 탭바는 테마 색을 따라가지 않으므로
-- ayu 팔레트에 맞춰 직접 지정한다 (지정하지 않으면 회색 기본값과 충돌)
config.colors = {
-- 스크롤바 손잡이 (배경 대비 1.98 — 은은하게 보이는 정도)
scrollbar_thumb = P.thumb,
-- 패널 분할선. 지정 안 하면 밝은 배경에 묻혀 화면이 나뉜 게 안 보인다.
split = P.accent,
-- 한글 IME 조합 중 커서 색 (조합 중/확정 구분)
compose_cursor = P.warn,
-- 복사 모드 선택 강조
copy_mode_active_highlight_bg = { Color = P.accent },
copy_mode_active_highlight_fg = { Color = P.bg },
copy_mode_inactive_highlight_bg = { Color = P.sel_bg },
copy_mode_inactive_highlight_fg = { Color = P.fg },
-- 퀵셀렉트(LEADER+e) 라벨
quick_select_label_bg = { Color = P.warn },
quick_select_label_fg = { Color = P.bg },
quick_select_match_bg = { Color = P.sel_bg },
quick_select_match_fg = { Color = P.fg },
tab_bar = {
-- [실측] 활성탭 글자 4.58 / 비활성탭 글자 4.51 / 배경 구분 4.02
background = P.tab_bar,
active_tab = {
bg_color = P.accent,
fg_color = P.bg,
intensity = 'Bold',
},
inactive_tab = {
bg_color = P.tab_bar,
fg_color = P.tab_ina,
},
inactive_tab_hover = {
bg_color = P.sel_bg,
fg_color = P.fg,
italic = false,
},
new_tab = {
bg_color = P.tab_bar,
fg_color = P.tab_ina,
},
new_tab_hover = {
bg_color = P.accent,
fg_color = P.bg,
intensity = 'Bold',
},
},
}
-- ---------------------------------------------------------
-- 5. 기본 셸 / 실행 메뉴
-- ---------------------------------------------------------
if is_windows then
-- PowerShell 7(pwsh)은 별도 설치 항목이다. 설치돼 있을 때만 기본 셸로 쓰고,
-- 없으면 윈도우에 항상 있는 powershell.exe 로 폴백한다.
local pwsh = first_existing {
'C:\\Program Files\\PowerShell\\7\\pwsh.exe',
'C:\\Program Files (x86)\\PowerShell\\7\\pwsh.exe',
(os.getenv('LOCALAPPDATA') or '') .. '\\Microsoft\\WindowsApps\\pwsh.exe',
(os.getenv('ProgramFiles') or '') .. '\\PowerShell\\7\\pwsh.exe',
}
if pwsh then
config.default_prog = { pwsh, '-NoLogo' }
else
config.default_prog = { 'powershell.exe', '-NoLogo' }
end
config.launch_menu = {
{ label = 'PowerShell 7', args = { 'pwsh.exe', '-NoLogo' } },
{ label = 'Windows PowerShell', args = { 'powershell.exe', '-NoLogo' } },
{ label = 'Command Prompt', args = { 'cmd.exe' } },
{ label = 'WSL', args = { 'wsl.exe', '~' } },
}
elseif is_linux then
config.launch_menu = {
{ label = 'bash', args = { 'bash', '-l' } },
{ label = 'zsh', args = { 'zsh', '-l' } },
}
end
-- ---------------------------------------------------------
-- 6. 키 바인딩
--
-- 설계 원칙:
-- (1) 창/탭/패널 조작은 전부 LEADER(Ctrl+A) 아래로 모은다.
-- -> 기본 키와 절대 충돌하지 않는 안전 지대
-- (2) 기본 키로 이미 되는 것은 다시 정의하지 않는다.
-- Ctrl+- / Ctrl+= / Ctrl+0 : 폰트 크기
-- Alt+Enter : 전체화면
-- Ctrl+Shift+C / V : 복사 / 붙여넣기
-- Ctrl+Shift+L : 디버그 오버레이 (문제 해결용, 덮지 말 것)
-- Ctrl+Shift+P : 명령 팔레트
-- Ctrl+Shift+Tab / Ctrl+Tab : 탭 이동
-- (3) ALT+문자 는 쓰지 않는다. 셸의 readline / vim 이 Meta 로 사용
-- ---------------------------------------------------------
config.leader = { key = 'a', mods = 'CTRL', timeout_milliseconds = 1000 }
config.keys = {
---------------- 패널 분할 ----------------
{ key = '\\', mods = 'LEADER', action = act.SplitHorizontal { domain = 'CurrentPaneDomain' } },
{ key = '-', mods = 'LEADER', action = act.SplitVertical { domain = 'CurrentPaneDomain' } },
---------------- 패널 이동 (vim 키) ----------------
{ key = 'h', mods = 'LEADER', action = act.ActivatePaneDirection 'Left' },
{ key = 'j', mods = 'LEADER', action = act.ActivatePaneDirection 'Down' },
{ key = 'k', mods = 'LEADER', action = act.ActivatePaneDirection 'Up' },
{ key = 'l', mods = 'LEADER', action = act.ActivatePaneDirection 'Right' },
---------------- 패널 크기 조정 ----------------
{ key = 'LeftArrow', mods = 'LEADER', action = act.AdjustPaneSize { 'Left', 5 } },
{ key = 'DownArrow', mods = 'LEADER', action = act.AdjustPaneSize { 'Down', 5 } },
{ key = 'UpArrow', mods = 'LEADER', action = act.AdjustPaneSize { 'Up', 5 } },
{ key = 'RightArrow', mods = 'LEADER', action = act.AdjustPaneSize { 'Right', 5 } },
---------------- 패널 제어 ----------------
{ key = 'z', mods = 'LEADER', action = act.TogglePaneZoomState },
{ key = 'x', mods = 'LEADER', action = act.CloseCurrentPane { confirm = true } },
{ key = 'q', mods = 'LEADER', action = act.PaneSelect { alphabet = 'asdfghjkl' } },
{ key = 'o', mods = 'LEADER', action = act.RotatePanes 'Clockwise' },
---------------- 탭 ----------------
{ key = 'c', mods = 'LEADER', action = act.SpawnTab 'CurrentPaneDomain' },
{ key = 'n', mods = 'LEADER', action = act.ActivateTabRelative(1) },
{ key = 'p', mods = 'LEADER', action = act.ActivateTabRelative(-1) },
-- '&' 같은 시프트 문자는 키보드 레이아웃에 따라 인식이 불안정하므로 'w' 사용
{ key = 'w', mods = 'LEADER', action = act.CloseCurrentTab { confirm = true } },
{ key = ',', mods = 'LEADER', action = act.PromptInputLine {
description = '새 탭 이름:',
action = wezterm.action_callback(function(window, _, line)
if line and #line > 0 then
window:active_tab():set_title(line)
end
end),
},
},
---------------- 검색 / 복사 / 선택 ----------------
{ key = '[', mods = 'LEADER', action = act.ActivateCopyMode },
{ key = ']', mods = 'LEADER', action = act.PasteFrom 'Clipboard' },
{ key = 'f', mods = 'LEADER', action = act.Search { CaseInSensitiveString = '' } },
{ key = 'e', mods = 'LEADER', action = act.QuickSelect },
{ key = 'u', mods = 'LEADER', action = act.CharSelect },
---------------- 유틸 ----------------
{ key = 'm', mods = 'LEADER', action = act.ShowLauncher },
-- ---- 탭 관리 ----
-- 탭이 많아지면 제목만으로 찾기 어렵다. 목록에서 골라 이동한다.
{ key = 't', mods = 'LEADER', action = act.ShowTabNavigator },
-- 탭 순서 바꾸기 ('<' '>' 같은 시프트 문자는 레이아웃 의존이라 화살표 사용)
{ key = 'LeftArrow', mods = 'LEADER|SHIFT', action = act.MoveTabRelative(-1) },
{ key = 'RightArrow', mods = 'LEADER|SHIFT', action = act.MoveTabRelative(1) },
-- 탭 닫기(확인 있음) / 강제 닫기
{ key = 'X', mods = 'LEADER|SHIFT', action = act.CloseCurrentTab { confirm = false } },
-- [UX] 크기 조절 모드. LEADER 는 1초 뒤 풀리므로 반복 조절이 불편하다.
-- LEADER+r 로 모드에 들어가면 화살표/hjkl 을 계속 눌러 조절할 수 있고
-- Esc 또는 Enter 로 빠져나온다. 진행 중에는 상태줄에 모드가 표시된다.
{ key = 'r', mods = 'LEADER', action = act.ActivateKeyTable {
name = 'resize_pane', one_shot = false, timeout_milliseconds = 3000 } },
{ key = 'K', mods = 'LEADER|SHIFT', action = act.ClearScrollback 'ScrollbackAndViewport' },
{ key = 'R', mods = 'LEADER|SHIFT', action = act.ReloadConfiguration },
{ key = 'd', mods = 'LEADER', action = act.ShowDebugOverlay },
---------------- Ctrl+A 원본을 셸로 전달 ----------------
-- Ctrl+A 를 두 번 누르면 '줄 맨 앞으로 이동'이 정상 동작
{ key = 'a', mods = 'LEADER|CTRL', action = act.SendKey { key = 'a', mods = 'CTRL' } },
}
-- LEADER + 1~9 로 탭 직접 이동
for i = 1, 9 do
table.insert(config.keys, {
key = tostring(i),
mods = 'LEADER',
action = act.ActivateTab(i - 1),
})
end
-- ---------------------------------------------------------
-- 7. 마우스 : Ctrl(mac은 Cmd) + 클릭으로 링크 열기
-- ---------------------------------------------------------
local link_mod = is_mac and 'CMD' or 'CTRL'
config.mouse_bindings = {
{
event = { Up = { streak = 1, button = 'Left' } },
mods = link_mod,
action = act.OpenLinkAtMouseCursor,
},
-- 누를 때의 클릭 이벤트가 셸로 새어나가지 않도록 차단
{
event = { Down = { streak = 1, button = 'Left' } },
mods = link_mod,
action = act.Nop,
},
}
-- ---------------------------------------------------------
-- 6-2. 모달 키 테이블 : 크기 조절 모드
-- LEADER+r 로 진입. 화살표 또는 hjkl 을 반복해서 누를 수 있다.
-- Esc / Enter / q 로 빠져나오며, 3초간 입력이 없어도 자동 해제된다.
-- ---------------------------------------------------------
config.key_tables = {
resize_pane = {
{ key = 'LeftArrow', action = act.AdjustPaneSize { 'Left', 3 } },
{ key = 'h', action = act.AdjustPaneSize { 'Left', 3 } },
{ key = 'DownArrow', action = act.AdjustPaneSize { 'Down', 3 } },
{ key = 'j', action = act.AdjustPaneSize { 'Down', 3 } },
{ key = 'UpArrow', action = act.AdjustPaneSize { 'Up', 3 } },
{ key = 'k', action = act.AdjustPaneSize { 'Up', 3 } },
{ key = 'RightArrow', action = act.AdjustPaneSize { 'Right', 3 } },
{ key = 'l', action = act.AdjustPaneSize { 'Right', 3 } },
{ key = 'Escape', action = 'PopKeyTable' },
{ key = 'Enter', action = 'PopKeyTable' },
{ key = 'q', action = 'PopKeyTable' },
},
}
-- ---------------------------------------------------------
-- 7-1. 상태 표시줄
-- [문제] LEADER(Ctrl+A)를 눌러도 화면에 아무 변화가 없어서
-- 눌렸는지 알 수 없고, 모드에 들어가 있는지도 보이지 않는다.
-- [해결] 왼쪽에 LEADER/모드 상태를, 오른쪽에 작업공간과 시간을 표시한다.
-- ---------------------------------------------------------
wezterm.on('update-status', function(window, pane)
local ok = pcall(function()
---------------- 왼쪽: 모드 표시 ----------------
local left = {}
local mode = window:active_key_table()
if mode == 'resize_pane' then
-- 크기 조절 모드: 주황색으로 강하게
left = {
{ Background = { Color = P.warn } },
{ Foreground = { Color = P.bg } },
{ Attribute = { Intensity = 'Bold' } },
{ Text = ' 크기조절 hjkl/화살표 Esc 종료 ' },
}
elseif window:leader_is_active() then
-- LEADER 대기 중: 청색
left = {
{ Background = { Color = P.accent } },
{ Foreground = { Color = P.bg } },
{ Attribute = { Intensity = 'Bold' } },
{ Text = ' LEADER ' },
}
else
left = { { Text = '' } }
end
window:set_left_status(wezterm.format(left))
---------------- 오른쪽: 작업공간 + 시간 ----------------
local right = {}
local ws = window:active_workspace()
if ws and ws ~= 'default' then
right[#right + 1] = { Foreground = { Color = P.accent } }
right[#right + 1] = { Text = ' ' .. ws .. ' ' }
end
-- 확대된 패널이 있으면 알려준다 (확대 중인 걸 모르고 헤매는 일 방지)
local tab = window:active_tab()
for _, p in ipairs(tab:panes_with_info()) do
if p.is_zoomed then
right[#right + 1] = { Foreground = { Color = P.warn } }
right[#right + 1] = { Attribute = { Intensity = 'Bold' } }
right[#right + 1] = { Text = ' 확대중 ' }
break
end
end
-- [시인성] 이전에는 흐린 회색(#8a7f74)이라 탭바 위에서 대비 2.97 로
-- 거의 읽히지 않았다. 진한 글자(대비 8.80)에 배경 칩을 깔아 분리한다.
right[#right + 1] = { Background = { Color = P.chip } }
right[#right + 1] = { Foreground = { Color = P.fg } }
right[#right + 1] = { Attribute = { Intensity = 'Bold' } }
right[#right + 1] = { Text = wezterm.strftime(' %m/%d (%a) %H:%M ') }
window:set_right_status(wezterm.format(right))
end)
if not ok then
window:set_left_status('')
window:set_right_status('')
end
end)
-- ---------------------------------------------------------
-- 7-2. 탭바의 [+] 버튼을 "화면 분할" 버튼으로 바꾼다
--
-- 좌클릭 1회 : 좌우 반반 (2분할)
-- 좌클릭 2회 : 균등 3분할
-- 좌클릭 3회 : 그 이상은 새 탭 생성
-- 우클릭 : 기본 동작(런처 메뉴) 유지
--
-- 3분할을 균등하게 만들기 위해 두 번째 분할은 top_level=true 를 쓴다.
-- 활성 패널만 쪼개면 50/25/25 가 되지만, 탭 전체를 기준으로 1/3 을 떼면
-- 기존 50/50 이 2/3 안으로 밀려 들어가 33/33/33 이 된다.
-- ---------------------------------------------------------
wezterm.on('new-tab-button-click', function(window, pane, button, default_action)
-- 좌클릭이 아니면 WezTerm 기본 동작에 맡긴다 (우클릭 = 런처 메뉴)
if button ~= 'Left' then return end
-- [성능 메모] 분할이 느리게 느껴지는 주된 원인은 이 핸들러가 아니라
-- 새 패널마다 셸 프로세스가 새로 뜨는 비용이다(측정: 핸들러 1회 0.004ms).
-- Windows PowerShell 은 프로필 로딩 때문에 특히 느리다.
-- 본인 환경 측정: Measure-Command { pwsh -NoLogo -Command exit }
-- 500ms 를 넘으면 프로필($PROFILE)을 정리하는 게 가장 효과적이다.
-- 아래 FAST_SPLIT 을 true 로 하면 분할된 패널은 프로필 없이 띄운다.
local FAST_SPLIT = false
local ok, err = pcall(function()
local tab = window:active_tab()
local count = #tab:panes()
local spawn = nil
if FAST_SPLIT and is_windows then
spawn = { args = { config.default_prog[1], '-NoLogo', '-NoProfile' } }
end
-- 확대(zoom) 상태에서는 분할이 어색하므로 먼저 해제
tab:set_zoomed(false)
if count == 1 then
pane:split { direction = 'Right', size = 0.5, args = spawn and spawn.args or nil }
elseif count == 2 then
pane:split { direction = 'Right', size = 1 / 3, top_level = true,
args = spawn and spawn.args or nil }
else
-- 3분할 이상이면 새 탭
if default_action then
window:perform_action(default_action, pane)
else
window:perform_action(act.SpawnTab 'CurrentPaneDomain', pane)
end
end
end)
if not ok then
wezterm.log_error('new-tab-button-click 실패: ' .. tostring(err))
end
-- 처리했음을 알려 기본 동작이 중복 실행되지 않게 한다
return false
end)
-- ---------------------------------------------------------
-- 8. 탭 제목 : 현재 디렉토리명 표시
-- current_working_dir 은 버전에 따라 Url 객체(userdata) 또는
-- 문자열을 반환하므로 양쪽 모두 처리한다
-- ---------------------------------------------------------
wezterm.on('format-tab-title', function(tab)
local pane = tab.active_pane
local title = pane.title or 'shell'
local cwd = pane.current_working_dir
if cwd then
local path
if type(cwd) == 'string' then
path = cwd
else
path = cwd.file_path or tostring(cwd)
end
local name = path:gsub('[/\\]+$', ''):match('([^/\\]+)$')
if name and #name > 0 then
title = name
end
end
-- 한글은 화면에서 2칸을 차지하므로 열 폭 기준으로 자른다
if wezterm.column_width(title) > 20 then
title = wezterm.truncate_right(title, 19) .. '…'
end
-- 분할 개수 / 확대 / 미확인 출력 상태를 수집
local panes = 1
local zoomed, unseen = false, false
if tab.panes then
panes = #tab.panes
for _, p in ipairs(tab.panes) do
if p.is_zoomed then zoomed = true end
if p.has_unseen_output and not tab.is_active then unseen = true end
end
end
local suffix = panes > 1 and (' ' .. panes) or ''
if zoomed then suffix = suffix .. ' Z' end
local items = {}
-- [UX] 비활성 탭에서 새 출력이 있으면 주황 점으로 알려준다.
-- 빌드/테스트를 다른 탭에서 돌릴 때 끝났는지 확인하러 갈 필요가 없다.
if unseen then
items[#items + 1] = { Foreground = { Color = P.warn } }
items[#items + 1] = { Text = ' •' }
else
items[#items + 1] = { Text = ' ' }
end
items[#items + 1] = { Attribute = { Intensity = tab.is_active and 'Bold' or 'Normal' } }
items[#items + 1] = { Text = string.format(' %d: %s%s ', tab.tab_index + 1, title, suffix) }
return items
end)
-- ---------------------------------------------------------
-- 9. 시작 시 창 최대화
-- ---------------------------------------------------------
-- [주의] 이 핸들러가 등록되면 WezTerm 은 기본 창을 스스로 만들지 않고
-- 이 함수에 위임한다. 여기서 예외가 나면 창이 아예 안 뜨거나
-- 기본 창과 겹쳐 두 개가 뜰 수 있으므로 전부 pcall 로 감싼다.
wezterm.on('gui-startup', function(cmd)
local ok, err = pcall(function()
-- 이미 창이 있으면 새로 만들지 않는다 (중복 창 방지)
local existing = wezterm.mux.all_windows()
if existing and #existing > 0 then
local gw = existing[1]:gui_window()
if gw then gw:maximize() end
return
end
local _, _, window = wezterm.mux.spawn_window(cmd or {})
local gw = window:gui_window()
if gw then gw:maximize() end
end)
if not ok then
wezterm.log_error('gui-startup 실패: ' .. tostring(err))
end
end)
return configㅇㅇㅇ
2026. 8. 5. 14:34
win11 최적화
2026. 8. 3. 00:15
아래 코드를 전체복사하여 관리자모드 CMD창에 복사
reg add "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32" /f /ve >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v UseCompactMode /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v LaunchTo /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKCU\Control Panel\Desktop" /v MenuShowDelay /t REG_SZ /d 10 /f >nul 2>&1
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Personalization" /v NoLockScreen /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKCU\Software\Policies\Microsoft\Windows\Explorer" /v DisableSearchBoxSuggestions /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Search" /v BingSearchEnabled /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Software\Classes\CLSID\{e88865ea-0e1c-4e20-9aa6-edcd0212c87c}" /v System.IsPinnedToNameSpaceTree /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Software\Classes\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}" /v System.IsPinnedToNameSpaceTree /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer" /v ShowRecent /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer" /v ShowFrequent /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer" /v ShowCloudFilesInQuickAccess /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v Start_TrackDocs /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v TaskbarAl /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v HideFileExt /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v ShowSecondsInSystemClock /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v DisallowShaking /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer" /v "Max Cached Icons" /t REG_SZ /d "8192" /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer" /v link /t REG_BINARY /d 00000000 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v NavPaneExpandToCurrentFolder /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell" /v "BagMRU Size" /t REG_DWORD /d 10000 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v SeparateProcess /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKCU\Software\Policies\Microsoft\Windows\Explorer" /v DisableThumbnailsOnNetworkFolders /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\CabinetState" /v FullPath /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags\AllFolders\Shell" /v FolderType /t REG_SZ /d "NotSpecified" /f >nul 2>&1
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer" /v ShowDriveLettersFirst /t REG_DWORD /d 4 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v Hidden /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v PersistBrowsers /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v TaskbarGlomLevel /t REG_DWORD /d 2 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v MMTaskbarMode /t REG_DWORD /d 2 /f >nul 2>&1
reg add "HKCU\Software\Policies\Microsoft\Windows\Explorer" /v HideRecentlyAddedApps /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Start" /v ShowFrequentList /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v Start_TrackProgs /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v Start_IrisRecommendations /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Explorer" /v HideRecommendedPersonalizedSites /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKCU\Software\Policies\Microsoft\Windows\Explorer" /v HideRecommendedPersonalizedSites /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Explorer" /v NoNewAppAlert /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize" /v EnableTransparency /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v SnapAssist /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Control Panel\Accessibility" /v DynamicScrollbars /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\System" /v DisableAcrylicBackgroundOnLogon /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKCU\Control Panel\Desktop\WindowMetrics" /v MinAnimate /t REG_SZ /d 0 /f >nul 2>&1
reg add "HKCU\Control Panel\Desktop" /v AutoEndTasks /t REG_SZ /d 1 /f >nul 2>&1
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" /v NoAutoRebootWithLoggedOnUsers /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Power" /v HiberbootEnabled /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\System\GameConfigStore" /v GameDVR_Enabled /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\GameDVR" /v AppCaptureEnabled /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKLM\SOFTWARE\Policies\Microsoft\Dsh" /v AllowNewsAndInterests /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKLM\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main" /v AllowPrelaunch /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKLM\SOFTWARE\Policies\Microsoft\MicrosoftEdge\TabPreloader" /v AllowTabPreloading /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Software\Policies\Microsoft\Windows\WindowsCopilot" /v TurnOffWindowsCopilot /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization" /v DODownloadMode /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKLM\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpClient" /v SpecialPollInterval /t REG_DWORD /d 43200 /f >nul 2>&1
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI\BootAnimation" /v DisableStartupSound /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKCU\Control Panel\Mouse" /v MouseHoverTime /t REG_SZ /d 100 /f >nul 2>&1
reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\UserProfileEngagement" /v ScoobeSystemSettingEnabled /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\SmartActionPlatform\SmartClipboard" /v Disabled /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKCU\Control Panel\Keyboard" /v KeyboardDelay /t REG_SZ /d 0 /f >nul 2>&1
reg add "HKCU\Control Panel\Keyboard" /v KeyboardSpeed /t REG_SZ /d 31 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v RestartApps /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Multimedia\SystemProfile" /v NetworkThrottlingIndex /t REG_DWORD /d 4294967295 /f >nul 2>&1
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting" /v Disabled /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\DataCollection" /v AllowTelemetry /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Software\Policies\Microsoft\Windows\CloudContent" /v DisableTailoredExperiencesWithDiagnosticData /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKCU\Control Panel\Accessibility\StickyKeys" /v Flags /t REG_SZ /d 506 /f >nul 2>&1
reg add "HKCU\Control Panel\Accessibility\Keyboard Response" /v Flags /t REG_SZ /d 122 /f >nul 2>&1
reg add "HKCU\Control Panel\Accessibility\ToggleKeys" /v Flags /t REG_SZ /d 58 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\AdvertisingInfo" /v Enabled /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\InputPersonalization" /v RestrictImplicitInkCollection /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\InputPersonalization" /v RestrictImplicitTextCollection /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\InputPersonalization\TrainedDataStore" /v HarvestContacts /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v SilentInstalledAppsEnabled /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Windows Search" /v AllowCortana /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Siuf\Rules" /v NumberOfSIUFInPeriod /t REG_DWORD /d 0 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband" /v MinThumbSizePx /t REG_DWORD /d 350 /f >nul 2>&1
reg add "HKCR\AllFilesystemObjects\shellex\ContextMenuHandlers\CopyToFolder" /ve /t REG_SZ /d "{C2FBB630-5571-11D1-A98C-00C04FD8D565}" /f >nul 2>&1
reg add "HKCR\AllFilesystemObjects\shellex\ContextMenuHandlers\MoveToFolder" /ve /t REG_SZ /d "{C2FBB631-5571-11D1-A98C-00C04FD8D565}" /f >nul 2>&1
reg add "HKCR\Directory\Background\shell\runas" /ve /t REG_SZ /d "관리자 권한으로 CMD 열기" /f >nul 2>&1
reg add "HKCR\Directory\Background\shell\runas" /v "HasLUAShield" /t REG_SZ /d "" /f >nul 2>&1
reg add "HKCR\Directory\Background\shell\runas\command" /ve /t REG_SZ /d "cmd.exe /s /k pushd \"%V\"" /f >nul 2>&1
reg add "HKCR\Directory\shell\runas" /ve /t REG_SZ /d "관리자 권한으로 CMD 열기" /f >nul 2>&1
reg add "HKCR\Directory\shell\runas" /v "HasLUAShield" /t REG_SZ /d "" /f >nul 2>&1
reg add "HKCR\Directory\shell\runas\command" /ve /t REG_SZ /d "cmd.exe /s /k pushd \"%1\"" /f >nul 2>&1
reg add "HKCR\Drive\shell\runas" /ve /t REG_SZ /d "관리자 권한으로 CMD 열기" /f >nul 2>&1
reg add "HKCR\Drive\shell\runas" /v "HasLUAShield" /t REG_SZ /d "" /f >nul 2>&1
reg add "HKCR\Drive\shell\runas\command" /ve /t REG_SZ /d "cmd.exe /s /k pushd \"%1\"" /f >nul 2>&1
reg add "HKCR\Directory\Background\shell\RestartExplorer" /ve /t REG_SZ /d "탐색기 다시 시작" /f >nul 2>&1
reg add "HKCR\Directory\Background\shell\RestartExplorer" /v "Icon" /t REG_SZ /d "explorer.exe" /f >nul 2>&1
reg add "HKCR\Directory\Background\shell\RestartExplorer\command" /ve /t REG_SZ /d "cmd.exe /c taskkill /f /im explorer.exe & start explorer.exe" /f >nul 2>&1
reg add "HKCR\Directory\Background\shell\ControlPanel" /ve /t REG_SZ /d "제어판 열기" /f >nul 2>&1
reg add "HKCR\Directory\Background\shell\ControlPanel" /v "Icon" /t REG_SZ /d "control.exe" /f >nul 2>&1
reg add "HKCR\Directory\Background\shell\ControlPanel\command" /ve /t REG_SZ /d "control.exe" /f >nul 2>&1
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations" /v DWMFRAMEINTERVAL /t REG_DWORD /d 15 /f >nul 2>&1
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v SelectTransport /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v fEnableWddmDriver /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v fEnableAVC444Mode /t REG_DWORD /d 1 /f >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\SearchSettings" /v IsDeviceSearchHistoryEnabled /t REG_DWORD /d 0 /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\SearchSettings" /v IsMSACloudSearchEnabled /t REG_DWORD /d 0 /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\SearchSettings" /v IsAADCloudSearchEnabled /t REG_DWORD /d 0 /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v AutoDetect /t REG_DWORD /d 0 /f
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v DisableAutomaticRestartSignOn /t REG_DWORD /d 1 /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v SystemPaneSuggestionsEnabled /t REG_DWORD /d 0 /f
reg add "HKCU\Software\Microsoft\Lighting" /v AmbientLightingEnabled /t REG_DWORD /d 0 /f
reg add "HKCU\Software\Microsoft\Clipboard" /v EnableClipboardHistory /t REG_DWORD /d 1 /f
reg add "HKCU\Software\Microsoft\Accessibility" /v CursorType /t REG_DWORD /d 4 /f
reg add "HKCU\Software\Microsoft\Accessibility" /v CursorColor /t REG_DWORD /d 65535 /f
ㅅㄹㅅㅎㅎㅎ
2026. 7. 31. 11:05
ddd
2026. 7. 31. 09:09
###
2026. 7. 30. 13:51
dddd
2026. 7. 27. 09:15
ㄹ
2026. 7. 22. 09:51
ip
2026. 7. 16. 14:12