[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] Changes to emacs/lisp/subr.el
From: |
Eli Zaretskii |
Subject: |
[Emacs-diffs] Changes to emacs/lisp/subr.el |
Date: |
Fri, 08 Oct 2004 13:35:16 -0400 |
Index: emacs/lisp/subr.el
diff -c emacs/lisp/subr.el:1.414 emacs/lisp/subr.el:1.415
*** emacs/lisp/subr.el:1.414 Sat Sep 25 02:32:15 2004
--- emacs/lisp/subr.el Fri Oct 8 17:21:57 2004
***************
*** 2652,2656 ****
--- 2652,2783 ----
(put symbol 'abortfunc (or abortfunc 'kill-buffer))
(put symbol 'hookvar (or hookvar 'mail-send-hook)))
+ ;; Standardized progress reporting
+
+ ;; Progress reporter has the following structure:
+ ;;
+ ;; (NEXT-UPDATE-VALUE . [NEXT-UPDATE-TIME
+ ;; MIN-VALUE
+ ;; MAX-VALUE
+ ;; MESSAGE
+ ;; MIN-CHANGE
+ ;; MIN-TIME])
+ ;;
+ ;; This weirdeness is for optimization reasons: we want
+ ;; `progress-reporter-update' to be as fast as possible, so
+ ;; `(car reporter)' is better than `(aref reporter 0)'.
+ ;;
+ ;; NEXT-UPDATE-TIME is a float. While `float-time' loses a couple
+ ;; digits of precision, it doesn't really matter here. On the other
+ ;; hand, it greatly simplifies the code.
+
+ (defun make-progress-reporter (message min-value max-value
+ &optional current-value
+ min-change min-time)
+ "Return an object suitable for reporting operation progress with
`progress-reporter-update'.
+
+ MESSAGE is shown in the echo area. When at least 1% of operation
+ is complete, the exact percentage will be appended to the
+ MESSAGE. When you call `progress-reporter-done', word \"done\"
+ is printed after the MESSAGE. You can change MESSAGE of an
+ existing progress reporter with `progress-reporter-force-update'.
+
+ MIN-VALUE and MAX-VALUE designate starting (0% complete) and
+ final (100% complete) states of operation. The latter should be
+ larger; if this is not the case, then simply negate all values.
+ Optional CURRENT-VALUE specifies the progress by the moment you
+ call this function. You should omit it or set it to nil in most
+ cases since it defaults to MIN-VALUE.
+
+ Optional MIN-CHANGE determines the minimal change in percents to
+ report (default is 1%.) Optional MIN-TIME specifies the minimal
+ time before echo area updates (default is 0.2 seconds.) If
+ `float-time' function is not present, then time is not tracked
+ at all. If OS is not capable of measuring fractions of seconds,
+ then this parameter is effectively rounded up."
+
+ (unless min-time
+ (setq min-time 0.2))
+ (let ((reporter
+ (cons min-value ;; Force a call to `message' now
+ (vector (if (and (fboundp 'float-time)
+ (>= min-time 0.02))
+ (float-time) nil)
+ min-value
+ max-value
+ message
+ (if min-change (max (min min-change 50) 1) 1)
+ min-time))))
+ (progress-reporter-update reporter (or current-value min-value))
+ reporter))
+
+ (defsubst progress-reporter-update (reporter value)
+ "Report progress of an operation in the echo area.
+ However, if the change since last echo area update is too small
+ or not enough time has passed, then do nothing (see
+ `make-progress-reporter' for details).
+
+ First parameter, REPORTER, should be the result of a call to
+ `make-progress-reporter'. Second, VALUE, determines the actual
+ progress of operation; it must be between MIN-VALUE and MAX-VALUE
+ as passed to `make-progress-reporter'.
+
+ This function is very inexpensive, you may not bother how often
+ you call it."
+ (when (>= value (car reporter))
+ (progress-reporter-do-update reporter value)))
+
+ (defun progress-reporter-force-update (reporter value &optional new-message)
+ "Report progress of an operation in the echo area unconditionally.
+
+ First two parameters are the same as for
+ `progress-reporter-update'. Optional NEW-MESSAGE allows you to
+ change the displayed message."
+ (let ((parameters (cdr reporter)))
+ (when new-message
+ (aset parameters 3 new-message))
+ (when (aref parameters 0)
+ (aset parameters 0 (float-time)))
+ (progress-reporter-do-update reporter value)))
+
+ (defun progress-reporter-do-update (reporter value)
+ (let* ((parameters (cdr reporter))
+ (min-value (aref parameters 1))
+ (max-value (aref parameters 2))
+ (one-percent (/ (- max-value min-value) 100.0))
+ (percentage (truncate (/ (- value min-value) one-percent)))
+ (update-time (aref parameters 0))
+ (current-time (float-time))
+ (enough-time-passed
+ ;; See if enough time has passed since the last update.
+ (or (not update-time)
+ (when (>= current-time update-time)
+ ;; Calculate time for the next update
+ (aset parameters 0 (+ update-time (aref parameters 5)))))))
+ ;;
+ ;; Calculate NEXT-UPDATE-VALUE. If we are not going to print
+ ;; message this time because not enough time has passed, then use
+ ;; 1 instead of MIN-CHANGE. This makes delays between echo area
+ ;; updates closer to MIN-TIME.
+ (setcar reporter
+ (min (+ min-value (* (+ percentage
+ (if enough-time-passed
+ (aref parameters 4) ;; MIN-CHANGE
+ 1))
+ one-percent))
+ max-value))
+ (when (integerp value)
+ (setcar reporter (ceiling (car reporter))))
+ ;;
+ ;; Only print message if enough time has passed
+ (when enough-time-passed
+ (if (> percentage 0)
+ (message "%s%d%%" (aref parameters 3) percentage)
+ (message "%s" (aref parameters 3))))))
+
+ (defun progress-reporter-done (reporter)
+ "Print reporter's message followed by word \"done\" in echo area."
+ (message "%sdone" (aref (cdr reporter) 3)))
+
;; arch-tag: f7e0e6e5-70aa-4897-ae72-7a3511ec40bc
;;; subr.el ends here
- [Emacs-diffs] Changes to emacs/lisp/subr.el,
Eli Zaretskii <=
- [Emacs-diffs] Changes to emacs/lisp/subr.el, Kim F . Storm, 2004/10/09
- [Emacs-diffs] Changes to emacs/lisp/subr.el, Kim F . Storm, 2004/10/11
- [Emacs-diffs] Changes to emacs/lisp/subr.el, Stefan Monnier, 2004/10/13
- [Emacs-diffs] Changes to emacs/lisp/subr.el, Richard M . Stallman, 2004/10/16
- [Emacs-diffs] Changes to emacs/lisp/subr.el, Richard M . Stallman, 2004/10/17
- [Emacs-diffs] Changes to emacs/lisp/subr.el, Simon Josefsson, 2004/10/25
- [Emacs-diffs] Changes to emacs/lisp/subr.el, Stefan Monnier, 2004/10/28
- [Emacs-diffs] Changes to emacs/lisp/subr.el, Simon Josefsson, 2004/10/29