Dennis Lambe Jr.'s Projects

Smart-Dash Mode

Smart-Dash mode is an Emacs minor mode which redefines the dash key to insert an underscore within C-style identifiers and a dash otherwise.

It is the product of a mind that writes C every day and wishes it was writing lisp instead. My goal was to let you to type the underscore_separated_identifiers that are common in C or Python or PHP as comfortably as you would type lisp-style-identifiers.


Smart-Dash mode is maintained under Mercurial on Get it by running

      hg clone

or by downloading a tarball of the latest revision.


Add the folder where you've unpacked smart-dash to your Emacs load-path, then (require 'smart-dash)


Activate the Smart-Dash minor mode in a buffer with M-x smart-dash-mode or by adding smart-dash-mode to the load hook for your favorite programming language's major mode.

Now, just type your code like you normally would, but stop pressing the shift key when you need an underscore inside an identifier.

If you need to type a literal dash right after an identifier (say, to type a cramped arithmetic expression like x-3), use the emacs quoted-insert character C-q to inhibit Smart-Dash behavior for one character, or use the minus key on the number pad.


You can customize the behavior of Smart-Dash mode by typing M-x customize-group RET smart-dash RET

Will It Get in My Way?

The short answer is: not if you put spaces around your identifiers in arithmetic expressions, no.

In creating Smart-Dash mode I've tried to make sure that it doesn't get in your way. For example, Smart-Dash mode uses the syntax information provided by the current major mode to detect when you are in a string or comment and disable itself, and has special cases for common idioms in C-like modes (described below).

However, since its behavior is heuristic, it may not interact well with your particular coding style. If you are in the habit of putting spaces between your identifiers and your arithmetic operators as in "foo - 7" then you'll probably get along with Smart-Dash mode just fine. If, however, you frequently write close expressions like "x-3", Smart-Dash mode might not be the right fit for you.

Extensions for C-Like Modes

C has two situations where even those of us who always carefully space out our arithmetic still want to put a dash right after an identifier. They are the -> struct access operator and the postfix -- post-decrement operator. If Smart-Dash mode detects that it has been activated in a C-like mode that uses these operators (C, C++, and Objective C by default, customizable with `smart-dash-c-modes') it installs two workarounds.

The first is that if you type > after an underscore, the underscore will be replaced with a dash. The typical sequence of operations, then, looks like this:


"The movie goes on, and nobody in the audience has any idea."

The second is a little more complicated, but I've found that it works in all syntactically-valid scenarios. If you type a dash and the previous character is an underscore, both characters are replaced by dashes. That sequence looks like this:


This requires that if you want a double-underscore in your identifier in a C-like mode, you will have to type it yourself. As for the rare case where you want to type __foo__--, Smart-Dash mode attempts to detect and handle it. It looks like this:


Isearch Support

When Smart-Dash mode is active on a buffer, the isearch-mode-map is modified in that buffer so that the isearch also has smart-dash behavior.

Minibuffer Support

Smart-Dash mode can be addictive, and the first thing beta testers noticed was that it wasn't turned on in minibuffers, so you had to flip a switch in your brain when you ran, for example, query-replace-regexp or find-tag.

Turning on Smart-Dash mode in all minibuffers started from a Smart-Dash-enabled buffer seems like a good idea until you actually try it. At that point you realize that it's a nuisance as often as a help; for example, in execute-extended-command and eval-expression minibuffers where you're typing lisp identifiers and expecting dashes to stay dashes.

By default, Smart-Dash mode will be turned on in minibuffers for commands listed in `smart-dash-minibuffer-allow-commands'. If you'd rather have it always turned on except in certain situations, set `smart-dash-minibuffer-by-default' to a non-nil value and use `smart-dash-minibuffer-deny-commands' to inhibit it.

This is an area of active research. Right now the allow and deny lists contain only a few commands. I'm very interested in what other commands users are putting in those two lists, and which value for smart-dash-minibuffer-by-default people prefer. Consider this an invitation to send me your own configuration.

Valid XHTML 1.1!

©2010 Dennis Lambe Jr. All rights reserved.