branch: externals/corfu commit 3a8a03110b3a3efa5357eb5ab2d8f3ff8e6a4547 Author: Daniel Mendler <m...@daniel-mendler.de> Commit: Daniel Mendler <m...@daniel-mendler.de>
Add corfu-history-duplicate --- CHANGELOG.org | 5 +++++ extensions/corfu-history.el | 24 +++++++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.org b/CHANGELOG.org index 17d1b0ac5e..a88528b7f0 100644 --- a/CHANGELOG.org +++ b/CHANGELOG.org @@ -2,6 +2,11 @@ #+author: Daniel Mendler #+language: en +* Development + +- ~corfu-history-duplicate~: Prioritize duplicate history elements when sorting by + history via ~corfu-history-mode~. + * Version 2.0 (2025-03-28) - ~corfu-quick~: Ensure that popup does not move. diff --git a/extensions/corfu-history.el b/extensions/corfu-history.el index d0821bc2d0..a93bc14754 100644 --- a/extensions/corfu-history.el +++ b/extensions/corfu-history.el @@ -49,6 +49,16 @@ or the property `history-length' of `corfu-history'.") (defvar corfu-history--hash nil "Hash table of Corfu candidates.") +(defcustom corfu-history-duplicate 1.0 + "Weight of duplicate elements, multiplied with `history-length'. +Duplicate elements in the history are prioritized such that they appear +earlier in the completion list. The value should be between 0.0 and +1.0. For 0 only the recency of history elements matters. If the value +is 1.0, frequency is more relevant than recency. Note that +`history-delete-duplicates' must be disabled for duplicates to appear." + :type 'float + :group 'corfu) + (defun corfu-history--sort-predicate (x y) "Sorting predicate which compares X and Y." (or (< (cdr x) (cdr y)) @@ -58,13 +68,13 @@ or the property `history-length' of `corfu-history'.") (defun corfu-history--sort (cands) "Sort CANDS by history." (unless corfu-history--hash - (let ((ht (make-hash-table :test #'equal :size (length corfu-history)))) - (cl-loop for elem in corfu-history for index from 0 do - (unless (gethash elem ht) (puthash elem index ht))) - (setq corfu-history--hash ht))) - (cl-loop for ht = corfu-history--hash for max = most-positive-fixnum - for cand on cands do - (setcar cand (cons (car cand) (gethash (car cand) ht max)))) + (setq corfu-history--hash (make-hash-table :test #'equal :size (length corfu-history))) + (cl-loop for weight = (round (* history-length corfu-history-duplicate)) + for elem in corfu-history for idx from 0 + for dup = (gethash elem corfu-history--hash) do + (puthash elem (if dup (- dup weight) idx) corfu-history--hash))) + (cl-loop for max = most-positive-fixnum for cand on cands do + (setcar cand (cons (car cand) (gethash (car cand) corfu-history--hash max)))) (setq cands (sort cands #'corfu-history--sort-predicate)) (cl-loop for cand on cands do (setcar cand (caar cand))) cands)