[16AnsiColors] wezterm の color selector と nvim 運用
これ見て試行錯誤していたのだがやっとできた。
wezterm は 1000 以上 builtin の color scheme があるのでメニューで適当に選びたいのである。
sed とか fzf に行くと難しくなる。
InputSelector により wezterm で完結する手法が簡単。
fzf なら preview ができてよさそうに思えたので osc1337 経由で挑戦したのだが、
激遅になり断念。
シンプル版
local choices = {}
for k, v in pairs(wezterm.color.get_builtin_schemes()) do
table.insert(choices, {
id = k,
label = k,
})
end
config.keys = {
{
mods = "ALT",
key = 'F12',
action = wezterm.action_callback(function(win, pane)
win:perform_action(wezterm.action.InputSelector({
title = 'color_scheme',
choices = choices,
action = wezterm.action_callback(function(inner_window, _, id)
if id then
inner_window:set_config_overrides {
color_scheme = id,
}
end
end),
fuzzy = true,
}), pane)
end),
}
}
ちょっとおされな choices
local choices = {}
local function make_pallete(ansi)
local SGR = '\x1b['
local str = ''
for _, v in ipairs(ansi) do
local r = tonumber(v:sub(2, 3), 16)
local g = tonumber(v:sub(4, 5), 16)
local b = tonumber(v:sub(6, 7), 16)
local add = string.format("%s48;2;%d;%d;%dm ", SGR, r, g, b)
str = str .. add
end
return str
end
for k, v in pairs(wezterm.color.get_builtin_schemes()) do
table.insert(choices, {
id = k,
label = wezterm.format({
{ Text = make_pallete(v.ansi) },
{ Text = make_pallete(v.brights) },
{ Text = '\x1b[0m ' },
{ Foreground = { Color = v.foreground } },
{ Background = { Color = v.background } },
{ Text = k }, }),
})
end

nvim の color scheme が ansi 16 色を使えばよいのでは?
せっかく wezterm の色を変えても、nvim は独自の色を使っているのが気になった。
以下の記事に ansi 16 色を使う colorscheme を自作する例がある。
以下のようにして、ansi16色を使う colortheme を用意すれば、
wezterm の色を活かせる。
" Force vim to use 16 colors only
set notermguicolors
TreeSitter の色付けをカスタムする
link を使って同系のものを同じ色にして、
色数減らすとわりと見やすいような気がする。
:Inspect で調べながら手作業で調整する感じに。
例👇
-- comment
vim.api.nvim_set_hl(0, "Comment", { ctermfg = 8, italic = true, })
vim.api.nvim_set_hl(0, "SpecialComment", { link = "Comment" })
vim.api.nvim_set_hl(0, "@comment", { link = "Comment" })
vim.api.nvim_set_hl(0, "@markup.quote", { link = "Comment" })
-- keyword
vim.api.nvim_set_hl(0, "Keyword", { ctermfg = 5 })
vim.api.nvim_set_hl(0, "@keyword", { link = "Keyword" })
vim.api.nvim_set_hl(0, "Operator", { link = "Keyword" })
vim.api.nvim_set_hl(0, "Delimiter", { link = "Keyword" })
vim.api.nvim_set_hl(0, "@punctuation", { link = "Keyword" })
vim.api.nvim_set_hl(0, "@operator", { link = "Keyword" })
vim.api.nvim_set_hl(0, "@keyword.type", { link = "Keyword" })
-- const / compile time
vim.api.nvim_set_hl(0, "Constant", { ctermfg = 3 })
vim.api.nvim_set_hl(0, "Type", { link = "Constant" })
vim.api.nvim_set_hl(0, "Define", { link = "Constant" })
vim.api.nvim_set_hl(0, "Structure", { link = "Constant" })
vim.api.nvim_set_hl(0, "@type", { link = "Constant" })
vim.api.nvim_set_hl(0, "@keyword.modifier.cpp", { link = "Constant" })
-- literal
vim.api.nvim_set_hl(0, "String", { ctermfg = 4 })
vim.api.nvim_set_hl(0, "@string", { link = "String" })
vim.api.nvim_set_hl(0, "@boolean", { link = "String" })
vim.api.nvim_set_hl(0, "@markup.link", { link = "String" })
vim.api.nvim_set_hl(0, "@number", { link = "String" })
-- id
vim.api.nvim_set_hl(0, "Identifier", { ctermfg = 2 })
vim.api.nvim_set_hl(0, "Function", { link = "Identifier" })
vim.api.nvim_set_hl(0, "@markup.heading", { link = "Identifier" })
vim.api.nvim_set_hl(0, "@variable", { link = "Identifier" })
-- vim.api.nvim_set_hl(0, "@function.call", { link = "Constant" })
lsp の semantic token を止める
強い。止めないと tree-sitter の色が負ける。
local function lsp_attach(args)
local client = assert(vim.lsp.get_client_by_id(args.data.client_id))
-- disable semantic highlights
client.server_capabilities.semanticTokensProvider = nil
end
Hlargs
色を減らしてから Hlargs で赤とかにすると見やすい。
vim.api.nvim_set_hl(0, "Hlargs", { ctermfg = 1, bold = true })
tsnode-marker
markdown のコードブロックの背景色指定とか。
色決めの方針
color_scheme を選択して具体的な色を決めるのを wezterm の責務にして、
シンタックスによる 16 色選択を tree-sitter の責務にする。
- comment 灰色とか目立たないが読める色
- keyword(if, for, return, operator, かっこなど ... etc)
- const(型名, 定数, enum...etc)
- id(変数名、関数名)
- literal(string, num, bool...etc)
👇 wezterm でカラーテーマを選択して、treesitter で文法要素の ansi16 割り当てを調整している

適当に色変えて試せるようになった。
wezterm.lua の lsp 支援
16色ではなかった
color palette には以下のスロットが有る。
base8(black, red, green, yellow, blue, magenta, cyan, white), brights8, foreground, background
都合18色指定できる。
普通は、foreground を white と同じ、background を black と同じにするようである。
そうすれば16色になる。
wezterm では color scheme の末尾に (base16) がついているものが
そういう規約を持っているようだ。
foreground と background
escape sequence は \e[39m および \e[49m となっていて、
foreground色を背景色に、逆にbackground色を前景色に指定することはできない。
neredfont の区切り線で表示できない組み合せがありえる。
neovim では ctermfg, ctermbg に nil を指定する
vim.api.nvim_set_hl(0, "String", { ctermfg = nil })
0 が背景色なのか黒なのか 7 が前景色なのか白なのか
という意味的な問題が発生しているのである。
dark テーマではあまり問題にならないのだが、
light テーマでは、意味を選択する必要が発生する。
白が 0, 黒が 7 になっているのが主流のようだが、
そうじゃないものもある。
Discussion