news 2026/9/15 18:54:12

GitHub Linguist 如何添加一种新语言:languages.yml、语法与样本的完整流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
GitHub Linguist 如何添加一种新语言:languages.yml、语法与样本的完整流程

GitHub Linguist 如何添加一种新语言:languages.yml、语法与样本的完整流程

【免费下载链接】linguistLanguage Savant. If your repository's language is being reported incorrectly, send us a pull request!项目地址: https://gitcode.com/GitHub_Trending/li/linguist

如果你的语言目前不被 GitHub 识别,仓库语言统计栏里没有它,或者你的扩展名被归到了别的语言下,Linguist 官方给出的解决方式就是向 linguist 仓库提交一个 pull request,走「languages.yml登记语言 + 添加高亮语法 + 补充样本代码」的完整流程。本文按 CONTRIBUTING.md 中 “Adding a language” 一节的实际操作路径展开:先搭好开发环境,再依次修改 lib/linguist/languages.yml、运行script/add-grammar引入 TextMate 兼容语法、在 samples/ 目录下放好真实代码样本、生成语言 ID,最后通过测试并开 PR。

开始之前有两个前提需要确认:

  • 使用量门槛:Linguist 只接受在公开 GitHub 仓库中有足够使用量的新语言,非常新或纯兴趣型(hobby)语言会被直接关闭。CONTRIBUTING.md 给出的量化标准是:
    • 每仓库会多次出现的扩展名(如.rb),要求近一年内被 GitHub Search 索引的文件数至少2000(不含 fork);
    • 每仓库只出现一次的文件名(如Makefile),要求近一年内至少200个文件(不含 fork);
    • 结果需要在不同的:user/:repo组合间分布合理,如果某个用户(比如语言作者本人)占比过高,评估时会用-user:<username>将其过滤后再看。
    • 这些证据要通过 PR 模板中要求的 GitHub 搜索链接提供,且要留意 GitHub Search 本身对可索引内容的限制。
  • 语法许可证script/add-grammar只接受带有 CONTRIBUTING.md 所链接许可证列表 之一的高亮语法;许可证不符的语法无法添加。

准备开发环境

Linguist 是 Ruby 库,本地贡献需要较新版本的 Ruby。macOS/XCode 自带的 Ruby 安装依赖时已知有问题,文档建议改用 Homebrew、rbenvrvmruby-buildasdf等包管理方式安装。

依赖方面(见 CONTRIBUTING.md):

  • 字符编码检测库charlock_holmes(依赖 ICU,即icu4c);
  • rugged提供的 libgit2 绑定(依赖cmakepkg-config);
  • 安装 gem 依赖需要 Bundler v1.10.0 或更新版本;
  • 添加或更新语法时还需要 Docker

在 Ubuntu 上,文档给出的系统依赖安装命令(需要 root 权限,会修改系统软件包)是:

apt-get install cmake pkg-config libicu-dev docker.io ruby ruby-dev zlib1g-dev build-essential libssl-dev

macOS 上则依赖 Getting started 步骤里的script/bootstrap自动处理。环境搭建有三种方式:GitHub Codespaces(文档推荐,开箱即用)、本地 VS Code dev container(打开仓库后 VS Code 会提示在容器内运行,无需额外配置)、或直接在本地系统安装。本文按本地系统方式写。

克隆仓库并运行script/bootstrap安装依赖。script/bootstrap的作用(见 script/bootstrap):在 macOS 上自动执行brew bundle安装 Homebrew 依赖,然后bundle install安装 gem 依赖(安装到vendor/gems),接着git submodule init/git submodule sync并调用 script/fast-submodule-update 初始化语法子模块,最后bundle exec rake samples生成样本数据。

git clone https://github.com/github/linguist.git cd linguist/ script/bootstrap

验证环境可用:从克隆的仓库直接运行 Linguist:

bundle exec bin/github-linguist --breakdown

能输出当前仓库的语言占比和文件明细,说明环境搭建完成。

在 languages.yml 中添加语言条目

在 lib/linguist/languages.yml 中为新语言添加一条目。该文件头部注释定义了各字段的含义和必填项,其中:

  • type必填,取值为dataprogrammingmarkupprosedata/prose类型的语言不计入仓库语言统计,见 docs/how-linguist-works.md);
  • extensions:关联的文件扩展名列表,按升序 ASCII 排序,主扩展名必须放在第一位
  • filenames:关联的文件名列表,与extensions二者至少其一;
  • tm_scope:该语言对应的 TextMate scope,需要与grammars.yml中列出的 scope 之一匹配;没有 TextMate 语法时填none
  • language_id:GitHub 内部使用的唯一标识,由script/update-ids生成,文档明确要求不要手工填写——所以这一步先留空。

如果新语言定义的扩展名已经存在于languages.yml并被别的语言使用,还有两个额外要求(与“给已有语言加扩展名”一节相同):

  1. samples目录中,每个使用该扩展名的语言至少要有两个示例文件;
  2. 如果两种语言外观相似,或其中一种有可唯一识别的特征,考虑写一个启发式(heuristic)帮助分类。目标是尽量减少误判(false positives)。

用 script/add-grammar 添加高亮语法

语法高亮由 TextMate 兼容语法驱动。为新语言添加语法的命令:

script/add-grammar https://github.com/某作者/MyGrammar

这条命令会分析语法仓库,没有问题时把它以子模块形式加入 Linguist 仓库;如果分析发现问题,你需要向该语法的维护者报告,否则无法添加(见 CONTRIBUTING.md)。命令的参数就是语法仓库的 URL,示例中https://github.com/某作者/MyGrammar需替换为你要添加的语言语法仓库地址。

script/add-grammar 本身还定义了-q/--quiet(失败时不输出额外信息)和-r/--replace <submodule>(替换已有语法子模块)两个选项;--replace用于切换已有语言的语法来源,属于另一个维护场景,添加新语言时用不到。该脚本启动时会检查docker git sed ruby bundle是否可用,缺失时会直接报错退出——这对应上面“添加语法需要 Docker”的前提。

语法的正则表达式兼容性会在编译阶段检查:Linguist 使用 PCRE,而 TextMate 语法基于 Oniguruma,两者大多兼容但偶有差异,CONTRIBUTING.md 说明语法更新时 Linguist 的 grammar compiler 会标出这些问题。

向 samples 目录添加样本代码

在 samples/ 目录下对应语言的子目录中添加样本文件,文件名使用该语言的扩展名。文档对样本的要求:

  • 优先选择展示常用写法的真实世界代码,越能代表该语言的结构越好;
  • “Hello world” 和教程里的示例不会被接受
  • 开 PR 时须明确说明样本代码的许可证:能直接链接到原始来源最好;如果样本是专为这个 PR 编写且同意按 Linguist 的 MIT 许可证收录,也可以这样声明。

样本的作用之一是喂给分类器:docs/how-linguist-works.md 描述了检测策略链(modeline、常见文件名、shebang、扩展名、XML header、man page section、启发式、朴素贝叶斯分类)按序生效,样本是分类器学习材料的来源;docs/troubleshooting.md 也提到“增加样本可以让分类器更聪明”。

生成 language_id

语言条目和样本都就位后,运行:

script/update-ids

script/update-ids 会读取lib/linguist/languages.yml,为所有缺少language_id字段的语言生成 ID 并写回文件。脚本输出的 “Updated N language(s)” 列表就是它更新的条目;没有缺失 ID 时会输出 “No languages were found with missing IDs.”。它还提供--check参数只做检查不改文件,用于查看哪些语言缺 ID。注意它更新的是所有缺 ID 的语言——因此不要在自己的分支上遗留他人未合并的改动,避免把无关语言一并带进你的 PR。

运行测试验证

CONTRIBUTING.md 给出两条本地验证命令:

# 运行完整测试套件 bundle exec rake test # 单独测试分类器 bundle exec script/cross-validation --test

如果本地跑测试困难(比如没有太多 Ruby 经验),文档明确表示可以让 GitHub Actions 代劳:直接开 pull request,CI 会自动开始跑测试。

开 PR 与后续

PR 必须使用并填写 PR 模板,未填模板的 PR 不会被 review。模板要求的关键内容:

  • 链接到展示该语言实际使用量的 GitHub 搜索结果(对应上面的使用量门槛);
  • 样本代码的许可证说明,能直接链接原始来源最好。

PR 合并后不会立刻出现在 GitHub 上:变更要等新的 Linguist 版本发布并部署到 GitHub.com 才生效,发布节奏没有固定时间,目标是每三到四个月至少一次(见 docs/troubleshooting.md)。另外注意:新语言在合并且新版本部署后,还会在 GitHub 的搜索结果中延迟数周到数月才出现,因为 GitHub 搜索使用一个独立于 Linguist 的内部语言检测库,会滞后于 Linguist。

限制与边界

  • 使用量不足的语言(非常新、纯兴趣型)PR 会被关闭,这是硬性门槛,样本和语法再完整也无法绕过;
  • 语法分析失败时script/add-grammar无法继续,只能向语法上游维护者报告问题,没有旁路;
  • 语法许可证不在允许列表内时同样无法添加;
  • 共享扩展名冲突(新语言复用了已被别的语言使用的扩展名)必须用“每个语言至少两个样本 + 必要时写启发式”来处理,这是为避免误判而设的要求。

按以上路径走完——languages.yml条目(留空language_id)、script/add-grammar引入语法、samples/样本、script/update-ids生成 ID、bundle exec rake test通过、按模板开 PR——就是为 Linguist 添加一种新语言的全部流程。

【免费下载链接】linguistLanguage Savant. If your repository's language is being reported incorrectly, send us a pull request!项目地址: https://gitcode.com/GitHub_Trending/li/linguist

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 18:54:09

如何用 deck.gl 的 JSON 模块从后端下发图层配置渲染可视化

如何用 deck.gl 的 JSON 模块从后端下发图层配置渲染可视化 【免费下载链接】deck.gl WebGL2 powered visualization framework 项目地址: https://gitcode.com/GitHub_Trending/de/deck.gl 当后端已经能产出一段描述可视化的 JSON 文本时&#xff0c;前端可以不用为每种…

作者头像 李华
网站建设 2026/9/15 18:53:19

使用 Encore 将单体(Monolith)拆分为微服务:完整实战指南

使用 Encore 将单体&#xff08;Monolith&#xff09;拆分为微服务&#xff1a;完整实战指南 【免费下载链接】encore The infrastructure platform for the intelligence era 项目地址: https://gitcode.com/GitHub_Trending/encor/encore 本指南基于 Encore Go 应用模型…

作者头像 李华
网站建设 2026/9/15 18:53:18

OI Wiki 弦图:如何判定弦图并利用其性质求解问题

OI Wiki 弦图&#xff1a;如何判定弦图并利用其性质求解问题 【免费下载链接】OI-wiki :star2: Wiki of OI / ICPC for everyone. &#xff08;某大型游戏线上攻略&#xff0c;内含炫酷算术魔法&#xff09; 项目地址: https://gitcode.com/GitHub_Trending/oi/OI-wiki …

作者头像 李华
网站建设 2026/9/15 18:52:46

电气原理图转PLC梯形图的逻辑重构方法

1. 电气图到梯形图&#xff1a;不是“翻译”&#xff0c;而是“控制逻辑的重新建模”你见过最让人头疼的工控现场吗&#xff1f;不是PLC程序跑不起来&#xff0c;也不是通讯连不上——而是手捧一张密密麻麻的电气原理图&#xff0c;站在控制柜前&#xff0c;盯着继电器、接触器…

作者头像 李华