给 OpenCode 换个皮肤

给 OpenCode 换个皮肤 不管是编辑器、终端工具还是像 OpenCode 这样的 AI 编码助手长时间盯着屏幕配色顺不顺眼真的挺影响心情。有人喜欢深夜绿字黑底的黑客风有人偏爱 Nord 那种冷静的蓝灰调也有人干脆就让工具跟着终端的颜色走懒得折腾。OpenCode 的主题系统基本把这些需求都覆盖了。先看看终端支不支持真彩色在挑主题之前有个小细节值得留意。OpenCode 的主题想要显示出原本设计的全部色彩终端得支持truecolor也就是 24 位色。好在现在大部分现代终端默认都支持像 iTerm2、Alacritty、Kitty、Windows Terminal还有比较新版本的 GNOME Terminal基本都没问题。如果不确定有个简单的检查方法在终端里跑一下echo $COLORTERM如果输出truecolor或24bit那就说明支持。万一输出为空或者别的什么可以在 shell 配置文件里加上export COLORTERMtruecolor来启用。要是终端不支持真彩色主题显示起来会打点折扣——颜色没那么准或者退回到 256 色的近似值。内置主题总有一款看着顺眼OpenCode 自带了好几个内置主题基本覆盖了社区里比较流行的配色方案。默认情况下用的是自己家的opencode主题。下面是目前内置的几个名字基本就能看出来风格主题名说明system跟着终端背景色自动适配tokyonight灵感来自 TokyonighteverforestEverforest 配色ayuAyu 深色主题catppuccinCatppuccin 经典版catppuccin-macchiatoCatppuccin 玛奇朵变体gruvboxGruvbox 复古风kanagawa神奈川冲浪里配色nordNord 北欧冷色调matrix黑客帝国风格绿字黑底one-darkAtom One Dark 主题而且官方还在不断往里面加新主题隔段时间更新一下可能就有惊喜。system 主题懒人福音自动适配终端这里面有个比较特别的存在——system 主题。它不是用固定颜色而是自动去适配用户终端的配色方案。具体来说做了三件事根据终端的背景色生成一套灰度色系保证对比度合适语法高亮和界面元素用的都是标准 ANSI 颜色0-15这样就能尊重终端自己的调色板文字和背景颜色设置为none相当于保留终端的原生样子不额外覆盖这个主题适合三类人希望 OpenCode 跟终端外观保持一致的用户、自己折腾了终端配色方案的用户、以及喜欢所有终端应用看起来都统一的用户。怎么切换主题换主题有两种办法。第一种最直接在 OpenCode 里输入/theme命令会弹出一个选择器上下翻翻选中意的就行。第二种是写配置文件。在项目根目录或者用户配置目录下的tui.json里指定。比如{$schema:https://opencode.ai/tui.json,theme:tokyonight}自己动手做主题内置主题再丰富也难免有人想自己调一套独一无二的配色。OpenCode 的主题系统是基于 JSON 的灵活性还不错。主题文件的存放位置OpenCode 会从多个目录加载主题后面目录的优先级高于前面的内置主题——编译在二进制文件里的那些用户配置目录——~/.config/opencode/themes/*.json或者$XDG_CONFIG_HOME/opencode/themes/*.json项目根目录——项目根/.opencode/themes/*.json当前工作目录——./.opencode/themes/*.json如果不同目录里有同名的主题后面目录里的会覆盖前面的。创建第一个自定义主题假设想要一个全局都能用的主题可以这样操作mkdir-p~/.config/opencode/themesvim~/.config/opencode/themes/my-theme.json如果只想给某个项目用就在项目根目录下创建mkdir-p.opencode/themesvim.opencode/themes/my-theme.jsonJSON 格式长什么样主题文件支持几种颜色值的写法Hex 颜色像#ffffff这样ANSI 颜色直接用数字3范围 0-255颜色引用可以引用primary或者自己在defs里定义的别名明暗色变体写成{dark: #000, light: #fff}OpenCode 会根据系统或终端环境自动选择无色none意思是沿用终端的默认色或者透明defs这个部分是选填的可以在里面定义一堆可复用的颜色名后面其他地方用nord0、nord1这样的名字直接引用省得反复写 hex 码。特别说一下none这个值none看起来像个普通字符串实际上挺有用。把它用在任意颜色字段上OpenCode 就会乖乖用终端自己的默认颜色。比如text: none就是用终端默认的前景色background: none就是用终端默认的背景色。这对于做那种想“融入”终端配色方案的主题特别方便。一个完整的例子下面是一个基于 Nord 配色方案的自定义主题示例基本上把能用到的颜色字段都展示了一遍{$schema:https://opencode.ai/theme.json,defs:{nord0:#2E3440,nord1:#3B4252,nord2:#434C5E,nord3:#4C566A,nord4:#D8DEE9,nord5:#E5E9F0,nord6:#ECEFF4,nord7:#8FBCBB,nord8:#88C0D0,nord9:#81A1C1,nord10:#5E81AC,nord11:#BF616A,nord12:#D08770,nord13:#EBCB8B,nord14:#A3BE8C,nord15:#B48EAD},theme:{primary:{dark:nord8,light:nord10},secondary:{dark:nord9,light:nord9},accent:{dark:nord7,light:nord7},error:{dark:nord11,light:nord11},warning:{dark:nord12,light:nord12},success:{dark:nord14,light:nord14},info:{dark:nord8,light:nord10},text:{dark:nord4,light:nord0},textMuted:{dark:nord3,light:nord1},background:{dark:nord0,light:nord6},backgroundPanel:{dark:nord1,light:nord5},backgroundElement:{dark:nord1,light:nord4},border:{dark:nord2,light:nord3},borderActive:{dark:nord3,light:nord2},borderSubtle:{dark:nord2,light:nord3},diffAdded:{dark:nord14,light:nord14},diffRemoved:{dark:nord11,light:nord11},diffContext:{dark:nord3,light:nord3},diffHunkHeader:{dark:nord3,light:nord3},diffHighlightAdded:{dark:nord14,light:nord14},diffHighlightRemoved:{dark:nord11,light:nord11},diffAddedBg:{dark:#3B4252,light:#E5E9F0},diffRemovedBg:{dark:#3B4252,light:#E5E9F0},diffContextBg:{dark:nord1,light:nord5},diffLineNumber:{dark:nord2,light:nord4},diffAddedLineNumberBg:{dark:#3B4252,light:#E5E9F0},diffRemovedLineNumberBg:{dark:#3B4252,light:#E5E9F0},markdownText:{dark:nord4,light:nord0},markdownHeading:{dark:nord8,light:nord10},markdownLink:{dark:nord9,light:nord9},markdownLinkText:{dark:nord7,light:nord7},markdownCode:{dark:nord14,light:nord14},markdownBlockQuote:{dark:nord3,light:nord3},markdownEmph:{dark:nord12,light:nord12},markdownStrong:{dark:nord13,light:nord13},markdownHorizontalRule:{dark:nord3,light:nord3},markdownListItem:{dark:nord8,light:nord10},markdownListEnumeration:{dark:nord7,light:nord7},markdownImage:{dark:nord9,light:nord9},markdownImageText:{dark:nord7,light:nord7},markdownCodeBlock:{dark:nord4,light:nord0},syntaxComment:{dark:nord3,light:nord3},syntaxKeyword:{dark:nord9,light:nord9},syntaxFunction:{dark:nord8,light:nord8},syntaxVariable:{dark:nord7,light:nord7},syntaxString:{dark:nord14,light:nord14},syntaxNumber:{dark:nord15,light:nord15},syntaxType:{dark:nord7,light:nord7},syntaxOperator:{dark:nord9,light:nord9},syntaxPunctuation:{dark:nord4,light:nord0}}}可以看到defs里面把所有 Nord 色板定义好后面theme部分里到处引用。而且每个颜色字段都写了dark和light两种模式OpenCode 会自动根据系统的深浅色模式来切换。比如在深色模式下主色用nord8冰蓝色浅色模式下用nord10深一点的蓝。小结OpenCode 的主题系统从“懒得管”到“完全自己定制”都照顾到了。懒得折腾就用默认或者 system 主题想要某个社区热门的内置那些大概率够用实在手痒想自己配一套JSON 写起来也不算麻烦放对目录就能生效。换主题这事说大不大说小不小但每天对着的工具配色舒服了写代码的心情确实会好一点。