From 3a5ead0342a50b1e7d1c07530dc883de9bd9b8a6 Mon Sep 17 00:00:00 2001 From: Dante Catalfamo Date: Sat, 27 Mar 2021 00:35:41 -0400 Subject: Rename to remove WIP --- content/posts/emacs-align-columns/index.org | 68 +++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 content/posts/emacs-align-columns/index.org (limited to 'content/posts/emacs-align-columns/index.org') diff --git a/content/posts/emacs-align-columns/index.org b/content/posts/emacs-align-columns/index.org new file mode 100644 index 0000000..a2c145d --- /dev/null +++ b/content/posts/emacs-align-columns/index.org @@ -0,0 +1,68 @@ +#+TITLE: Aligning columns in Emacs +#+DATE: 2021-03-26T11:27:34-04:00 +#+DRAFT: false +#+DESCRIPTION: How to align text separated by whitespace using Emacs +#+TAGS[]: emacs elisp +#+KEYWORDS[]: emacs elisp +#+SLUG: +#+ALIASES[]: /posts/wip-emacs-align-columns/ +#+SUMMARY: + +#+ATTR_HTML: :alt Before and after columns aligned +#+ATTR_HTML: :title Before and after aligned columns +[[file:cover.png]] + +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. + +#+begin_src elisp +(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)) +#+end_src + +Let's walk through what's going on here. + +- =BEG= and =END= 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 the =M-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. + #+begin_src elisp + (align-regexp BEG END REGEXP &optional GROUP SPACING REPEAT) + #+end_src + + - =BEG= and =END= 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 [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Regexp-Backslash.html][regular expression construct]] specific to Emacs which + specifies a type of /syntax/ which is to be matched. + - =-= refers to the [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Syntax-Class-Table.html][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 fields + - =1= is the number of spaces between fields once aligned + - =t= 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=. -- cgit v1.2.3