I've been writing a lot of GraphQL resolvers in ruby at work recently, and frequently run into a situation where I have to align many columns of text by hand. I figured this isn't a very unique problem, and that there was probably already some code within Emacs to handle it.
As it turns out I was correct in my assumption. There's an excellent
built-in package called align
that takes care of just that.
Many of the features of the align
package are mode-specific, but I
just wanted a function that can align columns regardless of which mode
they're used in. There's a function that's part of the package that
can be used for just that fortunately, align-regexp
, which takes a
regular expression as input and uses it to guide the alignment.
I was able to use it to make a generic function.
(defun align-non-space (BEG END)
"Align non-space columns in region BEG END."
(interactive "r")
(align-regexp BEG END "\\(\\s-*\\)\\S-+" 1 1 t))
Let's walk through what's going on here.
BEG
andEND
are the beginning and end positions of the area to be aligned-
(interactive "r")
tells Emacs that the function is interactive, meaning that it can be called from theM-x
menu"r"
tells Emacs that when the function is called interactively, it expects a region (beginning and end points) as arguments
-
align-regexp
where the work is happening. This function has the following signature.(align-regexp BEG END REGEXP &optional GROUP SPACING REPEAT)
BEG
andEND
is the region that it expects as the first arguments-
"\\(\\s-*\\)\\S-+"
is an Emacs regular expression. Backslashes are doubled because they need to be escaped in a string literal-
\( \)
is a capture group-
\s-
is a regular expression construct specific to Emacs which specifies a type of syntax which is to be matched.-
refers to the whitespace characters
*
means match zero or more
-
\S-
is similar to the previous construct, but instead means to match anything other than whitespace+
means one or more
-
1
here refers to the group within the regex that will be modified to align the fields1
is the number of spaces between fields once alignedt
indicates to repeat the rule multiple times on the same line
To use this function, simply highlight a region you want to align and
run M-x align-non-space
.