emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: simple patch for `etags.el'


From: Paul Pogonyshev
Subject: Re: simple patch for `etags.el'
Date: Mon, 20 Sep 2004 23:25:47 -0200
User-agent: KMail/1.4.3

I wrote:

> This patch speeds building of tags table completion up several
> times.

Better yet, how about generalizing progress reporting
between modules?  For instance, it could look like this...


(defun make-progress-reporter (format-string
                               min-value max-value &optional current-value)
  "Return a list suitable for reporting operation progress with 
`progress-reporter-update'.

FORMAT-STRING must contain a single %-sequence, `%d', which will
be substituted with the progress percentage.  If, for some
reason, you need to change this string, simply create a new
reporter.

MIN-VALUE and MAX-VALUE designate starting (0% complete) and
final (100% complete) states of operation.  Optional
CURRENT-VALUE specifies the progress by the moment you call this
function.  You should omit it in most cases."
  (let ((reporter (list min-value
                        (if (fboundp 'current-time) (list 0 0 0) nil)
                        min-value
                        (/ (float (- max-value min-value)) 100.0)
                        format-string)))
    (progress-reporter-update reporter (or current-value min-value))
    reporter))

(defun progress-reporter-update (reporter value)
  "Report progress of an operation in the minibuffer.

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 tries to be very inexpensive.  If Emacs has
`current-time' function, then it will update minibuffer at most 5
times a second.  In any case, it never prints same percentage
more than once."
  (when (and (>= value (car reporter))
             ;; Update time is nil if we don't have `current-time'
             ;; function anyway.
             (or (null (cadr reporter))
                 (let ((update-time  (cadr reporter))
                       (current-time (current-time)))
                   (when (and (>= (nth 1 current-time) (nth 1 update-time))
                              (>= (nth 2 current-time) (nth 2 update-time))
                              (>= (nth 0 current-time) (nth 0 update-time)))
                     ;; Compute the time of next update as now + 1/5
                     ;; of a second.
                     (setcar (cddr current-time)
                             (if (< (nth 2 current-time) 800000)
                                 (+ (nth 2 current-time) 200000)
                               (when (= (setcar (cdr current-time)
                                                (1+ (nth 1 current-time)))
                                        0)
                                 (setcar current-time (1+ (car current-time))))
                               (- (nth 2 current-time) 800000)))
                     (setcar (cdr reporter) current-time)))))
    (let* ((min-value   (nth 2 reporter))
           (one-percent (nth 3 reporter))
           (percentage  (truncate (/ (- value min-value) one-percent))))
      (message (nth 4 reporter) percentage)
      ;; Make sure we return as soon as possible from this function
      ;; anything until progress percentage changes.
      (setcar reporter (+ min-value (* (1+ percentage) one-percent)))
      (when (integerp value)
        (setcar reporter (ceiling (car reporter)))))))
                     

--- etags.el    28 Aug 2004 13:30:31 -0200      1.181
+++ etags.el    20 Sep 2004 23:25:01 -0200      
@@ -1229,10 +1229,11 @@ where they were found."
 
 (defun etags-tags-completion-table ()
   (let ((table (make-vector 511 0))
-       (point-max (/ (float (point-max)) 100.0))
-       (msg-fmt (format 
-                 "Making tags completion table for %s...%%d%%%%"
-                 buffer-file-name)))
+       (progress-reporter
+        (make-progress-reporter
+         (format "Making tags completion table for %s...%%d%%%%"
+                 buffer-file-name)
+         (point-min) (point-max))))
     (save-excursion
       (goto-char (point-min))
       ;; This monster regexp matches an etags tag line.
@@ -1253,7 +1254,7 @@ where they were found."
                           (buffer-substring (match-beginning 5) (match-end 5))
                         ;; No explicit tag name.  Best guess.
                         (buffer-substring (match-beginning 3) (match-end 3)))
-                 (message msg-fmt (/ (point) point-max)))
+                 (progress-reporter-update progress-reporter (point)))
                table)))
     table))
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]