142

I have decided to check out Emacs, and I liked it very much. Now, I'm using the Emacs Starter Kit, which sort of provides better defaults and some nice customizations to default install of Emacs.

I have customized it a little, added some stuff like yasnippet, color-themes, unbound, and other stuff. I've set up a github repository where I keep all of the customizations so I can access them from multiple places or in case something goes bad and I lose my .emacs.d directory.

All of this is very nice, but there is a problem: Emacs takes about 1-2 seconds to load. AFAIK I can compile individual .el files with M-x byte-compile-file to .elc, and it works. But there are a lot of .el files, and I wonder if there is a way to compile them all with a simple command or something, to speed up the loading of Emacs. My Emacs is not always open, and I open and close it quite frequently, especially after I've set it up as a default editor for edit command in Total Commander to get used to it faster (yeah, windows xp here).

My Emacs version is 22.3. And yes, the default Emacs installation without any customizations fires up instantly.

I am not sure which version is preferred when loading, the .el or compiled .elc one by the way O.o

So, is there an elisp command or Emacs command line switch to make Emacs byte-compile everything in .emacs.d directory?

Mikka
  • 2,073
  • 2
  • 16
  • 11

6 Answers6

219

C-u 0 M-x byte-recompile-directory

will compile all the .el files in the directory and in all subdirectories below.

The C-u 0 part is to make it not ask about every .el file that does not have a .elc counterpart.

Laurynas Biveinis
  • 10,500
  • 3
  • 50
  • 61
  • 9
    And thereafter (once each has been compiled once), just use the same command without the `C-u 0` (aka `C-0`, BTW). That will byte-compile only those source files that are more recent than their byte-compiled versions. – Drew Sep 05 '11 at 00:23
  • 1
    A little note: for me that didn't worked until I removed all an according «.elc» files. It just told something like «Done, 0 files comiled, α files skipped». – Hi-Angel Jan 12 '15 at 05:57
  • 1
    @Hi-Angel I have the same problem. Have you found any solution? – zhanxw Aug 28 '15 at 02:26
  • @zhanxw yep. Unfortunately the command compiles only files that either have changed, or have no «.elc» counterpart. So to recompile everything in a directory first you have to delete all «.elc» files. – Hi-Angel Aug 28 '15 at 03:24
  • 3
    The interactive command unfortunately doesn't expose it, but if you call the function directly you can use the optional argument `FORCE` to recompile files that already have an associated ".elc" even if they're not older than the source file: `M-: (byte-recompile-directory "/the/directory/" 0 t)` – jbm Jul 01 '17 at 23:41
46

To automatically byte compile everything that needs byte compiling each time I start emacs, I put the following after my changes to load-path at the top of my .emacs file:

(byte-recompile-directory (expand-file-name "~/.emacs.d") 0)

Surprisingly, it doesn't add much to my startup time (unless something needs to be compiled).

To speed up my emacs, I first identified the slow parts using profile-dotemacs.el and then replaced them with autoloads.

Richard Hansen
  • 44,218
  • 20
  • 84
  • 95
  • [autoloads](https://www.gnu.org/software/emacs/manual/html_node/elisp/Autoload.html) documentation has moved. That and the profile-dotemacs.el reference are exactly what I needed when I came across this page. – Digicrat Mar 01 '20 at 23:43
25

You can use the --batch flag to recompile from the command line.

To recompile all, do

emacs --batch --eval '(byte-recompile-directory "~/.emacs.d")'

or to recompile a single file as from a Makefile,

emacs --batch --eval '(byte-compile-file "your-elisp-file.el")'
Mike Samuel
  • 109,453
  • 27
  • 204
  • 234
  • 5
    use [batch-byte-compile](http://www.gnu.org/software/emacs/manual/html_node/elisp/Compilation-Functions.html#index-batch_002dbyte_002dcompile-909) instead. – npostavs Aug 24 '13 at 02:14
  • 1
    Could you should how to use it? – nacho4d Jul 29 '14 at 11:18
  • 8
    @nacho4d `emacs -Q --batch -f batch-byte-compile *.el foo/*.el` - it doesn't recurse like **byte-recompile-directory** does though. – Brian Burns Jan 10 '15 at 22:57
  • 3
    You probably want to add an argument to force recompilation, eg. emacs --batch --eval '(byte-recompile-directory "~/.emacs.d" 0)' – Ibrahim Aug 10 '16 at 01:59
18

This is swaying a bit from the question, but to solve the problem of loading slowly you can use the new daemon feature in Emacs 23.

"If you have a lot of support packages, emacs startup can be a bit slow. However, emacs 23 brings emacs --daemon, which enables you to start emacs in the background (for example when you log in). You can instantly pop up new emacs windows (frames) with emacsclient. Of course, you could already have an emacs 'server' in older versions, but being able to start it in the background makes this a much nicer solution"

From http://emacs-fu.blogspot.com/2009/07/emacs-23-is-very-near.html

mwilliams
  • 9,734
  • 13
  • 48
  • 71
  • I definitely gonna check this one one out. Thank you! – Mikka Aug 02 '09 at 20:04
  • 2
    If you add alias emacs='emacsclient -nw -a "" -c' to your .bashrc (or your shell's version) it will first try to connect to a running daemon if there is one, if not it will start one and connect you. – Frederick Apr 23 '14 at 07:24
2

For my using spacemacs, the command is spacemacs/recompile-elpa. The command byte-recompile-directory does not compile any file.

Yu Shen
  • 2,225
  • 3
  • 30
  • 37
  • 2
    Different things. ELPA/MELPA stuff has defined build methods in its own archive hierarchy. byte-recompile-directory tries to compile all .el files in a user defined directory. – RichieHH Mar 07 '19 at 11:37
1

The command I use is M-x byte-force-recompile RET, it then asks the directory so, for example, I give it ~/.emacs.d/elpa/. It then recompiles everything in there, usually no need to delete .elc files first or mess with it in other ways.