- When we add more and more lines into
~/.emacs.d/init.elfor 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?
~/.emacs.dlooks 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.3was manually installed, while
emacs-eclim-20140809.207was installed by
elpa, and I am not 100% sure that the other things under
elpa. How can I organize the content of
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 ] (
C-x n p (
narrow-to-page) to navigate through the file. See Section 25.4 (Pages) of the Emacs manual for more.
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
If you want to keep your
~/.emacs.d a bit more organized, you could also shift these config files into their own directory:
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.
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
(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.
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.
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
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
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
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).
(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.
The main .emacs file: without bulky code and bulky customization variables, it contains
requirecalls 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.
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
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