summaryrefslogtreecommitdiffstats
path: root/content/posts/WIP-emacs-align-columns
diff options
context:
space:
mode:
Diffstat (limited to 'content/posts/WIP-emacs-align-columns')
-rw-r--r--content/posts/WIP-emacs-align-columns/index.org65
1 files changed, 65 insertions, 0 deletions
diff --git a/content/posts/WIP-emacs-align-columns/index.org b/content/posts/WIP-emacs-align-columns/index.org
new file mode 100644
index 0000000..1aea7fd
--- /dev/null
+++ b/content/posts/WIP-emacs-align-columns/index.org
@@ -0,0 +1,65 @@
+#+TITLE: Aligning columns in Emacs
+#+DATE: 2021-03-26T11:27:34-04:00
+#+DRAFT: true
+#+DESCRIPTION:
+#+TAGS[]: emacs elisp
+#+KEYWORDS[]: emacs elisp
+#+SLUG:
+#+SUMMARY:
+
+I've been writing a lot of ruby GraphQL queries and mutations 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 in the infinite wisdom of Emacs developers over the
+last couple decades, someone must have included a piece of code to
+take care of exactly this kind of situation.
+
+As it turns out I was correct in my assumption. There's an excellent
+built in package called =align.el= 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=.