Typos

← 返回目录 > ← 返回总览

相关工具推荐

工具 说明
Codespell 基于 Python 的源代码拼写检查工具,采用词典匹配方式
Markdownlint Markdown 格式与质量检查工具(含拼写相关规则)
Pre-commit 多语言 Git hooks 框架,可集成各类拼写检查工具

1. 简介

typos 是一个用 Rust 编写的源代码拼写检查工具,采用"已知错误纠正"(Correction-based)方式而非传统词典匹配方式。它维护一个已知拼写错误到正确拼写的映射表,通过匹配已知的拼写错误来检测和修复问题,从而将误报率降到极低,使其可以安全地在 CI/CD 流水线和 PR 审查中无人值守运行。

  • 主要检查语言:通用(不限于特定语言)
  • 主要检查能力:检测源代码和文档中的拼写错误;涵盖拼写检查
  • 核心检查原理:基于已知拼写错误映射表进行 token 匹配,支持标识符拆分(snake_case、CamelCase 等)
  • 检查规则/选项:约 18 个配置项(分为 [files] 与 [default] 两组),内置维护的拼写纠错词典随版本动态变化,全量配置选项
  • GitHub 仓库https://github.com/crate-ci/typos(3,991 stars)
  • 开源协议:MIT / Apache-2.0
  • 最新稳定版本:v1.31.1
  • 运行环境要求:无(独立二进制)
  • 误报率:低

2. 官方文档

文档 链接
项目主页 / README https://github.com/crate-ci/typos
配置参考(完整配置项说明) https://github.com/crate-ci/typos/blob/master/docs/reference.md
GitHub Action 集成文档 https://github.com/crate-ci/typos/blob/master/docs/github-action.md
pre-commit 集成文档 https://github.com/crate-ci/typos/blob/master/docs/pre-commit.md
设计文档(纠正 vs 词典、标识符与单词) https://github.com/crate-ci/typos/blob/master/docs/design.md
与其他拼写检查工具的对比 https://github.com/crate-ci/typos/blob/master/docs/comparison.md
采用 typos 的项目列表 https://github.com/crate-ci/typos/wiki
配置 JSON Schema https://github.com/crate-ci/typos/blob/master/config.schema.json
CHANGELOG https://github.com/crate-ci/typos/blob/master/CHANGELOG.md

3. 社区优秀实践

以下项目在官方 Wiki 的"Projects Using Typos"列表中,且确认在仓库中包含 typos 配置文件:

3.1 Ruff(astral-sh/ruff)

Python 生态最主流的 lint 工具 Ruff 自身使用 typos 进行拼写检查。

  • 仓库:https://github.com/astral-sh/ruff
  • 配置文件:_typos.toml
  • 集成方式:通过 GitHub Actions 在 CI 中运行 typos,配置文件中通过 extend-wordsextend-identifiers 添加项目特定的合法拼写

3.2 Julia Language(JuliaLang/julia)

Julia 编程语言的核心仓库使用 typos 进行拼写检查。

3.3 fzf(junegunn/fzf)

流行的命令行模糊查找工具 fzf 使用 typos 检查源代码拼写。

3.4 Zed Editor(zed-industries/zed)

高性能代码编辑器 Zed 使用 typos 进行拼写检查。


4. 工具配置说明

typos 是拼写检查工具而非代码风格/lint 工具,没有传统意义上的"规则集"。其核心行为由内置的拼写错误字典决定,用户主要通过配置文件进行定制。

4.1 配置文件说明

typos 涉及以下配置文件:

配置文件 用途 使用场景
_typos.toml typos 主配置文件(TOML 格式,推荐命名) 所有项目,控制拼写检查行为与例外
typos.toml typos 备用配置文件名 _typos.toml 等价
.typos.toml typos 备用配置文件名 _typos.toml 等价,部分项目采用点文件命名约定
Cargo.toml Rust 项目构建文件(配置需在 [workspace.metadata.typos][package.metadata.typos] 下) Rust 项目复用已有构建文件
pyproject.toml Python 项目配置文件(配置需在 [tool.typos] 下) Python 项目复用已有配置文件

配置文件查找顺序(按优先级):

  1. 命令行参数 --config PATH
  2. 指定文件/目录的父级目录中搜索以下文件之一:
    • typos.toml
    • _typos.toml
    • .typos.toml
    • Cargo.toml(配置需在 [workspace.metadata.typos][package.metadata.typos] 下)
    • pyproject.toml(配置需在 [tool.typos] 下)

4.2 _typos.toml 配置详解

_typos.toml 是 typos 的主配置文件,用于控制拼写检查的方言、屏蔽规则、自定义合法单词与标识符、排除范围等。

配置项说明

配置项 类型 说明
locale string 英语方言选择(enen-usen-gben-caen-au),en 为最宽松的默认值
extend-ignore-re list[string] 通过正则表达式实现类似代码注释的屏蔽语法
extend-words map 将特定单词标记为合法(值等于键时表示"永远合法")
extend-identifiers map 将特定标识符标记为合法(值等于键时表示"永远合法")
extend-exclude list[string] 排除不需要检查的文件或目录
extend-ignore-identifiers-re list[string] 通过正则匹配忽略特定模式的标识符
extend-ignore-words-re list[string] 通过正则匹配忽略特定模式的单词

提示:运行 typos --dump-config - 可查看当前项目的完整有效配置,便于调试。运行 typos --identifierstypos --words 可分别查看会被检查的标识符和单词列表。

推荐配置示例

以下配置适合大多数项目作为起点,涵盖常见的屏蔽需求:

[_typos.toml]

# 忽略隐藏文件、.gitignore 中的文件等(默认已开启,此处显式声明)
[files]
extend-exclude = [
    # 根据项目需要排除的目录
    # "generated/",
    # "vendor/",
]

[default]
# 英语方言:en 为默认值,纠正到最接近的拼写
# 可选值:en, en-us, en-gb, en-ca, en-au
locale = "en"

# 通过正则表达式实现代码注释级别的拼写屏蔽
extend-ignore-re = [
    # 行级屏蔽
    "(?Rm)^.*(#|//)\\s*spellchecker:disable-line$",
    # 下一行屏蔽
    "(#|//)\\s*spellchecker:ignore-next-line\\n.*",
    # 块级屏蔽
    "(?s)(#|//)\\s*spellchecker:off.*?\\n\\s*(#|//)\\s*spellchecker:on",
]

# 项目特定的合法拼写(根据实际项目补充)
[default.extend-words]
# 示例:不纠正项目特定的缩写或专有名词
# teh = "teh"

# 项目特定的合法标识符(根据实际项目补充)
[default.extend-identifiers]
# 示例:不纠正包含已知拼写模式的标识符
# AttributeIDSupressMenu = "AttributeIDSupressMenu"

5. 主流集成方式

5.1 pre-commit 集成(推荐)

typos 官方提供 .pre-commit-hooks.yaml,可直接作为 pre-commit hook 使用。由于 typos 本身是预编译二进制,hook 使用 language: python 但实际通过 entry: typos 调用系统 PATH 中的 typos 二进制(pre-commit 会自动从 GitHub Releases 下载对应平台的预编译二进制)。

.pre-commit-config.yaml 配置示例:

repos:
  - repo: https://github.com/crate-ci/typos
    rev: v1.47.2
    hooks:
      - id: typos

说明:

  • typos hook id 会从 GitHub Releases 下载预编译二进制,无需本地安装 Rust 工具链
  • 默认使用 --write-changes --force-exclude 参数,即自动修复拼写错误;如果文件被修改则 pre-commit 会失败,提示开发者检查变更
  • 如果目标平台没有预编译二进制,可使用 typos-docker(需要 Docker)或 typos-src(需要 Rust 工具链)作为 hook id
  • pre-commit 默认仅将暂存区中的变更文件传给 hook,天然支持增量检查

仅检查不自动修复(报告模式):

repos:
  - repo: https://github.com/crate-ci/typos
    rev: v1.47.2
    hooks:
      - id: typos
        args: [] # 不传 --write-changes,仅报告不修复

增量检查:当 typos 作为 pre-commit hook 使用时,pre-commit 框架默认仅将暂存区中的变更文件传给 hook,天然实现文件级增量检查,无需额外配置。CI 中可通过 pre-commit run --all-files 做全量检查,或使用 --from-ref/--to-ref 做 PR 级增量。

5.2 IDE 集成

VS Code

安装 Typos spell checker 扩展(由 typos-lsp 项目提供),基于 LSP 协议实现实时拼写检查和快速修复。

  • 扩展名称:Typos spell checker(扩展 ID:tekumara.typos-vscode
  • 支持自定义配置文件:在 VS Code 设置中配置 typos.config 指定配置文件路径

Neovim

通过 mason.nvim 安装 typos-lsp,自动获得 LSP 拼写检查能力。

Vim

通过 vim-lsp-settings 安装,详见 typos-lsp Vim 文档

Zed Editor

从 Zed 扩展市场安装 Typos 扩展

5.3 二进制安装(推荐首选)

typos 的主要分发方式是预编译二进制文件,支持 Linux(x86_64 / aarch64)、macOS(x86_64 / aarch64)、Windows(x86_64)。

下载安装:

GitHub Releases 下载对应平台的预编译二进制文件。

包管理器安装:

# Homebrew (macOS / Linux)
brew install typos-cli

# Cargo(需要 Rust 工具链)
cargo install typos-cli --locked

# Conda
conda install typos

# Arch Linux
sudo pacman -S typos

5.4 命令行使用方式

常用命令:

# 检查当前目录下的所有文件(仅报告,不修复)
typos

# 自动修复拼写错误
typos --write-changes
typos -w

# 检查指定文件或目录
typos ./src ./docs

# 生成 diff 格式输出(查看会修改什么)
typos --diff

# JSON 格式输出(适合程序化处理)
typos --format json

# 从 stdin 读取,修复后写入 stdout
typos - --write-changes < input.txt > output.txt

调试命令:

# 查看有效配置
typos --dump-config -

# 查看会被检查的文件列表
typos --files

# 查看会被检查的标识符列表
typos --identifiers

# 查看会被检查的单词列表
typos --words

# 查看支持的文件类型
typos --type-list

退出码:

  • 0:未发现拼写错误
  • 2:发现拼写错误
  • 其他值:工具自身错误

增量检查:typos 可直接接收文件路径作为参数,只检查指定的文件:

# 检查指定文件
typos ./src/main.rs ./src/lib.rs

# 检查指定目录
typos ./src

# 从 stdin 读取单个文件
typos - --write-changes < file.txt

结合 git diff 筛选变更文件实现增量检查:

# 检查暂存区中变更的文件
typos $(git diff --name-only --diff-filter=ACMR --cached)

# 检查工作区中相对于 main 分支变更的文件
typos $(git diff --name-only --diff-filter=ACMR main)

# 检查未暂存的变更文件
typos $(git diff --name-only --diff-filter=ACMR)

CI 脚本调用

增量检查:GitHub Actions 中可仅检查 PR 变更文件,通过 git diff 获取变更文件列表后传给 typos Action 的 files 参数:

name: Spelling (Incremental)
permissions:
  contents: read
on: [pull_request]

jobs:
  spelling:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
        with:
          fetch-depth: 0
      - name: Get changed files
        id: changed
        run: |
          FILES=$(git diff --name-only --diff-filter=ACMR origin/${{ github.base_ref }})
          echo "files=$FILES" >> "$GITHUB_OUTPUT"
      - name: Spell Check changed files
        if: steps.changed.outputs.files != ''
        uses: crate-ci/typos@v1.47.2
        with:
          files: ${{ steps.changed.outputs.files }}

5.5 GitHub Action 插件

typos 官方提供 GitHub Action,适合在 PR 级别进行拼写检查。

基础 workflow 示例:

name: Spelling
permissions:
  contents: read
on: [pull_request]

jobs:
  spelling:
    name: Spell Check with Typos
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v5
      - name: Spell Check
        uses: crate-ci/typos@v1.47.2

带参数的示例:

jobs:
  spelling:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - name: Check specific files
        uses: crate-ci/typos@v1.47.2
        with:
          files: ./src ./docs
          config: ./_typos.toml

Action 支持的输入参数:

参数 说明 默认值
files 指定检查的文件或模式 未指定则检查默认文件集
config 自定义配置文件路径 未设置
isolated 忽略隐式配置文件 false
write_changes 在本地 checkout 中写入修复 false

注意:write_changes 仅在本地磁盘写入变更,不会自动提交或推送。可结合其他 Action(如 getsentry/action-git-diff-suggestions)将修复作为 PR 建议提交。


6. 告警抑制(屏蔽)方法

6.1 通过工具配置文件屏蔽

排除文件/目录: 使用 [files] 表的 extend-exclude 字段,支持 gitignore 语法。

[files]
extend-exclude = [
    "localized/",
    "*.po",
    "vendor/",
]

文档:配置参考 - files.extend-exclude

排除特定文件类型的内容检查: 使用 [type.NAME] 表,对特定 glob 模式的文件禁用内容检查(仍检查文件名):

[type.po]
extend-glob = ["*.po"]
check-file = false

文档:配置参考 - type.NAME

将特定单词标记为合法拼写: 使用 [default.extend-words],将拼写错误映射到自身表示"这是合法的":

[default.extend-words]
# 不纠正 "teh"(可能是姓氏)
teh = "teh"
# 项目特定缩写
taits = "taits"

文档:配置参考 - default.extend-words

将特定标识符标记为合法: 使用 [default.extend-identifiers]

[default.extend-identifiers]
# 不纠正这个标识符
AttributeIDSupressMenu = "AttributeIDSupressMenu"

文档:配置参考 - default.extend-identifiers

使用正则表达式忽略匹配的标识符或单词:

[default]
extend-ignore-identifiers-re = [
    # 忽略 SSL 密码套件格式的标识符
    "\\bTLS_[A-Z0-9_]+(_anon_[A-Z0-9_]+)?\\b",
    # 忽略短标识符(4 字符以下可能是噪音)
    "^[a-zA-Z]{1,4}$",
]
extend-ignore-words-re = [
    # 忽略短单词
    "^[a-zA-Z]{1,4}$",
]

文档:配置参考 - extend-ignore-identifiers-re / extend-ignore-words-re

使用正则表达式忽略特定行或代码块:

[default]
extend-ignore-re = [
    # 忽略以 `# spellchecker:disable-line` 结尾的行
    "(?Rm)^.*(#|//)\\s*spellchecker:disable-line$",
    # 忽略 `# spellchecker:ignore-next-line` 的下一行
    "(#|//)\\s*spellchecker:ignore-next-line\\n.*",
    # 忽略 `# spellchecker:off` 和 `# spellchecker:on` 之间的块
    "(?s)(#|//)\\s*spellchecker:off.*?\\n\\s*(#|//)\\s*spellchecker:on",
]

文档:配置参考 - extend-ignore-re

6.2 通过工具命令行参数屏蔽

# 排除文件/目录(gitignore 语法)
typos --exclude "localized/" --exclude "vendor/"

# 强制尊重配置文件中的 extend-exclude(即使命令行传入了文件路径)
typos --force-exclude ./src

# 不检查隐藏文件和目录
typos --hidden

# 不检查文件名
typos --no-check-filename

# 指定自定义配置文件
typos --config ./custom-typos.toml

文档:配置参考 - CLI 参数

6.3 通过 pre-commit 配置屏蔽

.pre-commit-config.yaml 中,可通过 hook 级别的 filesexcludetypesexclude_types 控制检查范围:

repos:
  - repo: https://github.com/crate-ci/typos
    rev: v1.47.2
    hooks:
      - id: typos
        exclude: ^(localized/|vendor/)
        files: \.(rs|py|js|ts|md)$
        types: [text]

文档:pre-commit 集成文档

6.4 通过代码注释屏蔽

typos 本身不提供内置的行级注释语法,但可通过配置文件中的 extend-ignore-re 正则表达式实现类似效果。官方推荐的注释屏蔽模式:

[default]
extend-ignore-re = [
    # 行级屏蔽:行尾添加 `# spellchecker:disable-line` 或 `// spellchecker:disable-line`
    "(?Rm)^.*(#|//)\\s*spellchecker:disable-line$",
    # 下一行屏蔽:添加 `# spellchecker:ignore-next-line`
    "(#|//)\\s*spellchecker:ignore-next-line\\n.*",
    # 块级屏蔽:`# spellchecker:off` ... `# spellchecker:on`
    "(?s)(#|//)\\s*spellchecker:off.*?\\n\\s*(#|//)\\s*spellchecker:on",
]

文档:配置参考 - 示例配置