diff options
| author | Spencer Baugh | 2023-10-17 09:09:55 -0400 |
|---|---|---|
| committer | Juri Linkov | 2023-12-03 19:24:16 +0200 |
| commit | e33f560badac3fd6bd23a6ffc1244afee7dec5f3 (patch) | |
| tree | ac1db1e51c8885d345a52dc48acd1be27785bcb2 | |
| parent | 3c093148958d56e0ed8e12a8e00ced1ef052259a (diff) | |
| download | emacs-e33f560badac3fd6bd23a6ffc1244afee7dec5f3.tar.gz emacs-e33f560badac3fd6bd23a6ffc1244afee7dec5f3.zip | |
Add historical option to completions-sort
Support sorting candidates in *Completions* by the order they show up
in the minibuffer history.
Also add minibuffer-sort-alphabetically and
minibuffer-sort-by-history, which are usable for both completions-sort
and display-sort-function.
* lisp/minibuffer.el (completions-sort): Document 'historical option.
(minibuffer-completion-help): Support 'historical option.
(minibuffer-sort-alphabetically)
(minibuffer-completion-base, minibuffer-sort-by-history): Add.
* etc/NEWS: Announce it.
| -rw-r--r-- | etc/NEWS | 5 | ||||
| -rw-r--r-- | lisp/minibuffer.el | 65 |
2 files changed, 64 insertions, 6 deletions
| @@ -637,6 +637,11 @@ new command 'minibuffer-choose-completion-or-exit' (bound by | |||
| 637 | contents instead. The deselection behavior can be controlled with the | 637 | contents instead. The deselection behavior can be controlled with the |
| 638 | new user option 'completion-auto-deselect'. | 638 | new user option 'completion-auto-deselect'. |
| 639 | 639 | ||
| 640 | *** New value 'historical' for user option 'completions-sort' | ||
| 641 | When 'completions-sort' is set to 'historical', completion candidates | ||
| 642 | will be sorted by their chronological order in the minibuffer history, | ||
| 643 | with more recent candidates appearing first. | ||
| 644 | |||
| 640 | ** Pcomplete | 645 | ** Pcomplete |
| 641 | 646 | ||
| 642 | --- | 647 | --- |
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 382d4458e26..03b64198bcf 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el | |||
| @@ -1314,14 +1314,27 @@ completion candidates than this number." | |||
| 1314 | (defcustom completions-sort 'alphabetical | 1314 | (defcustom completions-sort 'alphabetical |
| 1315 | "Sort candidates in the *Completions* buffer. | 1315 | "Sort candidates in the *Completions* buffer. |
| 1316 | 1316 | ||
| 1317 | The value can be nil to disable sorting, `alphabetical' for | 1317 | Completion candidates in the *Completions* buffer are sorted |
| 1318 | alphabetical sorting or a custom sorting function. The sorting | 1318 | depending on the value. |
| 1319 | function takes and returns a list of completion candidate | 1319 | |
| 1320 | strings." | 1320 | If it's nil, sorting is disabled. |
| 1321 | If it's the symbol `alphabetical', candidates are sorted by | ||
| 1322 | `minibuffer-sort-alphabetically'. | ||
| 1323 | If it's the symbol `historical', candidates are sorted by | ||
| 1324 | `minibuffer-sort-by-history'. | ||
| 1325 | If it's a function, the function is called to sort the candidates. | ||
| 1326 | The sorting function takes a list of completion candidate | ||
| 1327 | strings, which it may modify; it should return a sorted list, | ||
| 1328 | which may be the same. | ||
| 1329 | |||
| 1330 | If the completion-specific metadata provides a | ||
| 1331 | `display-sort-function', that function overrides the value of | ||
| 1332 | this variable." | ||
| 1321 | :type '(choice (const :tag "No sorting" nil) | 1333 | :type '(choice (const :tag "No sorting" nil) |
| 1322 | (const :tag "Alphabetical sorting" alphabetical) | 1334 | (const :tag "Alphabetical sorting" alphabetical) |
| 1335 | (const :tag "Historical sorting" historical) | ||
| 1323 | (function :tag "Custom function")) | 1336 | (function :tag "Custom function")) |
| 1324 | :version "29.1") | 1337 | :version "30.1") |
| 1325 | 1338 | ||
| 1326 | (defcustom completions-group nil | 1339 | (defcustom completions-group nil |
| 1327 | "Enable grouping of completion candidates in the *Completions* buffer. | 1340 | "Enable grouping of completion candidates in the *Completions* buffer. |
| @@ -1647,6 +1660,44 @@ Remove completion BASE prefix string from history elements." | |||
| 1647 | (substring c base-size))) | 1660 | (substring c base-size))) |
| 1648 | hist))))) | 1661 | hist))))) |
| 1649 | 1662 | ||
| 1663 | (defun minibuffer-sort-alphabetically (completions) | ||
| 1664 | "Sort COMPLETIONS alphabetically. | ||
| 1665 | |||
| 1666 | COMPLETIONS are sorted alphabetically by `string-lessp'. | ||
| 1667 | |||
| 1668 | This is a suitable function to use for `completions-sort' or to | ||
| 1669 | include as `display-sort-function' in completion metadata." | ||
| 1670 | (sort completions #'string-lessp)) | ||
| 1671 | |||
| 1672 | (defvar minibuffer-completion-base nil | ||
| 1673 | "The base for the current completion. | ||
| 1674 | |||
| 1675 | This is the part of the current minibuffer input which comes | ||
| 1676 | before the current completion field, as determined by | ||
| 1677 | `completion-boundaries'. This is primarily relevant for file | ||
| 1678 | names, where this is the directory component of the file name.") | ||
| 1679 | |||
| 1680 | (defun minibuffer-sort-by-history (completions) | ||
| 1681 | "Sort COMPLETIONS by their position in `minibuffer-history-variable'. | ||
| 1682 | |||
| 1683 | COMPLETIONS are sorted first by `minibuffer-sort-alphbetically', | ||
| 1684 | then any elements occuring in the minibuffer history list are | ||
| 1685 | moved to the front based on the chronological order they occur in | ||
| 1686 | the history. If a history variable hasn't been specified for | ||
| 1687 | this call of `completing-read', COMPLETIONS are sorted only by | ||
| 1688 | `minibuffer-sort-alphbetically'. | ||
| 1689 | |||
| 1690 | This is a suitable function to use for `completions-sort' or to | ||
| 1691 | include as `display-sort-function' in completion metadata." | ||
| 1692 | (let ((alphabetized (sort completions #'string-lessp))) | ||
| 1693 | ;; Only use history when it's specific to these completions. | ||
| 1694 | (if (eq minibuffer-history-variable | ||
| 1695 | (default-value minibuffer-history-variable)) | ||
| 1696 | alphabetized | ||
| 1697 | (minibuffer--sort-by-position | ||
| 1698 | (minibuffer--sort-preprocess-history minibuffer-completion-base) | ||
| 1699 | alphabetized)))) | ||
| 1700 | |||
| 1650 | (defun minibuffer--group-by (group-fun sort-fun elems) | 1701 | (defun minibuffer--group-by (group-fun sort-fun elems) |
| 1651 | "Group ELEMS by GROUP-FUN and sort groups by SORT-FUN." | 1702 | "Group ELEMS by GROUP-FUN and sort groups by SORT-FUN." |
| 1652 | (let ((groups)) | 1703 | (let ((groups)) |
| @@ -2440,6 +2491,7 @@ The candidate will still be chosen by `choose-completion' unless | |||
| 2440 | (let* ((last (last completions)) | 2491 | (let* ((last (last completions)) |
| 2441 | (base-size (or (cdr last) 0)) | 2492 | (base-size (or (cdr last) 0)) |
| 2442 | (prefix (unless (zerop base-size) (substring string 0 base-size))) | 2493 | (prefix (unless (zerop base-size) (substring string 0 base-size))) |
| 2494 | (minibuffer-completion-base (substring string 0 base-size)) | ||
| 2443 | (base-prefix (buffer-substring (minibuffer--completion-prompt-end) | 2495 | (base-prefix (buffer-substring (minibuffer--completion-prompt-end) |
| 2444 | (+ start base-size))) | 2496 | (+ start base-size))) |
| 2445 | (base-suffix | 2497 | (base-suffix |
| @@ -2506,7 +2558,8 @@ The candidate will still be chosen by `choose-completion' unless | |||
| 2506 | (funcall sort-fun completions) | 2558 | (funcall sort-fun completions) |
| 2507 | (pcase completions-sort | 2559 | (pcase completions-sort |
| 2508 | ('nil completions) | 2560 | ('nil completions) |
| 2509 | ('alphabetical (sort completions #'string-lessp)) | 2561 | ('alphabetical (minibuffer-sort-alphabetically completions)) |
| 2562 | ('historical (minibuffer-sort-by-history completions)) | ||
| 2510 | (_ (funcall completions-sort completions))))) | 2563 | (_ (funcall completions-sort completions))))) |
| 2511 | 2564 | ||
| 2512 | ;; After sorting, group the candidates using the | 2565 | ;; After sorting, group the candidates using the |