Theresa O’Connor

Running Gnus in a dedicated Emacs

Gnus is an awesome mail and news reader, but it can be a bit of a performance bear, especially when using IMAP. Since Emacs is single-threaded, IMAP operations that take too long can disconnect you from IRC, Jabber, or any number of other network services you also use from Emacs.

The typical solution to this problem is to run Gnus in a dedicated Emacs instance. Doing so is really easy—just make a gnus shell alias like so:

alias gnus 'emacs -f gnus'

The catch is, such an Emacs doesn't know it's a dedicated, Gnus-only Emacs. When I used this technique, it was always confusing that quitting Gnus didn't quit its Emacs.

We can use command-switch-alist to define a custom -gnus command line argument that does what we want. Here's what I have in my .emacs file:

(add-to-list
 'command-switch-alist
 '("gnus" . (lambda (&rest ignore)
              ;; Start Gnus when Emacs starts
              (add-hook 'emacs-startup-hook 'gnus t)
              ;; Exit Emacs after quitting Gnus
              (add-hook 'gnus-after-exiting-gnus-hook
                        'save-buffers-kill-emacs))))

To use the above, we just alter our shell alias to use our new argument:

alias gnus 'emacs -gnus'

The only other thing to keep in mind is how this sort of setup interacts with emacsclient. (This is a command that lets you edit files in an already-running Emacs.) I really only want emacsclient to open files in the other Emacs I have running, and not in my Gnus-only Emacs. Let's fix this by restricting when we start the server that emacsclient talks to.

(defvar ted-server-emacs t
  "If non-null, this emacs should run emacsclient.")

Now that we have a flag we can use, let's only call server-start when the flag's been raised:

(add-hook 'emacs-startup-hook
          (lambda ()
            (when ted-server-emacs
              (server-start))))

The only bit left to do is to (setq ted-server-emacs nil) inside the custom command line argument handler above.