]> git.eshelyaron.com Git - emacs.git/commitdiff
Add new macro dolist-with-progress-reporter
authorTino Calancha <tino.calancha@gmail.com>
Sun, 17 Jun 2018 09:28:34 +0000 (18:28 +0900)
committerTino Calancha <tino.calancha@gmail.com>
Sun, 17 Jun 2018 09:28:34 +0000 (18:28 +0900)
* lisp/subr.el (dolist-with-progress-reporter): New macro (Bug#31697).
* lisp/cus-edit.el (custom-group-value-create): Use it.
* lisp/dabbrev.el (dabbrev--progress-reporter): Delete variable.
(dabbrev--find-expansion): Use dotimes-with-progress-reporter.

* doc/lispref/display.texi: Document the macro.
; * etc/NEWS: Announce it.

doc/lispref/display.texi
etc/NEWS
lisp/cus-edit.el
lisp/dabbrev.el
lisp/subr.el

index 12c36bb08ff81b0e05fe9a6ee76d74479d98673d..feeb1caf197b9e880c42add62c8d83d82108da1e 100644 (file)
@@ -497,6 +497,21 @@ For instance, you can write previous example as follows:
 @end example
 @end defmac
 
+@defmac dolist-with-progress-reporter (var count [result]) reporter-or-message body@dots{}
+This is another convenience macro that works the same way as @code{dolist}
+does, but also reports loop progress using the functions described
+above.  As in @code{dotimes-with-progress-reporter}, @code{reporter-or-message} can be
+a progress reporter or an string.
+We can rewrite our previous example with this macro as follows:
+
+@example
+(dolist-with-progress-reporter
+    (k (number-sequence 0 500))
+    "Collecting some mana for Emacs..."
+  (sit-for 0.01))
+@end example
+@end defmac
+
 @node Logging Messages
 @subsection Logging Messages in @file{*Messages*}
 @cindex logging echo-area messages
index a77be110ffa1e7772ed98faafc468d1192a12a6c..b5d3d59320ad45460392c0a6166ed2c49aca0eb5 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -616,6 +616,9 @@ manual for more details.
 \f
 * Lisp Changes in Emacs 27.1
 
++++
+** New macro dolist-with-progress-reporter.
+
 +++
 ** New hook 'after-delete-frame-functions'.
 This works like 'delete-frame-functions', but runs after the frame to
index ff6a4f6d33c0d9dacc6b0072b5cb6ad4b1c36dbc..723cd5010df02ef32a23c8936c09a7b0730e67fd 100644 (file)
@@ -4221,19 +4221,14 @@ If GROUPS-ONLY is non-nil, return only those members that are groups."
                            custom-buffer-order-groups))
                  (prefixes (widget-get widget :custom-prefixes))
                  (custom-prefix-list (custom-prefix-add symbol prefixes))
-                 (len (length members))
-                 (count 0)
-                 (reporter (make-progress-reporter
-                            "Creating group entries..." 0 len))
                  (have-subtitle (and (not (eq symbol 'emacs))
                                      (eq custom-buffer-order-groups 'last)))
                  prev-type
                  children)
 
-            (dolist (entry members)
+            (dolist-with-progress-reporter (entry members) "Creating group entries..."
               (unless (eq prev-type 'custom-group)
                 (widget-insert "\n"))
-              (progress-reporter-update reporter (setq count (1+ count)))
               (let ((sym (nth 0 entry))
                     (type (nth 1 entry)))
                 (when (and have-subtitle (eq type 'custom-group))
@@ -4255,8 +4250,7 @@ If GROUPS-ONLY is non-nil, return only those members that are groups."
             (setq children (nreverse children))
             (mapc 'custom-magic-reset children)
             (widget-put widget :children children)
-            (custom-group-state-update widget)
-            (progress-reporter-done reporter))
+            (custom-group-state-update widget))
           ;; End line
           (let ((p (1+ (point))))
             (insert "\n\n")
index 57ee9a526a9ec1ad719675b7b77969a353f17115..4af22e61409f66177ae1160e2d0d23e3a69531ff 100644 (file)
@@ -327,9 +327,6 @@ this list."
 ;; The regexp for recognizing a character in an abbreviation.
 (defvar dabbrev--abbrev-char-regexp nil)
 
-;; The progress reporter for buffer-scanning progress.
-(defvar dabbrev--progress-reporter nil)
-
 ;;----------------------------------------------------------------
 ;; Macros
 ;;----------------------------------------------------------------
@@ -739,21 +736,19 @@ of the start of the occurrence."
         ;; Put that list in dabbrev--friend-buffer-list.
         (unless dabbrev--friend-buffer-list
            (setq dabbrev--friend-buffer-list
-                 (dabbrev--make-friend-buffer-list))
-           (setq dabbrev--progress-reporter
-                 (make-progress-reporter
-                  "Scanning for dabbrevs..."
-                  (- (length dabbrev--friend-buffer-list)) 0 0 1 1.5))))
+                 (dabbrev--make-friend-buffer-list))))
        ;; Walk through the buffers till we find a match.
        (let (expansion)
-        (while (and (not expansion) dabbrev--friend-buffer-list)
+        (dolist-with-progress-reporter
+            (_ dabbrev--friend-buffer-list)
+            (make-progress-reporter
+             "Scanning for dabbrevs..."
+             0 (length dabbrev--friend-buffer-list) 0 1 1.5)
           (setq dabbrev--last-buffer (pop dabbrev--friend-buffer-list))
           (set-buffer dabbrev--last-buffer)
-           (progress-reporter-update dabbrev--progress-reporter
-                                     (- (length dabbrev--friend-buffer-list)))
           (setq dabbrev--last-expansion-location (point-min))
-          (setq expansion (dabbrev--try-find abbrev nil 1 ignore-case)))
-        (progress-reporter-done dabbrev--progress-reporter)
+          (setq expansion (dabbrev--try-find abbrev nil 1 ignore-case))
+          (unless expansion (setq dabbrev--friend-buffer-list '())))
         expansion)))))
 
 ;; Compute the list of buffers to scan.
index d4383f862afc6f325c63506d7eb299c2b8ac34b8..dc946bd90b0e6776e68c08ad55582f6049904b0d 100644 (file)
@@ -5068,6 +5068,34 @@ This macro is a convenience wrapper around `make-progress-reporter' and friends.
        (progress-reporter-done ,prep)
        (or ,@(cdr (cdr spec)) nil))))
 
+(defmacro dolist-with-progress-reporter (spec reporter-or-message &rest body)
+  "Loop over a list and report progress in the echo area.
+Evaluate BODY with VAR bound to each car from LIST, in turn.
+Then evaluate RESULT to get return value, default nil.
+
+REPORTER-OR-MESSAGE is a progress reporter object or a string.  In the latter
+case, use this string to create a progress reporter.
+
+At each iteration, print the reporter message followed by progress
+percentage in the echo area.  After the loop is finished,
+print the reporter message followed by word \"done\".
+
+\(fn (VAR LIST [RESULT]) MESSAGE BODY...)"
+  (declare (indent 2) (debug ((symbolp form &optional form) form body)))
+  (let ((prep (make-symbol "--dolist-progress-reporter--"))
+        (count (make-symbol "--dolist-count--"))
+        (list (make-symbol "--dolist-list--")))
+    `(let ((,prep ,reporter-or-message)
+           (,count 0)
+           (,list ,(cadr spec)))
+       (when (stringp ,prep)
+         (setq ,prep (make-progress-reporter ,prep 0 (1- (length ,list)))))
+       (dolist (,(car spec) ,list)
+         ,@body
+         (progress-reporter-update ,prep (setq ,count (1+ ,count))))
+       (progress-reporter-done ,prep)
+       (or ,@(cdr (cdr spec)) nil))))
+
 \f
 ;;;; Comparing version strings.