Hello. My name is Amit Patel and I’m an Emacs user. I started using Emacs in 1990, switched to XEmacs in 1992, and switched back to GNU Emacs in 2007. I use Emacs on Linux, Mac, and occasionally Windows. I’m amitp on the #emacs irc channel.

You can find me at [1] or @redblobgames on twitter.

Welcome to the wiki. ☺ Never change a winning team, eh? – AlexSchroeder


Among classmates and coworkers I’m usually the one who tries out new packages and shares customization tweaks. I contribute small items to the Emacs Wiki, and I write blog posts about my emacs setup. However, I haven’t written any big packages that I’ve shared with the world.

One problem I have in and out of Emacs is keeping track of what window has focus. Long ago I wrote a simple XEmacs package to change the modeline color of the active window. I’m happy to see that GNU Emacs 22 has an active and inactive modeline color (‘mode-line-inactive’ face), although the active color is used even when Emacs doesn’t have OS-level focus. I also implemented something similar to highlight when the minibuffer is active, and it looks like GNU Emacs 22’s ‘minibuffer-prompt’ face can be used to achieve a similar effect.

Init file structure

I try to share the same Emacs setup across machines, but there are machine-specific settings that I keep in separate files. I then load those files with this:

;;; Try to load a package, but continue if it doesn't exist.
;;; TODO: switch to use-package
(defvar amitp--current-module "init")
(defmacro try-require (package &rest forms)
  "Execute FORMS only if (require PACKAGE) succeeds."
  (declare (indent 1))
  (let ((var (make-symbol "now")))
    `(when (condition-case e
               (let ((,var (current-time)))
                 (let ((amitp--current-module (format "%s/%s" amitp--current-module ,package)))
                   (require ,package))
                 (message "%s: loaded %s (%.3fs)"
                          (float-time (time-subtract (current-time) ,var))))
             (error (message "%s FAIL: package %s could not be loaded -- %s" amitp--current-module ,package e) nil))

;;; Make sure my load path includes my startup directory and other packages
(add-to-list 'load-path "~/.emacs.d/lisp")
(add-to-list 'load-path "~/.emacs.d/local")
(add-to-list 'load-path "~/.emacs.d/packages")
(let ((default-directory "~/.emacs.d/packages"))

(defun get-hostname-and-parents (hostname)
  "For a given hostname, return the list with that hostname and all suffixes, as symbols"
  (let ((suffix "")
        (results ()))
    (loop for component in (reverse (split-string hostname "\\.")) do
      (setq suffix (concat component (if (equal suffix "") "" ".") suffix))
      (setq results (cons (intern suffix) results)))

(try-require 'clean-directory)
(try-require 'settings)
(try-require 'keybindings)
(try-require 'decent-colors)

;; In addition to the modules that are always loaded, you can put
;; in user-specific customization into [username].el:
(try-require (intern (user-login-name)))

;; You can also put in machine-specific or domain-specific
;; customization.  For example, if you have both a
;; account and a account, you can create
;; (or and
;; (or or edu.el).
(loop for name in (get-hostname-and-parents
                   (or (getenv "HOSTNAME")
                       (getenv "COMPUTERNAME")
      do (try-require name))

;; And you can put in platform-specific customization (darwin, linux, w32)
(try-require (intern (subst-char-in-string
                       ?/ ?- (format "platform-%s" system-type))))

;; Window system (x, ns, mac, w32)
(try-require (intern (format "window-%s" (window-system))))

For example, I have Mac-specific settings in platform-darwin.el and my Stanford settings in stanford.el. Sometimes other people will copy my emacs setup but certain things are specific to me so I’ll put them in amitp.el so that they’re not automatically loaded by others. It’s not a clean use of module names but it’s simple and works reasonably well for me.

You can see that I like using the ‘loop’ macro.

My Emacs history

I started using GNU Emacs in 1990, then Epoch, then Lucid Emacs in 1992. I’m a visual person and find colors and fonts to be very useful; at the time, Emacs 18 didn’t have support for such things, so I switched. I stuck with Lucid/XEmacs 19, 20, 21. By the time XEmacs 21 came out, Emacs was starting to catch up, but it still didn’t have things like proportional fonts. XEmacs seemed more polished and more useful out of the box (for example, it came with python and ruby modes, as well as a package manager, and on GNU Emacs you had to download them an install them yourself, without a package manager). GNU Emacs seemed faster and more actively developed. By 2003 I was absolutely convinced that the two were diverging enough that I’d never be able to switch, nor would I want to. However, since then, XEmacs development has slowed to a crawl, here I switched to GNU Emacs on Mac, Windows, and Linux.