By:Stupid ET
Emacs在1975年就诞生了,想必比现在绝大多数程序员都要老。现在最新的Emacs已经是24.3.50.7,为了获取最新的特性,我的Emacs都是自己编译最新的开发版(在24.3正式版出了后就使用正式版了,正式版更为稳定)。Emacs其实是一个Lisp解释器,有着和Lisp纠缠不清的关系,我想这与Richard Stallman本人和MIT人工智能实验室有些许关系。Emacs许多逻辑都是用elisp写的。所有的配置也都是用elisp编写。
想起很久很久以前,第一次因为久闻Emacs大名打开了Emacs,看到这界面,不禁吐槽,这不就是一个Notepad吗?完全看不出这货竟然被尊称为「伪装成编辑器的操作系统」啊。
而且发现完全可以像用Notepad一样使用Emacs-.-(想想第一次打开Vim的童鞋们可能连输入都发现没反应)。
鉴于众大牛都推荐Emacs,我还是决定尝试一下Emacs。刚开始完全无法忍受着C-[pnbf]
的上下左右操作方式,找了一下发现有个Evil1插件,装上它Emacs立即拥有Vim的按键绑定,于是Emacs就这么变成了Vim!于是之后的一年我都是这么用的Emacs。
我曾经是一个忠实的Vim用户(当然现在还是),不过后来接触了Emacs后就欲罢不能,其中一个重要的原因是Lisp。用Emacs可以让我们有一个很好的机会去学习和使用Lisp。
我们在Emacs中键入M-x ielm
就可以打开Emacs Lisp交互解释器。可见,在Emacs中接触到Lisp是多么的容易2。
于是随着时间的推移,更多地把玩,开始逐渐对Emacs刮目相看,发现Emacs真的是「伪装成编辑器的操作系统」。于是调教Emacs成了茶余饭后的消遣活动。
作为一个被称为「Ctrl到死」的编辑器的用户,我们需要好好思考一下Ctrl这个按键。
Emacs的很多按键都需要配合Ctrl
,而Ctrl
在US键盘的左下角,按起来手形会比较纠结。所以强烈推荐将Ctrl
和Caps Lock
对调。当然如果你有HHKB3就不需要自己去切换了,因为已经物理支持了。于是Ctrl
就到了左手小拇指的位置,按起来就非常舒适了。
在Emacs中的M
(Meta)就是我们的Alt
,因为Alt
在空格的旁边,所以我们很容易就用左手大拇指按下。而一个非常常用的快捷键M-x
,我们可以用左手大拇指同时按下这两个按键。就不用将整个手掌卷起来按。对于Mac用户,因为Mac的键盘Alt
在普通键盘的Win键的位置,所以需要调换一下:
1 2 |
|
Emacs里面的扩展多到不计其数,我们如果自己手工安装扩展或者升级扩展是一件非常麻烦的事情。
对于debian或者ubuntu用户,大家是不是非常喜欢apt-get,只需要敲一条命令,你所需要的软件唰唰唰地就装好了。在Emacs中,我们也有这种便利的包管理——el-get4。
自从有了el-get,我就再也没有自己去手工下载升级那些软件包了,而且,el-get可以很好的处理软件包的依赖。例如我们安装Python的智能补全插件jedi5,就只需要键入M-x el-get-install jedi
,就可以装好jedi、epc、ctables等等,而且升级也非常方便。
另外,在el-get的帮助下,我们可以很容易将我们的Emacs配置用版本控制器进行管理,而不必将那些插件也纳入版本控制。在没有el-get的情况下,我们虽然可以通过忽略文件来忽略那些插件的文件,但是我们如果在一台全新的计算机将配置clone下来的时候,就没有了我们之前安装的插件了。
而有了el-get后,这些问题都得到了解决。el-get会在新计算机中自动为我们下载并安装好我们的插件。我用el-get管理了挺多插件,可以围观el-get配置。
作为Emacs User,使用效率也是十分重要。Emacs经过扩展后,可以比原版高效非常非常多。
我们可以围观一下这个screencast for AceJump。虽然说Vim的移动速度非常的快,但是Emacs加上Ace Jump之后,光标的移动速度完全不亚于Vim。
C-x o
估计是最常用的快捷键之一了,可以跳到其他window。不过如果在window特别多的时候,狂按C-x o
估计就是比较让人蛋碎了。于是我们可以借助switch window让C-x o
变得更加便捷。在window数目大于等于3个的时候,switch window就会给window标上“1,2,3……”,然后可以通过“1,2,3……”来选择window。
想要更加随心所欲地在window间移动,可以借助windmove6就可以通过上下左右移动了。我设了这些快捷键来移动:
1 2 3 4 |
|
在Vim中,我们可以按下f
或者是t
加上某个字符快速定位到光标之后的字符,这个非常的有用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
通过这个,我们可以通过C-t
加上指定字符向后跳,后者C-u C-t
向前跳。比如C-t w w w w …就一直往后跳到后续的w处。类似于Vim中的fw;;;…
Sublime Text中引以为傲的多光标编辑,Emacs装个multiple-cursors.el就可拥有。
Multiple Cursors让Emacs轻松就可以像Vim的C-v
列编辑,还有可以更高级的多光标编辑。可以看视频:Episode 13: multiple-cursors。
标记,估计是最常用的功能之一。默认的Set Mark命令是C-@
或者是C-SPC
,前者太难按(Ctrl-Shitf-2),后者和输入法冲突了。于是我们可以将其重新绑定为M-SPC
,这样用两个大拇指就可以轻松Set Mark了。
1 2 |
|
对于标记一块区域,像Vim中,我们可以vi(
,vi"
等等就可以标记括号、或者引号里面的内容了。在Emacs中,我们可以享有这种便捷。我们需要借助expand-region
7,具体可以围观视频:Emacs Rocks! Episode 09: expand-region。
而标记一个函数,可以用C-M-h
。往后标记C-M-SPC
。
对于非常常用的window分割快捷键默认为
C-x 1
:关闭其他windowC-x 2
:在下面分割一个window出来C-x 3
:在右边创建一个windowC-x 0
: 关闭当前window这些都有点不太直接,我们将其重新绑定到更快的按键上:
1 2 3 4 |
|
这样就缩短了分割window的键程,畅快许多。
如果我们有两个window,有时我们想切换左右或者上下window里面的内容,就可以通过以下脚本:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
更多window布局配置可以围观window-setting.el
我们经常会修改配置文件,一种让配置生效的方法是关闭Emacs,然后重新打开它。不过这也太慢了,如果不是到了迫不得已的情况,我们不需要如此大动干戈来使我们的修改生效。
我们在很多人的博客中都会看到一种方法,M-x eval-buffer
,嗯,(eval-buffer)可以重新解释运行一遍当前buffer的内容。在挺多时候还是挺有用的。
不过我们有时候仅仅只是修改了一小段配置,完全没有必要eval整个buffer。于是我们就可以eval一个局部。
eval-region1 2 |
|
然后,我们选择一个区域后,就可以用C-x C-r
来eval一个选区了。
Emacs使用Client/Server可以大大提高新Emacs的开启速度,所有的client共用server来处理数据。
首先添加一个开机启动,这个会启动一个Emacs Daemon进程。可以让其他emacsclient连接到server来编辑。
emacs --daemon
编辑~/.bashrc,加上
1 2 |
|
然后,就可以通过ec filename
来用emacs编辑文件。即使是有大量配置文件,开启速度也绝对不亚于Vim。因为client不加载任何配置,只是直接连到server。
修改快捷方式的的command为
不过,我觉得Desktop的Emacs不需要连接Daemon,因为Desktop的Emacs只需要开一次就好了。Daemon会有一些奇葩的问题,例如session似乎就没法保存。
使用Daemon主要是为了提高开启速度,这个在Terminal中经常开关Emacs编辑文件时就很重要。而在Desktop就开一次的情况就显得没什么了。
开始录制宏,用C-x (
; 结束录制宏,用C-x )
;
用C-x e
来使用宏。可以利用C-u
来重复使用100次这个宏,即命令C-u 100 C-x e
。
C-x e e e ...
将宏重复。
M-x name-last-kbd-macro
。M-x insert-kbd-macro
。M-x
调用了。Helm可以方便地帮助我们找到想要的buffer、文件。而且看上去也很酷。
smex提供了更好的M-x体验。它让M-x变成了像ido一样,可以实时提供补全。让M-x更加快速。
配合desktop可以保存我们上一次的工作状态。也就是重新打开Emacs的时候,会变成上次关闭的状态。当然也可以分项目保存不同的session,这样就和IDE保存工作区一样了。
Emacs的undo非常诡异,只有undo,没有redo。如果要redo,那只有undo undo。
不过这样的设计,让Emacs的撤销变得异常强大。Emacs可以帮你所有的修改记录都保存下来,我们可以肆意地修改、undo完修改,各种修改,我们都可以回到曾经的状态。这个是其他编辑器难以做到的。
undo-tree可以将所有的状态用树状结构绘制出来。然后我们轻松地可以找到我们需要的状态,甚至可以diff不同的状态。
我们按C-x u
可以进入undo-tree-visualizer-mode, 然后 p
、n
上下移动,在分支之前 b
、f
左右切换,t
显示时间戳,d
打开diff,选定需要的状态后,q
退出。这是主要的操作,其它的自己摸索好了…… 8
Emacs中还有很多很多非常有用的插件,我这里有一些我在用的。
Minimap, 这个也是Sublime Text中另一个经常被提起的特性,Emacs装一个minimap也即可拥有。不过说实话,这个功能感觉貌似没啥意义。
还有些比较好用的:
Emacs的默认界面,见文章第一张图,看起来非常挫。不过幸运的是,Emacs具有超强的可定制性,于是我们可以随心所欲地调整UI。
就可以显示当前项目名,当前编辑文件的完整路径。
1 2 3 4 |
|
这个需要装一个叫做tabbar的插件,装完后,就有了顶部的tab栏。具体颜色和形状的配置可以围观:my-tabbar.el。
没错,不像Vim里面直接set nu
就可以开启行号,Emacs的行号还需要装个插件来实现。不过庆幸的是,Emacs 22之后都自带了linum插件,只要启用就可以有行号了。
1 2 |
|
底部的一条显示了很多信息的东西叫做mode-line。默认的非常简单,我们可以对其进行定制。如果比较懒,可以直接用emacs-powerline插件就可以有一个漂亮的powerline。
不过我还是比较喜欢自己定制。
依次显示文件名、当前编辑状态、滚动进度,当前mode,使用何种版本控制以及分支,最后是当前时间。
具体可以围观:my-ui.el,里面有详细的配置。
eshell是用lisp实现的shell,具有跨平台、支持tramp、与Emacs水乳交融等等优点。
对于如此常用的功能,我们赶紧绑定一个好用快捷键:
(global-set-key [f4] 'eshell)
我们可以在lisp中定义alias,也可以专门为eshell定义alias。
Alias in lisp1 2 |
|
或者在~/.emacs.d/eshell/alias
中定义我们在eshell中的alias:
1 2 3 4 |
|
Eshell有个挺好的教程:A Complete Guide to Mastering Eshell。
TRAMP的全写为:Transparent Remote (file) Access, Multiple Protocol。在TRAMP的帮助下,我们可以很容易做到无缝编辑远程文件。
详细阅读:Emacs Tramp 详解
dired是Emacs自带的文件管理系统,能够和Tramp无缝配合使用。
默认的dired看上去显示太多东西了,我们可以通过dired的扩展来定制我们需要显示的东西。
我们用el-get很容易就安装好dired扩展”dired-details”和”dired-details+“。然后就可以定制dired显示内容了。默认会隐藏掉不那么常用的信息。如下:
当按下)
就可以显示详细信息了。
dired最强大之处,在于可以直接修改这个buffer里面的内容就可以直接对文件进行修改了,就可以很方便地批量重命名。我们按C-x C-q
(dired-toggle-read-only)进入Wdired mode
编辑模式,然后就可以像平时编辑文本一样编辑这个buffer,当完成后按C-c C-c
(wdired-finish-edit)保存到磁盘,就可以完成批量修改文件名了。
有时候Emacs的插件会出现各种问题,我们就需要进行调试了。
如果我们希望在出现错误的时候能够自动进入调试模式,那我们可以M-x toggle-debug-on-error
。
如果有时候Emacs卡住没有反应,但是按C-g
能够恢复的话,那说明可能是进入了死循环。我们可以在之前打开M-x toggle-debug-on-quit
,然后在我们按C-g
的时候就可以调试当前正在运行的elisp。
那有时候我们需要在某个elisp函数设置断点的话,我们可以通过M-x debug-on-entry [funcname]
来为某个函数设置断点。取消断点可以通过M-x cancel-debug-on-entry
。
在我们进入调试模式的时候,按d
可以单步,q
退出,e
执行lisp。
autocomplete9可以为我们提供类似常用IDE一样的弹出式提示。而补全来源也可以轻松的自定义,是一个非常好的补全框架。
Yasnippet是一个非常强大的模板替换扩展,可以轻松自己定制模板,而且模板还可以嵌入lisp进行逻辑处理,非常强大。
可以围观视频:Emacs Rocks! Episode 06: Yeah! Snippets!
作为一个Python程序员,拥有一个好用的Python开发环境是非常的重要的。
相信大家在网上找到的Emacs Python IDE搭建靠的都是PyMacs和Rope。Rope是一个很强的库,不仅可以用来补全,还可以用来重构等等。
不过Rope的补全速度有些缓慢,于是我们可以求助一个更强更迅速的补全库jedi10,这是一个异步的补全库,不会阻塞编辑。而且jedi已经对autocomplete有很好的兼容了。安装仅需要M-x el-get-install jedi
。
Emacs本来就是一个很好的elisp开发环境。不过Lisp里面的括号非常非常多,很容易就被搞晕了,一个有效的括号高亮显得非常重要。
达到上述逐级高亮的效果,需要借助highlight-parentheses,autopair。然后编写下述代码11。
括号高亮1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
像Emacs中的开发辅助插件还有很多,比较重型的有cedet(Collection of Emacs Development Environment Tools)、ecb(Emacs Code Browser)等等,都是有效的工具,可以帮助我们提高工作效率。另外还有挺多小工具。
像Git-timemachine,可以直接查看文件的不同版本历史:
对于平时的生活,Emacs可以编辑Chrome里面的内容,例如有时需要发段代码:Chrome Edit With Emacs。
对于用Markdown写Blog,Emacs甚至可以直接截图、插入图片:Screenshot and Image Paste in Emacs When Writing Markdown。
插入完图片后,可以直接在Emacs中预览Markdown中的图片:让Emacs显示Markdown中的图片,这个绝对让其他编辑器望尘莫及。
Emacs的Artist Mode
13可以直接画字符画,按下M-x artist-mode
就可以用鼠标画字符画图了,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
当然像上个网,煮个咖啡,听个音乐,聊个天,收发个邮件,Emacs都可以轻松做到。
如果在使用Emacs的过程中遇到什么问题,可以求助于Emacs强大的帮助系统。
打开 Emacs 的入门教程,
让Emacs告诉你某个快捷键是什么作用。首先按下C-h k
,然后按下我们的快捷键。就可以打开帮助了,于此同时,我们还可以看到我们的按键的是如何表示的。
查看按键绑定
注意这次是大写的 K 。对于 Emacs的一些内部命令,除了Elisp源代码中提供的文档以外,还有一个专门的 Info 文档进行了系统的介绍。C-h K 就是定位到 Info 文档中描述该命令的位置。
查看某个函数的文档。建议绑定一个快捷键,这样我们把光标放到某个函数的上面,一按快捷键就可以打开这个函数的文档了。
查看某个变量的文档。
当开当前mode的帮助。这里挺详细的对于当前可用快捷键的描述。
当我们不能完整记得某些快捷键的时候,可以按下前缀后,再按下C-h
。就可以看到以这个前缀开始的快捷键有哪些。
有些时候我们只知道一个关键字,这个时候可以用 C-h a
来通过正则表达式来查找命令名。Emacs 会列出所有匹配的命令以及一个简短的文档,并可以通过点击链接定位到该命令的详细文档。
Emacs中有个快捷键导师,可以在你需要的时候,提示你,可以围观:Emacs中的快捷键导师
C-M-h
标记一个函数定义C-h C-a
about-emacsC-h C
查看当前文件的编码C-u M-! date
插入当前时间C-u M-=
计算整个缓冲区的行数、字数和单词数C-x <RET> f utf-8
(set-buffer-file-coding-system),设置当前buffer的文件的编码C-x C-+
and C-x C--
to increase or decrease the buffer text font sizeC-x C-q
开关read-only-mode,在dired-mode中可以进入修改模式,可以批量修改文件名。C-x C-t
交换两行。可以用来调整python中importM-x sort-lines
排序选中行。C-x C-v
or M-x find-alternate-file
重新打开当前文件,在高亮后者插件出了bug可以用这个命令重新加载。C-x z
重复上一条命令。可以一直按z
不断执行,非常方便!M-&
异步运行一个shell命令M-:
运行一句lispM-@
mark-word,连续按连续mark单词。M-g M-g linenum
跳到某行,同vim中的[linenum]G
M-h
标记一段M-x dig
M-x ifconfig
M-x ping
M-x telnet
M-z
删除到某个字符,同Vim的df
C-u M-! date
插入当前时间C-q C-i
插入tabM-x list-colors-display
显示Emacs所有的颜色,方便我们来进行配色当然还有很多很多,就不再列了。
在英文版的系统里面,一般情况下Emacs可能打不开中文输入法,此时我们需要修改LC_CTYPE环境变量就好了。
可以在~/.profile最后加上一句
字符画1
|
|
将我们的el配置编译成字节码,可以加快Emacs的加载速度,特别是在配置文件特别多的时候。
我们去到我们的el配置文件目录,打开dired
,然后输入% m
来调用dired-mark-files-regexp
,然后输入.el
来标记所有的配置文件,然后按B
调用dired-do-byte-compile
,然后就可以把一个目录下面的el一次性编译成elc
。或者也可以直接C-u 0 M-x byte-recompile-directory
一次性编译一个目录及其子目录。
不过这样就会带来一个问题,就是如果我们修改了配置后,还是需要重新编译的。这里在ErgoEmacs14找到了自动重新编译的配置,就是在保存文件的时候检查当前是否为emacs-lisp-mode
,如果是,那么就编译它。这样我们修改配置的时候,就会自动重新编译了。
1 2 3 4 5 6 7 8 9 |
|
写了好几天(一年多了),发现还有挺多东西没写的,Emacs博大精深,还需要自己慢慢摸索。这里纯当为我的记忆做个快照,让以后的我可以看到在2013年初时,Emacs在我眼中的形象。
如果你阅读到了这里,非常感谢你的耐心,感谢你看完了我如此长篇的唠叨。祝你在2013年效率大大提高~
如果你有兴趣,可以浏览一下我的Emacs配置文件。
最后,我也不想挑起Vim和Emacs无谓的口水战。其实无论是Vim还是Emacs,它的好用程度完全取决于使用者的配置能力,所以好不好用,完全看个人。
第一版。
更新字节码编译 diff
更新大量新内容 diff
本文链接: http://everet.org/thinking-of-emacs.html