I am working in Haskell and frequently come across code similar to the following:
func i j | i == j = i
| otherwise = j
I want to align on the '=' character using align-regexp but don't have the elisp knowhow. I have tried just doing " = " without the quotes, but this inserts an unwanted space character before each '='. I have found a proposed solution here but I can't seem to get that to do anything at all.
Please help me write a function or hard-coded macro that will allow me to set a keybinding for this.
C-u M-x align-regexp
RET \(\s-*\) =
RET 1
RET 0
RET n
(n.b. there's a space after the '=', but it's not very obvious.)
Which is to say...
Use a prefix argument to tell align-regexp
to ask you for more parameters than it does by default.
See C-h f align-regexp
and C-h v align-rules-list
for details, but in short:
\(\s-*\)
is the default 'group' for deletion/expansion. We append our pattern to the end of that: ' = '. (Note that \s-
is Emacs regexp syntax for whitespace.)
1
simply refers to parenthesised group 1 (as above). This is the default.
0
for the spacing to use between the two parts of the line. By default this is 1, and is why you were ending up with an additional space.
n
to not align any subsequent pattern matches after the first in each line.
edit: Actually, the Q&A you linked to is near identical, and works fine for me on Emacs 23.2.1, so this is a duplicate, but to continue and answer the key-binding aspect:
You can bind that (or any) sequence via keyboard macros. Here's the end result, which you can probably just add to your init file, although I recommend you go through the process yourself. Use whatever you like in place of C-c a
for the key. C-c (letter)
and F5-F9 are reserved for end-users to bind as they please, so one of those will be safe from being clobbered by a mode's keymap.
(global-set-key (kbd "C-c a") (lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ([21 134217848 97 108 105 103 110 45 114 101 103 101 120 112 return 32 61 32 return return backspace 48 return 110] 0 "%d")) arg)))
I did that by:
align-regexp
as above (being careful to type everything verbatim, and not use minibuffer history or yanking).1
align-single-equals
RET to give the macro a nameinsert-kbd-macro
RET align-single-equals
RET to get the lisp.(lambda)
expression with (global-set-key)
to bind it. (Although you could also use the (fset 'align-single-equals ...)
code as provided, and then bind the key to that symbol.1 If you make a mistake when recording a complicated macro, don't fret — Emacs provides a really good macro editor which you can use to fix any mistakes after you finish recording (just type C-x C-k e), so you don't need to be perfect.
edit 2: May as well add an example of a function, as per comments.
(defun my-align-single-equals ()
"Align on a single equals sign (with a space either side)."
(interactive)
(align-regexp
(region-beginning) (region-end)
"\\(\\s-*\\) = " 1 0 nil))
(global-set-key (kbd "C-c a") 'my-align-single-equals)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With