29
  1. 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?
  2. 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, while emacs-eclim-20140809.207 was installed by elpa, and I am not 100% sure that the other things under elpa/ were by elpa. How can I organize the content of ~/.emacs.d/?

0

12 Answers 12

33

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.

7
  • 16
    There'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.
    – Drew
    Oct 24, 2014 at 4:34
  • 2
    Piggybacking 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.
    – Harvey
    Oct 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).
    – Drew
    Oct 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.
    – user227
    Oct 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.
    – jch
    Oct 26, 2014 at 15:50
24

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.

4
  • 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 by elpa? Can I move them elsewhere?
    – Tim
    Oct 23, 2014 at 22:39
  • 2
    You 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.
    – T. Verron
    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).
    – T. Verron
    Oct 24, 2014 at 8:22
17

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.

2
10

Just move pieces of code from init.el to separate files (libraries), which you then require. (Use provide in the libraries to be required.) Put those files wherever you want, and update load-path accordingly.

5
  • Thanks. (1) for example? (2) what do you suggest to organize ~/.emacs.d/?
    – Tim
    Oct 23, 2014 at 20:32
  • 1
    What 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 modify load-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.
    – Drew
    Oct 23, 2014 at 20:34
  • 1
    What do you mean by "for example"? What is it that you want an example of? (require 'foobar) is an example of using require. (add-to-list 'load-path "/my/lisp/dir") is an example of modifying load-path. (provide 'foobar) is an example of using provide.
    – Drew
    Oct 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/?
    – Tim
    Oct 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/.
    – Drew
    Oct 23, 2014 at 20:44
7

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")
6
  • The want us to provide more info than just a link - e.g., a summary description of what is at that link.
    – Drew
    Oct 23, 2014 at 20:37
  • You're right, I edited my answer. Oct 23, 2014 at 20:40
  • Hm. As a courtesy, at least, you should probably say that the code you swiped verbatim was written by targzeta. Summarizing a cross-referenced page does not mean plagiarizing its content. (Of course, if you are targzeta, then there is presumably no problem.)
    – Drew
    Oct 23, 2014 at 20:47
  • You're right again, edited. Thanks. Oct 23, 2014 at 20:49
  • Thanks. (I know it takes a little time to do it right, but it helps everyone a little more.)
    – Drew
    Oct 23, 2014 at 20:52
5

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.

1
  • 1
    I 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
4

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).

2

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.

1

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)
1
  • You could be using a file local variable instead of a hook.
    – YoungFrog
    Mar 29, 2017 at 3:19
1

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.

1

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.

4
  • 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.)
    – Drew
    Nov 10, 2014 at 14:45
  • 1
    actually, 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 bin
    Nov 11, 2014 at 11:12
  • 1
    It 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], and www.emacswiki.org, and [email protected], and even debbugs.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.
    – Drew
    Nov 11, 2014 at 14:41
  • 1
    It's because of "survivorship bias". Many people give up before they know emacswiki or mailing list.
    – chen bin
    Jun 28, 2016 at 0:21
0

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.