2009-01-17

balancing your parentheses

One of the biggests problems in the world today are unbalanced parentheses - i.e., an opening '(' without a corresponding ')'. Especially the closing ones are often forgotten, and not even the invention of :-) smileys has restored the balance. Fortunately, as with most problems, emacs has a solution: show-paren-mode.

show-paren-mode will visually indicate corresponding parentheses, so you are much less likely to forget them. Note that 'parentheses' are not just '()', but also '[]', '{}'; and others (for example, in html-mode, '<>' are also considered to be parentheses). Also note that 'parentheses' is the plural of 'parenthesis'.

Even without show-paren-mode, emacs gives small visual cues by temporarily moving the cursor to the opening parenthesis when it is positioned just after the closing one. What show-paren-mode does is to improve upon that, and decide exactly how that happens. This is best explained using an example; to put in your .emacs:

(setq show-paren-delay 0)           ; how long to wait?
(show-paren-mode t)                 ; turn paren-mode on
(setq show-paren-style 'expression) ; alternatives are 'parenthesis' and 'mixed'
This will enable show-paren-mode globally. The show-paren-delay determines how long to wait before any visual cues; if you set it to, say, 1, you won't see anything when you're quickly scrolling, but only after you're 'standing still' for a second.

Then, show-paren-style:

  • if you set it to 'expression, the whole expression will be highlighted - when your cursor is just before the 'world', you'll get:
    (hello)world
  • if you set it to 'parenthesis, only the corresponding parenthesis will be highlighted:
    (hello)world
  • finally, if you set it to 'mixed, it will behave like 'parenthesis when the matching parenthesis is visible, and like 'expression otherwise.
Now, of course it does not stop here. You can determine exactly what color, boldness, underline and other properties are used, by setting the faces that show-paren-mode uses. For example, if we add:
(set-face-background 'show-paren-match-face "#aaaaaa")
(set-face-attribute 'show-paren-match-face nil 
        :weight 'bold :underline nil :overline nil :slant 'normal)
This will give the whole expression a grayish background (the "#aaaaaa"), and makes it bold. There is lots of room for experimentation here, obviously. Note that show-paren-mode can also detect mismatches, e.g. when try to close a '(' with a ']'. You can tune this with show-paren-mismatch-face, e.g.:
(set-face-foreground 'show-paren-mismatch-face "red") 
(set-face-attribute 'show-paren-mismatch-face nil 
                    :weight 'bold :underline t :overline nil :slant 'normal)

6 comments:

self said...

Ironically, you have an extra paren at the end of your (set-face-attribute 'show-paren-match-face ...) form.

Anonymous said...

look up paredit

Thomas F. said...

Especially when you do programming in C (where matching parentheses can easily be out of sight), I find the following function quite useful:

(defun paren-match ()
"Tries to jump to the matching parenthesis to the one currently
under the point. Useful if the matching paren is out of sight. "
(interactive)
(cond ((looking-at "[{\[\(]") (forward-sexp 1) (backward-char))
((looking-at "[]})]") (forward-char) (backward-sexp 1))
(t (message "Point not at a parenthesis."))))

I usually bind it to C-x C-p globally.

Anonymous said...

Thank you,

I was looking exactly what Thomas F. just put there.. very handy.

bernievoigt said...

There are default keybindings for jumping to opening and closing delimiters
C-M b (move backward)
C-M f (move forward)

See http://www.emacswiki.org/emacs/ParenthesisMatching#toc2 for details

edwingt said...

Thanks a lot I was looking for some think like this for a while.