# 主题
`theme/` 加载、编辑并保存为 TUI 宿主着色的主题 `.dft` 文件 —— 这些
文件正是宿主在启动时扫描、stdext 在 `src/themes/` 下随附的那些。相关
函数操作普通映射,因此读取是一次深层 `get`,编辑返回一个新的映射,由你
重新绑定。该命名空间在每个宿主和脚本二进制中都可用;在 TUI 宿主中
将它与 `tui/theme-reload` 和 `tui/set-theme` 搭配,可形成
实时编辑 → 保存 → 应用的循环。
## 函数
| 函数 | 用途 |
|---|---|
| `theme/load name-or-path` | 词干、显示名称或 `.dft` 路径 → 完整主题映射;记录来源信息供 `theme/save` 使用 |
| `theme/current` | 当前工作区的活动主题映射;未应用宿主主题时为 `nil` |
| `theme/get $t path...` | 按关键字路径深层读取;任一层级缺失时返回 `nil` |
| `theme/set $t path... value` | 深层更新并返回新映射;缺失的中间层级会变成空映射 |
| `theme/unset $t path...` | 移除路径上的键,返回新映射 |
| `theme/save $t ?path` | 规范写入;返回写入的路径,失败时返回 `nil` |
| `theme/list` | 可见主题词干(关键字)的排序向量 |
说明:
- 搜索链。 `theme/load` 和 `theme/list` 按顺序查找,每个词干以
先命中者为准:项目 `.deft/local/themes/`、用户主目录
`local/themes/`、预置文件 `:themes :dir`(字符串或路径
向量)、stdext 挂载点的 `themes/`,以及旧版 `./themes/`
回退。
- 名称形式。 `theme/load` 接受文件词干(关键字或字符串,
`:dracula` → `dracula.dft`)、与文件 `:name` 字段匹配的显示名称
(`"Dracula"`),或显式的 `.dft` 路径。`theme/get`
和编辑函数会把字符串路径段强制转换为关键字,因此
`[theme/get $t "ui" "accent"]` 与
`[theme/get $t :ui :accent]` 读取同一个槽位。
- 编辑语义。 `theme/set` 和 `theme/unset` 从不修改
输入映射 —— 请绑定返回的映射。`theme/set` 具有 assoc-in 语义,
因此 `[theme/set $t :markdown :code-fg "#00ff00"]` 会在
`:markdown` 段尚不存在时创建它。
- 保存目标。 没有显式路径时,`theme/save` 遵循
`theme/load` 记录的来源。可写来源(项目
`.deft/local/themes`、用户主目录、预置文件 `:themes :dir`、旧版
`./themes`)会被就地覆盖。随 stdext 附带的默认值从不
修改:它会在 `<project`
.deft>/local/themes/<stem>.dft` 写入一个覆盖影子文件。在 Deft 中构建`
而非加载的映射,会以 `:name` 的 slug 保存到该影子目录
(`"Catppuccin Mocha"` → `catppuccin-mocha.dft`),当
`:name` 缺失时报错。显式的 `path` 参数优先于以上所有行为。
- 规范格式。 保存的文件带有 `# <name>` 头、4 空格
缩进的嵌套映射,段按 `name → ui → syntax → help →`
markdown` 排序后跟附加段,键按字母排序,并采用`
先写后重命名的原子写入 —— 因此主题往返后 diff 稳定。
- 当前主题。 `theme/current` 是宿主已应用的完整解析映射,
与 TUI 宿主中的 `[tui/theme]` 和 `[draw/theme $ctx]`
相同;各包的 `theme.dft` 默认值合并在各自的 app 键下。它在独立的
`deft` 二进制中返回 `nil` —— 在那里回退到
`theme/load` 加上你自己的默认值。它
每次调用都会解析,因此请缓存结果并在主题变更后重新读取
(stdext 的 `theme/on-change` 封装了脏检查模式)。
## 示例
# Load by stem, display name, or explicit path set t [theme/load :dracula] set t [theme/load "Dracula"] set t [theme/load "themes/my-theme.dft"] # Deep read [theme/get $t :ui :accent] # => "#7a64a1" [theme/get $t :help] # => the whole :help sub-map [theme/get $t :ui :nope] # => nil # Deep edits return a new map; rebind it set t [theme/set $t :ui :accent "#ffffff"] set t [theme/set $t :markdown :code-fg "#00ff00"] # section auto-created set t [theme/unset $t :markdown] # Save, then apply in a running TUI host [theme/save $t] # => ".deft/local/themes/dracula.dft" [tui/theme-reload] # rescan + re-apply; panels repaint [tui/set-theme "Nord"] # switch to another loaded theme # Discover what is installed [theme/list] # => @{ :catppuccin-mocha :dracula ... } [in? [theme/list] :dracula] # => true
在 TUI 宿主之外没有活动主题,因此脚本会回退到具名主题:
if [nil? [theme/current]] { set t [theme/load :dracula] }