没有时间把一件事情做好,却有时间把一件事情反复做!
全部博文(191)
分类: LINUX
2015-03-06 16:28:54
原文地址:加速你的 Emacs 作者:jiushen
会随着你定制的内容增多而启动速度越来越慢,当然,在很多服务器上是 启动之后就一直不会关闭的,但是自己的电脑不做服务器,会经常关机,而且有 些时候会临时启动一下编辑器,比如说环境变量里面的 EDITOR 就是很多程序经 常会调用的。那么,如何来加速自己的 Emacs 呢?下面给出了几个解决办法:
用 emacs -q
命令启动可以跳过加载自己的 ~/.emacs
而进行启动,如果版本比
较新的 Emacs ,还支持 -Q
选项,表示快速启动,其实这个选项是等价于这样
启动: emacs -q --no-site-file --no-splash
。这样一般就能够达到比较快
的速度了,不足的地方就是跳过了所有定制的部分,自己熟悉的定制的功能都没
有了,见到的只是一个陌生的朋友而已。
这个方法首先要有一个启动好了的 Emacs ,并且要已经启动了 server 模式,
你可以用 M-x server-start
来启动 server 模式,或者在自己的 ~/.emacs
里
面加入 (server-start)
来自动启动 server 。
然后,你就可以通过 emacsclient filename
来快速使用 Emacs 打开文件了!
事实上,文件是在作为 server 的那个 Emacs 里面打开的,而 emacsclient 将
等待 server 编辑文件。这个时候你可以转到 server 那里去编辑文件,编辑好
之后用 C-x #
来关闭文件并通知 emacsclient 文件已经编辑完成。现在,你就
可以把自己的 EDITOR 变量设置成 emacsclient 而不用怕启动速度慢了:
EDITOR="emacsclient +%d %s"
不过如果没有事先启动了一个 emacs server 的话,这个命令就会失败,他提供
的一个解决办法就是 --alternate-editor
参数,表示连接失败的时候调用的命
令,你可以把他设置成 vi 或者是其他小巧的编辑器,或者,你也可以在这儿直
接设置成 emacs ,不过这也许并不如想象中的那么美妙,也许你认为如果没有
启动 emacs ,那么在这儿就启动它,然后后面就可以顺利地调用 emacsclient
了!但是如果这儿是其他程序比如 mutt 或者 svn 之类的使用 EDITOR 环境变
量来调用的编辑器,他会等待编辑器退出来表示编辑完成,这个时候看着刚刚启
动的 emacs 马上又要关闭了,实在是不忍心呀!:) 不过这个也有个不爽的
地方就是打开文件都是在 server 里面打开的,还不能自动跳转到 server 那里
去,比较麻烦。
引用作者的一句话:
My goal is to allow opening multiple, different tty devices and simultaneous X (graphical) and tty frames from a single Emacs session.
这里是扩展了 emacs server 的这种方法。使用 emacsclient 的时候可以另外 打开一个 X 窗口或者是 tty 窗口进行编辑,而不是简单地把编辑任务发送到 emacs server 那里。
要使用这个补丁版本的 ,如果是 系统的话,可以直接使用他提 供的源下载安装或者下载源代码包自己编译:
# Multi-tty Emacs
deb ~lorentey/mirror/apt unstable multi-tty
deb-src ~lorentey/mirror/apt unstable multi-tty
其他系统可以直接下载源代码进行编译。作者提供了一个仓库,可以用 bazzar 软件来获取仓库中的源代码,他有好几个镜像,具体可以参见 ,我使用其中一个仓库:
baz register-archive -f
baz get lorentey@elte.hu--2004/emacs--multi-tty emacs-multi-tty
在我这里速度很慢,不知道是为什么,连接上去以后接近半个小时才开始真正下 载文件,几分钟之后就下载完毕了,我开始还一直以为是根本无法下载呢。
另外,也可以用 cvs 来获取的 22 的源码,并打上最新的multi-tty 给的 补丁,可以在 找到补丁文件,然后把他们打到 check out 出来的 emacs 的源码树上面去。这样也许速度会快一些,但是需要注意的是,最好是先下载补 丁文件,看是哪个日期的,再去获取对应那天的 的源代码,不过,即使是 同一天的源代码,也可能会有巨大变动的,所以还是直接获取 emacs—multi-tty 的源代码安全一点。
cvs -z3 -d:pserver:anonymous@cvs.savannah.gnu.org:/cvsroot/emacs co emacs
然后到 emacs 的目录里面去,打上补丁:
cd emacs
patch -p 1 < ../emacs--multi-tty--0--patch-555.2006-05-05.patch
编译之后尝试运行一下,有可能会出现 warning 说 ``Building Emacs overflow pure space'' 。事实上,因为 emacs 启动的时候有一部分只读的 不可扩展的内存,因为这儿用了 multi-tty 补丁,导致预先定义的那些内存无法 容纳下所有的预加载库,于是只有动态分配,所以会在启动的时候产生 warning 。
要解决这个问题,需要修改一下 src/pursize.h
文件,找到里面定义
PURESIZE_RATION
的地方,把值改大一点就可以了。我是把
改成了
这样可以重现这个问题:
emacs -nw
M-x server-start
emacsclient
C-x 5 0
这个时候可以看到 server 已经 Segment fault 退出了。galilette@Linuxsir
指出这是由于对 server 的不存在的 XIM 对象进行释放而造成的。如果不使用
X 下的输入法作为 的输入的话,这个问题很好解决,在 ~/.Xresources
里面加入
emacs*UseXIM: false
就可以了。但是通常 内置的输入法不如 X 下的输入法好用,这个问题已 经发送到 emacs—multi-tty 的邮件列表,可是至今还没有得到很好的解决。 galilette@Linuxsir 提供了一个解决办法,有些 dirty ,而且可能会导致资源 泄漏,但还是可以忍受的。除了心里面觉得不舒服以外,我还没有真正因为这个 碰到任何问题,即使一直开着 X 几个月后也许会发现可用资源越来越少,系统会 越来越慢,重新起动一下 X 也应该并不是件很难办的事情吧。
galilette@Linuxsir 的方法是这样的,打开 src/xterm.c
,定位到这里
并把这两行注释掉。
接下来就可以编译了:
$ ./configure --without-gtk
$ make bootstrap
$ make
# make install
启动 (可以以 X 或者非 X 方式启动),并启动 server : M-x
server-start
。现在可以去另外一个地方使用 emacsclient 了。扩展后的
emacsclient 支持更多选项,例如, -t
选项告诉 emacsclient 直接在终端里
面打开,而不是建立一个 X 窗口。启动之后会有提示,如果是有文件名作为参
数,编辑完成之后可以使用 C-x #
退出,否则可以使用 C-x 5 0
退出。
在 emacs—multi-tty 的 文件中提供了一个很 cool 的脚本,使用 把 服务器隐藏起来,事实上,只需要在计算机启动的时候启动 的 server ,之后就可以一直使用 emacsclient 进行连接,甚至在不同 的 X 会话中,甚至在重新登陆以后。非常舒服。
galilette@Linuxsir 提议说仅仅为了一个从来不会切换到前台进行使用的 的 server 而启动一个 会话对其进行维护太浪费了。使用更轻量 级的 更舒服一些。下面就是相关脚本。
首先是 preload-emacs
,用于检查是否有指定的 server 在运行,如果没有,
则启动它。
首先是 emacs—multi-tty README 里面提到的脚本,使用 :
这是 galilette@Linuxsir 提议使用 dtach 的脚本。
然后是 connect-emacs
然后分别是 e
与 et
:
在把 EDITOR
环境变量设置成 et
就可以了。
有很多可定制性很高的窗口管理器,比如 fvwm 、 之类的,可以写一个 脚本,调用 emacsclient 的同时叫窗口管理器切换到 窗口处,就非常方 便了,使用 的一个例子可以在找到。
有关 emacs 的 server 模式的更多内容,请参见 。
emacs multi-tty 的扩展主页在。
关于此的详细内容请参见 elisp 的手册: C-h i m elisp RET m Pure
Storage RET
。
注意这儿要选择 --without-gtk
,因为作者说了,目前对于编译为 gtk 的
模式还有问题,不过 x-toolkit 用什么都无所谓吧,因为平时使用的时候
用到 x-toolkit 的东西并不多嘛。
当我在 里面直接调用(例如使用 run-shell-command
) dtach 的时
候,dtach 会报错,说“tcgetattr: inappropriate ioctl for device” ,
应该是没有通过一个真正的终端来运行而造成的原因吧。因为我总是使用
的 jump-or-exec
来调用我常用的程序,而且我平时也一直在使用
,所以我还是使用 的那个脚本而不是 dtach 的那个。