emacs入门技巧

 
自从 开始对Emacs感兴趣,而不是仅局限于用 SLIME同Common Lisp偶尔亲热一下而已后,俺便断断续续读起号称Emacs初学者必备的 羚羊书第三版。一边读,一边笨手笨脚地使用Emacs。几周下来,虽然还要不时翻书,好歹开始习惯那些和Vim迥异的组合键。用C-f, C-n, C-p, M-d什么的也慢慢变成下意识的反应。俺的~/目录下也累积了50多兆各式扩展,模式,和配置文件。当然当然,作为初学者,俺坚持不用自己的key binding,除了把过气的/C-x/C-u映射到undo上以外。毕竟对缺省配置的极度熟悉有助于自己在不同的机器上使用Emacs。可移植性不仅是对程序的要求,也是对人的要求。总的来说,Emacs确实好用。扩展比郭敬明抄袭的文字都多,功能比黎叔吹的牛B还强。用于Common Lisp开发的SLIME,用于Ruby开发的Ruby Mode, 用于Java开发的JDE, 开发工具集合CEDET,让操作文件和缓冲方便之极的ECB。。。不过俺还是有些怀念Vim的方便,时不时用Vim编写点小东西。毕竟Vim区分编辑模式和控制模式,使得组合键简短。
 

图片来自 John Dierdorf

 
使用Emacs编写程序的过程中遇到几个问题。后来在网上找到了答案。下面是整理出的答案。既然俺作为初学者曾为这些简单的问题而花上几个小时,也许这些答案能让其它初学者节省一点时间。
 
第一个问题是自动匹配完成代码。俺用惯了Eclipse,所以习惯于完 int foo(){的时候,编辑器自动添上配对的 } 又比如编写Ruby代码的时候,当俺写完 def foo 的时候,编辑器会自动添加上 end 刚开始我在Google上用诸如emacs auto completion这类的字眼搜索,总是出来一大堆不相干的信息。后来读ruby-mode的说明,才明白Emacs把自动匹配完成的功能归在electric mode里面。这点明白了,在Google上搜索就知道用什么关键词了。使用时,记着在语言mode加载的时候同时加载electric mode就行了。比如说下面的代码在ruby-mode加载时加上ruby-electric-mode:

(add-hook 'ruby-mode-hook
          (lambda()
            (require 'ruby-electric)
            (ruby-electric-mode t)
            ))
 
第二个问题是自动缩进。在Eclipse的Java编辑器里,按下回车键会导致光标移到下一行,然后自动缩进到正确的位置。在俺看来,这是自然的行为。既然我在写程序,当然希望每一行都从正确的地方开始。编辑器应该帮我料理一切与写码无关的杂事。可惜Emacs(Vim一样)的缺省行为是光标移到下一行第一列。当我们完成一条表达式或statement后,改行自动缩进。这让俺非常不舒服,因为我容量小得可怜的大脑不得不分出1/7的空间去挂念缩进正确与否。后来俺知道了/C-j的功能正是回车然后缩进,相当于先ENTER,再TAB。但哪怕思考用/C-j还是回车都让俺举得大脑不堪重负(是的,卧春,卧室达春绿)。如果用set-global-key吧,又容易与有些模式下的/C-j冲突。把这段代码加到Emacs的配置文件解决了问题:

(mapcar
(lambda (mode)
   (let ((mode-hook (intern (concat (symbol-name mode) "-hook")))
         (mode-map (intern (concat (symbol-name mode) "-map"))))
     (add-hook mode-hook
               `(lambda nil
                        (local-set-key
                               (kbd "RET")
                               (or (lookup-key ,mode-map "/C-j")
                                   (lookup-key global-map "/C-j"))))))) '(c-mode c++-mode cperl-mode emacs-lisp-mode java-mode html-mode lisp-mode ruby-mode sh-mode))
这段代码对一列语言中的每一个创建一组mode-map(其实就是Lisp里的一个Pair类型)。如果在创建的mode-map或者global-map里找到了/C-j的定义,就把它替换成回车。这样做的好处是我们只需要替换自己关心的语言模式。其它情况下/C-j不受影响。比较有意思的是,我开始犯了初级错误,以为add-hook里的匿名函数是个closure(其实不是,因为那个匿名函数前面有个单引号),于是进一步以为(lookup-key ,mode-map "/C-j")里的那个逗号没有必要存在。结果自然得到Lisp里的NullPointerException,void-variable。一不小心,就可耻了一把。
第三个问题是格式化整个文件。Eclipse下面CTRL+SHIFT+F就解决问题了。Vim下面gg=G也顺利搞定。Emacs下面得C-x h TAB。怎么敲速度都上不去。 有了下面这段代码,事情就好办多了:
(defun iwb ()
 "indent whole buffer"
 (interactive)
 (delete-trailing-whitespace)
 (indent-region (point-min) (point-max) nil))
 
M-x iwb 格式化整个文件。如果还嫌不够,把iwb映射到自己喜欢的组合键上就行了。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值