From 6c6459a73b79fbf6303a41ebc24948b8f207a573 Mon Sep 17 00:00:00 2001 From: Robin Joy Date: Fri, 24 May 2024 14:26:39 +0200 Subject: [PATCH] Erase existing duplicates in eshell-history-ring Erase all existing duplicates instead of just the last duplicate entry when 'eshell-hist-ignoredups' is set to 'erase'. Multiple duplicates can exist in case 'eshell-hist-ignoredups' was set to something else than 'erase' in the past or if the history file contains duplicates (bug#71107). * lisp/eshell/em-hist.el (eshell-add-input-to-history): Remove all duplicates from history ring. * test/lisp/eshell/em-hist-tests.el (em-hist-test/add-to-history/erase-existing-dups): New test. (cherry picked from commit 984fb346fdf0d5ec9eaea6126aad0bea8823b8a3) --- lisp/eshell/em-hist.el | 8 +++----- test/lisp/eshell/em-hist-tests.el | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/lisp/eshell/em-hist.el b/lisp/eshell/em-hist.el index 21029eae1bc..b171a2850ff 100644 --- a/lisp/eshell/em-hist.el +++ b/lisp/eshell/em-hist.el @@ -398,11 +398,9 @@ 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 occurrence 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'? + (while-let ((old-index (ring-member eshell-history-ring input))) + ;; Remove the old occurrences of this input so we can + ;; add it to the end. (ring-remove eshell-history-ring old-index)) t) (_ ; Add if not already the latest entry diff --git a/test/lisp/eshell/em-hist-tests.el b/test/lisp/eshell/em-hist-tests.el index a4e1e01b124..40e6f90478d 100644 --- a/test/lisp/eshell/em-hist-tests.el +++ b/test/lisp/eshell/em-hist-tests.el @@ -163,6 +163,23 @@ elements against that; if t (the default), check against EXPECTED." (should (equal (ring-elements eshell-history-ring) '("echo hi" "echo bye")))))) +(ert-deftest em-hist-test/add-to-history/erase-existing-dups () + "Test adding to history, erasing any old dups after switching to 'erase." + (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") + (eshell-insert-command "echo bye") + (setq eshell-hist-ignoredups 'erase) + (eshell-insert-command "echo hi") + (should (equal (ring-elements eshell-history-ring) + '("echo hi" "echo bye" "echo bye" "echo bye"))) + (eshell-insert-command "echo bye") + (should (equal (ring-elements eshell-history-ring) + '("echo bye" "echo hi")))))) + (provide 'em-hist-test) ;;; em-hist-tests.el ends here -- 2.39.5