Paredit is an Emacs package for structural editing. It is particularly useful in Lisp languages to manipulate expressions instead of just characters.
One of the numerous little features of Paredit is the automatic insertion of a
space character before a delimiting pair. For example, if you are typing
(length
, typing (
will have Paredit automatically insert a space character
before the opening parenthesis, to produce the expected (length (
content.
Paredit is smart enough to avoid doing so after quote, backquote or comma
characters, but not after an unquote-splicing sequence (,@
) which is quite
annoying in languages such as Scheme or Common Lisp. As almost always in
Emacs, this behaviour can be customized.
Paredit decides whether to add a space or not using the
paredit-space-for-delimiter-p
function, ending up with applying a list of
predicates from paredit-space-for-delimiter-predicates
.
Let us add our own. For more flexibility, we will start by defining a list of prefixes which are not to be followed by a space:
(defvar g-paredit-no-space-prefixes (list ",@"))
We then write our predicate which simply checks if we are right after one of these prefixes:
(defun g-paredit-space-for-delimiter (endp delimiter)
(let ((point (point)))
(or endp
(seq-every-p
(lambda (prefix)
(and (> point (length prefix))
(let ((start (- point (length prefix)))
(end point))
(not (string= (buffer-substring start end) prefix)))))
g-paredit-no-space-prefixes))))
Finally we add a Paredit hook to append our predicate to the list:
(defun g-init-paredit-space-for-delimiter ()
(add-to-list 'paredit-space-for-delimiter-predicates
'g-paredit-space-for-delimiter))
(add-hook 'paredit-mode-hook 'g-init-paredit-space-for-delimiter)
Not only does it fix the problem for unquote-slicing, but it makes it easy to
add new prefixes. For example I immediately added #p
(used for pathnames in
Common Lisp, e.g. #p"/usr/bin/"
) to the list.