如何使Emacs的启动速度更快?


71

我在Linux上将Emacs v。22(控制台版本,通过PuTTY远程或通过Konsole在本地)用作我的主要文本编辑器。每次我启动它都需要一段时间才能加载,尽管几乎没有计时,但可能要花将近一秒钟的时间。我倾向于频繁地打开和关闭Emacs,因为使用Bash命令行进行文件/目录操作和编译更加舒适。

如何加快启动时间?


2
我在Ubuntu上也遇到过同样的问题。似乎有许多Emacs软件包在启动时会通过默认的软件包配置自动加载,我无法弄清楚如何阻止我不需要/不需要的软件包。
克里斯·康威

5
@Chris,尝试用--no-site-file盯住Emacs,这可能是安装程序加载了不需要的软件包。
Trey Jackson

2
通过删除客户端和服务器之间来回发送的一些颜色信息,我们极大地减少了我工作的emacs的加载时间(降低了80%的加载时间)。
Dominic Rodger

1
分析您的.emacs。我在下面的答案中发布了一个链接,解释了如何执行此操作。
Vicky Chijwani 2011年

您不必完全关闭Emacs,只需输入即可将其挂起C-z。然后,在bash中,键入命令fg以使其在前台继续。除此之外,请尝试M-x term在Emacs中在emacs中拥有一个shell(在您的shell中:-)。这样,您实际上不必离开Emacs,而只需在缓冲区中提供另一个bash shell。
托马斯

Answers:


40

除了Adam Rosenfield的解决方案外,我建议在服务器模式下使用Emacs。您可以添加(server-start)到dotemacs中,然后运行,emacsclient而不是emacs在要在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”选项。有什么建议?
科林

emacs --daemon仅在v23及更高版本中受支持。另外,如果它发现您的〜/ .emacs错误,并且无法正常启动,这可能是您首次移动到此新版本时可能发现的错误:)
Gregory 2010年

1
如果您在服务器模式下运行emacs,这是一种更快的方法。这些快捷方式可能会派上用场。...1.启动服务器,emacs --daemon这将导致它运行服务器并将控件返回到终端。2.然后编辑文件。emacsclient <filename>3.停止守护进程emacsclient -e "(kill-emacs)"
阿拉明'17

我遇到以下错误:*ERROR*: Unknown terminal type
alper


60

其他人介绍了使用gnuserveemacsclient,我建议在emacs中进行编译(能够跳到编译错误是一个胜利)。

但是,可以通过以下方式专门提高.emacs的速度:

  1. 字节编译.emacs文件,您可以使用此代码段自动完成

  2. (require 'package)自动加载功能替换尽可能多的语句。这将延迟Lisp的加载,直到实际需要为止。使用这项技术可以使我的启动速度从> 6秒提高到<1。这需要一点工作,因为并非所有库都已正确标记autoload

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

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

  5. 如果您真的很认真,则可以将自己喜欢的功能加载到自己的emacs中。当然,这意味着要更改您所拥有的内容,.emacs因为它是二进制文件的一部分,因此涉及更多。点击链接获取有关如何使用的信息dump-emacs

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

如何确定您的.emacs加载

现在,如何找出.emacs加载了什么?以删除功能或延迟功能为目标?检查您的*Messages*缓冲区,其中包含以下行:

正在载入/home/tjackson/.emacs.tjackson.el(来源)...
加载/home/tjackson/installed/emacs/lisp/loaddefs.el(源代码)...完成
加载/user/tjackson/.elisp/source/loaddefs.el(源)...完成
正在加载自动还原...完成
载入/home/tjackson/.emacs.tjackson.el(来源)...完成

如果您会注意到,这些Loading语句可以嵌套:第一个.emacs.tjackson.el以结尾,...最后一行显示.emacs.tjackson.el负载为...done。所有其他文件都从我的.emacs.tjackson.el文件内部加载。所有其他负载都是原子的。

注意:如果您有很大的.emacs,则*Messages*缓冲区可能会丢失一些消息,因为该缓冲区仅保留固定数量的信息。您可以及早添加此设置,.emacs以保留所有消息:

(setq message-log-max t)

注意:如果该'load命令的第四个参数nomessage为非nil,则该命令将禁止显示消息,因此请删除所有此类调用(或建议'load并强制第四个参数为nil)。


您能否详细说明第二条建议?我不明白如何用自动加载替换我的要求调用,因为自动加载似乎需要docstring参数。
itmuckel

@ Micha90好吧,单击链接以获取自动加载的详细信息,但是,如果您不能(或不想)修改源代码以插入;;;###autoload行,则可以(autoload 'tcl-mode "tcl-mode")在.emacs中手动添加行以启用自动功能。加载(tcl-mode在这种情况下)。
Trey Jackson,

30

每次要使用该外壳程序时,请不要关闭Emacs。使用Ctrl-Z将Emacs移至背景,并使用fgBash中的命令将其移至前景。


4
+1尝试避免该问题。您可以将开始另一个putty会话和/或运行添加screen到答案中。克里斯·康威(Chris Conway)的M-x shell回答也符合这种精神。
artless的噪音

只需将链接更正为官方的自动加载链接即可:gnu.org/software/emacs/manual/html_node/elisp/Autoload.html
Sebastien Varrette 2014年

没想到!一定要尝试一下!(y)
阿拉明'17

21

一些提示:

  1. 使用自动加载

    使用自动加载可以使您免于加载库,直到使用它们为止。例如:

    (if (locate-library "ediff-trees")
        (autoload 'ediff-trees "ediff-trees" "Start an tree ediff" t))
    
  2. 编译你的.emacs

    如果使用版本控制并且.emacs比.emacs.elc更新,尽管有一些陷阱,但速度会稍有提高。一种常见的技巧是:

    (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. 学会爱emacs服务器。

    将emacs作为服务器运行意味着无需关闭它。但是我注意到您仍在使用emacs22。emacs23支持multi-tty,这使得在一个屏幕会话中运行emacs并在另一个终端中打开新窗口变得容易得多。我使用emacs来编辑邮件客户端(mutt)的邮件,而emacsclient对于此类快速编辑而言非常出色。


19

之一

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

应该可以从Emacs中满足您的命令行需求。

您也可以使用M-!(aka M-x shell-command)来执行单行代码而不用掉到shell中。


16

检查.emacs文件以查看是否正在加载不必要的软件包。加载程序包可能会花费大量时间。例如,您可能只想php-mode在编辑PHP文件时加载程序包。您可以通过安装挂钩过程来做到这一点,尽管我不确定细节。

还要确保您正在加载的所有软件包都已编译(.elc文件)。您可以elisp通过运行来编译文件

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

编译的软件包比未编译的软件包加载速度快得多。


14

“我倾向于频繁地打开和关闭emacs,因为使用bash命令行进行文件/目录操作和编译更容易。”

您正在描述像vim这样的编辑器的使用方式。射入和射出。Emacs通常保持打开状态,并且几乎所有操作都是从“内部”完成的。hiena已经回答了这里正确的方法。


2
除了退出emacs之外,您还可以使用Cz挂起它,然后用fg将其唤醒……
Damien Pollet

2
@Damien Pollet-(感到困惑),...嗯,是的,我知道这一点。我不想重复已经说过的话,所以我只提到了hiena的帖子。
Rook


11

eval-after-load.emacs,除了autoload(正如其他人所建议的那样)之外,帮助我减少了我的加载时间的一件事。在下面的例子中,延迟调用不必加载节省你在你的,使得等植物学自动加载更有效。sql-set-productsql.emacssql

(加载后评估“ sql”
  '(progn
     (sql-set-product'mysql)
     (setq sql-mysql-options'(“ -C”“ -t”“ -f”“ -n”))
     (setq sql-sqlite-program“ sqlite3”)
     ))

当然,对于某些软件包,您可以使用钩子来执行相同的操作,但有时却没有,否则这种方法就更容易思考了。


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

8

Emacs旨在“始终”运行(或至少长时间运行),因此不建议在一天中多次启动和停止Emacs。

我建议使用屏幕。Screen是一个终端多路复用器,可在一个终端中为您提供无限的虚拟终端。

安装完成后,只需在终端中编写“ screen emacs”。Emacs将照常启动,但是按“ ca c”(即按ctrl-a再按c)将打开一个新的虚拟终端。您可以通过按“ ca ca”(这是ctrl-a的两倍)来返回emacs。

您甚至可以脱离正在运行的屏幕会话,键序列为“ ca d”。

通过发出“ screen -R”重新连接到会话,您将回到原来的位置。这使您能够在工作中启动emacs会话,分离,回家以及从家重新连接。

我已经连续几个月运行这样的Emacs了。

这是官方网站:http : //www.gnu.org/software/screen/,但尝试在Google搜索中查找屏幕教程和howtos


6

您可以使用Benchmark-init来分析Emacs启动。它将跟踪正在加载的模块以及在每个模块上花费了多少时间。结果可以列表形式或以树形形式显示。该树使跟踪谁加载哪些内容变得更容易,这在加载具有很多依赖项的程序包时会很有帮助,而表格形式的表格可以帮助您快速找到大部分时间在哪里。

获得这些结果后,尝试找出是否所有的模块都必须一直加载,或者是否可以按需加载其中的一些模块。例如,在我的配置中,当该模式实际上被激活时,我仅加载特定于某些模式的Emacs扩展,因为在大多数情况下,我在会话中仅使用它们的一小部分。 eval-after-load和mode挂钩将是您的朋友。

通过应用此方法,我的Emacs将在3-4秒内启动,并且我已安装了将近200个扩展。大部分时间都花在加载Helm上,因为我会始终替换查找文件和其他始终需要的核心功能,所以我会一直加载Helm,因为我使用的是最新版本,因此必须在Emacs尝试加载旧版本之前先加载它内置版本。


4

其他人没有提到的一件事是包括将elisp库用作转储的Emacs的一部分,以将库的加载时间从Emacs启动转移到Emacs构建。它不是为胆小者准备的,但是如果您在.emacs其中加载多个库,则可以赢得几秒钟的启动时间。


4

尝试使用https://github.com/jwiegley/use-package宏定义您的程序包加载和自定义。它为您处理软件包的延迟加载,即使存在大量已配置的软件包,也相对容易获得良好的启动时间。.emacs中引用了几乎100个软件包,但是在Linux上我的启动时间不到2秒,在Mac上我的启动时间不到2.2秒。


4

我大约有120秒的开始时间。我能够找到安装此的修复程序:

https://github.com/dholm/benchmark-init-el 放在您的init.el顶部

(let ((benchmark-init.el "~/.emacs.d/el-get/benchmark-init/benchmark-init.el"))
  (when (file-exists-p benchmark-init.el)
    (load benchmark-init.el)))

然后,一旦您的emacs启动,请运行:

MX基准测试初始化​​/显示持续时间树

在我这一边,问题是流浪汉-loaddefs中的127秒

我通过添加来修复它

127.0.0.1  host.does.not.exist

/ etc / hosts,这使我的启动很快

在此处查看更多信息:https : //github.com/emacs-helm/helm/issues/1045

可能对您有帮助的另一件事:https : //www.emacswiki.org/emacs/ProfileDotEmacs


1
你救了我的理智。因此,我的init文件花费了大约2分钟的时间。谢谢!
silgon

3

这没有回答问题,但是有点相关

我不知道如何使其启动更快,但是我可以建议以下几点:

  • 对于您在命令行上执行的大多数操作,可以在emacs中执行:

    • 编译:Mx编译,然后键入您使用的命令
    • 我的经验仅限于C ++,但是对于g ++,您可以按Cx`跳转到编译器抱怨的行
    • 运行shell命令:M- !,将输出转储到缓冲区中
    • 交互式外壳:Mx外壳
  • 或者,您可以像这样运行emacs:

    • emacs file.ext &
    • 它将在后台打开emacs,因此您仍然可以使用外壳程序(这最适用于腻子和使用Xming之类的X转发)

2

当我在这里遇到这个问题时,我正在尝试解决相同的问题。我只是想补充一点,对我而言,问题不是因为emacs lisp软件包的加载时间,而是因为主机没有完全解析的主机名

要检查您的包裹装载时间

M-x emacs-init-time

对我来说,这是0.3秒,但是加载时间却非常长。正确更改我的主机名后,它解决了该问题。

要配置完全解析的主机名,请使用以下命令编辑/ etc / hostname和/ etc / hostsfile:

127.0.0.1       localhost localhost.localdomain
192.168.0.2   hostname hostname.domain

1

我将不得不检查我的自定义,但是有一个名为gnuserve或emacsclient的软件包。它迁移很多,所以您必须用谷歌搜索它。

它在后台运行一个emacs会话。emacs的任何其他会话本质上只是该会话的新框架。一种优势是缩短了以后的会话的启动时间。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.