Cirru 演进历程: 2012 ~ 2016

360 阅读8分钟
原文链接: segmentfault.com

Cirru 的初衷是的逃脱文本语法的麻烦, 摆脱文本的局限,
基于 S-Expression 简化的结构用来表示表达式嵌套, 作为存储结构,
然后 Cirru Editor 基于这个结构实现, 通过图形界面来修改代码,
早期 Cirru 也提供了文本格式来兼容, 现在倾向于不使用.
目前基于 Cirru 设计的最重要的工具是 Stack Editor, 用于生成 Clojure 代码.
Stack Editor 需要维护和功能修补, 后续进展应该是非常缓慢的.

一个好的想法不会消亡, 但是 Cirru 目前的载体却可能被时间淹没,
也许未来别的代码方案会吸收 AST 编辑的想法, 只是不会用 Cirru 的代号了.
我希望未来 Cirru 能在某些场景发挥作用带来价值, 那也是我的价值...
对于 Cirru 的探索已经走到了一个岔路的尽头了, 但我没有开新项目的实力.
一个领域呈现的初期, 需要有人大胆想象用于开拓, 孤独地飞奔和碰壁,
等到行业成熟, 又需要维护和发展的能力, 要说服一大帮人一起缓慢直行.
有的人擅长探索, 有的人擅长守业, 有的人适合踏实做事, 只能找到自己的位置吧.

这篇文章我想梳理一下 Cirru 至今的历程, 改变, 和挫折,
Cirru 是基于 MIT 开源的, 或者说其实就是个想法, 自由传播吧,
一个想法可能会是另一个想法里缺失的一环, 随便拿去用吧.
后面的历史基于回忆和微博整理而成, 具体时间以微博为准:
weibo.com/jiyinyiyong…
时隔太久, 我显然不能回忆起每个细节, 总之供参考吧.

背景

当你像是玩具一样使用代码时, 语法设计的轻巧, 修改逻辑的便利, 就变得非常重要.
特别是写代码时你在思考, 那时繁琐的语法就会带来不是的分心和打断,
越是努力去思考问题, 越是反感这种语法上报错带来的打断. 就像在控制自己的手.
我认定了基于严格缩进设计的最精简语法才是我想要的工具, 比如 coffee.

所以很早的时候我做了一些试验, 把代码的层次尽量展示出来.
而在所有编程语言语法设计当中, 最明确表达这个理念的是 Lisp,
我也尝试过将 Lisp 跨行的括号用缩进取代, 其实也就是 Cirru 文本格式的雏形.

早期图形

那年王垠发了个文章"Unix的缺陷(1) - 从命令行谈起", 带给我不小的震撼,
www.zhihu.com/questio...
文本只是程序结构的一种表示而已, 我们可以换一种表示, 呈现相同的程序.
当时可能看过结构化编辑器的例子了, 然后我萌生了想法,
也就是用简化的 AST 表示代码, 再用图形界面去编辑, 绕过文本的限制.

现在能追溯到的最早的原型是 2012.05 放假期间发布的,
我用 DOM 实现了一个简单的 demo, 同时监听浏览器全局键盘事件进行操作,
每次操作诚心绘制整个页面, 输入文本都用的 prompt:
video.tudou.com/v/XMjE...

稍后几天还有一次样式的改进, 当时的嵌套的比较密集的,
布局算法过于简单, 随便写一点代码, 界面就有点难看懂了:
video.tudou.com/v/XMjE...

五月底经过一些样式的重新设计, 已经可以用来展示比较复杂的代码了,
重点还是在布局算法, 文本语法写的代码比较好看, 图形界面怎样才能做到更好看:
weibo.com/1651843872/…

七月初, 尝试了去优化树内容输入的问题, 去掉 prompt 引入 <div contenteditable>,
Cirru 这个名字大概是那时候取的, 参考微博的时间线, 很多信息遗漏了.
video.tudou.com/v/XMjE...

然后做的一个尝试是模仿 Sublime Text 自动提示已有的词语, 非常粗糙:
weibo.com/1651843872/…

七月底做一次尝试是在表达式上增加解释器执行的结果, 很稚嫩, 但有点意思吧,
模仿 LightTable 在每一行结尾显示当前结果, 我显示在表达式上:
video.tudou.com/v/XMjE...

十月初做了一次重写, 记不清当时的细节, 看上去背景色改变比较明显.
源代码我都还保留在 github.com/Cirru, 但是项目名对不上了.
weibo.com/1651843872/…

十月底我借助重构好的 Cirru Editor 做出了一个比较复杂的解释器的 demo,
demo 能被直接编辑, 然后点击触发运行, 行为相对复杂了:
weibo.com/1651843872/…

文本语法

早期的图形方案实现很差, 性能很差, 体验一般, 显然没法使用,
而且当时没有强大的模块化方案, 我的代码复用起来也挺麻烦的.
于是我开始考虑一个文本格式, 也就是去掉跨行括号的 Lisp, 等效图形界面的数据结构.

早期文本的写法要考虑特殊处理空格, 我是强行转义的,
当时应该会写简单的 Lisp 语法的 parser 了, 可能使用取巧的写法.
十二月份的时候, 竟然还尝试了做 Sublime Text 的语法高亮:
weibo.com/1651843872/…

2013 年一月底, 弄了一个看上去比较清爽的文本写法的
weibo.com/1651843872/…

后来语法经过一些修修补补, 增加了引号, 美元符, 逗号, 逐渐到现在的样子
十月份的时候 Sublime 高亮已经相当成熟.
weibo.com/1651843872/…

同时基于 Cirru 探索了一下解释器, 当时自己在学习这块东西:
weibo.com/1651843872/…

逐渐开始用 Cirru 文本语法尝试对付前端的问题. 比如生成 HTML.
weibo.com/1651843872/…

十月底增加了 codemirror 高亮:
weibo.com/1651843872/…

到 2014 年 2 月, 整个文本格式和 parser 算比较成熟了.
video.tudou.com/v/XMjI...

2014.10 界面也做过一些调整, 细节改进.
weibo.com/1651843872/…

还是那个基于表达式显示值的想法, 基于另一个思路做了探索:
video.tudou.com/v/XMjI...

四月底, 基于 Pygments 做了高亮, 几个月后 GitHub 支持 Cirru 的高亮.
weibo.com/1651843872/…
后面还有些多语言的 parser 之类的项目, 没有仔细追踪...

2015.08 试验基于 Cirru 的 Diff/Patch 算法.
weibo.com/1651843872/…

2016.01 制造了 GIF 来展示 Cirru 文本格式的解析.
weibo.com/1651843872/…

生成 AST

2013.10 也尝试了用 Cirru 生成 JavaScript, 还尝试了一下 SourceMaps.
weibo.com/1651843872/…

2014.03 Cirru HTML 做了一个比较清晰的版本.
video.tudou.com/v/XMjI...

2015.04 用 Cirru 生成 Rust AST, 然后生成 Ruby 代码.

2015.01 CirruScript 基本成熟,
weibo.com/1651843872/…

2015.05 切换到了现在的 Logo.
weibo.com/1651843872/…

图形界面

2014.10 重构了 Cirru Editor, 而且实现了简单的 Light Editor,
Light Editor 可以通过 WebSocket 发送代码给后端保存为文件,
这样就能做到从网页编辑器直接编辑保存文件了, 也就是 Stack Editor 的原型.
weibo.com/1651843872/…

2015.03 月底基于 React 重构了 Cirru Editor, 同时 Light Editor 更新.
这时候 React 实现的编辑器很慢, 没有基于 Immutable 优化.
video.tudou.com/v/XMjM...

2015 年三月, 基于的 React 进行 Cirru Editor 的重构,
然而没有解决性能问题, 只是解决了组件化的问题.
weibo.com/1651843872/…

2015.10 基于尝试了一下用分形来展示 Cirru 的 AST.
weibo.com/1651843872/…

2016.03 想到了一个可以扩展 Cirru 布局的办法, 也就是现在的疯狂缩进模式.
weibo.com/1651843872/…

2016.05 尝试了一下在触摸屏上输入 Cirru 代码.

2016.06 制作教程用到个图片, 已经用 Light Editor 写了挺久的代码.
weibo.com/1651843872/…

2016.07 使用 Light Editor 编写网页的体验.
weibo.com/1651843872/…

2016.08 用 ClojureScript 重新实现了 Cirru Editor 和 Light Editor.
weibo.com/1651843872/…

2016.08 Stack Editor 原型已经完成. 并且做了很多的小的改进.
weibo.com/1651843872/…


2016.08 演示了一下布局算法.
weibo.com/1651843872/…

2016.08 更新了一下折叠表达式的功能, 虽然后来很少用.
weibo.com/1651843872/…

2017.02 Stack Editor 存储格式已经整个是基于 EDN 了.
weibo.com/1651843872/…

总结

2016 之后的修改很多. 2017 年有很多的 Stack Editor 相关的修改. 都没有整理完成
本文主要基于微博整理. 后续的更新在 twitter.com/cirrulang
由于 Twitter 上记录比较详细, 我也不重复梳理一遍了.
更详细的时间要对照 GitHub, 然而那样非常无聊.
如果有时间, 把我微博, Twitter, GitHub 上所有相关信息爬一遍应该是最完整的.

基于时间线可以看到, 最初 Cirru 为了图形编辑器而设计, 实现比较粗糙,
当时我就记着尝试去配合解释器来实现 IDE 方向的一些功能了, 很原始.
随后的为了实用性, 设计了缩进的文本格式, 并且基于文本格式做了大量的应用,
比如 Cirru Html, CirruScript, 还有各种生成比如 Clojure 代码的 sepal.clj .
期间随着 React, ClojureScript 生态完善, 我用这些技术重新实现了图形编辑器,
这时有不可变数据优化的编辑器性能和体验就提升了很多, 复用性也不错.
并且基于编辑器逐步扩展成了整个文件夹源码编辑的 Stack Editor.

现在 Cirru 当初的想法稳定在 Stack Editor 这个工具上.
在 Stack Editor 里还加入了很多功能, 最主要的就是跳转到定义.
前面也说了, Stack Editor 会占用大量的精力维护, 很难继续探索 Cirru 了.
我相信基于 AST 的编程方案还有很多的可能性.