四月 27, 2008

Pretty print macro expansion

*scratch* buffer里面运行macroexpand展开宏后的程序全在一行,不好读,使用pp可以获得更好的效果。

(defun wl-pp-macroexpand-at-point ()
  (interactive)
  (pp-eval-expression '(macroexpand (read (thing-at-point 'sexp)))))

(define-key emacs-lisp-mode-map (kbd "C-c C-c") 'wl-pp-macroexpand-at-point)

将光标放在想要展开的宏调用的左括号前,调用该程序,宏展开的结果显示在*Pp Eval Output* buffer里。

如果想看宏调用执行后的结果,可以使用下面的函数。

(defun wl-pp-evaluate-at-point ()
  (interactive)
  (pp-eval-expression (macroexpand (read (thing-at-point 'sexp)))))

(define-key emacs-lisp-mode-map (kbd "C-c C-e") 'wl-pp-evaluate-at-point)

四月 23, 2008

Emacs lisp unit test framework

几经修改,终于让evil eval里面提到的Emacs lisp单元测试框架成形了。你可以通过http://www.wanglianghome.org/svn/test/test.el查看或下载,也可以通过subversion。

$ svn co http://www.wanglianghome.org/svn/test

里面还有一个小例子和一张截屏

test和其它单元测试框架有两点不同,首先是抛弃了suite概念,而改用tag,同一个case可以属于多个tag;其次是通过一个test-assert-compare函数包含了所以已经实现和还没有实现的、二元assert功能,这使得整个代码无需很长(除去开头的文档,250行左右),却可以提供更多的功能,而且接口很一致。除此之外,还给用户提供了一定的扩展能力,使其能够编写更复杂的assert函数。

第一次在emacswiki上添加了属于自己的一笔,在UnitTest页面Automated testing frameworks一节的末尾。:-)

四月 20, 2008

Git is available on Windows

最近看到git在一些中文blog中被提及,互相分享使用经验和感受,但是其中有一些误区,比如Windows上没有git。在Windows上是可以使用git的,我就在使用,使用的是Cygwin提供的git。

实际上,Cygwin维护的git是相当新的,早就是1.5版本了,而在Ubuntu和Debian上还都是1.4,连git tag列出tag的功能都没有,我只好自己编译最新的版本。git的开发虽然不能说一日千里,但速度确实非常快,所以请尽量使用最新发布的版本,阅读最新的文档。前两天还看到有人通过del.icio.us分享的中文git文档,最后更新时间是2006年初。比如该文开头提到的命令git-init-db,现在已经改为git init。而且早期的git被认为是比较难用,难以上手的。

四月 16, 2008

Evil eval

lisp中的eval和C中的goto一样,都被人强烈建议不要使用。奈何咱水平有限,也只好evil一把了。

都是为了做单元测试,emacswiki上逛了一圈,没发现什么好用的,文档也有限,看看人家的代码不长,索性自己写一个吧,几个函数加一个macro搞定,只是用了eval。有了单元测试,写起代码来底气十足,再也不会像以前那样补了东墙弄倒西墙。尽管看common lisp的书要多一些,但代码还是写emacs lisp多。代码写得多了发现很多功能很容易实现,越写越想写,一天下来,几乎精疲力尽,其它的事情都不想做了。

写lisp程序真的很容易上瘾。

四月 09, 2008

Define mode-map before mode definition

在Intel的时候写过一个简单的emacs mode,这次又写了一个。和前一个一样,都是用来显示编译器打印出来的中间语言,不过这次的要复杂一些,除了高亮、光标定位之外,还有narrow、以及自动生成控制流图等(用dot)。

写得过程中发现一个问题,即define-derived-mode要在定义mode-map的语句之后,如:

(defvar foo-mode-map ...)
(define-derived-mode foo-mode ...)

否则keybinding为空!因为define-derived-mode如果发现mode-map没有定义,就会自动定义一个,而后面的defvar在发现mode-map已经定义,就不会再赋值了。

四月 06, 2008

Late code contribution

偶然发现server.el里的server-running-p应该是用来检测是否有emacs server已经启动,但实际上却没有作用。前后看了看,原来是server-socket-dir的设置有问题,于是自己做了修改,把server-running-p里面的server-socket-dir换成了(or server-socket-dir (format "/tmp/
emacs%d" (user-uid))),这样就可以了。

其实这个问题上周四就发现了,拖了拖,到周六晚上无聊的时候才在gnu.emacs.bug上发了帖子,第二天早上发现有了回帖,原来人家刚刚修改过,只是方法不太一样,我也没仔细看,便以为问题还在,冒冒失失地发了帖子。第一次试图给自由软件贡献代码就这样失败了。:-(

整个事情的发展还真符合我的性格,呵呵!

四月 02, 2008

git

git上手的难度堪比学习emacs,虽说都是版本控制工具,可是跟CVS、Subversion有太多的不同。要不是发现了git-emacs,恐怕还是没有勇气尝试。获得git-emacs及其文档的方式如下:

$ git clone git://github.com/tsgates/git-emacs.git

也可以在线http://tsgates.cafe24.com/git/git-emacs.html查看。基本的功能都有,但是git实在是有太多的命令和用法,很多情况下还是要用命令行。其实这些都不是问题,关键还是git太不一样了。举个例子,git commit并不会提交修改的文件,一定要用git commit -a;git声称其track的是文件的内容,而不是文件本身,这句话一直不太理解。

上手的时候可以参考Everyday GIT With 20 Commands Or So,至少可以做到知其然,尽管不知其所以然。一定要尽早尝试,我看过各式各样的文档好多个,仍然不知道怎么用,直到真正用起来,才有了一点感受。总之,理论基础要有,但实践更重要。