Emacs has a few commands that can line up text with respect to whitespace, assignment, columns or regexp specified delimiters.
For version 22 or higher, the following commands are available:
align align-current align-entire align-newline-and-indent align-regexp
Alignment is done with respect to a set of rules (e.g. line up the = signs). Which rules exactly depend on the current mode, and should provide some sort of “Do What I Mean” feeling. These rules are described in the variable align-rules-list, a few of them are explained below. Documentation is scarce at the moment and inspection of the list given by this variable is perhaps the best way to find which one is available in which mode.
Some custom settings are available through the use of the customize buffer. Just type M-x customize-group RET align RET.
Sidenote: The default text-mode rules in ‘align-rules-list’ are “too aggressive” to be enabled by default, therefore you need to specify the universal arg (C-u) to enable them. See below.
In text mode, C-u M-x align lines up text in selected region, using whitespaces (or tabs) as the column delimiter:
lastname firstname lastname firstname Smith John 33-88 Smith John 33-88 Gere Alan 24-23 => Gere Alan 24-23 Verne Bill 12-34 Verne Bill 12-34
Note that C-u M-x align fails to align words of length one (bug ? feature ?). See below for a fix. Figures can also be lined up with respect to the decimal point, using M-- M-x align.
green apples 10.00 green apples 10.00 carrots 16.5 => carrots 16.5 patatoes 12. patatoes 12.
Instead of working on a region, M-x align-current operates on the current section. Here is an example, taken from the blog of the Lazy Programmer, which shows how the align-current command works in perl-mode:
my %h = my %h =
( (
key1 => value1, key1 => value1,
key11 => value11, gives key11 => value11,
key111 => value111, key111 => value111,
); ); Here is another example in c-mode:
LongTypeName a; LongTypeName a; int b; gives int b; float c; float c;
This command aligns the current region using a column delimiter given by a regular expression. For example, assume we want to align firstnames in a list of the form:
LASTNAME Firstname SMITH John BOLL� �milien MOHAMED SALEM El Balem
There are two difficulties here: case and accented letters. First ensure that the case is taken into account. For this, just type:
M-: (setq case-fold-search nil) RET
Then, select the region and use the align-regexp command:
M-x align-regexp RET [[:upper:]][[:lower:]] RET
The regular expression given above matches the beginning of the firstname, which is of the form, a upper-case letter followed by a lower-case letter. This syntax is sufficiently general to deal with accented letters. The result is as follow:
LASTNAME Firstname SMITH John BOLL� �milien MOHAMED SALEM El Balem
For example, let us align numbers as follows:
4000 1 2 4000 1 2 11 1 44 => 11 1 44 1 0000 999 1 0000 999
M-x align-regexp with [[:space:]] only align with respect to the first match of the regular expression. C-u M-x align fails to align strings of length one (bug ? feature ?).
The align-regexp command, however, allows a few options. These are activated by giving a prefix to the command: C-u M-x align-regexp. The user is then prompted with a few choices:
\(\s-*\), which stands for “an arbitrary number of spacing characters”.n/y, depending whether the alignment must be done once or repeated.So, in short, lining up numbers as given above amounts to typing:
C-u M-x align-regexp RET SPC RET RET RET y
Don’t forget to mark the region first.
Arguably, for daily use, it’s better to define some adhoc align command, e.g.
(defun align-repeat (start end regexp) "Repeat alignment with respect to the given regular expression." (interactive "r\nsAlign regexp: ") (align-regexp start end (concat "\\(\\s-*\\)" regexp) 1 1 t))
The final t (aka true) is responsible for repeating the task. Call that command with the regular expression [[:space:]]+
An alternate way is to modify the align-rules-list variable. Here is a quick hack: eval the following code, just by entering it in the scratch buffer and typing C-x C-e at the end.
(add-to-list 'align-rules-list
'(text-column-whitespace
(regexp . "\\(^\\|\\S-\\)\\([ \t]+\\)")
(group . 2)
(modes . align-text-modes)
(repeat . t)))This defines a new alignment rule, valid both in text-mode and outline mode, lining up sequences of whitespaces, repeatedly. You must have used M-x align at least once before, in order to activate the align-rules-list variable. In text mode or in outline-mode, M-x align and M-x align-current now put text strings in columns, using whitespace as delimiter.
This alignment rule may be loaded at startup by adding the above code to the align-load-hook:
(add-hook 'align-load-hook (lambda () (add-to-list 'align-rules-list '(text-column-whitespace (regexp . "\\(^\\|\\S-\\)\\([ \t]+\\)") (group . 2) (modes . align-text-modes) (repeat . t)))))
Align currently has (partial) built-in support for:
New languages can be supported by adding approriate rules to align-rules-list, align-exclude-rules-list and perhaps a custom align-region-separate, see the link(s) below:
See SmartTabs.