aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorChong Yidong2012-03-15 16:00:43 +0800
committerChong Yidong2012-03-15 16:00:43 +0800
commit3f2eafd1fbb706a8774a61b4b633d5f4e24b9cc1 (patch)
tree4858d050ba1396e494b9cc95907f8b1cbcadd174 /lisp
parent663b16775f660c1a10caa52e8964ee9e196af88d (diff)
downloademacs-3f2eafd1fbb706a8774a61b4b633d5f4e24b9cc1.tar.gz
emacs-3f2eafd1fbb706a8774a61b4b633d5f4e24b9cc1.zip
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. Fixes: debbugs:11019
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog8
-rw-r--r--lisp/comint.el49
-rw-r--r--lisp/emacs-lisp/ring.el33
3 files changed, 57 insertions, 33 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index f19d5e8ab79..427d7d87979 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,11 @@
12012-03-15 Chong Yidong <cyd@gnu.org>
2
3 * emacs-lisp/ring.el (ring-extend): New function.
4 (ring-insert+extend): Extend the ring correctly (Bug#11019).
5
6 * comint.el (comint-read-input-ring)
7 (comint-add-to-input-history): Grow comint-input-ring lazily.
8
12012-03-15 Stefan Monnier <monnier@iro.umontreal.ca> 92012-03-15 Stefan Monnier <monnier@iro.umontreal.ca>
2 10
3 * progmodes/perl-mode.el (perl-syntax-propertize-special-constructs): 11 * progmodes/perl-mode.el (perl-syntax-propertize-special-constructs):
diff --git a/lisp/comint.el b/lisp/comint.el
index 4c2229f2f83..9306bf8dbb2 100644
--- a/lisp/comint.el
+++ b/lisp/comint.el
@@ -922,15 +922,18 @@ See also `comint-input-ignoredups' and `comint-write-input-ring'."
922 (t 922 (t
923 (let* ((file comint-input-ring-file-name) 923 (let* ((file comint-input-ring-file-name)
924 (count 0) 924 (count 0)
925 (size comint-input-ring-size) 925 ;; Some users set HISTSIZE or `comint-input-ring-size'
926 (ring (make-ring size))) 926 ;; to huge numbers. Don't allocate a huge ring right
927 ;; away; there might not be that much history.
928 (ring-size (min 1500 comint-input-ring-size))
929 (ring (make-ring ring-size)))
927 (with-temp-buffer 930 (with-temp-buffer
928 (insert-file-contents file) 931 (insert-file-contents file)
929 ;; Save restriction in case file is already visited... 932 ;; Save restriction in case file is already visited...
930 ;; Watch for those date stamps in history files! 933 ;; Watch for those date stamps in history files!
931 (goto-char (point-max)) 934 (goto-char (point-max))
932 (let (start end history) 935 (let (start end history)
933 (while (and (< count size) 936 (while (and (< count comint-input-ring-size)
934 (re-search-backward comint-input-ring-separator 937 (re-search-backward comint-input-ring-separator
935 nil t) 938 nil t)
936 (setq end (match-beginning 0))) 939 (setq end (match-beginning 0)))
@@ -941,15 +944,18 @@ See also `comint-input-ignoredups' and `comint-write-input-ring'."
941 (point-min))) 944 (point-min)))
942 (setq history (buffer-substring start end)) 945 (setq history (buffer-substring start end))
943 (goto-char start) 946 (goto-char start)
944 (if (and (not (string-match comint-input-history-ignore 947 (when (and (not (string-match comint-input-history-ignore
945 history)) 948 history))
946 (or (null comint-input-ignoredups) 949 (or (null comint-input-ignoredups)
947 (ring-empty-p ring) 950 (ring-empty-p ring)
948 (not (string-equal (ring-ref ring 0) 951 (not (string-equal (ring-ref ring 0)
949 history)))) 952 history))))
950 (progn 953 (when (= count ring-size)
951 (ring-insert-at-beginning ring history) 954 (ring-extend ring (min (- comint-input-ring-size ring-size)
952 (setq count (1+ count))))))) 955 ring-size))
956 (setq ring-size (ring-size ring)))
957 (ring-insert-at-beginning ring history)
958 (setq count (1+ count))))))
953 (setq comint-input-ring ring 959 (setq comint-input-ring ring
954 comint-input-ring-index nil))))) 960 comint-input-ring-index nil)))))
955 961
@@ -1691,13 +1697,18 @@ Argument 0 is the command name."
1691(defun comint-add-to-input-history (cmd) 1697(defun comint-add-to-input-history (cmd)
1692 "Add CMD to the input history. 1698 "Add CMD to the input history.
1693Ignore duplicates if `comint-input-ignoredups' is non-nil." 1699Ignore duplicates if `comint-input-ignoredups' is non-nil."
1694 (if (and (funcall comint-input-filter cmd) 1700 (when (and (funcall comint-input-filter cmd)
1695 (or (null comint-input-ignoredups) 1701 (or (null comint-input-ignoredups)
1696 (not (ring-p comint-input-ring)) 1702 (not (ring-p comint-input-ring))
1697 (ring-empty-p comint-input-ring) 1703 (ring-empty-p comint-input-ring)
1698 (not (string-equal (ring-ref comint-input-ring 0) 1704 (not (string-equal (ring-ref comint-input-ring 0) cmd))))
1699 cmd)))) 1705 ;; If `comint-input-ring' is full, maybe grow it.
1700 (ring-insert comint-input-ring cmd))) 1706 (let ((size (ring-size comint-input-ring)))
1707 (and (= size (ring-length comint-input-ring))
1708 (< size comint-input-ring-size)
1709 (ring-extend comint-input-ring
1710 (min size (- comint-input-ring-size size)))))
1711 (ring-insert comint-input-ring cmd)))
1701 1712
1702(defun comint-send-input (&optional no-newline artificial) 1713(defun comint-send-input (&optional no-newline artificial)
1703 "Send input to process. 1714 "Send input to process.
diff --git a/lisp/emacs-lisp/ring.el b/lisp/emacs-lisp/ring.el
index 4b07de523c3..cee6a43df86 100644
--- a/lisp/emacs-lisp/ring.el
+++ b/lisp/emacs-lisp/ring.el
@@ -185,26 +185,31 @@ Raise error if ITEM is not in the RING."
185 (unless curr-index (error "Item is not in the ring: `%s'" item)) 185 (unless curr-index (error "Item is not in the ring: `%s'" item))
186 (ring-ref ring (ring-minus1 curr-index (ring-length ring))))) 186 (ring-ref ring (ring-minus1 curr-index (ring-length ring)))))
187 187
188(defun ring-extend (ring x)
189 "Increase the size of RING by X."
190 (when (and (integerp x) (> x 0))
191 (let* ((hd (car ring))
192 (length (ring-length ring))
193 (size (ring-size ring))
194 (old-vec (cddr ring))
195 (new-vec (make-vector (+ size x) nil)))
196 (setcdr ring (cons length new-vec))
197 ;; If the ring is wrapped, the existing elements must be written
198 ;; out in the right order.
199 (dotimes (j length)
200 (aset new-vec j (aref old-vec (mod (+ hd j) size))))
201 (setcar ring 0))))
202
188(defun ring-insert+extend (ring item &optional grow-p) 203(defun ring-insert+extend (ring item &optional grow-p)
189 "Like `ring-insert', but if GROW-P is non-nil, then enlarge ring. 204 "Like `ring-insert', but if GROW-P is non-nil, then enlarge ring.
190Insert onto ring RING the item ITEM, as the newest (last) item. 205Insert onto ring RING the item ITEM, as the newest (last) item.
191If the ring is full, behavior depends on GROW-P: 206If the ring is full, behavior depends on GROW-P:
192 If GROW-P is non-nil, enlarge the ring to accommodate the new item. 207 If GROW-P is non-nil, enlarge the ring to accommodate the new item.
193 If GROW-P is nil, dump the oldest item to make room for the new." 208 If GROW-P is nil, dump the oldest item to make room for the new."
194 (let* ((vec (cddr ring)) 209 (and grow-p
195 (veclen (length vec)) 210 (= (ring-length ring) (ring-size ring))
196 (hd (car ring)) 211 (ring-extend ring 1))
197 (ringlen (ring-length ring))) 212 (ring-insert ring item))
198 (prog1
199 (cond ((and grow-p (= ringlen veclen)) ; Full ring. Enlarge it.
200 (setq veclen (1+ veclen))
201 (setcdr ring (cons (setq ringlen (1+ ringlen))
202 (setq vec (vconcat vec (vector item)))))
203 (setcar ring hd))
204 (t (aset vec (mod (+ hd ringlen) veclen) item)))
205 (if (= ringlen veclen)
206 (setcar ring (ring-plus1 hd veclen))
207 (setcar (cdr ring) (1+ ringlen))))))
208 213
209(defun ring-remove+insert+extend (ring item &optional grow-p) 214(defun ring-remove+insert+extend (ring item &optional grow-p)
210 "`ring-remove' ITEM from RING, then `ring-insert+extend' it. 215 "`ring-remove' ITEM from RING, then `ring-insert+extend' it.