emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] /srv/bzr/emacs/trunk r107606: Fix ring extension code in r


From: Chong Yidong
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r107606: Fix ring extension code in ring.el, and tweak comint-input-ring handling.
Date: Thu, 15 Mar 2012 16:00:43 +0800
User-agent: Bazaar (2.3.1)

------------------------------------------------------------
revno: 107606
fixes bug(s): http://debbugs.gnu.org/11019
committer: Chong Yidong <address@hidden>
branch nick: trunk
timestamp: Thu 2012-03-15 16:00:43 +0800
message:
  Fix ring extension code in ring.el, and tweak comint-input-ring handling.
  
  * lisp/emacs-lisp/ring.el (ring-extend): New function.
  (ring-insert+extend): Extend the ring correctly.
  
  * lisp/comint.el (comint-read-input-ring)
  (comint-add-to-input-history): Grow comint-input-ring lazily.
modified:
  lisp/ChangeLog
  lisp/comint.el
  lisp/emacs-lisp/ring.el
=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2012-03-15 03:09:26 +0000
+++ b/lisp/ChangeLog    2012-03-15 08:00:43 +0000
@@ -1,3 +1,11 @@
+2012-03-15  Chong Yidong  <address@hidden>
+
+       * emacs-lisp/ring.el (ring-extend): New function.
+       (ring-insert+extend): Extend the ring correctly (Bug#11019).
+
+       * comint.el (comint-read-input-ring)
+       (comint-add-to-input-history): Grow comint-input-ring lazily.
+
 2012-03-15  Stefan Monnier  <address@hidden>
 
        * progmodes/perl-mode.el (perl-syntax-propertize-special-constructs):

=== modified file 'lisp/comint.el'
--- a/lisp/comint.el    2012-02-19 13:59:42 +0000
+++ b/lisp/comint.el    2012-03-15 08:00:43 +0000
@@ -922,15 +922,18 @@
        (t
         (let* ((file comint-input-ring-file-name)
                (count 0)
-               (size comint-input-ring-size)
-               (ring (make-ring size)))
+               ;; Some users set HISTSIZE or `comint-input-ring-size'
+               ;; to huge numbers.  Don't allocate a huge ring right
+               ;; away; there might not be that much history.
+               (ring-size (min 1500 comint-input-ring-size))
+               (ring (make-ring ring-size)))
           (with-temp-buffer
              (insert-file-contents file)
              ;; Save restriction in case file is already visited...
              ;; Watch for those date stamps in history files!
              (goto-char (point-max))
              (let (start end history)
-               (while (and (< count size)
+               (while (and (< count comint-input-ring-size)
                            (re-search-backward comint-input-ring-separator
                                                nil t)
                            (setq end (match-beginning 0)))
@@ -941,15 +944,18 @@
                          (point-min)))
                  (setq history (buffer-substring start end))
                  (goto-char start)
-                 (if (and (not (string-match comint-input-history-ignore
-                                             history))
-                          (or (null comint-input-ignoredups)
-                              (ring-empty-p ring)
-                              (not (string-equal (ring-ref ring 0)
-                                                 history))))
-                     (progn
-                       (ring-insert-at-beginning ring history)
-                       (setq count (1+ count)))))))
+                 (when (and (not (string-match comint-input-history-ignore
+                                              history))
+                           (or (null comint-input-ignoredups)
+                               (ring-empty-p ring)
+                               (not (string-equal (ring-ref ring 0)
+                                                  history))))
+                  (when (= count ring-size)
+                    (ring-extend ring (min (- comint-input-ring-size ring-size)
+                                           ring-size))
+                    (setq ring-size (ring-size ring)))
+                  (ring-insert-at-beginning ring history)
+                  (setq count (1+ count))))))
           (setq comint-input-ring ring
                 comint-input-ring-index nil)))))
 
@@ -1691,13 +1697,18 @@
 (defun comint-add-to-input-history (cmd)
   "Add CMD to the input history.
 Ignore duplicates if `comint-input-ignoredups' is non-nil."
-  (if (and (funcall comint-input-filter cmd)
-          (or (null comint-input-ignoredups)
-              (not (ring-p comint-input-ring))
-              (ring-empty-p comint-input-ring)
-              (not (string-equal (ring-ref comint-input-ring 0)
-                                 cmd))))
-      (ring-insert comint-input-ring cmd)))
+  (when (and (funcall comint-input-filter cmd)
+            (or (null comint-input-ignoredups)
+                (not (ring-p comint-input-ring))
+                (ring-empty-p comint-input-ring)
+                (not (string-equal (ring-ref comint-input-ring 0) cmd))))
+    ;; If `comint-input-ring' is full, maybe grow it.
+    (let ((size (ring-size comint-input-ring)))
+      (and (= size (ring-length comint-input-ring))
+          (< size comint-input-ring-size)
+          (ring-extend comint-input-ring
+                       (min size (- comint-input-ring-size size)))))
+    (ring-insert comint-input-ring cmd)))
 
 (defun comint-send-input (&optional no-newline artificial)
   "Send input to process.

=== modified file 'lisp/emacs-lisp/ring.el'
--- a/lisp/emacs-lisp/ring.el   2012-01-19 07:21:25 +0000
+++ b/lisp/emacs-lisp/ring.el   2012-03-15 08:00:43 +0000
@@ -185,26 +185,31 @@
     (unless curr-index (error "Item is not in the ring: `%s'" item))
     (ring-ref ring (ring-minus1 curr-index (ring-length ring)))))
 
+(defun ring-extend (ring x)
+  "Increase the size of RING by X."
+  (when (and (integerp x) (> x 0))
+    (let* ((hd       (car ring))
+          (length   (ring-length ring))
+          (size     (ring-size ring))
+          (old-vec  (cddr ring))
+          (new-vec  (make-vector (+ size x) nil)))
+      (setcdr ring (cons length new-vec))
+      ;; If the ring is wrapped, the existing elements must be written
+      ;; out in the right order.
+      (dotimes (j length)
+       (aset new-vec j (aref old-vec (mod (+ hd j) size))))
+      (setcar ring 0))))
+
 (defun ring-insert+extend (ring item &optional grow-p)
   "Like `ring-insert', but if GROW-P is non-nil, then enlarge ring.
 Insert onto ring RING the item ITEM, as the newest (last) item.
 If the ring is full, behavior depends on GROW-P:
   If GROW-P is non-nil, enlarge the ring to accommodate the new item.
   If GROW-P is nil, dump the oldest item to make room for the new."
-  (let* ((vec (cddr ring))
-        (veclen (length vec))
-        (hd (car ring))
-        (ringlen (ring-length ring)))
-    (prog1
-        (cond ((and grow-p (= ringlen veclen)) ; Full ring.  Enlarge it.
-               (setq veclen (1+ veclen))
-               (setcdr ring (cons (setq ringlen (1+ ringlen))
-                                  (setq vec (vconcat vec (vector item)))))
-               (setcar ring hd))
-              (t (aset vec (mod (+ hd ringlen) veclen) item)))
-      (if (= ringlen veclen)
-          (setcar ring (ring-plus1 hd veclen))
-        (setcar (cdr ring) (1+ ringlen))))))
+  (and grow-p
+       (= (ring-length ring) (ring-size ring))
+       (ring-extend ring 1))
+  (ring-insert ring item))
 
 (defun ring-remove+insert+extend (ring item &optional grow-p)
   "`ring-remove' ITEM from RING, then `ring-insert+extend' it.


reply via email to

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