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.
This commit is contained in:
Tino Calancha 2018-06-17 18:28:34 +09:00
parent 5099b3abb2
commit edb1f85a27
5 changed files with 56 additions and 21 deletions

View 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

View file

@ -616,6 +616,9 @@ manual for more details.
* 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

View 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")

View 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.

View 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))))
;;;; Comparing version strings.