Writing an editor in less than 1000 lines of code, just for fun

Salvatore Sanfilippo

为了好玩,在不到 1000 行代码中编写一个编辑器

警告:这是一篇又长又没什么用的博客文章。TLDR 是:我只是为了好玩,用不到 1000 行代码写了一个不依赖 ncurses 的文本编辑器,并支持语法高亮和搜索功能。代码在这里:http://github.com/antirez/kilo

录屏在这里:https://asciinema.org/a/90r2i9bq8po03nazhqtsifksb

感伤派请继续往下读……

几周前,有一则关于 Nano 编辑器不再属于 GNU 项目的新闻。我的第一反应是:哇,人们居然还真的在乎一个老编辑器,而它还是一个最初属于基于终端的 EMAIL CLIENT 的编辑器的克隆版本。再说一遍,“email client”。“电子邮件客户端”这个概念如今本身都已经消失了,一切都变了。然而我在 Hacker News 上读到,有不少人写道,他们在随机系统上执行系统管理员任务时,经常因为能用到 nano 而得到帮助。我的儿子写的第一个 C 程序也是用 nano 写的。它带来的是一种可以接受的体验,不要求用户此前有编辑文件的经验。

于是我开始想,要写一个比 Nano 本身小得多的文本编辑器。基本上只是为了好玩,因为我喜欢并且欣赏小程序。

如今写一个编辑器究竟有多无聊、多没用、多浪费时间?我们理应去编写那些闪亮、不可思议的项目——非常酷、非常复杂、很有价值的东西。但有时候,做一些没有明确用途的事情反而令人耳目一新。这里面也有一些回忆……

我记得自己最初使用 Commodore 16 内置 ROM 汇编器的经历,也记得后来童年时期用过的那些家用电脑和 BASIC 解释器。编辑器是人与机器之间一种根本性的连接。它让人能够写下计算机可以解释的东西。方形提示符一闪一闪的样子,是我们许多人永远不会忘记的。

好吧,这些都很美好,但我的时间非常有限。两个周末里,我只有几个小时可用,其间还安排了家庭活动,并且要在漫长的烧烤聚会中准备给朋友吃的肉。也许我还是可以靠一些小技巧,利用几个空闲小时写出一个编辑器。我的目标是写一个非常小、不使用 curses、带语法高亮的编辑器。基本上,要能用就行。这就是全部……东西虽小,但要在几个小时内从头写完这一切,已经很难了。

不过……等等,我过去其实写过一个编辑器,它是 LOAD81 项目的一部分——一个基于 Lua、面向儿童的编程环境。也许我可以直接复用它……另外,与其使用 SDL 把内容写到屏幕上,不如直接向终端发送 VT100 转义序列?而且我在 linenoise 里也写过这部分代码;linenoise 是另一个玩具项目,后来最终被一些其他严肃项目采用了。所以,也许可以把两者混合起来……

第一个星期的周六早上,我去了海边,感觉非常棒。后来我的兄弟从 Edinburg 来到 Catania。一天结束时,我们一起坐在花园里,带着各自的笔记本电脑,努力抵挡白天 30 度的高温,于是我开始搭建这个编辑器的第一个骨架。LOAD81 的代码模块化程度相当高,把它从原项目中抽出来简直不费吹灰之力。几个小时后,我已经大致能编辑了,而这时也到了该睡觉的时间。第二天,在再次出发去海边之前,我又继续做了一会儿。我的 15 岁孩子睡到下午 1 点才起床——毕竟我 15 岁那年暑假也是这样——所以我利用等他起床的时间,每次冲刺编码 30 分钟,其余时间则陪我可爱的女儿玩。最后,到了星期日晚上晚些时候,我试着把剩下的问题全部修好。

嘿,我记得几年前,搞一个项目就是要全职投入,连续好多天地去“hack”它。我现在老了,但还年轻得足以编写玩具编辑器,并把它当成一项严肃的事业 :-)

不过生活是艰难的,星期一还是来了。真正的工作,没有时间做玩具项目,甚至没有时间发布我周末写出来的东西……它值得进行一些最低限度的润色,再配上一篇博客文章。

直到这个星期一,我才又有机会着手处理“Kilo”编辑器。它之所以叫 Kilo,是因为它的代码少于 1024 行。用于统计代码行数的“cloc”工具告诉我,在达到 1024 LOC 之前,我还剩大约 100 行空间,而一个严肃的编辑器毕竟需要“搜索”功能。所以我又回到代码中,同时也试着稍微重构并重新添加一些注释。毕竟你知道,在几个小时内把两个项目的代码片段混在一起时,代码质量很可能不会太理想。

好了,现在是发布它的时候了,这个疯狂项目也就结束了。也许有人会把它作为起点,用来编写一个真正的编辑器;或者,也可以用它来编写某种新的、有趣的 CLI,超越通常的 REPL 风格模型。

代码在:http://github.com/antirez/kilo

HN 评论:https://news.ycombinator.com/item?id=12065217