Logo
热心市民王先生

02. 技术架构

技术研究 架构分析 Rust

深入分析 Kaku 的源码结构、模块系统设计、基于 WezTerm 的改造方式和配置文件加载机制。

2.1 源码目录结构

Kaku 采用 Rust Workspace 结构组织代码,将 WezTerm 拆分为多个独立 crates 以实现模块化编译和功能裁剪。

2.1.1 核心目录结构

Kaku/
├── Cargo.toml              # Workspace 配置
├── kaku/                   # CLI 命令行工具
│   └── Cargo.toml
├── kaku-gui/               # GUI 应用程序
│   └── Cargo.toml
├── crates/                 # 核心功能 crates
│   ├── bidi/               # 双向文本渲染
│   ├── wezterm-blob-leases/
│   ├── wezterm-cell/       # 终端单元格数据结构
│   ├── wezterm-escape-parser/
│   ├── wezterm-dynamic/
│   ├── wezterm-open-url/
│   ├── wezterm-ssh/
│   ├── wezterm-surface/
│   └── wezterm-uds/        # Unix Domain Socket
├── lua-api-crates/         # Lua API 绑定
│   ├── battery/
│   ├── color-funcs/
│   ├── filesystem/
│   ├── logging/
│   ├── mux/
│   ├── plugin/
│   └── ...
├── mux/                    # 多路复用器核心
├── term/                   # 终端模拟核心
├── termwiz/                # 终端 UI 工具库
├── window/                 # 窗口管理
├── config/                 # 配置解析
├── assets/                 # 资源文件
│   ├── fonts/              # 内置字体
│   ├── shell-integration/  # Shell 集成脚本
│   ├── vendor/             # 第三方工具(Starship、zsh 插件等)
│   └── macos/              # macOS 应用资源
└── scripts/                # 构建脚本
    ├── build.sh            # 主构建脚本
    └── download_vendor.sh  # 下载第三方工具

2.1.2 Workspace Members 分析

根据 Cargo.toml,Kaku 的 Workspace 包含以下成员:

[workspace]
members = [
  "crates/bidi",
  "deps/cairo",
  "kaku",                      # 主 CLI 程序
  "crates/wezterm-blob-leases",
  "crates/wezterm-cell",
  "crates/wezterm-escape-parser",
  "crates/wezterm-dynamic",
  "kaku-gui",                  # GUI 应用程序
  "crates/wezterm-open-url",
  "crates/wezterm-ssh",
  "crates/wezterm-surface",
  "crates/wezterm-uds",
]

关键观察

  1. kaku vs kaku-gui 分离:CLI 和 GUI 分别编译,允许独立优化
  2. 精简的 crate 列表:相比 WezTerm 原版,Kaku 删除了大量未使用的 crates
  3. deps/cairo:使用自定义 vendored Cairo 图形库,减少外部依赖

2.2 基于 WezTerm 的改造方式

2.2.1 改造层次

Kaku 对 WezTerm 的改造可分为三个层次:

graph TB
    A[WezTerm 源码] --> B[代码层改造]
    A --> C[配置层改造]
    A --> D[资源层改造]
    
    B --> B1[删除未使用模块]
    B --> B2[优化加载逻辑]
    B --> B3[添加 Kaku 特有功能]
    
    C --> C1[预设默认配置]
    C --> C2[内置主题]
    C --> C3[Shell 集成]
    
    D --> D1[内置字体]
    D --> D2[应用图标]
    D --> D3[第三方工具]
    
    B1 --> E[Kaku 应用]
    C1 --> E
    D1 --> E

2.2.2 代码层改造详情

删除的模块

根据 Makefile 和构建脚本分析,Kaku 删除或禁用了以下 WezTerm 模块:

  1. 跨平台兼容性模块

    • Windows 特定功能(Kaku 目前仅支持 macOS)
    • Linux/Unix 特定功能的部分裁剪
    • Wayland 支持(仅保留基础支持)
  2. 未使用的协议支持

    • 部分 SSH 功能
    • 串口通信(Serial)的部分功能
    • 实验性功能
  3. 冗余依赖

    • 移除了多种图像格式支持,仅保留:
      image = { version = "0.25", default-features = false, 
                features = ["png", "jpeg", "gif", "webp"] }
    • 移除了 tiff、bmp、ico、pnm、dds、tga、openexr、qoi、hdr、farbfeld 等格式

优化的加载逻辑

  1. Lazy Loading(懒加载)

    -- Kaku 配置文件中的懒加载策略
    -- 配色方案在需要时才加载
    config.color_schemes = {}  -- 初始为空
    -- 动态加载用户实际使用的方案
  2. JIT Initialization(即时初始化)

    // 构建配置优化
    [profile.release-opt]
    inherits = "release"
    opt-level = "z"        // 优化体积
    lto = "fat"            // 全链路优化
    codegen-units = 1      // 单编译单元,更好的优化
    strip = "symbols"      // 剥离符号
    panic = "abort"        // 更小的 panic 实现
  3. 符号剥离(Symbol Stripping)

    # build.sh 中的配置
    strip = true
    lto = "fat"
    codegen-units = 1

添加的 Kaku 特有功能

  1. Kaku Assistant

    • 自动分析失败命令
    • 调用 AI API 生成修复建议
    • 快捷键应用建议(Cmd+Shift+E)
  2. 智能 Yazi 检测

    -- 检测 Yazi 文件管理器并自动调整布局
    local function pane_is_yazi(pane)
      -- 通过进程名和进程信息检测
      -- 自动切换全屏模式和 Tab 栏显示
    end
  3. 自适应分辨率检测

    -- 根据屏幕分辨率自动调整字体大小和间距
    local function is_low_resolution_screen()
      -- 检测内置 Retina 显示屏
      -- 低分辨率屏幕使用 15px 字体
      -- 高分辨率屏幕使用 17px 字体
    end

2.2.3 配置层改造

默认配置文件

Kaku 在 Kaku.app/Contents/Resources/kaku.lua 中提供内置默认配置:

-- Kaku 内置默认配置
local config = {}

-- 1. 字体配置
config.font = wezterm.font 'JetBrains Mono'
config.font_size = if_is_low_res_screen then 15.0 else 17.0

-- 2. 主题配置
config.color_scheme = resolve_kaku_color_scheme(user_setting)
-- 内置 Kaku Dark 和 Kaku Light 主题

-- 3. 窗口配置
config.window_padding = get_default_padding()
config.hide_tab_bar_if_only_one_tab = true

-- 4. 集成配置
config.copy_on_select = true  -- 选中即复制
config.audible_bell = false   -- 静音

-- 5. 快捷键配置(macOS 原生)
config.leader = { key = 'a', mods = 'CTRL', timeout_milliseconds = 1000 }
config.keys = {
  { key = 'T', mods = 'CMD', action = 'SpawnTab' },
  { key = 'W', mods = 'CMD', action = 'CloseCurrentTab' },
  -- ... 更多 macOS 原生快捷键
}

用户配置加载

Kaku 按以下优先级加载配置:

1. 环境变量 KAKU_CONFIG_FILE 指定的路径
2. 默认路径 ~/.config/kaku/kaku.lua
3. 内置默认配置 Kaku.app/Contents/Resources/kaku.lua

加载逻辑:

local function kaku_user_config_path()
  -- 优先使用运行时配置文件
  if type(wezterm.config_file) == 'string' and wezterm.config_file ~= '' then
    runtime_config = wezterm.config_file
  end
  
  -- 检查环境变量
  if (not runtime_config or runtime_config == '') then
    local env_config = os.getenv('KAKU_CONFIG_FILE')
    if env_config and env_config ~= '' then
      runtime_config = env_config
    end
  end
  
  -- 回退到默认路径
  if not runtime_config then
    return default_kaku_user_config_path()
  end
  
  return runtime_config
end

2.2.4 资源层改造

内置资源

资源类型内容大小优化
字体JetBrains Mono, Nerd Font Symbols, Noto Color Emoji仅包含必要字体
Shell 插件z, zsh-completions, zsh-autosuggestions, zsh-syntax-highlighting精选常用插件
CLI 工具Starship, Delta, Lazygit, Yazi通过 Homebrew 按需安装
主题Kaku Dark, Kaku Light内置 2 个精简主题

资源懒加载

-- 配色方案懒加载
config.color_schemes = {}
-- 仅在用户选择时才加载实际方案
local function load_color_scheme(name)
  -- 动态加载
end

2.3 模块化系统设计

2.3.1 模块架构

graph LR
    A[kaku-gui] --> B[window]
    A --> C[mux]
    A --> D[termwiz]
    
    B --> B1[macOS Cocoa]
    B --> B2[Metal 渲染]
    
    C --> C1[Pane 管理]
    C --> C2[Tab 管理]
    C --> C3[Session 管理]
    
    D --> D1[终端模拟]
    D --> D2[字体渲染]
    D --> D3[配色方案]
    
    A --> E[kaku CLI]
    E --> E1[命令解析]
    E --> E2[配置命令]
    E --> E3[AI 助手]

2.3.2 核心模块职责

kaku-gui(GUI 应用程序)

[package]
name = "kaku-gui"
version = "0.6.0"
build = "build.rs"

[features]
default = ["vendored-fonts", "wayland"]
vendored-fonts = [
  "vendor-nerd-font-symbols-font",
  "vendor-jetbrains-font",
  "vendor-roboto-font",
  "vendor-noto-emoji-font"
]

职责

  • 窗口管理与渲染
  • GUI 事件处理
  • Metal 图形后端
  • macOS 原生集成

kaku(CLI 工具)

[package]
name = "kaku"
version = "0.6.0"

职责

  • 命令行接口
  • 配置管理(kaku config
  • AI 助手(kaku ai
  • 诊断工具(kaku doctor
  • 多路复用器控制(kaku cli

mux(多路复用器)

职责

  • Pane/Tab/Session 管理
  • 进程通信
  • 状态持久化

termwiz(终端 UI 库)

职责

  • 终端模拟核心
  • 字符渲染
  • 字体管理
  • 配色方案

2.3.3 模块依赖关系

graph TD
    A[kaku-gui] --> B[kaku]
    A --> C[mux]
    A --> D[termwiz]
    A --> E[window]
    A --> F[config]
    
    B --> C
    B --> G[portable-pty]
    
    C --> D
    C --> H[wezterm-uds]
    
    D --> I[wezterm-cell]
    D --> J[wezterm-font]
    
    E --> K[Metal/wgpu]
    E --> L[Cocoa/macOS]
    
    F --> M[mlua/Lua]

2.4 配置文件加载机制

2.4.1 配置加载流程

sequenceDiagram
    participant App as Kaku App
    participant Env as Environment
    participant FS as File System
    participant Lua as Lua Engine
    participant Config as Config Builder
    
    App->>Env: 检查 KAKU_CONFIG_FILE
    Env-->>App: 返回路径或空
    
    alt 环境变量存在
        App->>FS: 加载指定路径
    else 环境变量不存在
        App->>FS: 加载 ~/.config/kaku/kaku.lua
    end
    
    FS-->>App: 返回配置内容或空
    
    alt 用户配置存在
        App->>Lua: 解析 Lua 配置
        Lua-->>App: 返回 config 表
    else 用户配置不存在
        App->>FS: 加载内置默认配置
        FS-->>App: 返回内置配置
    end
    
    App->>Config: 应用配置
    Config-->>App: 配置生效

2.4.2 配置验证

Kaku 提供配置验证机制:

-- 严格模式(通过环境变量启用)
if os.getenv('KAKU_STRICT_CONFIG') == '1' and wezterm.config_builder then
  config = wezterm.config_builder()
end
-- config_builder 会验证每个配置项

2.4.3 配置热重载

Kaku 支持配置热重载:

  • 修改配置文件后,通过 Cmd+Shift+R 重新加载
  • 某些配置项(如字体大小)可立即生效
  • 某些配置项(如配色方案)需要重启会话

2.5 字体渲染机制

2.5.1 字体加载流程

graph TD
    A[配置 font] --> B{字体类型}
    
    B -->|系统字体 | C[Core Text 查询]
    B -->|内置字体 | D[资源目录加载]
    B -->|字体文件 | E[直接加载 .ttf/.otf]
    
    C --> F[字体匹配]
    D --> F
    E --> F
    
    F --> G{找到字体?}
    G -->|是 | H[创建 Font 对象]
    G -->|否 | I[回退到备用字体]
    
    H --> J[字体渲染]
    I --> J
    
    J --> K[Metal 纹理]
    K --> L[屏幕显示]

2.5.2 字体配置选项

WezTerm(Kaku)支持以下字体配置:

local wezterm = require 'wezterm'
local config = {}

-- 1. 基本字体配置
config.font = wezterm.font 'JetBrains Mono'

-- 2. 带属性的字体配置
config.font = wezterm.font('JetBrains Mono', {
  weight = 'Bold',
  italic = true,
  stretch = 'Normal',
})

-- 3. 字体回退链
config.font = wezterm.font_with_fallback {
  'JetBrains Mono',
  'Nerd Font Symbols',
  'Noto Color Emoji',
}

-- 4. 字体大小
config.font_size = 17.0  -- 点数

-- 5. 字体规则(针对粗体、斜体等)
config.font_rules = {
  {
    intensity = 'Bold',
    font = wezterm.font('JetBrains Mono', { weight = 'Bold' }),
  },
  {
    intensity = 'Half',
    font = wezterm.font('JetBrains Mono', { weight = 'Light' }),
  },
  {
    italic = true,
    font = wezterm.font('JetBrains Mono', { italic = true }),
  },
}

-- 6. 字体目录(添加自定义字体路径)
config.font_dirs = {
  '/Users/username/Library/Fonts',
  '/Library/Fonts',
}

-- 7. 行高和字间距
config.line_height = 1.2
config.character_spacing = 1

-- 8. 连字支持
config.harfbuzz_features = { 'calt', 'clig', 'liga' }

2.5.3 macOS 字体渲染优化

Kaku 针对 macOS 进行了字体渲染优化:

  1. 使用 Core Text:macOS 原生字体渲染引擎
  2. 低分辨率屏幕适配
    • 内置屏幕(Built-in Retina):15px
    • 外接显示器:17px
  3. 抗锯齿优化:次像素渲染(Sub-pixel Rendering)
  4. 连字支持:通过 HarfBuzz 实现编程字体连字

2.6 本章小结

Kaku 的技术架构可总结为:

  1. Rust Workspace 模块化:将 WezTerm 拆分为独立 crates,支持选择性编译
  2. 三层改造:代码层(删除冗余)、配置层(预设优化)、资源层(精简打包)
  3. Lua 配置系统:完全兼容 WezTerm API,支持热重载和验证
  4. 字体渲染优化:针对 macOS 优化,支持完整的字体配置选项

关键洞察

  • Kaku 的成功在于精准的功能裁剪,而非简单包装
  • 模块化设计允许按需编译,减小最终体积
  • 完全兼容 WezTerm 生态是降低迁移成本的关键
  • 字体渲染是终端体验的核心,Kaku 在此做了大量优化

下一章将通过对比分析,进一步理解 Kaku 相对于其他终端的优劣势。