emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master aab5d7b3f3 1/3: Add a KEEP-NEWLINES argument to string-lines


From: Lars Ingebrigtsen
Subject: master aab5d7b3f3 1/3: Add a KEEP-NEWLINES argument to string-lines
Date: Sat, 30 Apr 2022 06:57:28 -0400 (EDT)

branch: master
commit aab5d7b3f3bb6fb82924aaabdfdd6e2a79ad3141
Author: Lars Ingebrigtsen <larsi@gnus.org>
Commit: Lars Ingebrigtsen <larsi@gnus.org>

    Add a KEEP-NEWLINES argument to string-lines
    
    * doc/lispref/strings.texi (Creating Strings): Document it.
    
    * lisp/subr.el (string-lines): Add a KEEP-NEWLINES argument.
---
 doc/lispref/strings.texi |  6 ++++--
 lisp/subr.el             | 32 +++++++++++++++++++++++++++++---
 test/lisp/subr-tests.el  | 22 ++++++++++++++++++++++
 3 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi
index d31807ad2a..6f620c9d76 100644
--- a/doc/lispref/strings.texi
+++ b/doc/lispref/strings.texi
@@ -434,9 +434,11 @@ display purposes; use @code{truncate-string-to-width} or
 (@pxref{Size of Displayed Text}).
 @end defun
 
-@defun string-lines string &optional omit-nulls
+@defun string-lines string &optional omit-nulls keep-newlines
 Split @var{string} into a list of strings on newline boundaries.  If
-@var{omit-nulls}, remove empty lines from the results.
+@var{omit-nulls}, remove empty lines from the results.  if
+@var{keep-newlines}, don't remove the trailing newlines from the
+result strings.
 @end defun
 
 @defun string-pad string length &optional padding start
diff --git a/lisp/subr.el b/lisp/subr.el
index 9623ea63b5..14cab04d42 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -6646,10 +6646,36 @@ is inserted before adjusting the number of empty lines."
      ((< (- (point) start) lines)
       (insert (make-string (- lines (- (point) start)) ?\n))))))
 
-(defun string-lines (string &optional omit-nulls)
+(defun string-lines (string &optional omit-nulls keep-newlines)
   "Split STRING into a list of lines.
-If OMIT-NULLS, empty lines will be removed from the results."
-  (split-string string "\n" omit-nulls))
+If OMIT-NULLS, empty lines will be removed from the results.
+If KEEP-NEWLINES, don't strip trailing newlines from the result
+lines."
+  (let ((lines nil)
+        (start 0))
+    (while (< start (length string))
+      (if-let ((newline (string-search "\n" string start)))
+          (progn
+            (when (or (not omit-nulls)
+                      (not (= start newline)))
+              (let ((line (substring string start
+                                     (if keep-newlines
+                                         (1+ newline)
+                                       newline))))
+                (when (not (and keep-newlines omit-nulls
+                                (equal line "\n")))
+                  (push line lines))))
+            (setq start (1+ newline))
+            ;; Include the final newline.
+            (when (and (= start (length string))
+                       (not omit-nulls)
+                       (not keep-newlines))
+              (push "" lines)))
+        (if (zerop start)
+            (push string lines)
+          (push (substring string start) lines))
+        (setq start (length string))))
+    (nreverse lines)))
 
 (defun buffer-match-p (condition buffer-or-name &optional arg)
   "Return non-nil if BUFFER-OR-NAME matches CONDITION.
diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el
index e027c68d0b..c431930c27 100644
--- a/test/lisp/subr-tests.el
+++ b/test/lisp/subr-tests.el
@@ -1028,5 +1028,27 @@ final or penultimate step during initialization."))
   (should (readablep "foo"))
   (should-not (readablep (list (make-marker)))))
 
+(ert-deftest test-string-lines ()
+  (should (equal (string-lines "foo") '("foo")))
+  (should (equal (string-lines "foo\n") '("foo" "")))
+  (should (equal (string-lines "foo\nbar") '("foo" "bar")))
+
+  (should (equal (string-lines "foo" t) '("foo")))
+  (should (equal (string-lines "foo\n" t) '("foo")))
+  (should (equal (string-lines "foo\nbar" t) '("foo" "bar")))
+  (should (equal (string-lines "foo\n\n\nbar" t) '("foo" "bar")))
+
+  (should (equal (string-lines "foo" nil t) '("foo")))
+  (should (equal (string-lines "foo\n" nil t) '("foo\n")))
+  (should (equal (string-lines "foo\nbar" nil t) '("foo\n" "bar")))
+  (should (equal (string-lines "foo\n\n\nbar" nil t)
+                 '("foo\n" "\n" "\n" "bar")))
+
+  (should (equal (string-lines "foo" t t) '("foo")))
+  (should (equal (string-lines "foo\n" t t) '("foo\n")))
+  (should (equal (string-lines "foo\nbar" t t) '("foo\n" "bar")))
+  (should (equal (string-lines "foo\n\n\nbar" t t)
+                 '("foo\n" "bar"))))
+
 (provide 'subr-tests)
 ;;; subr-tests.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]