如何让Emacs启动更快?

76
我使用Emacs v. 22(控制台版本,可以通过PuTTY远程或在本地使用Konsole)作为我的Linux主要文本编辑器。每次启动它都需要一段时间来加载,可能接近一秒钟,虽然我从未计时过。我倾向于经常打开和关闭Emacs,因为我更喜欢使用Bash命令行进行文件/目录操作和编译。
如何加快启动时间?

2
我在Ubuntu上遇到了同样的问题。默认软件包配置会自动加载许多Emacs包,我无法弄清楚如何阻止我不需要的那些包。 - Chris Conway
5
@Chris,尝试使用--no-site-file启动Emacs,可能安装了不需要的包。 - Trey Jackson
2
我们通过减少客户端和服务器之间传输的一些颜色信息,大幅度地降低了我所在工作场所的Emacs的加载时间(加载时间减少了约80%)。 - Dominic Rodger
1
优化你的 .emacs 配置文件。我在下面的回答中发布了一个链接,解释了如何做到这一点。 - Vicky Chijwani
你不需要完全关闭Emacs, 只需通过输入'C-z'将其挂起。然后,在bash中键入命令'fg'以在前台继续它。除此之外,尝试在Emacs中键入'M-x term',以便在Emacs内(在你的shell内部)拥有一个shell。这样,你实际上永远不必离开Emacs,只需要在缓冲区中拥有另一个bash shell即可。 - Thomas
17个回答

61

其他人已经介绍了如何使用gnuserveemacsclient,我建议在emacs中编译(能够跳转到编译错误是一个优势)。

但是,具体加速.emacs的方法是:

  1. 通过使用这段代码,可以自动编译.emacs文件。

  2. 将尽可能多的(require 'package)语句替换为autoload功能。这将延迟加载lisp直到它实际需要。使用这种技术使我的启动时间从>6秒加快到<1秒。这需要一些工作,因为并非所有库都被正确标记为autoload

  3. 删除您不再使用的代码/功能。

  4. 尝试使用选项--no-site-file运行emacs,以避免在站点安装site-start.el中加载不必要的软件包。

  5. 如果您真的很认真,可以使用您喜欢的功能自己滚动emacs。当然,这意味着更难更改您在.emacs中拥有的内容,因为它是二进制文件的一部分。单击链接了解如何使用dump-emacs

  6. 购买更快的计算机和/或更快的磁盘。

如何确定您的.emacs加载了什么

现在,您如何找出您的 .emacs 加载了什么?是为了删除功能还是延迟它?请检查您的 *Messages* 缓冲区,其中包含以下行:
Loading /home/tjackson/.emacs.tjackson.el (source)...
Loading /home/tjackson/installed/emacs/lisp/loaddefs.el (source)...done
Loading /user/tjackson/.elisp/source/loaddefs.el (source)...done
Loading autorevert...done
Loading /home/tjackson/.emacs.tjackson.el (source)...done
如果您注意到,Loading 语句可以嵌套:第一个 .emacs.tjackson.el 以 ... 结尾,最后一行显示 .emacs.tjackson.el 的加载状态为 ...done。所有其他文件都从我的 .emacs.tjackson.el 文件中加载。所有其他加载都是原子性的。
注意:如果您有一个很大的 .emacs,则可能会丢失一些消息,因为 *Messages* 缓冲区只保留固定数量的信息。您可以在 .emacs 中早期添加此设置以保留所有消息。
(setq message-log-max t)

注意: 如果'load命令的第四个参数nomessage非空,则会抑制消息,因此请删除任何这样的调用(或建议'load并强制第四个参数为nil)。


你能详细说明第二条建议吗?我不明白如何用autoload替换我的require调用,因为autoload似乎需要一个docstring参数。 - itmuckel
@Micha90 好的,点击链接 autoload 获取完整细节,但如果您不能(或不想)修改源代码以插入 ;;;###autoload 行,则可以在您的 .emacs 中手动添加类似 (autoload 'tcl-mode "tcl-mode") 的行以启用自动加载(在这种情况下为 tcl-mode)。 - Trey Jackson
我可以同时为 emacsclient 应用 --no-site-file 吗? - alper

43

除了Adam Rosenfield的解决方案之外,我建议使用Emacs服务器模式。您可以将(server-start)添加到您的 dotemacs 中,并在您想要在 Emacs 中打开文件时运行 emacsclient 而不是 emacs 。这样一来,您只需要付出 Emacs 的加载成本一次,然后就可以立即弹出客户端。

编辑

您是对的,v22不会创建新的框架。创建一个可以完成任务的 shell 脚本:

#!/bin/bash
# Argument: filename to open in new Emacs frame
/usr/bin/emacsclient -e '(let ((default-directory "`pwd`/")) (select-frame (make-frame)) (find-file "'$1'"))'

编辑2

在v24+中,您可以执行emacsclient -c来创建一个新的框架。


1
我在解决这个问题时遇到了困难 - 我已经启动了服务器,但似乎无法让emacsclient启动一个新的框架。显然,我的Emacs版本不支持“-c”或“-t”选项。有什么建议吗? - Paul
emacs --daemon仅支持v23及以上版本。如果发现~/.emacs中存在错误,它在第一次移动到这个新版本时可能无法正确启动 :) - Gregory
1
如果您在服务器模式下运行emacs,这是一种相当快速的方式。这些快捷键可能会很方便...
  1. 启动服务器
emacs --daemon 这将使其运行服务器并将控制返回到终端。 2. 然后编辑文件。 emacsclient <filename> 3. 停止守护进程 emacsclient -e "(kill-emacs)"
- alamin
我遇到了以下错误:*ERROR*: 未知终端类型 - alper
@alper 看看这个能否帮到你:https://unix.stackexchange.com/questions/119871/unknown-terminal-type-error-when-trying-to-run-emacsclient - viam0Zah

30

不要每次想使用shell时都关闭Emacs。使用Ctrl-Z将Emacs移至后台,然后在Bash中使用fg命令将其移回前台。


4
避免问题的尝试不错。您可以在回答中加入启动另一个 putty 会话和/或运行 screen。Chris Conway 的 M-x shell 回答也是此精神的一部分。 - artless noise
只需更正官方autoload链接即可:它是http://www.gnu.org/software/emacs/manual/html_node/elisp/Autoload.html。 - Sebastien Varrette
从没想过这个!我一定会尝试的!(y) - alamin

21
一些小提示:
  1. Use autoloads

    Using autoload saves you from loading libraries until you use them. For example:

    (if (locate-library "ediff-trees")
        (autoload 'ediff-trees "ediff-trees" "Start an tree ediff" t))
    
  2. Compile your .emacs

    Gives you a slight speed increase although there are pitfalls if you work with version control and your .emacs is newer than .emacs.elc. One common trick is:

    (defun autocompile nil
      "compile itself if ~/.emacs"
      (interactive)
      (require 'bytecomp)
      (let ((dotemacs (file-truename user-init-file)))
        (if (string= (buffer-file-name) (file-chase-links dotemacs))
          (byte-compile-file dotemacs))))
    
    (add-hook 'after-save-hook 'autocompile)
    
  3. Learn to love emacs server.

    Running emacs as a server means never having to close it down. However I note your still using emacs22. emacs23 supports multi-tty which makes it a lot easier to run emacs in one screen session and then bring up new windows in another terminal. I use emacs to edit mail for my mail client (mutt) and emacsclient is fantastic for these sort of quick edits.


我可以在gccemacs(https://www.emacswiki.org/emacs/GccEmacs)中使用`(add-hook 'after-save-hook 'autocompile)`方法吗? - alper

19

其中之一

M-x shell
M-x eshell
M-x term
M-x ansi-term

你可以使用 M-! (也称为 M-x shell-command) 在 Emacs 中执行一个一行命令而无需退出到 shell。


16

检查你的.emacs文件,看看是否加载了不必要的包。加载包可能需要相当长的时间。例如,如果你只想在编辑PHP文件时加载php-mode包,你可以通过安装钩子程序来实现,但我并不确定具体细节。

此外,请确保你正在加载的任何包都是已编译的(.elc文件)。你可以通过运行命令编译elisp文件。

emacs -batch -f batch-byte-compile thefile.el

编译后的程序包比未编译的程序包加载速度更快。


我该如何从编译文件(.elc)中加载? - alper

14

"我经常打开和关闭emacs,因为我更喜欢使用bash命令行来操作文件/目录和编译。"

您所描述的是像vim这样的编辑器的使用方式。快速进出。Emacs通常保持打开状态,并且大部分工作都在“其中”完成。hiena已经回答了正确的方法。


2
不要退出emacs,你可以使用C-z暂停它,然后用fg唤醒它... - Damien Pollet
2
@Damien Pollet - (困惑),...嗯,是的,我知道。我觉得重复已经说过的话有点多余,所以我只是指向了hiena的帖子。 - Rook

13

最快的方法是 分析你的 .emacs 配置文件。在发现我的 .emacs 中的4行代码占用了80%以上的加载时间后,我花了5分钟将加载时间从 >3秒降至1秒。


profile-dotemacs 包似乎没有得到积极维护(此答案链接的 Emacswiki 页面的“下载”部分指向一个存档的网页)。相反,Emacs Start Up Profiler (ESUP) 似乎更为更新。 - Giuseppe
你找到了哪4行? - alper

11
除了其他人建议的autoload,有一件事帮助我减少.emacs的加载时间,那就是eval-after-load。在下面的示例中,延迟调用sql-set-product可以避免在.emacs中加载sql,使得现有的sql自动加载更加有效。
(eval-after-load "sql"
  '(progn
     (sql-set-product 'mysql)
     (setq sql-mysql-options '("-C" "-t" "-f" "-n"))
     (setq sql-sqlite-program "sqlite3")
     ))
当然,对于某些包,可能会有一个hook可用,您可以做同样的事情,但有时没有,或者这种方式更容易思考。

1
使用eval-after-load的一个缺点是它阻止了对代码的编译时检查,当自定义变得复杂时,这种检查非常有用。我在这种情况下的标准方法是例如(eval-after-load "org" (require 'my-org-customization)),即将自定义移动到单独的(已编译)文件中。 - kdb

8

Emacs旨在长时间运行,因此不建议在一天中多次启动和停止Emacs。

我建议使用screen。Screen是一个终端复用器,在一个终端中提供无限虚拟终端。

安装后,只需在终端中输入“screen emacs”。 Emacs将像往常一样启动,但按下“c-a c”(即按下ctrl-a,然后按c)将打开一个新的虚拟终端。按“c-a c-a”(即两次ctrl-a)可以返回到emacs。

您甚至可以从正在运行的screen会话中分离出来,“c-a d”是键序列。

通过发出“screen -R”重新连接到会话,您将回到离开的地方。这使您可以在工作中启动emacs会话,分离,回家并从家中重新连接。

我已经连续几个月以这种方式运行Emacs。

这是官方网站:http://www.gnu.org/software/screen/,但请尝试搜索screen教程和操作指南。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接