Read-Time String Concatenation

Sometimes, I miss the string concatenation capability of C. I mean, the way
that you can split a long string into smaller ones and have them automatically
concatenated together. The format
function has a tilde (~) directive that
does something along these lines, but there are two problems:
- first, I’m not necessarily facing the problem in
format
calls, - next, my favorite text editor cannot properly indent the string contents
when I press the
TAB
key.
Here’s an example:
(defclass sample ()
((slot :documentation
"A very long slot documentation, that doesn't even fit in 80 columns, which is a shame...")))
If that were C code, I could write this:
(defclass sample ()
((slot :documentation
"A very long slot documentation, "
"that doesn't even fit in 80 columns, "
"which is a shame...")))
But this is not C code. We can come very close to that however. Here’s a small
reader function that will automatically concatenate strings prefixed with a
tilde (~) character (in honor of the eponymous format
directive):
(defun ~-reader (stream char)
"Read a series of ~\"string\" to be concatenated together."
(declare (ignore char))
(flet ((read-string (&aux (string (read stream t nil t)))
(check-type string string "a string")
string))
(apply #'concatenate 'string
(read-string)
(loop :while (char= (peek-char t stream nil nil t) #\~)
:do (read-char stream t nil t)
:collect (read-string)))))
Let’s add it to the current readtable:
(set-macro-character #\~ #~-reader)
And now I can write this:
(defclass sample ()
((slot :documentation
~"A very long slot documentation, "
~"that doesn't even fit in 80 columns, "
~"which is a shame...")))
Everyday of my life I thank Common Lisp for being so flexible. The next step
would be to make cl-indent.el
aware that tilde-strings really are the same
object, and hence should be vertically aligned in all contexts. I’m not there
yet. Jeeze, this indentation hacking will never end… 😃