branch: externals/corfu commit ed0ba822c90b8c345877bd58fc4189b2773fd328 Author: Daniel Mendler <m...@daniel-mendler.de> Commit: Daniel Mendler <m...@daniel-mendler.de>
Use exponential decay --- extensions/corfu-history.el | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/extensions/corfu-history.el b/extensions/corfu-history.el index 1fbf3b4398..c1d505960a 100644 --- a/extensions/corfu-history.el +++ b/extensions/corfu-history.el @@ -50,11 +50,18 @@ or the property `history-length' of `corfu-history'.") "Hash table of Corfu candidates.") (defcustom corfu-history-duplicate 10 - "Number of history positions gained by duplicate history elements. + "Maximal number of history positions gained by duplicate history elements. The more often a duplicate element occurs in the history, the earlier it -appears in the completion list. Note that duplicates occur only if +appears in the completion list. The position gain decays exponentially +with `corfu-history-decay'. Note that duplicates occur only if `history-delete-duplicates' is disabled." - :type 'natum + :type 'number + :group 'corfu) + +(defcustom corfu-history-decay 0.005 + "Exponential decay for the position gain of duplicate elements. +See also `corfu-history-duplicate'." + :type 'float :group 'corfu) (defun corfu-history--sort-predicate (x y) @@ -67,11 +74,14 @@ appears in the completion list. Note that duplicates occur only if "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 idx from 0 do - (puthash elem (if-let ((n (gethash elem ht))) - (- n corfu-history-duplicate) - (if (= idx 0) (/ most-negative-fixnum 2) idx)) - ht)) + (cl-loop for elem in corfu-history for idx from 0 + for w = (if-let ((w (gethash elem ht))) + ;; Reduce duplicate weight with exponential decay. + (- w (round (* corfu-history-duplicate + (exp (* -1.0 corfu-history-decay idx))))) + ;; Never outrank the most recent element. + (if (= idx 0) (/ most-negative-fixnum 2) idx)) + do (puthash elem w ht)) (setq corfu-history--hash ht))) (cl-loop for ht = corfu-history--hash for max = most-positive-fixnum for cand on cands do