In The Armchair

Automatically Inserting Matching Parentheses for LaTeX in Emacs

Posted in Computers by Armchair Guy on November 1, 2008

My use of emacs varies, but a good chunk of my time is spent writing in LaTeX for mathematical formulae. AuCTeX simplifies my life quite a bit, and whizzytex makes it awesome. But one feature that would really save me some typing is auto-completion of matching parenthetical symbols. In LaTeX, such matching delimiter pairs are $$, [], {}, \{\}, \left\{\right\}, \left(\right), etc. I found a major mode called Ultratex that does exactly this (and much more), but unfortunately it replaces AuCTeX rather than augment it, and isn’t maintained any more.

Here’s some trivial emacs lisp code for a minor mode that accomplishes this. You can easily modify it yourself to add or remove simple matching completions. You can put it directly in your .emacs file, or in a file called dlmins.el, and add the line

(load "/path/to/dlmins.el" t t)

to load it. If you want this to be activated every time LaTeX is fired up, put the following line in your .emacs file:

(add-hook 'LaTeX-mode-hook 'dlmins-mode)

To toggle the mode manually, use command M-x dlmins-mode. Here’s the code for the minor mode.

;;; dlmins.el -- Trivial minor mode to insert matching LaTeX
;;; delimiters automatically.
;; Copyright (c) 2008 Rajeev Ayyagari

;; Author:   Rajeev Ayyagari
;; Keywords: Parenthesis matching
;; Version:  0.01 of Sat Nov  1 11:22:44 EDT 2008

;; This file is not part of GNU Emacs.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Minor mode: dlmins-mode
;;
;; Entering a left-parenthetical symbol causes the corresponding
;; right-parenthetical symbol to be inserted automatically, and point
;; is positioned appropriately.
;;
;; To use, place this code in a file called dlmins.el and add the line
;;
;; (load "/path/to/dlmins.el" t t)
;;
;; to your .emacs.  To make the mode start automatically when a latex
;; document is opened, add the line
;;
;; (add-hook 'LaTeX-mode-hook 'dlmins-mode)
;;
;; to your .emacs after the above "load" line. Manually toggle (enable
;; or disable) the mode using M-x dlmins-mode.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Set up keymaps and list of delimiter pairs.
(defun dlmins-setup ()
 "Initialize delimiter auto-insertion."
 (interactive)
 ;; Order matters in the list below!
 ;; The rule is if STR2 is a suffix of STR1, then STR2 should come
 ;; after STR1.
 (setq dlmins-dlm-list
'(
  ("\\left\\{" "\\right\\}")
  ("\\{"       "\\}")
  ("\\frac{"   "}{}")
  ("{"         "}")
  ("\\left("   "\\right)")
  ("("         ")")
  ("\\left\\|" "\\right\\|")
  ("\\|"       "\\|")
  ("|"         "|")
  ("\\left|"   "\\right|")
  ("\\left["   "\\right]")
  ("["         "]")
  ("$"         "$")
  ))
 (define-key (current-local-map) (kbd "{") (lambda () (interactive) (insert "{") (dlmins-pair)))
 (define-key (current-local-map) (kbd "[") (lambda () (interactive) (insert "[") (dlmins-pair)))
 (define-key (current-local-map) (kbd "(") (lambda () (interactive) (insert "(") (dlmins-pair)))
 (define-key (current-local-map) (kbd "$") (lambda () (interactive) (insert "$") (dlmins-pair)))
 (define-key (current-local-map) (kbd "|") (lambda () (interactive) (insert "|") (dlmins-pair))))
;; Called when left delim is typed, finds and inserts appropriate
;; right delim.
(defun dlmins-pair ()
 "This should be called as soon as an opening delimiter has been typed.
  When called, looks backward to see which delimiter has just been typed.
  It inserts the matching closing delimiter.
  Eventually it will be smart enough to take care of \left and \right as well."
 (interactive)
 (catch 'getout
   (mapcar
    (lambda (dlm)
      "If expression before point matches open dlm, insert close dlm."
      (if (looking-back (regexp-quote (car dlm)))
   (save-excursion
     (insert (car (cdr dlm)))
     (throw 'getout nil))))
    dlmins-dlm-list)))
;; Toggle the parenthesis matching mode
(define-minor-mode dlmins-mode
 "Minor mode LaTeX matching delimiter auto-insertion. use
 \"dlmins-mode\" to toggle."
 :init-value nil
 :lighter " DlmIns"
 :keymap '()
 (dlmins-setup)
 )

Advertisements

2 Responses

Subscribe to comments with RSS.

  1. fuco1 said, on December 27, 2012 at 1:34 am

    Hi. This can be achieved with package smartparens which provides a nice interface for adding/removing and manipulating pairs like these.

    It also provide features to navigate such expressions (such as jumping out of a pair or to the next pair etc.) and also many features from paredit package.

    Suggestions are welcomed 🙂

  2. Armchair Guy said, on December 27, 2012 at 4:10 am

    Hi Fuco1,

    Thanks for the tip. Smartparens sounds very useful — I’ll check it out.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: