aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2004-10-08 17:23:40 +0000
committerEli Zaretskii2004-10-08 17:23:40 +0000
commitb4329caaf870b78b09bfbbc0b5e79f3b3296b230 (patch)
tree36aab2a5f0c8fb0c1c0bd456e4e5806805a2e975
parente42d647407c8c0fc5af5ecd635fb27dfa8eaa643 (diff)
downloademacs-b4329caaf870b78b09bfbbc0b5e79f3b3296b230.tar.gz
emacs-b4329caaf870b78b09bfbbc0b5e79f3b3296b230.zip
(make-progress-reporter, progress-reporter-update)
(progress-reporter-force-update, progress-reporter-do-update) (progress-reporter-done): New functions.
-rw-r--r--lisp/ChangeLog6
-rw-r--r--lisp/subr.el127
2 files changed, 133 insertions, 0 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index f71d6800846..a0dd9c28a36 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,9 @@
12004-10-08 Paul Pogonyshev <pogonyshev@gmx.net>
2
3 * subr.el (make-progress-reporter, progress-reporter-update)
4 (progress-reporter-force-update, progress-reporter-do-update)
5 (progress-reporter-done): New functions.
6
12004-10-08 Alan Mackenzie <acm@muc.de> 72004-10-08 Alan Mackenzie <acm@muc.de>
2 8
3 * isearch.el (isearch-yank-line): C-y yanks to next EOL, not end 9 * isearch.el (isearch-yank-line): C-y yanks to next EOL, not end
diff --git a/lisp/subr.el b/lisp/subr.el
index 0a01c8982c3..2abf953090a 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -2652,5 +2652,132 @@ The properties used on SYMBOL are `composefunc', `sendfunc',
2652 (put symbol 'abortfunc (or abortfunc 'kill-buffer)) 2652 (put symbol 'abortfunc (or abortfunc 'kill-buffer))
2653 (put symbol 'hookvar (or hookvar 'mail-send-hook))) 2653 (put symbol 'hookvar (or hookvar 'mail-send-hook)))
2654 2654
2655;; Standardized progress reporting
2656
2657;; Progress reporter has the following structure:
2658;;
2659;; (NEXT-UPDATE-VALUE . [NEXT-UPDATE-TIME
2660;; MIN-VALUE
2661;; MAX-VALUE
2662;; MESSAGE
2663;; MIN-CHANGE
2664;; MIN-TIME])
2665;;
2666;; This weirdeness is for optimization reasons: we want
2667;; `progress-reporter-update' to be as fast as possible, so
2668;; `(car reporter)' is better than `(aref reporter 0)'.
2669;;
2670;; NEXT-UPDATE-TIME is a float. While `float-time' loses a couple
2671;; digits of precision, it doesn't really matter here. On the other
2672;; hand, it greatly simplifies the code.
2673
2674(defun make-progress-reporter (message min-value max-value
2675 &optional current-value
2676 min-change min-time)
2677 "Return an object suitable for reporting operation progress with `progress-reporter-update'.
2678
2679MESSAGE is shown in the echo area. When at least 1% of operation
2680is complete, the exact percentage will be appended to the
2681MESSAGE. When you call `progress-reporter-done', word \"done\"
2682is printed after the MESSAGE. You can change MESSAGE of an
2683existing progress reporter with `progress-reporter-force-update'.
2684
2685MIN-VALUE and MAX-VALUE designate starting (0% complete) and
2686final (100% complete) states of operation. The latter should be
2687larger; if this is not the case, then simply negate all values.
2688Optional CURRENT-VALUE specifies the progress by the moment you
2689call this function. You should omit it or set it to nil in most
2690cases since it defaults to MIN-VALUE.
2691
2692Optional MIN-CHANGE determines the minimal change in percents to
2693report (default is 1%.) Optional MIN-TIME specifies the minimal
2694time before echo area updates (default is 0.2 seconds.) If
2695`float-time' function is not present, then time is not tracked
2696at all. If OS is not capable of measuring fractions of seconds,
2697then this parameter is effectively rounded up."
2698
2699 (unless min-time
2700 (setq min-time 0.2))
2701 (let ((reporter
2702 (cons min-value ;; Force a call to `message' now
2703 (vector (if (and (fboundp 'float-time)
2704 (>= min-time 0.02))
2705 (float-time) nil)
2706 min-value
2707 max-value
2708 message
2709 (if min-change (max (min min-change 50) 1) 1)
2710 min-time))))
2711 (progress-reporter-update reporter (or current-value min-value))
2712 reporter))
2713
2714(defsubst progress-reporter-update (reporter value)
2715 "Report progress of an operation in the echo area.
2716However, if the change since last echo area update is too small
2717or not enough time has passed, then do nothing (see
2718`make-progress-reporter' for details).
2719
2720First parameter, REPORTER, should be the result of a call to
2721`make-progress-reporter'. Second, VALUE, determines the actual
2722progress of operation; it must be between MIN-VALUE and MAX-VALUE
2723as passed to `make-progress-reporter'.
2724
2725This function is very inexpensive, you may not bother how often
2726you call it."
2727 (when (>= value (car reporter))
2728 (progress-reporter-do-update reporter value)))
2729
2730(defun progress-reporter-force-update (reporter value &optional new-message)
2731 "Report progress of an operation in the echo area unconditionally.
2732
2733First two parameters are the same as for
2734`progress-reporter-update'. Optional NEW-MESSAGE allows you to
2735change the displayed message."
2736 (let ((parameters (cdr reporter)))
2737 (when new-message
2738 (aset parameters 3 new-message))
2739 (when (aref parameters 0)
2740 (aset parameters 0 (float-time)))
2741 (progress-reporter-do-update reporter value)))
2742
2743(defun progress-reporter-do-update (reporter value)
2744 (let* ((parameters (cdr reporter))
2745 (min-value (aref parameters 1))
2746 (max-value (aref parameters 2))
2747 (one-percent (/ (- max-value min-value) 100.0))
2748 (percentage (truncate (/ (- value min-value) one-percent)))
2749 (update-time (aref parameters 0))
2750 (current-time (float-time))
2751 (enough-time-passed
2752 ;; See if enough time has passed since the last update.
2753 (or (not update-time)
2754 (when (>= current-time update-time)
2755 ;; Calculate time for the next update
2756 (aset parameters 0 (+ update-time (aref parameters 5)))))))
2757 ;;
2758 ;; Calculate NEXT-UPDATE-VALUE. If we are not going to print
2759 ;; message this time because not enough time has passed, then use
2760 ;; 1 instead of MIN-CHANGE. This makes delays between echo area
2761 ;; updates closer to MIN-TIME.
2762 (setcar reporter
2763 (min (+ min-value (* (+ percentage
2764 (if enough-time-passed
2765 (aref parameters 4) ;; MIN-CHANGE
2766 1))
2767 one-percent))
2768 max-value))
2769 (when (integerp value)
2770 (setcar reporter (ceiling (car reporter))))
2771 ;;
2772 ;; Only print message if enough time has passed
2773 (when enough-time-passed
2774 (if (> percentage 0)
2775 (message "%s%d%%" (aref parameters 3) percentage)
2776 (message "%s" (aref parameters 3))))))
2777
2778(defun progress-reporter-done (reporter)
2779 "Print reporter's message followed by word \"done\" in echo area."
2780 (message "%sdone" (aref (cdr reporter) 3)))
2781
2655;; arch-tag: f7e0e6e5-70aa-4897-ae72-7a3511ec40bc 2782;; arch-tag: f7e0e6e5-70aa-4897-ae72-7a3511ec40bc
2656;;; subr.el ends here 2783;;; subr.el ends here