unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Sorting command completions by recency
@ 2021-02-17 17:53 Juri Linkov
  2021-02-17 18:33 ` Lars Ingebrigtsen
  0 siblings, 1 reply; 8+ messages in thread
From: Juri Linkov @ 2021-02-17 17:53 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 472 bytes --]

The recent discussion about filtering out command completions by mode
reminded the problem that while icomplete shows the most recently used
commands at the top of the list for M-x, trying to see a complete list
with TAB changes the order of displayed commands, i.e. in icomplete
there is one sorting order by recency, but in the *Completions* buffer
alphabetical sorting order.

This code puts the recent commands at the top as well,
but probably it needs to be opt-in:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: sort-extended-command.patch --]
[-- Type: text/x-diff, Size: 1478 bytes --]

diff --git a/lisp/simple.el b/lisp/simple.el
index 80bc968950..838f344ab5 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1969,6 +1969,23 @@ read-extended-command
        (lambda (string pred action)
          (if (and suggest-key-bindings (eq action 'metadata))
 	     '(metadata
+               (display-sort-function
+                . (lambda (commands)
+                    (if (minibufferp)
+                        ;; Prefer recently used completions and put the default,
+                        ;; if it exists, on top.
+                        (let ((hist (symbol-value minibuffer-history-variable)))
+                          (sort commands
+                                (lambda (c1 c2)
+                                  (cond ((equal c1 minibuffer-default) t)
+                                        ((equal c2 minibuffer-default) nil)
+                                        ((and (member c1 hist) (member c2 hist))
+                                         (> (length (member c1 hist))
+                                            (length (member c2 hist))))
+                                        ((member c1 hist) t)
+                                        ((member c2 hist) nil)
+                                        (t (string-lessp c1 c2))))))
+                      commands)))
 	       (affixation-function . read-extended-command--affixation)
 	       (category . command))
            (complete-with-action action obarray string pred)))

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: Sorting command completions by recency
  2021-02-17 17:53 Sorting command completions by recency Juri Linkov
@ 2021-02-17 18:33 ` Lars Ingebrigtsen
  2021-02-17 19:55   ` Stefan Monnier
  0 siblings, 1 reply; 8+ messages in thread
From: Lars Ingebrigtsen @ 2021-02-17 18:33 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

Juri Linkov <juri@linkov.net> writes:

> This code puts the recent commands at the top as well,
> but probably it needs to be opt-in:

Makes sense to me, and, yes.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Sorting command completions by recency
  2021-02-17 18:33 ` Lars Ingebrigtsen
@ 2021-02-17 19:55   ` Stefan Monnier
  2021-02-17 20:03     ` Clemens
  2021-02-17 20:09     ` Juri Linkov
  0 siblings, 2 replies; 8+ messages in thread
From: Stefan Monnier @ 2021-02-17 19:55 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: emacs-devel, Juri Linkov

>> This code puts the recent commands at the top as well,
>> but probably it needs to be opt-in:
> Makes sense to me, and, yes.

FWIW, the minibuffer.el code already uses this kind of sorting for the
list of completions used in things like `icomplete` and
`completion-cycle-threshold`.

For *Completions* the sort was kept alphabetical so far because that's
also useful (for example in the case of M-x completion, it makes it
easier to skip over blocs of commands sharing the same prefix).

So, while I think it can be useful to sort by some kind of "guessed
usefulness" such as presence in the history, I don't think this should
be forced by the completion table of commands.


        Stefan




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Sorting command completions by recency
  2021-02-17 19:55   ` Stefan Monnier
@ 2021-02-17 20:03     ` Clemens
  2021-02-17 20:58       ` Stefan Monnier
  2021-02-17 20:09     ` Juri Linkov
  1 sibling, 1 reply; 8+ messages in thread
From: Clemens @ 2021-02-17 20:03 UTC (permalink / raw)
  To: Stefan Monnier, Lars Ingebrigtsen; +Cc: Juri Linkov, emacs-devel

>>> This code puts the recent commands at the top as well,
>>> but probably it needs to be opt-in:
>> Makes sense to me, and, yes.
> 
> FWIW, the minibuffer.el code already uses this kind of sorting for the
> list of completions used in things like `icomplete` and
> `completion-cycle-threshold`.
> 
> For *Completions* the sort was kept alphabetical so far because that's
> also useful (for example in the case of M-x completion, it makes it
> easier to skip over blocs of commands sharing the same prefix).
> 
> So, while I think it can be useful to sort by some kind of "guessed
> usefulness" such as presence in the history, I don't think this should
> be forced by the completion table of commands.


Maybe it would make sense to have a general option to configure this 
history sorting. When the table doesn't specify its own sorting one 
could opt in to always sort base on history.



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Sorting command completions by recency
  2021-02-17 19:55   ` Stefan Monnier
  2021-02-17 20:03     ` Clemens
@ 2021-02-17 20:09     ` Juri Linkov
  2021-02-17 22:02       ` [External] : " Drew Adams
  1 sibling, 1 reply; 8+ messages in thread
From: Juri Linkov @ 2021-02-17 20:09 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Lars Ingebrigtsen, emacs-devel

>>> This code puts the recent commands at the top as well,
>>> but probably it needs to be opt-in:
>> Makes sense to me, and, yes.
>
> FWIW, the minibuffer.el code already uses this kind of sorting for the
> list of completions used in things like `icomplete` and
> `completion-cycle-threshold`.

I stole code from `completion-all-sorted-completions' used by `icomplete`,
but see no way to call it directly.

> For *Completions* the sort was kept alphabetical so far because that's
> also useful (for example in the case of M-x completion, it makes it
> easier to skip over blocs of commands sharing the same prefix).
>
> So, while I think it can be useful to sort by some kind of "guessed
> usefulness" such as presence in the history, I don't think this should
> be forced by the completion table of commands.

Maybe a new option should allow switching the sorting order.
Perhaps, it should have a form of an alist:

  '(("alphabetical" . identity)
    ("by recency" . (lambda (commands)
                      (if (minibufferp)
                          ;; Prefer recently used completions and put the default,
                          ;; if it exists, on top.
                          (let ((hist (symbol-value minibuffer-history-variable)))
                            (sort commands
  ...



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Sorting command completions by recency
  2021-02-17 20:03     ` Clemens
@ 2021-02-17 20:58       ` Stefan Monnier
  2021-02-18 17:34         ` Juri Linkov
  0 siblings, 1 reply; 8+ messages in thread
From: Stefan Monnier @ 2021-02-17 20:58 UTC (permalink / raw)
  To: Clemens; +Cc: Lars Ingebrigtsen, Juri Linkov, emacs-devel

>>>> This code puts the recent commands at the top as well,
>>>> but probably it needs to be opt-in:
>>> Makes sense to me, and, yes.
>> FWIW, the minibuffer.el code already uses this kind of sorting for the
>> list of completions used in things like `icomplete` and
>> `completion-cycle-threshold`.
>> For *Completions* the sort was kept alphabetical so far because that's
>> also useful (for example in the case of M-x completion, it makes it
>> easier to skip over blocs of commands sharing the same prefix).
>> So, while I think it can be useful to sort by some kind of "guessed
>> usefulness" such as presence in the history, I don't think this should
>> be forced by the completion table of commands.
> Maybe it would make sense to have a general option to configure this history
> sorting. When the table doesn't specify its own sorting one could opt in to
> always sort base on history.

Agreed.
It'd make sense to have it as a global option, like
`completion-cycle-threshold` and it would also make sense to be able to
override it individually via `completion-category-overrides` (which is
also the case for the cycling behavior).


        Stefan




^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [External] : Re: Sorting command completions by recency
  2021-02-17 20:09     ` Juri Linkov
@ 2021-02-17 22:02       ` Drew Adams
  0 siblings, 0 replies; 8+ messages in thread
From: Drew Adams @ 2021-02-17 22:02 UTC (permalink / raw)
  To: Juri Linkov, Stefan Monnier; +Cc: Lars Ingebrigtsen, emacs-devel@gnu.org

> Maybe a new option should allow switching the sorting order.
> Perhaps, it should have a form of an alist:
> 
>   '(("alphabetical" . identity)
>     ("by recency" .
>?      (lambda (commands)
>        (if (minibufferp)
>            (let ((hist
>                   (symbol-value
>                     minibuffer-history-variable)))
>              (sort commands ...

FWIW, Icicles has such an option (but it also lets
you change the option value during completion, by
hitting a key).

Commands can bind it to get relevant sort orders.
For example, this is its let-binding for command
`icicle-complete-keys':

(icicle-sort-orders-alist
  '(("by key name, local bindings first" . icicle-local-keys-first-p)
    ("by key name, prefix keys first" . icicle-prefix-keys-first-p)
    ("by command name" . icicle-command-names-alphabetic-p)
    ("turned OFF")))

,----
| icicle-sort-orders-alist is a variable defined in `icicles-opt.el'.
| Its value is nil.
| 
| Documentation:
| Alist of available sort functions.
| This is a pseudo option - you probably do NOT want to customize this.
| Instead, use macro `icicle-define-sort-command' to define a new sort
| function and automatically add it to this list.
| 
| Each alist element has the form (SORT-ORDER . COMPARER):
| 
|  SORT-ORDER is a short string or symbol describing the sort order.
|  Examples: "by date", "alphabetically", "directories first".
| 
|  COMPARER compares two items.  It must be acceptable as a value of
|  `icicle-sort-comparer'.
| 
| You can customize this variable.
`----

COMPARER here can be a simple predicate; a list
of special predicates, which return (t) for true,
(nil) for false, or nil for undecided; or such a
list followed by a simple predicate.

You can easily combine multiple predicates in a
manner similar to running through hook functions
with `run-hook-with-args-until-(failure|success)',
i.e. until one of the predicates decides:

https://www.emacswiki.org/emacs/ApplesAndOranges

(Bookmark+ makes more use of such predicate
combinations.  It uses the same idea.)
 
Macro `define-sort-command' defines a command to
switch to a given sort order during completion
(or any other time).

Sorting, together with filtering and progressive
completion (aka narrowing), can greatly improve
usability.  Cycling without being able to sort in a
useful way can amount to drudgery.

https://www.emacswiki.org/emacs/Icicles_-_Sorting_Candidates

HTH.



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Sorting command completions by recency
  2021-02-17 20:58       ` Stefan Monnier
@ 2021-02-18 17:34         ` Juri Linkov
  0 siblings, 0 replies; 8+ messages in thread
From: Juri Linkov @ 2021-02-18 17:34 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Lars Ingebrigtsen, Clemens, emacs-devel

>> Maybe it would make sense to have a general option to configure this history
>> sorting. When the table doesn't specify its own sorting one could opt in to
>> always sort base on history.
>
> Agreed.
> It'd make sense to have it as a global option, like
> `completion-cycle-threshold` and it would also make sense to be able to
> override it individually via `completion-category-overrides` (which is
> also the case for the cycling behavior).

Todo in minibuffer.el:

  ;; - for M-x, cycle-sort commands that have no key binding first.

So there are at least 3 possible sort orders:

- alphabetical
- no key binding first
- history sorting

Then the question is how the users could select a sort order.
Maybe either by customization or using a keybinding.



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-02-18 17:34 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-17 17:53 Sorting command completions by recency Juri Linkov
2021-02-17 18:33 ` Lars Ingebrigtsen
2021-02-17 19:55   ` Stefan Monnier
2021-02-17 20:03     ` Clemens
2021-02-17 20:58       ` Stefan Monnier
2021-02-18 17:34         ` Juri Linkov
2021-02-17 20:09     ` Juri Linkov
2021-02-17 22:02       ` [External] : " Drew Adams

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).