简体   繁体   English

如何让 Emacs 启动更快?

[英]How can I make Emacs start-up faster?

I use Emacs v. 22 (the console version, either remotely with PuTTY or locally with Konsole ) as my primary text editor on Linux.我在 Linux 上使用Emacs v. 22(控制台版本,远程使用PuTTY或本地使用Konsole )作为我的主要文本编辑器。 It takes a while to load up each time I start it though, probably almost a second, although I never timed it.每次启动它都需要一段时间来加载,可能几乎一秒钟,尽管我从来没有计时过。 I tend to open and close Emacs a lot, because I'm more comfortable using the Bash command-line for file/directory manipulation and compiling.我倾向于经常打开和关闭 Emacs,因为我更习惯使用Bash命令行进行文件/目录操作和编译。

How can I speed up the start-up time?如何加快启动时间?

Others have covered using gnuserve and emacsclient , and I'd suggest compiling within emacs (being able to jump to compilation errors is a win).其他人已经涵盖了使用gnuserveemacsclient ,我建议在 emacs 中编译(能够跳转到编译错误是一种胜利)。

But, specifically speeding up the .emacs can be done by:但是,可以通过以下方式特别加快 .emacs 的速度:

  1. Byte compiling the .emacs file, which you can do automatically by using this snippet of code字节编译 .emacs 文件,您可以使用这段代码自动完成

  2. Replacing as many of the (require 'package) statements with autoload ed functionality.自动加载功能替换尽可能多的(require 'package)语句。 This will delay loading of lisp until it's actually required.这将延迟 lisp 的加载,直到真正需要它为止。 Using this technique allowed me to speed up my startup from >6 seconds to <1.使用这种技术,我可以将启动速度从 >6 秒加速到 <1 秒。 This takes a little bit of work because not all libraries come properly marked autoload .这需要一些工作,因为并非所有库都正确标记为autoload

  3. Removing code/functionality you no longer use.删除不再使用的代码/功能。

  4. Try running emacs with the option --no-site-file to avoid loading unnecessary packages in the site installation site-start.el .尝试使用选项--no-site-file运行 emacs 以避免在站点安装site-start.el加载不必要的包。

  5. If you are really serious, you can roll your own emacs with your favorite functionality already loaded.如果你真的很认真,你可以使用已经加载的你最喜欢的功能来推出你自己的 emacs。 This, of course, means it's more involved to make changes to what you have in your .emacs because it's a part of the binary.当然,这意味着更需要对.emacs内容进行更改,因为它是二进制文件的一部分。 Follow the link for information on how to use dump-emacs .按照链接获取有关如何使用dump-emacs

  6. Buy a faster computer and/or faster disk.购买更快的计算机和/或更快的磁盘。

How to determine what your .emacs loads如何确定您的 .emacs 加载的内容

Now, how do you find out what your .emacs loads?现在,您如何找出 .emacs 加载的内容? With the goal to remove the functionality, or to delay it?目标是删除功能还是延迟它? Check your *Messages* buffer, which contains lines like:检查您的*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

If you'll notice, the Loading statements can nest: the first .emacs.tjackson.el ends with ... and the last line shows the .emacs.tjackson.el load is ...done .如果您注意到, Loading语句可以嵌套:第一个.emacs.tjackson.el...结尾,最后一行显示.emacs.tjackson.el load is ...done All those other files are loaded from inside my .emacs.tjackson.el file.所有其他文件都是从我的.emacs.tjackson.el文件中加载的。 All the other loads are atomic.所有其他负载都是原子的。

Note: If you have a large .emacs, it's possible that the *Messages* buffer will lose some of the messages because it only keeps a fixed amount of information.注意:如果您有一个很大的 .emacs, *Messages*缓冲区可能会丢失一些消息,因为它只保留了固定数量的信息。 You can add this setting early on to your .emacs to keep all the messages around:您可以尽早将此设置添加到.emacs以保留所有消息:

(setq message-log-max t)

Note: It the 'load command will suppress the messages if its fourth argument nomessage is non-nil, so remove any such invocations (or, advise 'load and force the fourth argument to be nil ).注意:如果'load命令的第四个参数nomessage则它会抑制消息,因此删除任何此类调用(或者,建议'load并强制第四个参数为nil )。

In addition to Adam Rosenfield's solution , I recommend to use Emacs in server mode .除了Adam Rosenfield 的解决方案,我建议在服务器模式下使用Emacs You may add (server-start) to your dotemacs, and run emacsclient instead of emacs whenever you want to open file in Emacs.您可以将(server-start)添加到您的 dotemacs,并在您想在 Emacs 中打开文件时运行emacsclient而不是emacs That way you have to pay the loading cost of Emacs only once, after then clients pop up immediately.这样你只需支付一次 Emacs 的加载成本,然后客户端就会立即弹出。

Edit编辑

You're right, v22 does not create a new frame.没错,v22 不会创建新框架。 Create a shell script that do the trick:创建一个执行此操作的 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'"))'

Edit 2编辑 2

In v24+, you can do emacsclient -c to create a new frame.在 v24+ 中,您可以执行emacsclient -c来创建新框架。

Don't close Emacs every time you want to use the shell.不要在每次要使用 shell 时都关闭 Emacs。 Use Ctrl-Z to move Emacs to the background and the fg command in Bash to move it back to the foreground.使用 Ctrl-Z 将 Emacs 移至后台,使用 Bash 中的fg命令将其移回前台。

A couple of tips:一些提示:

  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编译你的 .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.使您的速度略有提高,但如果您使用版本控制并且您的 .emacs 比 .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.学会爱上 emacs 服务器。

    Running emacs as a server means never having to close it down.将 emacs 作为服务器运行意味着永远不必关闭它。 However I note your still using emacs22.但是我注意到您仍在使用 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. emacs23 支持多 tty,这使得在一个屏幕会话中运行 emacs 然后在另一个终端中打开新窗口变得更加容易。 I use emacs to edit mail for my mail client (mutt) and emacsclient is fantastic for these sort of quick edits.我使用 emacs 为我的邮件客户端 (mutt) 编辑邮件,而 emacsclient 非常适合此类快速编辑。

One of之一

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

should meet your command-line needs from within Emacs.应该在 Emacs 中满足您的命令行需求。

You can also use M-!您也可以使用M-! (aka Mx shell-command ) to execute a one-liner without dropping to the shell. (又名Mx shell-command )执行单行而不落到 shell。

Check your .emacs file to see if you're loading unnecessary packages.检查您的.emacs文件,看看您是否正在加载不必要的包。 Loading packages can take a significant amount of time.加载包可能需要大量时间。 For example, you might only want to load the php-mode package if you're editing a PHP file.例如,如果您正在编辑 PHP 文件,您可能只想加载php-mode包。 You can do that by installing a hook procedure, although I'm not certain of the details.你可以通过安装一个钩子程序来做到这一点,尽管我不确定细节。

Also make sure that any packages you're loading are compiled ( .elc files).还要确保您加载的任何包都已编译( .elc文件)。 You can compile an elisp file by running你可以通过运行编译一个elisp文件

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

Compiled packages load much faster than uncompiled packages.编译包的加载速度比未编译包快得多。

"I tend to open and close emacs a lot, because I'm more comfortable using the bash command line for file/directory manipulation and compiling." “我倾向于经常打开和关闭 emacs,因为我更习惯使用 bash 命令行进行文件/目录操作和编译。”

You're describing the way an editor like vim is used like.您正在描述像 vim 这样的编辑器的使用方式。 Shoot in&out.射进射出。 Emacs is usually kept open, and mostly all is done from "within it". Emacs 通常保持打开状态,并且大部分都是从“内部”完成的。 hiena already answered what would be the correct approach here. hiena 已经在这里回答了正确的方法是什么。

The fastest way is to profile your .emacs .最快的方法是配置您的 .emacs I cut down my load time from >3s to 1s in 5 minutes after I found that 4 particular lines in my .emacs were taking up more than 80% of the load time.在我发现 .emacs 中的 4 条特定行占用了超过 80% 的加载时间后,我在 5 分钟内将加载时间从 > 3 秒缩短到 1 秒。

One thing that helped me reduce the load time of my .emacs , in addition to autoload (as others have suggested), is eval-after-load .除了autoload (正如其他人所建议的)之外,帮助我减少.emacs加载时间的一件事是eval-after-load In the following example, delaying the call to sql-set-product saves you from having to load sql in your .emacs , making the exisiting sql autoloads more effective.在以下示例中,延迟对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")
     ))

Of course, for some packages there will be a hook available that you can do the same thing, but sometimes there isn't, or else this way just proves easier to think about.当然,对于某些包,您可以使用一个钩子来做同样的事情,但有时没有,否则这种方式更容易思考。

Emacs is designed to run "all the time" (or at least for long periods of time), thus starting and stopping Emacs several times during a day is not recommended. Emacs 被设计为“一直”运行(或至少长时间运行),因此不建议在一天内多次启动和停止 Emacs。

I would suggest using screen.我建议使用屏幕。 Screen is a terminal multiplexer, giving you an unlimited virtual terminals in one terminal. Screen 是一个终端多路复用器,在一个终端中为您提供无限的虚拟终端。

After installing simply write "screen emacs" in your terminal.安装后,只需在终端中写入“screen emacs”即可。 Emacs will start as usual, but pressing "ca c" (that is press ctrl-a and then c) will open a new virtual terminal. Emacs 将照常启动,但按“ca c”(即按 ctrl-a 然后按 c)将打开一个新的虚拟终端。 You can get back to emacs by pressing "ca ca" (that's two times ctrl-a).您可以通过按“ca ca”(即两次 ctrl-a)返回到 emacs。

You can even detach from the running screen session, the key sequence is "ca d".您甚至可以从正在运行的屏幕会话中分离出来,关键序列是“ca d”。

Re-attach to the session by issuing "screen -R" and you will be back where you left.通过发出“screen -R”重新连接到会话,您将回到离开的地方。 This enables you to start an emacs session at work, detach, go home, and re-attach from home.这使您能够在工作中启动 emacs 会话、分离、回家和从家里重新连接。

I've been running Emacs like this for months in a row.我已经连续几个月这样运行 Emacs。

Here's the official web site: http://www.gnu.org/software/screen/ but try googling for screen tutorials and howtos这是官方网站: http : //www.gnu.org/software/screen/但尝试谷歌搜索屏幕教程和操作指南

You can use benchmark-init to profile your Emacs startup.您可以使用benchmark-init来分析您的 Emacs 启动。 It will keep track of what modules are being loaded and how much time is spent on each.它将跟踪正在加载哪些模块以及在每个模块上花费了多少时间。 The results can be presented either in a tabulated form or as a tree.结果可以以表格或树的形式呈现。 The tree makes it easier to track who loads what, which can be helpful when you load a package with a lot of dependencies, and the tabulated form helps you quickly find where most of the time is being spent.该树可以更轻松地跟踪谁加载了什么,这在您加载具有大量依赖项的包时会很有帮助,并且表格形式可以帮助您快速找到大部分时间都花在了哪里。

Once you have these results try to figure out if all of the modules have to be loaded all the time or if you can perhaps load some of them on-demand.获得这些结果后,请尝试确定是否必须始终加载所有模块,或者是否可以按需加载其中一些模块。 For instance, in my configuration I only load Emacs extensions that are specific to certain modes when that mode is actually activated since most of the time I only use a small subset of them in a session.例如,在我的配置中,我只加载特定于某些模式的 Emacs 扩展,当该模式实际激活时,因为大多数时候我只在会话中使用它们的一小部分。 eval-after-load and mode hooks will be your friends here. eval-after-load和 mode hooks 将成为你的朋友。

By applying this method my Emacs starts in 3-4 seconds and I have close to 200 extensions installed.通过应用这种方法,我的 Emacs 可以在 3-4 秒内启动,并且我已经安装了近 200 个扩展 Most of the time is spent loading Helm, which I always load since it replaces find-file and other core functions that are always needed, and CEDET, since I use the latest version and it has to be loaded before Emacs tries to load the older built-in version.大部分时间都花在加载 Helm 上,我总是加载 Helm,因为它替换了始终需要的 find-file 和其他核心功能,以及 CEDET,因为我使用的是最新版本,并且必须在 Emacs 尝试加载旧版本之前加载它内置版本。

Try using the https://github.com/jwiegley/use-package macro to define your package loads and customizations.尝试使用https://github.com/jwiegley/use-package宏来定义您的包加载和自定义。 It handles deferred loading of packages for you, making it relatively easy to get good startup times even in the presence of large numbers of configured packages.它为您处理包的延迟加载,即使在存在大量配置包的情况下,也可以相对容易地获得良好的启动时间。 I have almost 100 packages referenced in my .emacs, but my startup time is under 2 seconds on Linux, and 2.2s on the Mac.我的 .emacs 中引用了近 100 个包,但我的启动时间在 Linux 上不到 2 秒,在 Mac 上不到 2.2 秒。

I had around 120sec start time.我有大约 120 秒的开始时间。 I was able to find the fix installing this:我能够找到安装此修复程序:

https://github.com/dholm/benchmark-init-el put on top of your init.el 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)))

then once your emacs started, run:然后一旦你的 emacs 启动,运行:

Mx benchmark-init/show-durations-tree Mx benchmark-init/show-durations-tree

On my side the problem was 127 secs in tramp-loaddefs在我这边,问题是tramp-loaddefs 中的127 秒

I fixed it by adding我通过添加修复它

127.0.0.1  host.does.not.exist

to /etc/hosts and that made my startup fast/etc/hosts ,这使我的启动速度很快

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

another thing that maybe helpful to you: https://www.emacswiki.org/emacs/ProfileDotEmacs另一件事可能对您有帮助: https : //www.emacswiki.org/emacs/ProfileDotEmacs

One thing that others haven't mentioned is to include the elisp libraries you use as part of the dumped Emacs to move the library loading time from Emacs startup to Emacs build.其他人没有提到的一件事是包含您用作转储 Emacs 的一部分的 elisp 库,以将库加载时间从 Emacs 启动转移到 Emacs 构建。 It is not for the faint-hearted, but if you load several libraries in .emacs it could win you a few seconds of startup time.它不适合胆小的人,但如果您在.emacs加载多个库,它可以为您赢得几秒钟的启动时间。

This doesn't answer the question, but is kind of relevant这不能回答问题,但有点相关

I don't know how to make it start faster, but there are a few things I could suggest:我不知道如何让它启动得更快,但我可以建议一些事情:

  • for most things you do on the command line, you can do them in emacs:对于你在命令行上做的大多数事情,你可以在 emacs 中做:

    • compile: Mx compile, then type the command you use compile:mx compile,然后输入你使用的命令
    • my experience is only with C++, but with g++ you can press Cx ` to jump to lines that the compiler complains about我的经验仅适用于 C++,但使用 g++ 你可以按 Cx ` 跳转到编译器抱怨的行
    • run shell commands: M-!, dumps output into a buffer运行 shell 命令:M-!,将输出转储到缓冲区
    • interactive shell: Mx shell交互式外壳:Mx 外壳
  • alternatively, you could run emacs like this:或者,您可以像这样运行 emacs:

    • emacs file.ext &
    • which opens emacs in the background so you can still use the shell ( this works best with putty and X forwarding with something like Xming)它在后台打开 emacs,因此您仍然可以使用外壳(这最适用于腻子和 X 转发,例如 Xming)

I was trying to solve the same problem, when I came across this question here.当我在这里遇到这个问题时,我正试图解决同样的问题。 I just wanted to add that the problem for me was not because of the load time of emacs lisp packages, but the fact that the host did not have a fully resolved hostname我只是想补充一点,我的问题不是因为 emacs lisp 包的加载时间,而是主机没有完全解析的主机名这一事实

To check your package load time do要检查您的包加载时间,请执行以下操作

M-x emacs-init-time

For me it was 0.3 seconds, and yet the load time was extremely high.对我来说是 0.3 秒,但加载时间非常长。 After changing my hostname correctly, it fixed the problem.正确更改我的主机名后,它解决了问题。

To configure your fully resolved hostname edit /etc/hostname, and /etc/hostsfile with:要配置完全解析的主机名,请使用以下命令编辑 /etc/hostname 和 /etc/hostsfile:

127.0.0.1       localhost localhost.localdomain
192.168.0.2   hostname hostname.domain

I would have to check my customization, but there is a package called gnuserve or emacsclient.我必须检查我的自定义,但有一个名为 gnuserve 或 emacsclient 的包。 It migrates a lot so you will have to google for it.它迁移了很多,所以你必须谷歌搜索它。

It runs one emacs session in the background.它在后台运行一个 emacs 会话。 Any further sessions of emacs are essentially just new frames of that session.任何进一步的 emacs 会话本质上只是该会话的新框架。 One advatage is quick startup times for your later sessions.一个优势是为您以后的会话快速启动。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM