Fix behavior of 'eshell-hist-ignoredups' when set to 'erase'

* lisp/eshell/em-hist.el (eshell-add-input-to-history): Refactor to
use 'pcase' and correct the logic for the 'erase' case.

* test/lisp/eshell/em-hist-tests.el: Require our test helpers.
(eshell-write-readonly-history): Rename to...
(em-hist-test/write-readonly-history): ... this.
(em-hist-test/add-to-history/allow-dups)
(em-hist-test/add-to-history/no-consecutive-dups)
(em-hist-test/add-to-history/erase-dups): New tests (bug#63360).
This commit is contained in:
Jim Porter 2023-08-23 18:27:45 -07:00
parent 1986484d4d
commit 7b0f24ab1f
2 changed files with 55 additions and 15 deletions

View file

@ -381,20 +381,19 @@ Input is entered into the input history ring, if the value of
variable `eshell-input-filter' returns non-nil when called on the
input."
(when (and (funcall eshell-input-filter input)
(if (eq eshell-hist-ignoredups 'erase)
;; Remove any old occurrences of the input, and put
;; the new one at the end.
(unless (ring-empty-p eshell-history-ring)
(ring-remove eshell-history-ring
(ring-member eshell-history-ring input))
t)
;; Always add...
(or (null eshell-hist-ignoredups)
;; ... or add if it's not already present at the
;; end.
(not (ring-p eshell-history-ring))
(ring-empty-p eshell-history-ring)
(not (string-equal (eshell-get-history 0) input)))))
(pcase eshell-hist-ignoredups
('nil t) ; Always add to history
('erase ; Add, removing any old occurrences
(when-let ((old-index (ring-member eshell-history-ring input)))
;; Remove the old occurence of this input so we can
;; add it to the end. FIXME: Should we try to
;; remove multiple old occurrences, e.g. if the user
;; recently changed to using `erase'?
(ring-remove eshell-history-ring old-index))
t)
(_ ; Add if not already the latest entry
(or (ring-empty-p eshell-history-ring)
(not (string-equal (eshell-get-history 0) input))))))
(eshell-put-history input))
(setq eshell-save-history-index eshell-history-index)
(setq eshell-history-index nil))

View file

@ -22,8 +22,16 @@
(require 'ert)
(require 'ert-x)
(require 'em-hist)
(require 'eshell)
(ert-deftest eshell-write-readonly-history ()
(require 'eshell-tests-helpers
(expand-file-name "eshell-tests-helpers"
(file-name-directory (or load-file-name
default-directory))))
;;; Tests:
(ert-deftest em-hist-test/write-readonly-history ()
"Test that having read-only strings in history is okay."
(ert-with-temp-file histfile
(let ((eshell-history-ring (make-ring 2)))
@ -33,6 +41,39 @@
(propertize "echo bar" 'read-only t))
(eshell-write-history histfile))))
(ert-deftest em-hist-test/add-to-history/allow-dups ()
"Test adding to history, allowing dups."
(let ((eshell-hist-ignoredups nil))
(with-temp-eshell
(eshell-insert-command "echo hi")
(eshell-insert-command "echo bye")
(eshell-insert-command "echo bye")
(eshell-insert-command "echo hi")
(should (equal (ring-elements eshell-history-ring)
'("echo hi" "echo bye" "echo bye" "echo hi"))))))
(ert-deftest em-hist-test/add-to-history/no-consecutive-dups ()
"Test adding to history, ignoring consecutive dups."
(let ((eshell-hist-ignoredups t))
(with-temp-eshell
(eshell-insert-command "echo hi")
(eshell-insert-command "echo bye")
(eshell-insert-command "echo bye")
(eshell-insert-command "echo hi")
(should (equal (ring-elements eshell-history-ring)
'("echo hi" "echo bye" "echo hi"))))))
(ert-deftest em-hist-test/add-to-history/erase-dups ()
"Test adding to history, erasing any old dups."
(let ((eshell-hist-ignoredups 'erase))
(with-temp-eshell
(eshell-insert-command "echo hi")
(eshell-insert-command "echo bye")
(eshell-insert-command "echo bye")
(eshell-insert-command "echo hi")
(should (equal (ring-elements eshell-history-ring)
'("echo hi" "echo bye"))))))
(provide 'em-hist-test)
;;; em-hist-tests.el ends here