read-print: Support printing multi-line comments.

* guix/read-print.scm (%not-newline): New variable.
(print-multi-line-comment): New procedure.
(pretty-print-with-comments): Use it.
* tests/read-print.scm ("pretty-print-with-comments, multi-line
comment"): New test.
This commit is contained in:
Ludovic Courtès 2022-08-02 22:52:10 +02:00
parent a109ee9048
commit 445a0d134c
No known key found for this signature in database
GPG Key ID: 090B11993D9AEBB5
2 changed files with 38 additions and 2 deletions

View File

@ -387,6 +387,27 @@ particular newlines, is left as is."
line "\n")
(comment-margin? comment)))))
(define %not-newline
(char-set-complement (char-set #\newline)))
(define (print-multi-line-comment str indent port)
"Print to PORT STR as a multi-line comment, with INDENT spaces preceding
each line except the first one (they're assumed to be already there)."
;; While 'read-with-comments' only returns one-line comments, user-provided
;; comments might span multiple lines, which is why this is necessary.
(let loop ((lst (string-tokenize str %not-newline)))
(match lst
(() #t)
((last)
(display last port)
(newline port))
((head tail ...)
(display head port)
(newline port)
(display (make-string indent #\space) port)
(loop tail)))))
(define* (pretty-print-with-comments port obj
#:key
(format-comment
@ -486,8 +507,9 @@ FORMAT-VERTICAL-SPACE; a useful value of 'canonicalize-vertical-space'."
(unless (= column indent)
(newline port)
(display (make-string indent #\space) port))
(display (comment->string (format-comment comment indent))
port)))
(print-multi-line-comment (comment->string
(format-comment comment indent))
indent port)))
(display (make-string indent #\space) port)
indent)
((? vertical-space? space)

View File

@ -341,4 +341,18 @@ mnopqrstuvwxyz.\")"
#:format-vertical-space
canonicalize-vertical-space)))))
(test-equal "pretty-print-with-comments, multi-line comment"
"\
(list abc
;; This comment spans
;; two lines.
def)"
(call-with-output-string
(lambda (port)
(pretty-print-with-comments port
`(list abc ,(comment "\
;; This comment spans\n
;; two lines.\n")
def)))))
(test-end)