From 9b00c97de41165beefe3eff936470f8e081ca600 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Tue, 2 Aug 2022 17:08:53 +0200 Subject: read-print: Add code to read and write sequences of expressions/blanks. * guix/read-print.scm (read-with-comments): Add #:blank-line? and honor it. (read-with-comments/sequence, pretty-print-with-comments/splice): New procedures. * tests/read-print.scm (test-pretty-print/sequence): New macro. Add tests using it. --- guix/read-print.scm | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'guix/read-print.scm') diff --git a/guix/read-print.scm b/guix/read-print.scm index 33ed6e3dbe..4a3afdd4f9 100644 --- a/guix/read-print.scm +++ b/guix/read-print.scm @@ -25,7 +25,9 @@ #:use-module (srfi srfi-34) #:use-module (srfi srfi-35) #:export (pretty-print-with-comments + pretty-print-with-comments/splice read-with-comments + read-with-comments/sequence object->string* blank? @@ -147,8 +149,9 @@ single record." ((? space?) (loop)) (chr (unread-char chr port))))) -(define (read-with-comments port) - "Like 'read', but include objects when they're encountered." +(define* (read-with-comments port #:key (blank-line? #t)) + "Like 'read', but include objects when they're encountered. When +BLANK-LINE? is true, assume PORT is at the beginning of a new line." ;; Note: Instead of implementing this functionality in 'read' proper, which ;; is the best approach long-term, this code is a layer on top of 'read', ;; such that we don't have to rely on a specific Guile version. @@ -167,7 +170,7 @@ single record." dotted)) ((x . rest) (loop (cons x result) rest))))) - (let loop ((blank-line? #t) + (let loop ((blank-line? blank-line?) (return (const 'unbalanced))) (match (read-char port) ((? eof-object? eof) @@ -217,6 +220,20 @@ single record." ((and token '#{.}#) (if (eq? chr #\.) dot token)) (token token)))))))) + +(define (read-with-comments/sequence port) + "Read from PORT until the end-of-file is reached and return the list of +expressions and blanks that were read." + (let loop ((lst '()) + (blank-line? #t)) + (match (read-with-comments port #:blank-line? blank-line?) + ((? eof-object?) + (reverse! lst)) + ((? blank? blank) + (loop (cons blank lst) #t)) + (exp + (loop (cons exp lst) #f))))) + ;;; ;;; Comment-preserving pretty-printer. @@ -625,3 +642,12 @@ passed as-is to 'pretty-print-with-comments'." (apply pretty-print-with-comments port obj #:indent indent args)))) + +(define* (pretty-print-with-comments/splice port lst + #:rest rest) + "Write to PORT the expressions and blanks listed in LST." + (for-each (lambda (exp) + (apply pretty-print-with-comments port exp rest) + (unless (blank? exp) + (newline port))) + lst)) -- cgit v1.2.3