diff options
| author | Chong Yidong | 2012-03-15 16:00:43 +0800 |
|---|---|---|
| committer | Chong Yidong | 2012-03-15 16:00:43 +0800 |
| commit | 3f2eafd1fbb706a8774a61b4b633d5f4e24b9cc1 (patch) | |
| tree | 4858d050ba1396e494b9cc95907f8b1cbcadd174 /lisp | |
| parent | 663b16775f660c1a10caa52e8964ee9e196af88d (diff) | |
| download | emacs-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/ChangeLog | 8 | ||||
| -rw-r--r-- | lisp/comint.el | 49 | ||||
| -rw-r--r-- | lisp/emacs-lisp/ring.el | 33 |
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 @@ | |||
| 1 | 2012-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 | |||
| 1 | 2012-03-15 Stefan Monnier <monnier@iro.umontreal.ca> | 9 | 2012-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. |
| 1693 | Ignore duplicates if `comint-input-ignoredups' is non-nil." | 1699 | Ignore 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. |
| 190 | Insert onto ring RING the item ITEM, as the newest (last) item. | 205 | Insert onto ring RING the item ITEM, as the newest (last) item. |
| 191 | If the ring is full, behavior depends on GROW-P: | 206 | If 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. |