Configuring Emacs through Emacs Lisp

15 Apr 2010

I’ve been an Emacs fanboy for close to 15 years. For a long time I used Emacs solely on Linux because of it’s ubiquity. But written in C and Emacs Lisp, Emacs has great cross-platform support, and now I use it daily on Windows too. Installing Emacs on Windows is as straightforward as downloading and extracting the most recent Zip file.

Code equals data

Configuring the editor is done by placing Emacs Lisp code in the .emacs file. Whenever Emacs starts, it looks for this file in the directory specified by the HOME environment variable and executes its content. Unlike the XML configuration files of .NET and Java, with Emacs there’s no intermediate configuration format. There’s no extra language to learn and no limitation in the expressiveness of the configuration language. With this interchangeability of code and data, every behavior of Emacs can be hooked into and tailored and every global variable redefined.

Starting Emacs from the Windows taskbar

On my machine, I like everything Emacs-related to reside in the directory that I extracted Emacs to, yet I want to be able to start Emacs from the taskbar. I do this by pinning cmd.exe to the taskbar and modifying its destination so it defines HOME for this instance before spawning Emacs. This way the HOME of Emacs doesn’t conflict with the HOME of other applications.

cmd.exe /C "set HOME=...\emacs-23.1&&...\emacs-23.1\bin\runemacs.exe"

My .emacs isn’t too esoteric. Nevertheless, here it is for posterity. Reading on, keep in mind that unless otherwise noted, all referenced packages come with Emacs 23.1.

General settings

I start off redefining a couple of global variables. Much functionality relies on the user name and mail address to be known in advance. I then remove the toolbar at the top of the Emacs window, because I use menus or keyboard shortcuts anyway. Next I disable the splash screen on startup, and redefine a few global variables governing Emacs’ scrolling behavior. By default scrolling isn’t line by line, but chuck by chuck of text. I find this behavior confusing.

(setq user-full-name "Ronnie Holm")
(setq user-mail-address "foo@bar.baz")

(tool-bar-mode nil)                            ;; don't show the toolbar

(setq inhibit-startup-message t                ;; don't show ...
      inhibit-startup-echo-area-message t)     ;; ... startup messages

(setq scroll-margin 1                          ;; do smooth scrolling
      scroll-conservatively 100000
      scroll-up-aggressively 0.01
      scroll-down-aggressively 0.01)

Next I turn on automatic syntax highlighting and commands specific to known file types. Following that I turn the blinking square cursor into a solid and less distracting one. Also, I instruct Emacs not to retain backups of files that I edit or save. I don’t discount the value of backups, but I also don’t like having to remove backup and auto-save files when they clutter my folders. Instead  Emacs should move these files to the Windows Recycle Bin. Lastly, I enable iswitchb-mode, which makes switching buffers easier by providing on-the-fly suggestions.

(global-font-lock-mode t)                      ;; always do syntax highlighting
(blink-cursor-mode 0)                          ;; don't blink cursor
(setq backup-inhibited t)                      ;; no backup files
(setq delete-by-moving-to-trash t)             ;; delete moves to recycle bin
(iswitchb-mode t)                              ;; easy buffer switching

The last of the general settings involve modifications to the modeline at the bottom of the Emacs window. By default it displays the buffer name, the line number, and the modes Emacs is in. I extend the modeline with the column cursor position and the size of the current buffer.

(column-number-mode t)                         ;; show column numbers
(size-indication-mode t)                       ;; show file size

Package settings

Oftentimes I find myself editing the same set of files every day. So having the cursor move to where I left it editing the file the last time is handy. This is done by save-place mode. Behind the scenes it stores a file name/offset mapping in a file below HOME.

(setq save-place-file "~/.emacs.d/saveplace")  ;; location of saveplace file
(setq-default save-place t)                    ;; activate for all buffer
(require 'saveplace)

As hinted by Getting organized with Emacs Org-mode, I very much enjoy using Org-mode for keeping notes, maintaining lists, and much more. The next section of my .emacs is therefore dedicated to customizing org-mode. Firstly, to make documents easier to read, instead of displaying all the asterisks that designate an indentation level, only display the last one. Secondly, align each indentation level by always adding two asterisks on indentation. Thirdly, when clocking time, have Emacs remember what I was doing and for how long across restarts. But remove clocked time less than one minute.

(setq org-hide-leading-stars t)                ;; hide but one star in outline
(setq org-add-levels-only t)                   ;; align items nicely
(setq org-clock-persist t)                     ;; keep track of time ...
(org-clock-persistence-insinuate)              ;; ... across sessions
(setq org-clock-out-remove-zero-time-clocks t) ;; remove 0-duration clocked

The default Emacs color theme looks kind of dull. So I downloaded the color-theme package and selected a more aesthetically pleasing theme. After downloading color-theme, place its Lisp files in ~/site-lisp. That’s one of the places where Emacs will automatically look for packages. The 300 or so packages that come with Emacs are in the ~/lisp folder.

(require 'color-theme)                         ;; use a color theme
(color-theme-initialize)
(color-theme-arjen)

My last additions to .emacs involve Haskell. Emacs doesn’t support Haskell out-of-the-box. But a haskell-mode is available for download. It turns Emacs into a decent Haskell development environment. Besides syntax highlighting and code formatting capabilities, it adds to Emacs commands for interacting with the Haskell compiler and Haskell interactive.

(load "~/site-lisp/haskell-mode-2.6.4/haskell-site-file")
(add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
(add-hook 'haskell-mode-hook 'turn-on-haskell-indentation)

This concludes my .emacs. Quite a few of these settings I picked up reading the emacs-fu blog.