From b97e311ee42f7f9021b3c0e017636e258dd6d5d9 Mon Sep 17 00:00:00 2001 From: Spencer Baugh Date: Tue, 17 Oct 2023 09:09:55 -0400 Subject: [PATCH] Add a historical option to completions-sort This causes completion to sort based on history. This is useful for getting, e.g., most-recently-used order from C-x b. We only do historical sorting when there's a completion-specific history variable. Otherwise, candidate would be spuriously brought to the front if they just happened to match a string that the user has entered before. Also, the presence of a completion-specific history variable is a decent proxy for "does history matter for this command?"; if there isn't a specific history variable, sorting based on history would probably be undesirable. (Note also that the user can always choose to do historical sorting mid-completion by running minibuffer-complete-history.) * lisp/minibuffer.el (completions-sort): Document 'historical option. (minibuffer-completion-help): Support 'historical option. --- lisp/minibuffer.el | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index f53cd739e2f..782efff80f9 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -1313,14 +1313,26 @@ completion-cycle-threshold (defcustom completions-sort 'alphabetical "Sort candidates in the *Completions* buffer. -The value can be nil to disable sorting, `alphabetical' for -alphabetical sorting or a custom sorting function. The sorting -function takes and returns a list of completion candidate -strings." +Candidate completions in the *Completions* are sorted depending +on the value. + +If nil, sorting is disabled. +If `alphabetical', candidates are sorted alphabetically. +If `historical', candidates are first sorted alphabetically, then +candidates occurring in `minibuffer-history-variable' are moved +to the front based on the order they occur in the history. +If a function, the function is called to sort the candidates. +The sorting function takes and returns a list of completion +candidate strings. + +If the completion-specific metadata provides a +`display-sort-function', that is used instead and this value is +ignored." :type '(choice (const :tag "No sorting" nil) (const :tag "Alphabetical sorting" alphabetical) + (const :tag "Historical sorting" historical) (function :tag "Custom function")) - :version "29.1") + :version "30.1") (defcustom completions-group nil "Enable grouping of completion candidates in the *Completions* buffer. @@ -2510,6 +2522,15 @@ minibuffer-completion-help (pcase completions-sort ('nil completions) ('alphabetical (sort completions #'string-lessp)) + ('historical + (let ((alphabetized (sort completions #'string-lessp))) + ;; Only use history when it's specific to these completions. + (if (eq minibuffer-history-variable 'minibuffer-history) + alphabetized + (minibuffer--sort-by-position + (minibuffer--sort-preprocess-history + (substring string 0 base-size)) + alphabetized)))) (_ (funcall completions-sort completions))))) ;; After sorting, group the candidates using the -- 2.41.0