branch: master commit 11b34357c50788ec5e6e5f433f9a2a9f55d5f7be Author: Nicolas Petton <nico...@petton.fr> Commit: Nicolas Petton <nico...@petton.fr>
Update stream.el to v2.0.2. * packages/stream/stream.el: * packages/stream/tests/stream-tests.el: Update. --- packages/stream/stream.el | 36 ++++++++++++++++++++++----------- packages/stream/tests/stream-tests.el | 6 +++++ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/packages/stream/stream.el b/packages/stream/stream.el index 6b3fa74..6bbf99f 100644 --- a/packages/stream/stream.el +++ b/packages/stream/stream.el @@ -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)))) diff --git a/packages/stream/tests/stream-tests.el b/packages/stream/tests/stream-tests.el index a7cb727..0033ed7 100644 --- a/packages/stream/tests/stream-tests.el +++ b/packages/stream/tests/stream-tests.el @@ -168,5 +168,11 @@ (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