25.5 Code Alignment

Alignment is the process of adjusting whitespace in a sequence of lines in the region such that in all lines certain parts begin at the same column. This is usually something you do to enhance readability of a piece of text or code. The classic example is aligning a series of assignments in C-like programming languages:

int a = 1;
short foo = 2;
double blah = 4;

is commonly aligned to:

int    a    = 1;
short  foo  = 2;
double blah = 4;

You can use the command M-x align to align lines in the current region. This command knows about common alignment patterns across many markup and programming languages. It encodes these patterns as a set of alignment rules, that say how to align different kinds of text in different contexts.

The user option align-rules-list says which alignment rules M-x align should consult. The value of this option is a list with elements describing alignment rules. Each element is a cons cell (title . attributes), where title is the name of the alignment rule as a symbol, and attributes is a list of rule attributes that define when the rule should apply and how it partitions and aligns lines. Each rule attribute is a cons cell (attribute . value), where attribute is the name of attribute and value is its value. The only required attribute is regexp, whose value is a regular expression with sub-expressions matching the parts of each line where M-x align should expand or contract whitespace (see Backslash in Regular Expressions). See the documentation string of align-rules-list (C-h v align-rules-list RET) for a full description of possible alignment rule attributes. By default, this option is set to a long list of alignment rules for many languages that Emacs supports. The default rules use the modes rule attribute to specify major modes in which M-x align should apply them. Major modes can also override align-rules-list by setting the buffer-local variable align-mode-rules-list to a non-nil list of alignment rules. When align-mode-rules-list is non-nil, M-x align consults it instead of align-rules-list.

Besides alignment rules, M-x align uses another kind of rules called exclusion rules. The exclusion rules say which parts in the region M-x align should not align and instead leave them intact. The user option align-exclude-rules-list specifies these exclusion rules. Similarly to align-rules-list, the value of align-exclude-rules-list is also a list of cons cells that describe the exclusion rules. By default, align-exclude-rules-list includes rules that exclude alignment in quoted strings and comments in Lisp, C and other languages. Beyond the default exclusion rules in align-exclude-rules-list, major modes can define bespoke exclusion rules by setting align-mode-exclude-rules-list to a non-nil list of rules, this overrides align-exclude-rules-list just like align-mode-rules-list overrides align-rules-list.

M-x align splits the region into a series of sections, usually sequences of non-blank lines, and aligns each section according to all matching alignment rule by expanding or contracting stretches of whitespace. M-x align consistently aligns all lines inside a single section, but it may align different sections in the region differently. The user option align-region-separate specifies how M-x align separates the region to sections. This option can be one of the symbols entire, group, or a regular expression. If align-region-separate is entire, Emacs aligns the entire region as a single section. If this option is group, Emacs aligns each group of consecutive non-blank lines in the region as a separate section. If align-region-separate is a regular expression, M-x align scans the region for matches to that regular expression and treats them as section separators. By default align-region-separate is set to a regular expression that matches blank lines and lines that contains only whitespace and a single curly brace (‘{’ or ‘}’). For special cases where regular expressions are not accurate enough, you can also set align-region-separate to a function that says how to separate the region to alignment sections. See the documentation string of align-region-separate for more details. Specific alignment rules can override the value of align-region-separate and define their own section separator by specifying the separate rule attribute.

If you call M-x align with a prefix argument (C-u), it enables more alignment rules that are often useful but may sometimes be too intrusive. For example, in a Lisp buffer with the following form:

(set-face-attribute 'mode-line-inactive nil
                    :box nil
                    :background nil
                    :underline "black")

Typing (C-u M-x align) yields:

(set-face-attribute 'mode-line-inactive nil
                    :box                nil
                    :background         nil
                    :underline          "black")

In most cases, you should try M-x align without a prefix argument first, and if that doesn’t produce the right result you can undo with C-/ and try again with C-u M-x align.

You can use the command M-x align-highlight-rule to visualize the effect of a specific alignment or exclusion rule in the current region. This command prompts you for the title of a rule and highlights the parts on the region that this rule affects. For alignment rules, this command highlights the whitespace that M-x align would expand or contract, and for exclusion this command highlights the parts that M-x align would exclude from alignment. To remove the highlighting that this command creates, type M-x align-unhighlight-rule.

The command M-x align-current is similar to M-x align, except that it operates only on the alignment section that contains point regardless of the current region. This command determines the boundaries of the current section according to the section separators that align-region-separate define. M-x align-entire is another variant of M-x align, that disregards align-region-separate and aligns the entire region as a single alignment section with consistent alignment. If you set align-region-separate to entire, M-x align behaves like M-x align-entire by default. To illustrate the effect of aligning the entire region as a single alignment section, consider the following code:

one = 1;
foobarbaz = 2;

spam = 3;
emacs = 4;

when the region covers all of these lines, typing M-x align yields:

one       = 1;
foobarbaz = 2;

spam  = 3;
emacs = 4;

On the other hand, M-x align-entire aligns all of the lines as a single section, so the ‘=’ appears at the same column in all lines:

one       = 1;
foobarbaz = 2;

spam      = 3;
emacs     = 4;

The command M-x align-regexp lets you align the current region with an alignment rule that you define ad-hoc, instead of using the predefined rules in align-rules-list. M-x align-regexp prompts you for a regular expression and uses that expression as the regexp attribute for an ad-hoc alignment rule that this command uses to align the current region. By default, this command adjusts the whitespace that matches the first sub-expression of the regular expression you specify. If you call M-x align-regexp with a prefix argument, it also prompts you for the sub-expression to use and lets you specify the amount of whitespace to use as padding, as well as whether to apply the rule repeatedly to all matches of the regular expression in each line. See Backslash in Regular Expressions, for more information about regular expressions and their sub-expressions.

If the user option align-indent-before-aligning is non-nil, Emacs indents the region before aligning it with M-x align. See Indentation. By default align-indent-before-aligning is set to nil.

The user option align-to-tab-stop says whether aligned parts should start at a tab stop (see Tab Stops). If this option is nil, M-x align uses just enough whitespace for alignment, disregarding tab stops. If this is a non-nil symbol, M-x align checks the value of that symbol, and if this value is non-nil, M-x align aligns to tab stops. By default, this option is set to indent-tabs-mode, so alignment respects tab stops in buffers that use tabs for indentation. See Tabs vs. Spaces.

The user option align-default-spacing specifies the default amount of whitespace that M-x align and its related commands use for padding between the different parts of each line when aligning it. When align-to-tab-stop is nil, the value of align-default-spacing is the number of spaces to use for padding; when align-to-tab-stop is non-nil, the value of align-default-spacing is instead the number of tab stops to use. Each alignment rule can override the default that align-default-spacing specifies with the spacing attribute rule.