如何向开源项目贡献代码

2018 年 12 月 08 日

在写 「The Little Schemer」知识点整理 系列的时候,理想状态是我一口气把书看完,并快速概括出其中的要点并写下来。往往事与愿违。本文就是阅读此书过程中,“一口气”被分割成好几口气之后的附属品,根据这几天在 GitHub 上提交的几个有关代码高亮的 PR,谈谈前因后果以及心得体会。

1. 博客的代码高亮问题

1.1 起因

我在写到系列第三篇时,文章里的代码块比较多,却基本没有高亮。本着就算不是对读者,对自己来说观感也不佳的想法,开始着手解决这个问题。

1.2 经过

首先分析具体现象,发现不支持 scheme 的语法高亮,以前文章里所用到的 js bash 等语言就没有问题。

于是我们从源头——此博客的生成框架—— Hexo 开始一步步查找原因:

  1. 阅读其源码可以知道,它使用了业界运用最广泛的 highlight.js 来高亮代码;
  2. 再看 highlight.js 文档,发现它是支持像 Scheme 这样的 Lisp 语言的高亮的;
  3. 而后查看生成文章的页面元素,按照 Hexo 和 highlight.js 的设置,格式正确无误。

排除了框架自身的原因后,我们来看看主题部分。博客现在使用 NexT 主题,按照如下步骤寻找问题:

  1. 找到主题里设置高亮部分的 css,与 highlight.js 对 Scheme 语言的设置进行对比;
  2. 我们发现,在 highlightjs/highlight.js@8616294 这个 commit 里,引入了对 Lisp 语言更好的支持,其中新的 builtin-name 是 NexT 所欠缺的。

1.3 结果

解决方案:theme-next/hexo-theme-next#492

经过测试,证明上面得出的结论无误,只要在主题里的高亮部分也引入 builtin-name 这个新的 css class 就可以实现对 Scheme 的高亮。回去看之前的几篇文章,可以看到代码块的关键字部分已经被高亮为橘色。

2. Markdown 文件的代码高亮问题

2.1 起因

我是在 Typora 下完成的前三章整理,写作体验相当不错。但是当我从第四章开始使用 VS Code 书写 Markdown 之后,又出现了新的问题:Scheme 代码块不能被高亮,只有预览才可以。

2.2 经过

有了刚才的经验,我们先与现有的比较,发现常用语言表现良好。

继续。源头指向 VS Code,查看源码我们找到它用来描述 markdown 的文件: /extensions/markdown-basics/syntaxes/markdown.tmLanguage.json。可以看到里面有大量 fenced_code_block_language 字段,不言而喻,这些就是用来描述 markdown 里不同语言的代码块的。啊,果然没有 Scheme 语言的实现。

如果再仔细读每个 fenced_code_block_language 字段下的内容,会发现大同小异,有所变化的只有匹配正则以及每个语言所对应的 "patterns": "source.language"

那么 source.language 是哪里来的呢。是通过叫 language identifier 的东西定义出来的。观察 /extensions 目录,包含了一大堆常用语言的目录,这些就是 VS Code 内建的语言支持,一种语言即一个内建插件,也相应地定义了该语言的 language identifier。没有列出的语言需要通过插件引入,于是我们可能需要自行创建对 Scheme 语言的定义了。在此之前,最好搜索一下 VS Code 市场,也许会发现目标语言已经有了一份相对完整的定义,比如我找到了 vscode-scheme。试用一下,咦,.scm .rkt 等文件的高亮和快捷键什么的倒是有了,markdown 里面代码块的高亮却是不支持。事情到现在应该比较清晰了,我们的目标就是去扩展这个插件。

下一个问题,如何扩展?天下代码一大抄 😂,我们搜索 VS Code 的 Issues 或者 Pull requests,看是否有过类似的实现。最后找到一个可以直接注入配置的例子:injection-example。蛋疼的搜索和 debug 过程略去不表,最终实现看上去挺简单的:

  1. 根据例子新建一个该语言 markdown 部分的描述文件 scheme.markdown.tmLanguage.json
  2. package.json 里面引入此文件并定义对应的 scopeName,注入 markdown 配置;
  3. 这时 VS Code 的 Markdown 插件可以读到这份配置,当在代码块里看到 scheme 时,就调用 vscode-scheme 已经定义好的 parser。

2.3 结果

解决方案:sjhuangx/vscode-scheme#3

3. 面向需求编程

以前总在想着怎么造轮子,不出意外,想造的轮子都已经有了相应的实现。虽然自己可以继续造一个,但是没有必要。所谓“开源”的目的是什么呢?其中一点就是可以通过社区改进项目中的不足。既然当不成 Maintainer,那就做个 Contributor 吧,解决自己需求的同时,完善和加强原项目的功能。这就是我认为向开源项目贡献代码最直接而简单的方式。

有一个特别佩服的人—— @Easy,观察他的日常微博不难发现,他通常都会因为某个在市面上暂时没有的功能,而根据自己的需求马上动手实现一份,而且产出速度特别惊人。我很想学习其中的精神,缺什么写什么。

需求不是经常会有,但是一旦来临,我希望自己有这个能力去完成它。以上就是自己对于这几天提交的 PR 的一个记录。短期目标:Make my life better。至少是开发生活吧。🎉


EOF

Twinkle 的博客
瞎折腾