Emacs

Prompt Before Closing Emacs

I developed a bad habit of quitting Emacs from my earlier days of using Emacs mostly in a terminal session (where even there quitting it is not the best idea). Now that I use GUI versions of Emacs, I sometimes find myself hitting C-x C-c and wishing I didn't because I really intended to kill the current buffer, not completely close Emacs. So what I have done to deal with this is, when running a GUI version (which can be detected by checking the window-system variable), I always prompt to ask if I really want to quit. Here is the code I use:

(defun ask-before-closing ()
  "Ask whether or not to close, and then close if y was pressed"
  (interactive)
  (if (y-or-n-p (format "Are you sure you want to exit Emacs? "))
      (if (< emacs-major-version 22)
          (save-buffers-kill-terminal)
        (save-buffers-kill-emacs))
    (message "Canceled exit")))
 
(when window-system 
  (global-set-key (kbd "C-x C-c") 'ask-before-closing))

I do this only for the GUI version, but you could remove the check for window-system if you want it to work in the terminal version as well. I use when instead of if in this case, because I do other things if I am running the GUI version, like (server-start), which I have excluded from this code sample.

Get Emacs-style keyboard shortcuts in Cocoa text widgets

Mac OS X already has defined some basic Emacs-style keyboard shortcuts (CTRL-N/P/B/F/K/Y/T/etc) which are available in Cocoa text widgets. But Cocoa is highly configurable, and allows for configuring a larger subset of Emacs-style keybindings (among many other possibilities).

These two references written by Jacob Rus are very useful for understanding what you can do with the Cocoa text system:

Customizing the Cocoa Text System
Customize the Cocoa text binding system

If you want to see my Emacs-style keybindings you can get it here. I did not enable incremental search yet as I couldn't get the input manager for it working yet.

Now this only gives you these keybindings when you're editing text in a Cocoa application. Non-Cocoa applications will not be affected. Firefox is not affected even though it uses Cocoa. It does appear to affect Java Swing apps, though, such as IntelliJ IDEA and Oracle SQL Developer, which both have Emacs keybindings that don't work properly until you make these changes (combinations such as Option-v output a special character otherwise, rather than performing M-v).

In a future entry I will talk about how to use Butler and Firemacs to give Firefox more Emacs-style text editing and keyboard shortcuts. Butler's ability to simulate keystrokes (and trigger on keyboard combinations) is pretty powerful.

Emacs on Mac OS X

There are a couple of different options for Emacs on OS X. OS X comes with the text-mode version of Emacs (22.1.1 in Leopard). If you use the text-mode version frequently through Terminal.app, be sure to enable Terminal.app's "Use option as meta key." However, if you spend a lot of time in Emacs you'll probably want to use one of the GUI versions. There are a couple of options:

Aquamacs - An "Aqua-native" fork of Emacs that makes it work more like a Mac application. For example, it supports many of the typical Mac keyboard shortcuts and has tabs. From my brief usage of this, it looked very nice, but since I also use Linux and Windows (as well as text-mode Emacs on the Mac), I want my Emacs experience to be fairly consistent across all platforms.

Carbon Emacs - A Carbon port of Emacs (currently version 22). This is what I would have used if I couldn't get the Cocoa build to work.

GTK Emacs - This is available from Fink (currently version 22), but like all GTK apps built through Fink, uses X11. Using X11 apps on OS X is rather inconvenient, so I didn't bother trying this.

Emacs.app - A Cocoa port of Emacs. This code has been recently integrated into GNU Emacs for the upcoming version 23, but you have to build from the CVS source for that, which is what I chose to do.

The page for Emacs.app contains instructions for how to build from GNU Emacs CVS, but I'll describe the process here:

Syndicate content