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.
ENDare 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 the
"r"tells Emacs that when the function is called interactively, it expects a region (beginning and end points) as arguments
align-regexpwhere the work is happening. This function has the following signature.
(align-regexp BEG END REGEXP &optional GROUP SPACING REPEAT)
ENDis 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 similar to the previous construct, but instead means to match anything other than whitespace
+means one or more
1here refers to the group within the regex that will be modified to align the fields
1is the number of spaces between fields once aligned
tindicates to repeat the rule multiple times on the same line
To use this function, simply highlight a region you want to align and