Aligning text

Emacs has a flexible tool, align-regexp, for aligning text but it is surprisingly fiddly to use. For example to align a section of text like this:

the quick brown fox
jumped over the lazy
dogs the quick brown

into columns like this:

the     quick  brown  fox
jumped  over   the    lazy
dogs    the    quick  brown

you would highlight the text and use C-u M-x align-regexp \(\s-*\)\s- RET 1 RET 0 RET y. See what I mean!

The function is of course documented (use C-h f align-regexp to read it), but I found it a bit hard to follow. The \(\s-*\)\s- string is the regular expression that is used to align on, and the final \s- in that string tells emacs to align on a whitespace character. You could replace that with e.g. & to align on & characters. The other three options (i) control how the columns are justified (generally can leave this as 1); (ii) add spaces between columns; and (iii) repeat the alignment throughout the line.

To make life easier, I wrote a couple of simple wrappers around align-regexp for common tasks. The first aligns on whitespace, and the second aligns on & (useful for LaTeX tables).

(defun bjm/align-whitespace (start end)
  "Align columns by whitespace"
  (interactive "r")
  (align-regexp start end
                "\\(\\s-*\\)\\s-" 1 0 t))

(defun bjm/align-& (start end)
  "Align columns by ampersand"
  (interactive "r")
  (align-regexp start end
                "\\(\\s-*\\)&" 1 1 t))
  • offby1

    I find those regexes more readable when they’re written like this:

    (rx (group (zero-or-more (syntax whitespace))) (syntax whitespace))
    (rx (group (zero-or-more (syntax whitespace))) “&”)

    Also, \& seems to not be a proper regex.

    • Thanks – I’ve fixed the syntax in my regex. Also rx looks interesting I’ll have to look more at that!

  • The irony of emacs is that, for all it’s a text editing powerhouse, the fact that the lisp interpreter sees everything first makes any embedded DSL, e.g. regexes, a study in suffering.

    When I’m an 800 emacs dev gorilla, I’d like to crib python’s triple quote approach to embedding arbitrary stringage, e.g.: “””(s-*)s-“””

  • Alfredo Buttari

    In latex-mode I just position the cursor on the table I want to align, type M-x align-current and it just does the trick.

  • Pingback: 2016-01-18 Emacs News - sacha chua :: living an awesome life()