]> code.delx.au - gnu-emacs-elpa/commitdiff
Update stream.el to v2.0.2.
authorNicolas Petton <nicolas@petton.fr>
Wed, 4 Nov 2015 08:50:32 +0000 (09:50 +0100)
committerNicolas Petton <nicolas@petton.fr>
Wed, 4 Nov 2015 08:51:02 +0000 (09:51 +0100)
* packages/stream/stream.el:
* packages/stream/tests/stream-tests.el: Update.

packages/stream/stream.el
packages/stream/tests/stream-tests.el

index 6b3fa7416ca7a916cc4ed628154e3bf610b90fee..6bbf99fce596ce1d5cb98b306220cf111e34f76b 100644 (file)
@@ -62,7 +62,7 @@
 
 (defmacro stream-make (&rest body)
   "Return a stream built from BODY.
-BODY must return nil or a cons cell, which cdr is itself a
+BODY must return nil or a cons cell whose cdr is itself a
 stream."
   (declare (debug t))
   `(list ',stream--identifier (thunk-delay ,@body)))
@@ -98,7 +98,7 @@ SEQ can be a list, vector or string."
 
 (cl-defmethod stream ((buffer buffer) &optional pos)
   "Return a stream of the characters of the buffer BUFFER.
-BUFFER-OR-NAME may be a buffer or a string (buffer name).
+BUFFER may be a buffer or a string (buffer name).
 The sequence starts at POS if non-nil, 1 otherwise."
   (with-current-buffer buffer
     (unless pos (setq pos (point-min)))
@@ -113,6 +113,15 @@ The sequence starts at POS if non-nil, 1 otherwise."
            (char-after (point)))))
      (stream buffer (1+ pos)))))
 
+(defun stream-regexp (buffer regexp)
+  (stream-make
+   (let (match)
+     (with-current-buffer buffer
+       (setq match (re-search-forward regexp nil t)))
+     (when match
+       (cons (match-data) (stream-regexp buffer regexp))
+       nil))))
+
 (defun stream-range (&optional start end step)
   "Return a stream of the integers from START to END, stepping by STEP.
 If START is nil, it defaults to 0. If STEP is nil, it defaults to
@@ -191,7 +200,7 @@ This function will eagerly consume the entire stream."
   (seq-take (seq-drop stream start) (- end start)))
 
 (cl-defmethod seq-into-sequence ((stream stream))
-  "Convert STREAM into a sequence"
+  "Convert STREAM into a sequence."
   (let ((list))
     (seq-doseq (elt stream)
       (push elt list))
@@ -244,19 +253,22 @@ This function will eagerly consume the entire stream."
            (stream-rest stream)))))
 
 (cl-defmethod seq-map (function (stream stream))
-  "Return a stream.
-The elements of the produced sequence consist of the application
-of FUNCTION to each element of STREAM."
-  (if (stream-empty-p stream)
-      stream
-    (stream-cons
-      (funcall function (stream-first stream))
-     (seq-map function (stream-rest stream)))))
+    "Return a stream representing the mapping of FUNCTION over STREAM.
+The elements of the produced stream are the results of the
+applications of FUNCTION on each element of STREAM in succession."
+  (stream-make
+   ;; Avoid using `stream-empty-p', as it will consume the first element of the
+   ;; stream before iterating over the stream.
+   (let ((first (stream-first stream)))
+     (when first
+       (cons (funcall function first)
+             (seq-map function (stream-rest stream)))))))
 
 (cl-defmethod seq-do (function (stream stream))
   "Evaluate FUNCTION for each element of STREAM eagerly, and return nil.
 
-`seq-do' should never be used on infinite streams."
+`seq-do' should never be used on infinite streams without some
+kind of nonlocal exit."
   (while (not (stream-empty-p stream))
     (funcall function (stream-first stream))
     (setq stream (stream-rest stream))))
index a7cb727298709d907662cf49bf6cbd138a0de3cf..0033ed74a394830ab5b4f9773c80bc2ec6ed2718 100644 (file)
   (should (= (seq-length (seq-subseq (stream-range 2 10) 1 3)) 2))
   (should (= (seq-elt (seq-subseq (stream-range 2 10) 1 3) 1) 4)))
 
+(ert-deftest stream-seq-map-should-not-consume-stream-elements ()
+  (let* (consumed
+         (stream (stream-cons (setq consumed t) (stream-empty))))
+    (seq-map #'identity stream)
+    (should-not consumed)))
+
 (provide 'stream-tests)
 ;;; stream-tests.el ends here