It turns out that the behavior of a given regexp is dependent upon the syntax table of the buffer in which it is being run. So in your case, the \s-
matches any character that is part of the whitespace syntax class in that buffer. If the newline characters is part of that syntax class, then you have the possibility of getting matches that span multiple lines. Unfortunately, there seems to be a built-in assumption to the function align-region
that matches will be confined to a single line.
The following function provides a wrapper around align-regexp
which creates a temporary syntax table, if needed, based on the current syntax table of the buffer. It then modifies the temporary table to make sure that the newline character is not part of the whitespace syntax class:
;; Source: http://emacs.stackexchange.com/a/21776/93
(defun my-align-regexp ()
"Wrapper around align-regexp which works around issues that
can occur when newlines are included in the whitespace syntax
class. [bug #23339]"
(interactive)
(setq this-command 'align-regexp)
(if (eq ?\s (char-syntax ?\n))
(let ((table (copy-syntax-table (syntax-table))))
(modify-syntax-entry ?\n ">" table)
(with-syntax-table table
(call-interactively 'align-regexp)))
(call-interactively 'align-regexp)))
I assume you could achieve the same result with advice, but I tend to avoid advice unless it is unavoidable. I have submitted a bug report for this issue [#23339], so hopefully this will get fixed in a future release.
\(\s-*\)
is a regular expression subgroup (bounded by\(
and\)
), and matching on zero or more whitespace characters:\s-
matches whitespace, and*
matches zero or more. Details are in the manual\s
as being whitespace rather than\s-
.spacemacs/align-repeat-bar
does the correct thing.*scratch*
buffer.