unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Tino Calancha <tino.calancha@gmail.com>
To: 31697@debbugs.gnu.org
Cc: stefan monnier <monnier@iro.umontreal.ca>,
	Noam Postavsky <npostavs@gmail.com>
Subject: bug#31697: 27.0.50; Add new macro dolist-with-progress-reporter
Date: Sun, 03 Jun 2018 23:00:02 +0900	[thread overview]
Message-ID: <87vab03r8d.fsf@gmail.com> (raw)
In-Reply-To: <8736y457ty.fsf@gmail.com> (Tino Calancha's message of "Sun, 03 Jun 2018 22:16:09 +0900")

Tino Calancha <tino.calancha@gmail.com> writes:

> +  (declare (indent 2) (debug ((symbolp form &optional form) form body)))
> +  (let ((prep (make-symbol "--dolist-progress-reporter--"))
> +        (count (make-symbol "--dolist-count--")))
> +    `(let ((,prep ,reporter-or-message)
> +           (,count 0))
> +       (when (stringp ,prep)
> +         (setq ,prep (make-progress-reporter ,prep 0 (1- (length ,(cadr spec))))))
> +       (dolist ,spec
> +         ,@body
> +         (progress-reporter-update ,prep (setq ,count (1+ ,count))))
> +       (progress-reporter-done ,prep)
> +       (or ,@(cdr (cdr spec)) nil))))
As pointed out by Noam in Bug#31696, I am also evaluating twice here the
form at (nth 1 SPEC).  I must add another variable.
Here is the updated patch.

--8<-----------------------------cut here---------------start------------->8---
commit 0cd28b8a33fcd1c5e348af67462257b707b79bad
Author: Tino Calancha <tino.calancha@gmail.com>
Date:   Sun Jun 3 22:56:02 2018 +0900

    Add new macro dolist-with-progress-reporter
    
    * 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.

diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index ce7ec3ac10..dd1d1e80e9 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -485,6 +485,12 @@ Progress
 @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.
+@end defmac
+
 @node Logging Messages
 @subsection Logging Messages in @file{*Messages*}
 @cindex logging echo-area messages
diff --git a/etc/NEWS b/etc/NEWS
index 1b324986d9..16e2d6d752 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -562,6 +562,8 @@ manual for more details.
 * Lisp Changes in Emacs 27.1
 
 +++
+** New macro dolist-with-progress-reporter.
++++
 ** New function assoc-delete-all.
 
 +++
diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el
index a12897e799..c227bb0a26 100644
--- a/lisp/cus-edit.el
+++ b/lisp/cus-edit.el
@@ -4221,19 +4221,14 @@ custom-group-value-create
 			    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 @@ custom-group-value-create
 	     (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")
diff --git a/lisp/dabbrev.el b/lisp/dabbrev.el
index 57ee9a526a..4af22e6140 100644
--- a/lisp/dabbrev.el
+++ b/lisp/dabbrev.el
@@ -327,9 +327,6 @@ dabbrev--check-other-buffers
 ;; 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 @@ dabbrev--find-expansion
 	 ;; 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.
diff --git a/lisp/subr.el b/lisp/subr.el
index 914112ccef..0a4de8365f 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -5039,6 +5039,33 @@ dotimes-with-progress-reporter
 				   (setq ,(car spec) (1+ ,(car spec)))))
        (progress-reporter-done ,temp2)
        nil ,@(cdr (cdr spec)))))
+(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.

--8<-----------------------------cut here---------------end--------------->8---





  reply	other threads:[~2018-06-03 14:00 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-03 13:16 bug#31697: 27.0.50; Add new macro dolist-with-progress-reporter Tino Calancha
2018-06-03 14:00 ` Tino Calancha [this message]
2018-06-17  9:38   ` Tino Calancha

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87vab03r8d.fsf@gmail.com \
    --to=tino.calancha@gmail.com \
    --cc=31697@debbugs.gnu.org \
    --cc=monnier@iro.umontreal.ca \
    --cc=npostavs@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).