General customization

ido-mode

Other editors and IDEs have nice tree views of directories and files, as well as tabs for switching between buffers. Emacs does have a rather ugly tree view—M-x speedbar if you want to see how ugly—but the real Emacs answer to navigating large projects is ido-mode.

init.el

(ido-mode 1)  
-U:--- init.el All L17 (Emacs-Lisp)----------------------------------------

Find file: .../readline/ex{examples/ | histexpand.c | text.c}

ido-mode remaps the keybindings for find-file and switch-to-buffer to more powerful versions of the same. You’ll only need to type a few letters of the file or buffer name (not necessarily matching the beginning of the name, and not necessarily adjacent letters). A list of matches, in most-recently-used order, is displayed in the minibuffer; <right> and <left> (or C-s and C-r) navigate amongst the matches. If nothing matches, after a brief (and configurable) pause ido can search previously-used directories.

Because RET opens the first matching file, to open a directory you’ll have to use C-d. Or you could use C-f (at the ido-find-file prompt) to drop into normal find-file.

ido ships with Emacs but isn’t present at all in the manual; read the online help for the ido-find-file command. For more details and configuration instructions, use C-h f ido-mode to find its elisp implementation, and read the long comment at the top of the elisp file.

Emacs users tend to leave buffers open when they have finished with them, and after a while have hundreds of buffers open so ido-switch-buffer effectively becomes “find file in project”.

To save your list of open files between invocations of Emacs, or to manage separate sets of open files (if you’re working on several projects in parallel), see “Saving Emacs Sessions” in the Emacs manual.

Minimalism

To make the most of your screen space, consider disabling the toolbar and scrollbars:

init.el

(tool-bar-mode -1) (scroll-bar-mode -1)

Similarly, you can disable the menu bar with (menu-bar-mode -1), though I find the menu bar useful for discovering Emacs features; major and minor modes often add their own menu to the menu bar. As previously noted, you certainly shouldn’t disable the menu bar on OS X; if you’d like to share your Emacs init file among several environments you could conditionally disable menu-bar-mode based on the value of variables system-type and window-system.

Some commands like revert-buffer force you to confirm by typing yes; it would be nice to just type y. If you look at the definition of revert-buffer you’ll find it calls yes-or-no-p, which we can redefine to call y-or-n-p instead:

(defun yes-or-no-p (prompt) (y-or-n-p prompt))

Or more simply:

(defalias 'yes-or-no-p 'y-or-n-p)

Another thing everyone does the second they install Emacs is to prevent the creation of a “~”-suffixed backup file on every save:

(setq make-backup-files nil)

Rely on your version control system for backups instead.

Navigating Emacs Lisp

In the last couple of chapters I have encouraged you to discover Emacs functionality by studying the elisp code directly. To make the job easier we already saw show-paren-mode and eldoc-mode; let’s enable them globally because they’re useful in other programming languages too.

(show-paren-mode 1) (eldoc-mode 1)

We’ll also re-bind M-. from its default find-tag to find-function-at-point, but only for elisp files, for which you don’t need a tags table because Emacs already knows all about every elisp function it has loaded.

(define-key emacs-lisp-mode-map (kbd "M-.") 'find-function-at-point)

If you plan on writing a lot of Lisp, paredit-mode is great for always keeping your parentheses balanced, and for moving whole forms around when refactoring—but it does take some getting used to.

shell

If you ever tried to run a program like git under M-x shell, you will have come across the warning “terminal is not fully functional” followed by unusable behavior. This is because git sends its output through a pager (probably less), which requires a real terminal emulator.

Setting the PAGER environment variable to /bin/cat (but only inside Emacs) solves this problem:

init.el

(setenv "PAGER" "/bin/cat")

This also allows you to use git grep from M-x grep.

Make sure you don’t override PAGER in your ~/.gitconfig file or the GIT_PAGER environment variable (and MANPAGER for the man program, etc).

If you need to make customizations in your ~/.bashrc file (or the corresponding file for your shell of choice) you can test for the environment variable INSIDE_EMACS. To configure which shell Emacs uses, see the manual.

Other ideas

Other customizations you might like to make are covered by the Emacs manual:

For further inspiration you might want to look at other people’s init files, widely available on the Emacs wiki and on the internet at large. Some of the customizations I have presented here came from the Emacs Starter Kit, a collection of elisp files to provide “a more pleasant set of defaults than you get normally with Emacs”.