- When we add more and more lines into
~/.emacs.d/init.el
for various purposes (for python-mode, for emacs-eclim, for ...), the file becomes lengthy and less readable. Is there a way to help organize its content? My current
~/.emacs.d
looks like this$ ls * init.el auto-save-list: elisp: python-mode.el-6.1.3 elpa: archives auctex-readme.txt s-20140910.334 auctex-11.87.7 emacs-eclim-20140809.207 eshell: history
python-mode.el-6.1.3
was manually installed, whileemacs-eclim-20140809.207
was installed byelpa
, and I am not 100% sure that the other things underelpa/
were byelpa
. How can I organize the content of~/.emacs.d/
?
12 Answers
People using lesser editors like to split their code into multiple files. If you're using Emacs, there's no reason to do that: just use a single large file, which you split into sections.
Each section should start with
^L
;;; title of the section
where you insert the ^L
character by typing C-q C-l
. You can then use commands such as C-x ]
(forward-page
) or C-x n p
(narrow-to-page
) to navigate through the file. See Section 25.4 (Pages) of the Emacs manual for more.
-
16There's also no special reason not to split code into multiple files. It depends on what you want the grouping of stuff together to mean - how you want it to behave. And it can depend on how large LARGE is. And it can depend on whether pieces of your code are shared with others, as libraries, for instance.– DrewOct 24, 2014 at 4:34
-
2Piggybacking on @Drew's comments, the user may want to have different configs for different emacs versions and environments and load the relevant elisp accordingly. That said, I like the pagination tip.– HarveyOct 24, 2014 at 13:31
-
4@Harvey: Pagination and using separate files are independent ways to organize text. You can use both, obviously. I use pagination in all of my libraries, to separate sections. But I also have separate libraries (files).– DrewOct 24, 2014 at 14:10
-
1@jch If you are using this style, you might also want to enable Outline Minor Mode or a similar feature, to allow folding of sections and functions. Folding all top-level headings gives you a nice overview of all sections in your Emacs configuration.– user227Oct 26, 2014 at 7:43
-
@lunaryorn, I've tried, but I've found it distracting — I'm finding the page movement commands sufficient most of the time, I only occasionally need to narrow. Perhaps my
.emacs
and.wl
are not long enough.– jchOct 26, 2014 at 15:50
A classic way of doing this is splitting your .emacs
into separate files. For example, you could move all your web stuff into ~/.emacs.d/web-config.el
and then load it inside init.el
:
(load "~/.emacs.d/web-config.el")
If you want to keep your ~/.emacs.d
a bit more organized, you could also shift these config files into their own directory:
(load "~/.emacs.d/config/web.el")
Now you can just jump to the appropriate file when making changes to your config.
One thing that's missing from this are variables set via the customize system. These will still all be in your main init.el. Apparently, there's a little utility called init split which lets you make rules about which customize setting goes where, but I've never used it myself. Alternatively, the “customize” system can be configured to use a separate file for its modifications to your settings. Set the custom-file
variable to specify where the “customize” settings should be read from and written to.
As far as the directory itself goes, I've always been happy with the default layout. The main change I made was creating a directory for all of my own custom packages and libraries that are not managed by package.el
. This gives a single home to my custom elisp that isn't related to configuration.
-
Thanks. (1) what is the directory for packages and libraries that are managed by package.el? (2) Are the contents of the dir
elpa
managed byelpa
? Can I move them elsewhere?– TimOct 23, 2014 at 22:39 -
2You can specify a separate file for Customize variables by setting
custom-file
variable. Source Oct 23, 2014 at 22:56 -
@Tim: The directory managed by package.el is elpa. Elpa is not a lisp package, it's a package repository. Package.el will still add all packages it installs (be it from elpa or from another repository --- for example in your case, I don't think eclim and s are from elpa) in the directory elpa. And yes, you shouldn't need to worry about the content of this directory. Oct 24, 2014 at 5:22
-
(Cannot edit anymore) What I wrote above is not rigorously true: elpa is the format of the package archives, package.el is the package manager. For the user, there is no real difference between the two. My comment above mistakes elpa with GNU elpa, which is one of the available elpa packages (and the only official one). Oct 24, 2014 at 8:22
If you like Org-mode, you can use it to organize your .emacs
without splitting it. Under my current configuration my .emacs
file just bootstraps an init.org file I have under ~/.emacs.d/init/init.org
(require 'org)
;; Load the actual configuration file
(org-babel-load-file
(expand-file-name (concat user-emacs-directory "init/init.org")))
By using different files you need to grep
instead of simple C-s
to search for something, and so on. Also, it's easier to add several levels to your organization.
-
1I'm currently in the process of doing this, though I didn't think to use
org-babel-load-file
. Sweet! (Examples: github.com/vermiculus/dotfiles/blob/…, github.com/larstvei/dot-emacs) Oct 26, 2014 at 3:39 -
More on using org-mode for Emacs config on this question: Can I use org-mode to structure my .emacs or other .el configuration file? Jun 12, 2018 at 21:47
Just move pieces of code from init.el
to separate files (libraries), which you then require
. (Use provide
in the libraries to be require
d.) Put those files wherever you want, and update load-path
accordingly.
-
Thanks. (1) for example? (2) what do you suggest to organize ~/.emacs.d/?– TimOct 23, 2014 at 20:32
-
1What do you mean by "organize the content of
~/.emacs.d/
? You offer no specification of what you want. You are not constrained to having everything in one directory. You can put stuff anywhere you like, and modifyload-path
accordingly. If some program/tool only puts stuff in~/.emacs.d/
(i.e., if you cannot tell it where to put stuff), then move it where you want it after that program/tool is done.– DrewOct 23, 2014 at 20:34 -
1What do you mean by "for example"? What is it that you want an example of?
(require 'foobar)
is an example of usingrequire
.(add-to-list 'load-path "/my/lisp/dir")
is an example of modifyingload-path
.(provide 'foobar)
is an example of usingprovide
.– DrewOct 23, 2014 at 20:37 -
by "organize the content of ~/.emacs.d/, I, as a human, can understand it better, not for emacs to understand. It is a habit, just like organizing your cabinet, drawers, bookshelves. For example, python-mode.el-6.1.3 was manually installed, while emacs-eclim-20140809.207 was installed by elpa. Are they both packages? If they are, is it a good idea to put them under one subdirectory of ~/.emacs.d/?– TimOct 23, 2014 at 20:40
-
You are the human who can answer what organization might help you understand it better. (Emacs doesn't understand anything.) Use whatever folder structure you like. Call them cabinets, drawers, bookshelves, or just folders. And again, your
init.el
can load libraries located anywhere, not just within~/.emacs.d/
.– DrewOct 23, 2014 at 20:44
I use the suggestion by targzeta found on the Emacs Wiki: Load directory.
Basically I have a ~/.emacs.d/load-directory.el:
;;;; ~/.emacs.d/load-directory.el
;; Handy function to load recursively all '.el' files in a given directory
(defun load-directory (directory)
"Load recursively all '.el' files in DIRECTORY."
(dolist (element (directory-files-and-attributes directory nil nil nil))
(let* ((path (car element))
(fullpath (concat directory "/" path))
(isdir (car (cdr element)))
(ignore-dir (or (string= path ".") (string= path ".."))))
(cond
((and (eq isdir t) (not ignore-dir))
(load-directory fullpath))
((and (eq isdir nil) (string= (substring path -3) ".el"))
(load (file-name-sans-extension fullpath)))))))
Then I just put separate files in my ~/.emacs.d/config:
~/.emacs.d/config ls
01-packages.el 02-style.el 03-modes.el 04-keybindings.el 05-functions.el
And finally I have this in my ~/.emacs.d/init.el:
;; Load all ".el" files under ~/.emacs.d/config directory.
(load "~/.emacs.d/load-directory")
(load-directory "~/.emacs.d/config")
There is obviously more than one way to skin this particular cat. My current favourite is to use outline-minor-mode
with outshine. Excerpt:
;; * This here is my emacs init file
;; ** Many subsections with headlines like this one omitted
;; ** Customising modes
;; […] more lines omitted
;; *** Org and outline modes
(autoload 'outshine-hook-function "outshine")
(add-hook 'outline-minor-mode-hook 'outshine-hook-function)
;; […] and more
;; * Emacs Magic
;;; Local Variables:
;;; mode: emacs-lisp
;;; coding: utf-8
;;; mode: outline-minor
;;; fill-column: 79
;;; End:
Note that you will need to get outshine from your favourite package repository.
-
1I started out with outline-minor-mode, but found the keybindings too painful, and never quite found the time to do anything about it myself. So I moved to orgstruct-mode after discovering org-mode, but then I found out about outshine. Bliss! I currently use outline+outshine for all my structuring of elisp, latex and other files with their own major mode, and org-mode for all kinds of notes. Oct 26, 2014 at 9:27
I use the following structure to keep track of packages and files
~/.emacs.d
|-- elpa ;; Package.el packages
|-- hack ;; Development versions of packages (e.g. org, personal packages)
|-- single-lisp ;; Individual lisp files from outside sources (e.g. EmacsWiki)
|-- site-lisp ;; Lisp packages not managed by package.el (directories)
|-- user-config ;; Machine/situation specific customization (work vs home)
| `-- custom.el ;; Customization settings
|-- lisp ;; Individual .el files to keep init.el clean
| `-- defaults.el ;; Default configuration settings
`-- init.el
I then use use-package
to manage which packages are loaded and which customizations are set for each package. Most of the time only hack
and elpa
require updating, the other folders are often for one-off packages that I want to test or use briefly but do not need to load (even idly).
custom.el
is for Customize settings, which I prefer not to use (and do not version even if I do use).
defaults.el
is for general configuration (menu-bar, font, encoding, etc) that can then be overwritten in any .el file in user-config/
to allow for a system that will work as I expect, but can be adjusted to fit the environment.
I had previously tried to keep functions
, macros
, advice
in separate packages to allow for delineation between content, but ran into definition/require issues so have put those back into init.el
. They may eventually be put back into ~/.emacs.d/lisp/
.
I try to keep init.el
tidy, sort content by function and purpose so that finding it again will be straightforward. I've had the monolithic init.el
file and kept adding new content at the end (or where I thought it might fit) and then would end up not knowing what I had added or where I had added it when I went to look for it (and sometimes searching using isearch
did not help since I could not remember how I named things at the time).
All of the existing answers address best practices for organizing manually created files, like init.el
and friends. Equally important is the organization of all the automatically created files from various packages, and for this the package no-littering
is excellent.
I added
(when (string= (buffer-name) "init.el")
(setq imenu-generic-expression
'((nil "^;; \\[ \\(.*\\)" 1))))
to emacs-lisp-mode-hook. Then add to the file sections "yasnippet", "packaging", "java mode", etc. This Works nice for my 1000 lines of code (comments included).
EDIT: Finally i switch between sections with helm-imenu. Actually helm hooks into normal imenu function automagically so all i need is
(local-set-key (kbd "C-*") 'imenu)
I split my relatively small .emacs
file into three parts:
emacs-custom.el for customizations, ripping out lots of bulky and useless data; the file is automatically rewritten without touching the main .emacs file, preventing spurious changes.
(setq custom-file "~/.emacs-custom.el") (load custom-file)
lg-lib.el for code rather than configuration: loading my own libraries from nonstandard source locations rather than from the packages directory and defining various functions (mostly copied and hacked in the absence of a proper package); it is another large reduction of .emacs line count.
(load "~/lg-lib")
The main .emacs file: without bulky code and bulky customization variables, it contains
require
calls for packages, variables that aren't part of the Customize system, and assorted function calls to load and initialize packages. I "organize" it by carefully keeping all lines pertaining to the same package or feature together, and further separating package loading and package-related settings from "core" functionality. A fairly representative excerpt:(require 'ido) (ido-mode t) (require 'auto-complete) (add-to-list 'ac-dictionary-directories "~/.emacs.d/ac-dict") (require 'auto-complete-config) (ac-config-default) (global-auto-complete-mode t)
These sections are tiny, but they would remain manageable with many more lines of configuration for each package.
Follow the setup of an Emacs master, e.g., https://github.com/purcell/emacs.d
For example, regarding how to organize manually installed packages and packages installed from ELPA, Steven Purcell's setup has
a place for 3rd party code which isn't available in MELPA or other
package repositories. This directory and its immediate
subdirectories will be added to load-path at start-up time.
Notably, in Emacs 23.x, a backported package.el is automatically
downloaded and installed here
Why follow a master? A major point of my "Master emacs in one year" is that newbies can thus efficiently avoid setup overhead and "gotchas."
I understand that many people don't agree with me, but here's my case (detailed in my article):
I started using Emacs by using Purcell's well-respected (1403 GitHub stars as of Nov 2014!), stable (5 years in development) configuration. Despite starting from that, I still had many problems. Steve Purcell helped me solve all those problems. (I actually became his Padawan for over a year.) By using his setup, and using his repo's issues to report problems, and taking advantage of his experience, I avoided wasting much time. Even today, I still observe many people using git submodule
to manage the third-party plugins. Both Steve and I gave up using git submodule
for this because it can be such a PITA.
But if you are very confident of your skills or much prefer self-learning, this is not the path for you.
-
2"Cloning the setup from master": Without specific regard to the references you cite, which might provide wonderful features or advice (I haven't checked), I disagree in general that people should start by cloning init files or other setups from others. That has even been an explicitly discouraged policy, IIRC, as it can lead to problems. Better to start from scratch and be aware of (and even understand!), whatever you use as basic setup. Of course there is nothing wrong with studying and learning from what others have done. But blindly copying init files is not advisable. (Just one opinion.)– DrewNov 10, 2014 at 14:45
-
1actually, I write my article because there are still many people believes that they should start from the scratch on the setup. it's not the best way for most people, as I observed, and unnecessarily hard way for newbies. just search– chen binNov 11, 2014 at 11:12
-
1It is "the best way for most people". Just search for discussions and advice against starting out by using someone else's init file. Search
[email protected]
, andwww.emacswiki.org
, and[email protected]
, and evendebbugs.gnu.org
. That said, there is nothing wrong with sharing one's init file, to serve others as food for thought. The advice is for newbies not to start out that way; the advice is not for people not to share their own startup approaches and tips.– DrewNov 11, 2014 at 14:41 -
1It's because of "survivorship bias". Many people give up before they know emacswiki or mailing list.– chen binJun 28, 2016 at 0:21
An innovative and simple way to cleanup your .emacs.d
folder is to use org-mode
and outline everything using source blocks. Then, in your .emacs
file, point to your config.org
.
A wonderful resource on this is Harry Schwartz. He has a youtube video that touches and a blog post that explains the details. I was able to follow it as an emacs noob and get all setup. Works like a charm. 1 file for my entire init
.