使用emacs而非普通ide的几个理由

轻便:emacs包括海量的文档也只有28M, 而eclipse一般是100多M,这就算轻便的了,visual studio是以G记的。而且emacs在启动时会占用更小的内存,更小的资源占用意味着更稳定,可以反复启动多次也不觉得浪费时间

支持:ide里eclipse只有对java和c++算是全功能,其他语言支持较少。visual studio因为是微软产品,除了对微软自家东西之外没有任何支持。而对python和ruby等开源语言或者clojure等新兴语言甚至是小众语言。这些ide要对一门新语言支持,等把。而emacs和vim等文本编辑器就好得多。

可定制性:在ide中想增加一个新功能,哪怕比较简单。提交bug报告然后等新版本吧,还不一定有。在emacs里你只要用lisp写新的代码然后hook到已有的模式,甚至直接改写已有模式就行了。

文本编辑功能:在emacs中即使在特定模式一般全局按键都是可用的,比如跳转到行首行尾,按词移动等。eclipse里也有类似特性但是emacs里更多。

因为ide能做的emacs大部分都能做到,而emacs能做的很多ide都无法实现,所以干嘛要用ide呢,无非是要付出时间去学习而已

Ruby与emacs IDE,第一季

emacs安装后自带一个ruby模式,但是这个ruby mode功能弱的只能用敷衍来形容。与之相对c++和python就提供了完善的支持。不公平啊。所以不自己配置是肯定不行的。但是配置这货的过程充满了艰辛,就和我天天早起喝得叫人撞墙的中药一个味儿。现在想起来从一个小白起到能获得一个勉强能跑的emacs环境真是奇迹。问题在于相关的过程极度缺乏正规的文档化,有用的文章几乎都出自个人的摸索,分布于广大的互联网上各个blog里,很多是被封锁的,而且很大一部分都是用日文写成的,所幸的是这两点对我都不是问题。

ruby其实和emacs是很有渊源的。ruby的作者,松本行宏先生,在发布ruby前最有名的作品就是emacs的一个扩展。他的作业环境毫无疑问也是emacs。但是现在要设置emacs却如此麻烦。需要注意的是我配置的是ruby开发环境,而不是rails的,而且是1.9,很不成熟。首先是主模式,在ruby的源码包下misc目录里,有一堆el文件 ,这就是ruby在emacs中的基本。

ruby-mode.el 这是基本ruby-mode主模式。
inf-ruby.el 在ruby主模式里运行内置的irb
ruby-electric.el 一个加强副模式
rubydb3x.el 在emacs里调用debugger

要在emacs里使用这些文件需要把他们拷贝到执行路径中,我新建了名为myEmacsEl的文件夹并将其添加到执行路径中。我的.emacs如下:

(set-default-font "DejaVu Sans Mono-14")
(set-fontset-font (frame-parameter nil 'font)
    'han'("WenQuanYi Micro Hei"))
(defun toggle-fullscreen()
  (interactive)
  (x-send-client-message
   nil 0 nil "_NET_WM_STATE" 32
   '(2 "_NET_WM_STATE_FULLSCREEN" 0))
)
(run-with-idle-timer 0.1 nil 'toggle-fullscreen)
(run-with-idle-timer 0.1 nil 'delete-other-windows)
(tool-bar-mode nil)

;;;;;;;;
;;ruby;;
;;;;;;;;
(setq ruby-program-name "/home/???/.rvm/rubies/ruby-1.9.3-p194/bin/irb --inf-ruby-mode")
;Allows syntax highlighting to work, among other things
(global-font-lock-mode 1)
; directory to put various el files into
(add-to-list 'load-path "/home/???/myEmacsEl/ruby")
; loads ruby mode when a .rb file is opened.
(autoload 'ruby-mode "ruby-mode"
  "Mode for editing ruby source files" t)
(setq auto-mode-alist
      (append '(("\\.rb$" . ruby-mode)) auto-mode-alist))
(setq interpreter-mode-alist (append '(("ruby" . ruby-mode))
                     interpreter-mode-alist))
; set to load inf-ruby and set inf-ruby key definition in ruby-mode.
(autoload 'run-ruby "inf-ruby"
  "Run an inferior Ruby process")
(autoload 'inf-ruby-keys "inf-ruby"
  "Set local key defs for inf-ruby in ruby-mode")
(add-hook 'ruby-mode-hook
          '(lambda ()
             (inf-ruby-keys)
         ))
; adding ruby electric
(add-hook 'ruby-mode-hook
          (lambda()
            (add-hook 'local-write-file-hooks
                      '(lambda()
                         (save-excursion
                           (untabify (point-min) (point-max))
                           (delete-trailing-whitespace)
                           )))
            (set (make-local-variable 'indent-tabs-mode) 'nil)
            (set (make-local-variable 'tab-width) 2)
            (imenu-add-to-menubar "IMENU")
            (define-key ruby-mode-map "\C-m" 'newline-and-indent)
            (require 'ruby-electric)
            (ruby-electric-mode t)
            ))
;ruby debug
(autoload 'rubydb "rubydb3x" "run rubydb on program file in buffer" t)
;Auto-complete.el
(add-to-list 'load-path "/home/???/myEmacsEl/auto-complete")
(require 'auto-complete)
(global-auto-complete-mode t)
(add-to-list 'ac-dictionary-directories "/home/???/myEmacsEl/auto-complete/dict")
(require 'auto-complete-config)
(ac-config-default)
(add-to-list 'load-path "/home/???/.rvm/gems/ruby-1.9.3-p194/gems/rcodetools-0.8.5.0")
(require 'auto-complete-ruby)

从ruby标记往下是ruby的。

要注意的部分如下;
(setq ruby-program-name “/home/???/.rvm/rubies/ruby-1.9.3-p194/bin/irb –inf-ruby-mode”)
设置irb解释器的变量,务必要设定,否则inf-ruby内置解释器无法工作。因为我用的是rvm所以路径比较特殊。–inf-rubymode这个选项也是必须的,否则虽然可以用但是输出会很难看。这里用一个变量来确定irb的位置,我是很喜欢的,因为以后可以用pry之类的加强型irb替代。
(add-to-list ‘load-path “/home/???/myEmacsEl/ruby”)
追加路径

ruby-mode的主要功能就是tab的缩进功能被大幅在增强了,比如if或者循环可能嵌套很多层,按一下tab或者在回车时就可以正确缩进到当前应该缩进的位置,而不是仅仅插入一个制表符。
ruby-electric为ruby-mode提供一个副模式,其主要功能就是你在输入class或者def,while等等时会自动在下一行插入一个end,不要你手动去输了,而且双引号括号等等输入一个会自动出来一对,就跟eclipse一样。
inf-ruby自动hook到了ruby主模式上,按下C-c c-s会在emacs中出来一个irb,可以把buffer内的源代码分部分自动发到这个irb里去执行,方便的很。
rubydb3x.el这个就有点麻烦了,正确设定好.emacs后,按下M-x运行rubydb函数,在弹出来的minibuffer中输入当前ruby的全部路径和文件名才行,会自动在emacs里打开一个调试器,这实在说不上方便,我估计只是赋值一个变量的事儿,但是现在的我还做不到,而且ruby自带的调试器实在说不上好。

现在已经有了自动高亮,自动缩进,自动插入end和一个勉强可用的调试器

接下来是加入自动完成,可以自动输入代码中那些为了说明用途而长长的函数名还是很好的。

我用的是auto-complete.el,网址:http://www.cx4a.org/software/auto-complete/ 这货就叫这名字,是一个日本程序员的作品,令人不安的是从2010年后它就没有更新了,当然你也可以用yasppnet,或者其他自动完成后端。auto-complete提供了一个安装脚本,甚至还提供了一个Make文件,但是你读一遍就会发现它实际上就是把一些el文件放在安装的位置而已,所以你也可以手动做这些事,下载安装包,解压之后把所有的el文件和dict目录放在执行路径下,编辑.emacs文件。然后要再从这个作者的网站下载一个auto-complete-ruby.el文件放在路径下,因为auto-complete是一个泛用模式,它会给所有的主模式添加一个副模式,而auto-complete-ruby.el是为ruby特化,可是他需要require rodetools,这玩意儿从哪呢,gem install rcodetools.但是我就奇怪,你gem安装它和emacs有何关,能require到么?然后我在启动emacs时看到了一个warning,解决办法是你到rcodetools的目录下看看,那里面有很多el文件,把它的目录加入执行路径就没事了,这一点所有人都没提到。

悲剧的是auto-complete据我测试,似乎只按照预先定义好的字典和buffer里的上下文进行补全。就是说比如你导入一个第三方库,然后声明一个这个库里的对象,是没法补全他的方法的。因为ruby是动态语言,似乎也没法和java一样补全,因为在运行前无法确定对象的类型好像,我也不是很懂。这在技术上是毫无难度的,连我都可以想到,先运行补全位置之上的所有代码,之后对补全对象调用methods方法,然后根据出来的内容进行补全即可。但是没有必要:1.如果上面的代码有错误怎么办,这是很常见的 2.运行代码尤其当工程很大时要消耗大量时间,如果对这个进程进行优先级调度,则每次运行补全的结果会不一样。3 至少我是没见过ruby的库公共接口有java一样又臭又长的函数名

你可以用yas,但是我估计他和auto-complete没什么区别。Rsense是用java写的,不过按理只有速度上的提示而已。以后再努力尝试更多的补全插件。

我大致是按http://kimiboku.wordpress.com/2011/11/20/emacs-ruby/ 来的,中间也参考了无数其他网页,我看youtube一个视频里它只用了ruby-mode,yas,mate三个模式,mate我还没有尝试,但是基本的上面都有了,勉强也运行的起来。要进一步深入,我估计还是得学会emacs lisp,读懂那些长长的代码,因为文档实在太少了,靠文档和别人的经验活下去,实在只能靠运气。

Emacs是什么?说说我认为的这个黑客专用文本编辑器

Emacs是什么?它是个文本编辑器,emacs和windows自带记事本一样都是文本编辑器,就像我和奥巴马都是人类一样。我为什么选择emacs而不是vim?理由有三:

  • emacs是gnu计划的第一个项目,可以说它和理查德·斯托曼的大胡子一样有着图腾般的宗教性象征意义,这是vim没有的
  • emacs的根基是用c写的一个lisp解释器,其他部分全是用lisp写的。你不觉得这个构想非常酷么?《社交网络》里马克伯格就是用emacs
    和perl黑掉了哈佛(是哈佛么?)所有的网站。你不觉得emacs本身就很酷么?有点“专业黑客就要用emacs”的感觉么?
  • 也是最重要的一点,emacs的扩展语言是Lisp,反正早晚都要学Lisp的,而vim的扩展语言是一个特有的普通脚本语言,学了只是浪费宝贵的时间,反正我是这么认为。

今天基本搞定了emacs,指的是搞定了这货作为一个编辑器的基本功能,接下来的路还长的很。我的环境是32位linux mint13 xfce,emacs23.3 从源安装。

首先是个人配置文件,就是和.vimrc一样的玩意儿,安装vim后,会默认建立这么一个东西,并往里写入一些脚本,就像.bashrc一样。但是emacs默认是没有这个文件的。根据gnu网站的说法,这货叫做init file,程序会默认到家目录下寻找.emacs,如果没有的话,到.emacs.d/下寻找init.el,但是默认是全没有的。有.emacs.d目录,但是下面只有auto-save-list。自己手动建立一个(在家目录下),emacs .emacs.

内容是:

(global-unset-key (kbd "C-SPC"))
(set-default-font "DejaVu Sans Mono-14")
(set-fontset-font (frame-parameter nil 'font)
'han'("WenQuanYi Micro Hei"))
(defun toggle-fullscreen()
(interactive)
(x-send-client-message
nil 0 nil "_NET_WM_STATE" 32
'(2 "_NET_WM_STATE_FULLSCREEN" 0))
)
(run-with-idle-timer 0.1 nil 'toggle-fullscreen)

基本都是google来的,以前也不会lisp,凭着一点点编程基础,勉强能看懂不到 一半。

(global-unset-key (kbd “C-SPC”)) 指的是解除ctrl+空格的键位绑定,因为和系统的切换输入法冲突。

(set-default-font “DejaVu Sans Mono-14″)
(set-fontset-font (frame-parameter nil ‘font)
‘han’(“WenQuanYi Micro Hei”))

指的是切换默认字体,默认字体难看而且太小。主要意思呢大概就是说设置DejaVu Sans Mono为默认情况下的字体,字号为14号。然后再设置一个字符集,设置字符集字体为WenQuanYi Micro Hei(文泉驿微米黑),当编码为非拉丁字母时,系统自动会在/etc/fonts/conf.avail中寻找编码,比如汉字,就对应han,泰文就对应thai,等等。当系统找到编码之后呢,就搜索编码后面的字体了,如果成功找到了,便显示出来,找不到就报错。

(defun toggle-fullscreen()
(interactive)
(x-send-client-message
nil 0 nil "_NET_WM_STATE" 32
'(2 "_NET_WM_STATE_FULLSCREEN" 0))
)
(run-with-idle-timer 0.1 nil 'toggle-fullscreen)

指的是打开emacs时自动全屏,因为我的屏幕太小,这是在ubuntu论坛找到的,意思是啥不明白。这样打开emacs时就会自动放大字体然后全屏了,但是依然ctrl+空格无法切换输入法,emacs显示键位未绑定,但是中断到这里被拦截了,没有继续向下传。我是修改了ibus的快捷键,从c+空格换成shit+空格。

但是切换为拼音输入法也无法输入中文,输入不进去,google之后sudo emacs /etc/environment,添加

LC_CTYPE="zh_CN.UFT-8"

修改完毕以后,重启生效。可能因为我安装的是英文系统,这样改过后显示依然是英文。emacs就可以输入中文了,再加上一行

(run-with-idle-timer 0.1 nil 'delete-other-windows)

本来打开后会有一个额外的开始界面,这样就去掉了。这和打开后手动按C-x 1 效果是一样的。

我对emacs的理解

emacs的底部是一个用c书写的lisp解释器,这只上所有都是用lisp书写的,也就是说一切都是lisp。你在buffer里打字时实际上是一个单纯的文本编辑器。所有的Ctrl-,alt- 组合键运行的都是绑定的命令,这在帮助里可以看到。比如C-x 1运行了delete-other-windows这个Lisp函数。一切都是lisp函数在起作用,你也可以写自己的lisp函数来定制emacs,可以把简单的函数写在。emacs文件里,也可以写在el文件中然后在.emacs里载入,使用时可以绑定在相应键位上,也可以M-x来执行。总之,emacs的功能全来自那些复杂的lisp函数,离开这些代码,emacs就只是一个单纯的记事本而已。