From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Paul Pogonyshev Newsgroups: gmane.emacs.devel Subject: Re: simple patch for `etags.el' Date: Wed, 22 Sep 2004 22:30:55 -0200 Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Message-ID: <200409222230.55996.pogonyshev@gmx.net> References: <200409201650.26315.pogonyshev@gmx.net> <200409202325.47369.pogonyshev@gmx.net> NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Trace: sea.gmane.org 1095881981 18461 80.91.229.6 (22 Sep 2004 19:39:41 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Wed, 22 Sep 2004 19:39:41 +0000 (UTC) Cc: emacs-devel@gnu.org, "Kim F. Storm" Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Sep 22 21:39:26 2004 Return-path: Original-Received: from lists.gnu.org ([199.232.76.165]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1CACxZ-0004fY-00 for ; Wed, 22 Sep 2004 21:39:25 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1CAD3Y-000627-Q8 for ged-emacs-devel@m.gmane.org; Wed, 22 Sep 2004 15:45:36 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.33) id 1CAD3Q-00060p-CG for emacs-devel@gnu.org; Wed, 22 Sep 2004 15:45:28 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.33) id 1CAD3P-00060J-JM for emacs-devel@gnu.org; Wed, 22 Sep 2004 15:45:28 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1CAD3P-0005zv-Hv for emacs-devel@gnu.org; Wed, 22 Sep 2004 15:45:27 -0400 Original-Received: from [213.165.64.20] (helo=mail.gmx.net) by monty-python.gnu.org with smtp (Exim 4.34) id 1CACwq-0003dv-7K for emacs-devel@gnu.org; Wed, 22 Sep 2004 15:38:40 -0400 Original-Received: (qmail 4387 invoked by uid 65534); 22 Sep 2004 19:31:54 -0000 Original-Received: from unknown (EHLO localhost.localdomain) (195.50.12.120) by mail.gmx.net (mp002) with SMTP; 22 Sep 2004 21:31:54 +0200 X-Authenticated: #16844820 Original-To: rms@gnu.org User-Agent: KMail/1.4.3 In-Reply-To: X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:27461 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:27461 > These functions would go in subr.el. Here is the patch. I rewrote it almost from scratch. * Very fast. * Used time handling as suggested by Kim F. Storm (i.e. cheap time handling). I also used `float-time' instead of `current-time' to simplify code. * Added MIN-CHANGE and MIN-TIME as suggested by RMS. * New functions `progress-reporter-force-update' and `progress-reporter-done'. Now you don't need to duplicate strings: all needed messages can be printed with progress reporter. * Reporter structure is documented (in comments). I'd like to move progress reporting in `cc-cmds.el' to new functions, but it is very complicated. Maybe someone who is familiar with the code can do it. Also, is it common in English not to put a space after ellipsis? I.e. in Russian I'd write ``Parsing tar file... done'' instead of ``Parsing tar file...done''. 2004-09-22 Paul Pogonyshev =09* tar-mode.el (tar-summarize-buffer): Use progress reporter. =09* progmodes/etags.el (etags-tags-completion-table): Use progress =09reporter. =09(etags-tags-apropos): Likewise. =09* subr.el (make-progress-reporter, progress-reporter-update) =09(progress-reporter-force-update, progress-reporter-do-update) =09(progress-reporter-done): New functions. Unfortunately, I'm experiencing severe problems with my internet connections over certain ports. In particular, I cannot use CVS lately. So here are patches to the three files as generated by `C-x v =3D'. I hope it's not much of a problem to combine them. --- subr.el=0908 Sep 2004 10:24:29 -0200=091.407 +++ subr.el=0922 Sep 2004 21:52:47 -0200=09 @@ -2644,5 +2644,134 @@ The properties used on SYMBOL are `compo (put symbol 'abortfunc (or abortfunc 'kill-buffer)) (put symbol 'hookvar (or hookvar 'mail-send-hook))) =20 +=20 +;; Standardized progress reporting + +;; Progress reporter has the following structure: +;; +;;=09(NEXT-UPDATE-VALUE . [NEXT-UPDATE-TIME +;;=09=09=09 MIN-VALUE +;;=09=09=09 MAX-VALUE +;;=09=09=09 MESSAGE +;;=09=09=09 MIN-CHANGE +;;=09=09=09 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 +=09=09=09=09 &optional current-value +=09=09=09=09 min-change min-time) + "Return an object suitable for reporting operation progress with `prog= ress-reporter-update'. + +MESSAGE is shown in the minibuffer. 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 minibuffer updates (default is 0.2 seconds.) If +`current-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 +=09 (cons min-value ;; Force a call to `message' now +=09 (vector (if (and (fboundp 'float-time) +=09=09=09=09(>=3D min-time 0.02)) +=09=09=09 (float-time) nil) +=09=09 min-value +=09=09 max-value +=09=09 message +=09=09 (if min-change (max (min min-change 50) 1) 1) +=09=09 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 minibuffer. +However, if the change since last minibuffer 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 (>=3D value (car reporter)) + (progress-reporter-do-update reporter value))) + +(defun progress-reporter-force-update (reporter value &optional new-mess= age) + "Report progress of an operation in the minibuffer 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)) +=09 (min-value (aref parameters 1)) +=09 (max-value (aref parameters 2)) +=09 (one-percent (/ (- max-value min-value) 100.0)) +=09 (percentage (truncate (/ (- value min-value) one-percent))) +=09 (update-time (aref parameters 0)) +=09 (current-time (float-time)) +=09 (enough-time-passed +=09 ;; See if enough time has passed since the last update. +=09 (or (not update-time) +=09 (when (>=3D current-time update-time) +=09=09;; Calculate time for the next update +=09=09(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 minibuffer + ;; updates closer to MIN-TIME. + (setcar reporter +=09 (min (+ min-value (* (+ percentage +=09=09=09=09 (if enough-time-passed +=09=09=09=09=09(aref parameters 4) ;; MIN-CHANGE +=09=09=09=09 1)) +=09=09=09=09 one-percent)) +=09=09 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) +=09 (message "%s%d%%" (aref parameters 3) percentage) +=09(message "%s" (aref parameters 3)))))) + +(defun progress-reporter-done (reporter) + "Print reporter's message followed by word \"done\" in minibuffer." + (message "%sdone" (aref (cdr reporter) 3))) + ;;; arch-tag: f7e0e6e5-70aa-4897-ae72-7a3511ec40bc ;;; subr.el ends here --- etags.el=0928 Aug 2004 13:30:31 -0200=091.181 +++ etags.el=0922 Sep 2004 21:30:55 -0200=09 @@ -1229,10 +1229,10 @@ where they were found." =20 (defun etags-tags-completion-table () (let ((table (make-vector 511 0)) -=09(point-max (/ (float (point-max)) 100.0)) -=09(msg-fmt (format=20 -=09=09 "Making tags completion table for %s...%%d%%%%" -=09=09 buffer-file-name))) +=09(progress-reporter +=09 (make-progress-reporter +=09 (format "Making tags completion table for %s..." buffer-file-name) +=09 (point-min) (point-max)))) (save-excursion (goto-char (point-min)) ;; This monster regexp matches an etags tag line. @@ -1253,7 +1253,7 @@ where they were found." =09=09=09 (buffer-substring (match-beginning 5) (match-end 5)) =09=09=09 ;; No explicit tag name. Best guess. =09=09=09 (buffer-substring (match-beginning 3) (match-end 3))) -=09=09 (message msg-fmt (/ (point) point-max))) +=09=09 (progress-reporter-update progress-reporter (point))) =09=09table))) table)) =20 @@ -1433,11 +1433,12 @@ where they were found." (tags-with-face 'highlight (princ buffer-file-name)) (princ "':\n\n")) (goto-char (point-min)) - (let ((point-max (/ (float (point-max)) 100.0))) + (let ((progress-reporter (make-progress-reporter +=09=09=09 (format "Making tags apropos buffer for `%s'..." +=09=09=09=09 string) +=09=09=09 (point-min) (point-max)))) (while (re-search-forward string nil t) - (message "Making tags apropos buffer for `%s'...%d%%" -=09 string -=09 (/ (point) point-max)) + (progress-reporter-update progress-reporter (point)) (beginning-of-line) =20 (let* ( ;; Get the local value in the tags table --- tar-mode.el=0909 Feb 2004 03:47:32 -0200=091.95 +++ tar-mode.el=0922 Sep 2004 21:42:29 -0200=09 @@ -404,11 +404,10 @@ Place a dired-like listing on the front; then narrow to it, so that only that listing is visible (and the real data of the buffer is hidden)." (set-buffer-multibyte nil) - (message "Parsing tar file...") (let* ((result '()) =09 (pos (point-min)) -=09 (bs (max 1 (- (buffer-size) 1024))) ; always 2+ empty blocks at end. -=09 (bs100 (max 1 (/ bs 100))) +=09 (progress-reporter "Parsing tar file..." +=09=09=09 (point-min) (max 1 (- (buffer-size) 1024))) =09 tokens) (while (and (<=3D (+ pos 512) (point-max)) =09=09(not (eq 'empty-tar-block @@ -416,10 +415,7 @@ is visible (and the real data of the buf =09=09=09 (tar-header-block-tokenize =09=09=09=09(buffer-substring pos (+ pos 512))))))) (setq pos (+ pos 512)) - (message "Parsing tar file...%d%%" -=09 ;(/ (* pos 100) bs) ; this gets round-off lossage -=09 (/ pos bs100) ; this doesn't -=09 ) + (progress-reporter-update progress-reporter pos) (if (eq (tar-header-link-type tokens) 20) =09 ;; Foo. There's an extra empty block after these. =09 (setq pos (+ pos 512))) @@ -446,7 +442,7 @@ is visible (and the real data of the buf ;; A tar file should end with a block or two of nulls, ;; but let's not get a fatal error if it doesn't. (if (eq tokens 'empty-tar-block) -=09(message "Parsing tar file...done") +=09(progress-reporter-done progress-reporter) (message "Warning: premature EOF parsing tar file"))) (save-excursion (goto-char (point-min))