* bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function`
@ 2021-05-20 18:56 Daniel Mendler
2021-08-17 12:17 ` João Távora
0 siblings, 1 reply; 21+ messages in thread
From: Daniel Mendler @ 2021-05-20 18:56 UTC (permalink / raw)
To: 48545; +Cc: Gregory Heytings
The recently introduced `icomplete-vertical-mode` should support the
`group-function`, which can be specified by the completion metadata. The
group function allows grouping the completion candidates by group titles.
Additional to the default completion UI, support for group functions is
already present in the following vertical minibuffer UIs, which are
similar to `icomplete-vertical-mode`: Vertico (GNU ELPA), Selectrum
(MELPA) and Icomplete-vertical (MELPA).
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function`
2021-05-20 18:56 bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function` Daniel Mendler
@ 2021-08-17 12:17 ` João Távora
2021-08-18 9:38 ` Kévin Le Gouguec
0 siblings, 1 reply; 21+ messages in thread
From: João Távora @ 2021-08-17 12:17 UTC (permalink / raw)
To: Daniel Mendler; +Cc: Gregory Heytings, 48545
Daniel Mendler <mail@daniel-mendler.de> writes:
> The recently introduced `icomplete-vertical-mode` should support the
> `group-function`, which can be specified by the completion metadata. The
> group function allows grouping the completion candidates by group titles.
>
> Additional to the default completion UI, support for group functions is
> already present in the following vertical minibuffer UIs, which are
> similar to `icomplete-vertical-mode`: Vertico (GNU ELPA), Selectrum
> (MELPA) and Icomplete-vertical (MELPA).
I just tried
(setq xref-show-definitions-function 'xref-show-definitions-completing-read)
To enable what seems to be the only table in Emacs core that has this
feature with fido-vertical-mode.
It seemed to do the right thing, prepending each entry with the name of
its associated "group". Is this what it means to support this? If so,
I'll close. Else, please explain what support you're looking for.
Thanks,
João
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function`
2021-08-17 12:17 ` João Távora
@ 2021-08-18 9:38 ` Kévin Le Gouguec
2021-08-18 9:55 ` João Távora
0 siblings, 1 reply; 21+ messages in thread
From: Kévin Le Gouguec @ 2021-08-18 9:38 UTC (permalink / raw)
To: João Távora; +Cc: Daniel Mendler, Gregory Heytings, 48545
João Távora <joaotavora@gmail.com> writes:
> It seemed to do the right thing, prepending each entry with the name of
> its associated "group". Is this what it means to support this? If so,
> I'll close. Else, please explain what support you're looking for.
I think Daniel is referring to what happens if you set completions-group
to t and type e.g. C-x 8 RET ROMAN TAB TAB (without icomplete): you will
see two "sections" titled 'symbol' and 'ancient-symbol'.
Right now icomplete-vertical-mode does not make use of this information,
AFAICT (unlike e.g. Vertico).
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function`
2021-08-18 9:38 ` Kévin Le Gouguec
@ 2021-08-18 9:55 ` João Távora
2021-08-19 11:18 ` João Távora
0 siblings, 1 reply; 21+ messages in thread
From: João Távora @ 2021-08-18 9:55 UTC (permalink / raw)
To: Kévin Le Gouguec; +Cc: Daniel Mendler, Gregory Heytings, 48545
Kévin Le Gouguec <kevin.legouguec@gmail.com> writes:
> João Távora <joaotavora@gmail.com> writes:
>
>> It seemed to do the right thing, prepending each entry with the name of
>> its associated "group". Is this what it means to support this? If so,
>> I'll close. Else, please explain what support you're looking for.
>
> I think Daniel is referring to what happens if you set completions-group
> to t and type e.g. C-x 8 RET ROMAN TAB TAB (without icomplete): you will
> see two "sections" titled 'symbol' and 'ancient-symbol'.
Thanks you, easy to reproduce and see clearly what you mean now that
you've filled the missing information in this bug report.
> Right now icomplete-vertical-mode does not make use of this information,
> AFAICT (unlike e.g. Vertico).
That's right. I guess I'll copy Vertico's UI here, it seems reasonable.
João
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function`
2021-08-18 9:55 ` João Távora
@ 2021-08-19 11:18 ` João Távora
2021-08-19 12:38 ` Kévin Le Gouguec
2021-08-19 15:02 ` Dmitry Gutov
0 siblings, 2 replies; 21+ messages in thread
From: João Távora @ 2021-08-19 11:18 UTC (permalink / raw)
To: Kévin Le Gouguec
Cc: Daniel Mendler, Gregory Heytings, 48545-done, dgutov
[Dmitry, I've tagged you since you're generally interested in this
stuff.]
João Távora <joaotavora@gmail.com> writes:
> Kévin Le Gouguec <kevin.legouguec@gmail.com> writes:
>> I think Daniel is referring to what happens if you set completions-group
>> to t and type e.g. C-x 8 RET ROMAN TAB TAB (without icomplete): you will
>> see two "sections" titled 'symbol' and 'ancient-symbol'.
> Thanks you, easy to reproduce and see clearly what you mean now
I've pushed this feature. This is how I tested:
src/emacs -Q --eval '(setq completions-group t)' \
--eval '(setq xref-show-definitions-function (quote xref-show-definitions-completing-read))'
-f fido-vertical-mode
C-U M-. xref-location-marker RET
This should produce 5 locations. It shows, with section headers, how 4
of these belong to xref.el and 1 belongs to elisp-mode.el. When typing
a pattern which leads to filtering (e.g. with flex) sections are
preserved. Sane scrolling should also be maintained, though this was
complicated to get right and may still have some bugs (I haven't
noticed any yet.)
I noticed a quirk, though. If I add '-l etags' to the 'emacs -Q' line,
one gets 6 matches instead of 5 (due to etags having another
xref-location-marker). That's fine, but due to the default
alphanumeric/length sorting, it gets shoved into the group of xref.el
matches and thus we get two xref.el groups. I.e. it looks like
xref.el
(cl-defgeneric xref-location-marker)
(cl-defmethod xref-location-marker ((l xref-file-location)))
(cl-defmethod xref-location-marker ((l xref-bogus-location)))
etags.el
(cl-defmethod xref-location-marker ((l xref-etags-location)))
xref.el
(cl-defmethod xref-location-marker ((l xref-buffer-location)))
elisp-mode.el
(cl-defmethod xref-location-marker ((l xref-elisp-location)))
I don't use completions-group so I don't care strongly for this, but I
believe that this is generally undesired, for non-filtering scenarios.
All the entries from the xref.el group should probably be clumped
together. If a user were flex-matching and thus expecting certain sort
score-based order, it _would_ make sense to me, but here no flexy things
were happening at all.
To fix this, perhaps the default sorting methods should be turned off in
completion-all-sorted-completions in minibuffer.el if a table supplies
`group-function`. A patch for this is after my sig.
Alternatively, tables that do support `group-function` could also start
specifying:
(display-sort-function . identity)
I've tested both alternatives and they seem to do the right thing. But
this may be the subject for some other bug, if someone cares.
Anyway, I'm marking this closed this bug since its main work is done.
Feedback welcome, of course.
João
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index ffcd5d88ab..20fbc326a2 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -1506,17 +1506,18 @@ completion-all-sorted-completions
(setq all (delete-dups all))
(setq last (last all))
- (if sort-fun
- (setq all (funcall sort-fun all))
- ;; Sort first by length and alphabetically.
- (setq all (minibuffer--sort-by-length-alpha all))
- ;; Sort by history position, put the default, if it
- ;; exists, on top.
- (when (minibufferp)
- (setq all (minibuffer--sort-by-position
- (minibuffer--sort-preprocess-history
- (substring string 0 base-size))
- all))))
+ (cond (sort-fun
+ (setq all (funcall sort-fun all)))
+ ((not (completion-metadata-get all-md 'group-function))
+ ;; Sort first by length and alphabetically.
+ (setq all (minibuffer--sort-by-length-alpha all))
+ ;; Sort by history position, put the default, if it
+ ;; exists, on top.
+ (when (minibufferp)
+ (setq all (minibuffer--sort-by-position
+ (minibuffer--sort-preprocess-history
+ (substring string 0 base-size))
+ all)))))
^ permalink raw reply related [flat|nested] 21+ messages in thread
* bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function`
2021-08-19 11:18 ` João Távora
@ 2021-08-19 12:38 ` Kévin Le Gouguec
2021-08-19 13:29 ` João Távora
2021-08-19 15:02 ` Dmitry Gutov
1 sibling, 1 reply; 21+ messages in thread
From: Kévin Le Gouguec @ 2021-08-19 12:38 UTC (permalink / raw)
To: 48545; +Cc: mail, Gregory Heytings, joaotavora, dgutov
João Távora <joaotavora@gmail.com> writes:
> To fix this, perhaps the default sorting methods should be turned off in
> completion-all-sorted-completions in minibuffer.el if a table supplies
> `group-function`. A patch for this is after my sig.
FWIW (I didn't take the time to understand the ins and outs of the
completion system nor the changes that are being made; sorry about
that), with this tentative patch, Icomplete seems to honour
read-char-by-name-sort. With icomplete enabled and
read-char-by-name-sort set to 'code, try
C-x 8 RET CLOCK FACE
- with the current master branch, the completions are sorted
alphabetically,
- with the tentative patch applied, the completions are sorted by code
point.
This seems to compose well with completions-group AFAICT (see e.g. C-x 8
RET ROMAN).
At any rate, thanks for teaching icomplete-vertical about
group-function!
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function`
2021-08-19 12:38 ` Kévin Le Gouguec
@ 2021-08-19 13:29 ` João Távora
2021-08-19 19:36 ` Kévin Le Gouguec
0 siblings, 1 reply; 21+ messages in thread
From: João Távora @ 2021-08-19 13:29 UTC (permalink / raw)
To: Kévin Le Gouguec
Cc: Daniel Mendler, Gregory Heytings, 48545, Dmitry Gutov
[-- Attachment #1: Type: text/plain, Size: 936 bytes --]
On Thu, Aug 19, 2021, 13:38 Kévin Le Gouguec <kevin.legouguec@gmail.com>
wrote:
> João Távora <joaotavora@gmail.com> writes:
>
> FWIW (I didn't take the time to understand the ins and outs of the
> completion system nor the changes that are being made; sorry about
> that),
Don't beat yourself over it, it's not an easy or pleasent thing to
understand.
with this tentative patch, Icomplete seems to honour
> read-char-by-name-sort. With icomplete enabled and
> read-char-by-name-sort set to 'code, try
>
> C-x 8 RET CLOCK FACE
>
> - with the current master branch, the completions are sorted
> alphabetically,
> - with the tentative patch applied, the completions are sorted by code
> point.
>
Yes I think that's the idea. But do you think that's good or bad?
This seems to compose well with completions-group AFAICT (see e.g. C-x 8
> RET ROMAN).
>
This is good, right?
João
>
[-- Attachment #2: Type: text/html, Size: 2492 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function`
2021-08-19 11:18 ` João Távora
2021-08-19 12:38 ` Kévin Le Gouguec
@ 2021-08-19 15:02 ` Dmitry Gutov
2021-08-19 19:41 ` João Távora
1 sibling, 1 reply; 21+ messages in thread
From: Dmitry Gutov @ 2021-08-19 15:02 UTC (permalink / raw)
To: 48545, joaotavora, mail
On 19.08.2021 14:18, João Távora wrote:
> I noticed a quirk, though. If I add '-l etags' to the 'emacs -Q' line,
> one gets 6 matches instead of 5 (due to etags having another
> xref-location-marker). That's fine, but due to the default
> alphanumeric/length sorting, it gets shoved into the group of xref.el
> matches and thus we get two xref.el groups. I.e. it looks like
>
> xref.el
> (cl-defgeneric xref-location-marker)
> (cl-defmethod xref-location-marker ((l xref-file-location)))
> (cl-defmethod xref-location-marker ((l xref-bogus-location)))
> etags.el
> (cl-defmethod xref-location-marker ((l xref-etags-location)))
> xref.el
> (cl-defmethod xref-location-marker ((l xref-buffer-location)))
> elisp-mode.el
> (cl-defmethod xref-location-marker ((l xref-elisp-location)))
>
> I don't use completions-group so I don't care strongly for this, but I
> believe that this is generally undesired, for non-filtering scenarios.
> All the entries from the xref.el group should probably be clumped
> together. If a user were flex-matching and thus expecting certain sort
> score-based order, it_would_ make sense to me, but here no flexy things
> were happening at all.
>
> To fix this, perhaps the default sorting methods should be turned off in
> completion-all-sorted-completions in minibuffer.el if a table supplies
> `group-function`. A patch for this is after my sig.
We discussed this problem when group-function was introduced. Another
approach is to just change the method of grouping: first the completions
are sorted, and then they are sorted into groups.
The group that goes first is the group to which the first completion in
the sorted list belongs to. It doesn't matter whether some of the
subsequent items in it are sorted at the end of the list: as long as
they return the same value for "group", they get put into that first group.
I wonder which strategy Daniel ultimately chose to use in Consult.
Perhaps we should document it in the API, so that the implementations
stay consistent.
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function`
2021-08-19 13:29 ` João Távora
@ 2021-08-19 19:36 ` Kévin Le Gouguec
0 siblings, 0 replies; 21+ messages in thread
From: Kévin Le Gouguec @ 2021-08-19 19:36 UTC (permalink / raw)
To: João Távora
Cc: Daniel Mendler, Gregory Heytings, 48545, Dmitry Gutov
João Távora <joaotavora@gmail.com> writes:
> FWIW (I didn't take the time to understand the ins and outs of the
> completion system nor the changes that are being made; sorry about
> that),
>
> Don't beat yourself over it, it's not an easy or pleasent thing to understand.
(It's not for lack of trying either *cough*bug#40152*cough*)
> with this tentative patch, Icomplete seems to honour
> read-char-by-name-sort. With icomplete enabled and
> read-char-by-name-sort set to 'code, try
>
> C-x 8 RET CLOCK FACE
>
> - with the current master branch, the completions are sorted
> alphabetically,
> - with the tentative patch applied, the completions are sorted by code
> point.
>
> Yes I think that's the idea. But do you think that's good or bad?
Apologies, my message was fairly clinical and lacked emphasis.
Icomplete heeding read-char-by-name-sort? Yes please! 👍 for this
tentative patch.
> This seems to compose well with completions-group AFAICT (see e.g. C-x 8
> RET ROMAN).
>
> This is good, right?
Yes, also good 👍
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function`
2021-08-19 15:02 ` Dmitry Gutov
@ 2021-08-19 19:41 ` João Távora
2021-08-19 22:37 ` Dmitry Gutov
0 siblings, 1 reply; 21+ messages in thread
From: João Távora @ 2021-08-19 19:41 UTC (permalink / raw)
To: Dmitry Gutov; +Cc: mail, 48545
Dmitry Gutov <dgutov@yandex.ru> writes:
> On 19.08.2021 14:18, João Távora wrote:
>> completion-all-sorted-completions in minibuffer.el if a table supplies
>> `group-function`. A patch for this is after my sig.
>
> We discussed this problem when group-function was introduced. Another
> approach is to just change the method of grouping: first the
> completions are sorted, and then they are sorted into groups.
That's a possiblity. But it might be performing too much work, at least
at first sight. For the C-x 8 RET case and the xref table (the only
tables I know which use this) things seem to be naturally put into
groups already. So sorting them alphabetically, by length, by history,
and _then_ destroying most (but not all) with the grouping could be not
so interesting if the there's a big a price to pay.
I recommend whatever is done that some quantitative benchmarking is
performed to the before/after. Enabling fido-vertical-mode and pressing
C-u C-x C-e C-m after
(benchmark-run (call-interactively 'insert-char))
Seems to be a decent way to measure.
Currently, with the alpha/length/history sorting, it takes about 1
second in my machine. Without any sorting (and the natural grouping),
takes about 0.6 seconds. You should measure what the re-grouping
sorting does.
João
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function`
2021-08-19 19:41 ` João Távora
@ 2021-08-19 22:37 ` Dmitry Gutov
2021-08-19 23:39 ` João Távora
0 siblings, 1 reply; 21+ messages in thread
From: Dmitry Gutov @ 2021-08-19 22:37 UTC (permalink / raw)
To: João Távora; +Cc: mail, 48545
On 19.08.2021 22:41, João Távora wrote:
>> We discussed this problem when group-function was introduced. Another
>> approach is to just change the method of grouping: first the
>> completions are sorted, and then they are sorted into groups.
>
> That's a possiblity. But it might be performing too much work, at least
> at first sight.
Not sure I understand. Grouping is a linear operation, isn't it? O(N).
Which is generally cheaper than the sorting step that came before.
> For the C-x 8 RET case and the xref table (the only
> tables I know which use this) things seem to be naturally put into
> groups already. So sorting them alphabetically, by length, by history,
> and _then_ destroying most (but not all) with the grouping could be not
> so interesting if the there's a big a price to pay.
Could be it misses information.
OTOH, if you split completions belonging to the same group apart, you
can end up with a list where there as as many group headers, as there
completions (in the extreme case).
What behavior does (setq completions-group t) have? It affects the
default UI, IIUC.
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function`
2021-08-19 22:37 ` Dmitry Gutov
@ 2021-08-19 23:39 ` João Távora
2021-08-19 23:51 ` Dmitry Gutov
0 siblings, 1 reply; 21+ messages in thread
From: João Távora @ 2021-08-19 23:39 UTC (permalink / raw)
To: Dmitry Gutov; +Cc: Daniel Mendler, 48545
[-- Attachment #1: Type: text/plain, Size: 2626 bytes --]
On Thu, Aug 19, 2021, 23:37 Dmitry Gutov <dgutov@yandex.ru> wrote:
> On 19.08.2021 22:41, João Távora wrote:
>
> > That's a possiblity. But it might be performing too much work, at least
> > at first sight.
>
> Not sure I understand. Grouping is a linear operation, isn't it? O(N).
> Which is generally cheaper than the sorting step that came before.
>
Yes, but you'd be adding to it and that is always worse than _not_ adding
to it. And there's a constant factor in front of that O(N). So that's why I
think measurements should be taken, always.
Not to mention that if the table is already "naturally" grouped upfront,
your're incurring in both the sorting cost and the grouping cost, when you
could just be skipping both with little to no downsides, I would presume.
Of course, maybe I presume wrong, but Kévins report, who does use
completions-group, seems to confirm it.
> For the C-x 8 RET case and the xref table (the only
> > tables I know which use this) things seem to be naturally put into
> > groups already. So sorting them alphabetically, by length, by history,
> > and _then_ destroying most (but not all) with the grouping could be not
> > so interesting if the there's a big a price to pay.
>
> Could be it misses information.
>
? Don't understand this...
OTOH, if you split completions belonging to the same group apart, you
> can end up with a list where there as as many group headers, as there
> completions (in the extreme case).
>
That's true. That's why my idea is to skip sorting altogether when tables
have a group-function, under the assumption that good speed matters much
more than applying the default sorting within each group.
For example, what does it matter to have a recently chosen UTF-8 completion
bubble up to the top of a group that's buried deep down in the long list of
groups? Not much, I think. And largely the same for the length and
lexicographical sorting.
I'd even venture to say it's like this for any table with a group-function,
though I only know two such tables. And that's why I proposed that generic
minibuffer.el patch. But, the alternative, to do it per table, could also
be fine and is reasonably short, too.
What behavior does (setq completions-group t) have?
Seems to be a flag that controls the presence of 'group-function' in some
tables. Can't speak of the other UIs, but icomplete just honors
'group-function' and does not double check the flag. It could, if it were
relevant, I guess.
It affects the default UI, IIUC.
Yes, I believe so. But what is the relevance?
João
[-- Attachment #2: Type: text/html, Size: 4856 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function`
2021-08-19 23:39 ` João Távora
@ 2021-08-19 23:51 ` Dmitry Gutov
2021-08-20 10:35 ` João Távora
2021-08-21 0:24 ` João Távora
0 siblings, 2 replies; 21+ messages in thread
From: Dmitry Gutov @ 2021-08-19 23:51 UTC (permalink / raw)
To: João Távora; +Cc: Daniel Mendler, 48545
On 20.08.2021 02:39, João Távora wrote:
> Not sure I understand. Grouping is a linear operation, isn't it? O(N).
>
>
> Which is generally cheaper than the sorting step that came before.
>
>
> Yes, but you'd be adding to it and that is always worse than _not_
> adding to it.
True, but since sorting has higher complexity, for large N it should
take much longer, and for small N anything is fast anyway.
> And there's a constant factor in front of that O(N). So
> that's why I think measurements should be taken, always.
Please go ahead, if you like. I just wanted to make a couple of
suggestions here.
> Not to mention that if the table is already "naturally" grouped upfront,
> your're incurring in both the sorting cost and the grouping cost, when
> you could just be skipping both with little to no downsides, I would
> presume.
Right. I just don't think either is costly, most of the time.
> Of course, maybe I presume wrong, but Kévins report, who does use
> completions-group, seems to confirm it.
Performance degradation? Guess I missed it.
> Could be it misses information.
>
>
> ? Don't understand this...
Maybe I should say: destroys information. One conveyed by the original
sorting order.
> OTOH, if you split completions belonging to the same group apart, you
> can end up with a list where there as as many group headers, as there
> completions (in the extreme case).
>
>
> That's true. That's why my idea is to skip sorting altogether when
> tables have a group-function, under the assumption that good speed
> matters much more than applying the default sorting within each group.
>
> For example, what does it matter to have a recently chosen UTF-8
> completion bubble up to the top of a group that's buried deep down in
> the long list of groups? Not much, I think. And largely the same for the
> length and lexicographical sorting.
Suppose the sorting was performed by the 'flex' style (as one example).
Then, at the very least, you will see at the top of the first group the
best available match for your input. That's useful, I think. Even if the
remaining items in that group are much worse matches.
> What behavior does (setq completions-group t) have?
>
>
> Seems to be a flag that controls the presence of 'group-function' in
> some tables. Can't speak of the other UIs, but icomplete just honors
> 'group-function' and does not double check the flag. It could, if it
> were relevant, I guess.
>
> It affects the default UI, IIUC.
>
>
> Yes, I believe so. But what is the relevance?
icomplete's grouping behavior should probably match the default UI's
behavior in that regard. Or, if people actually don't like it, see it
changed in both places.
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function`
2021-08-19 23:51 ` Dmitry Gutov
@ 2021-08-20 10:35 ` João Távora
2021-08-21 2:09 ` Dmitry Gutov
2021-08-21 0:24 ` João Távora
1 sibling, 1 reply; 21+ messages in thread
From: João Távora @ 2021-08-20 10:35 UTC (permalink / raw)
To: Dmitry Gutov; +Cc: Daniel Mendler, 48545
Dmitry Gutov <dgutov@yandex.ru> writes:
> On 20.08.2021 02:39, João Távora wrote:
>
>> Not sure I understand. Grouping is a linear operation, isn't it? O(N).
>> Which is generally cheaper than the sorting step that came
>> before.
>> Yes, but you'd be adding to it and that is always worse than _not_
>> adding to it.
>
> True, but since sorting has higher complexity, for large N it should
> take much longer, and for small N anything is fast anyway.
This is IME a common misunderstanding, that is usually cleared up by the
phrase "constant factors matter". In
k1 * O(NlogN) + k2 * O(N)
which is our example, Big-O notation can drop the constants to describe
the growth rate of functions, but in the real world and for a real N, k1
and k2 matter.
In the particular case we're discussing k2 isn't even under "our"
(meaning minibuffer.el or "the framework") control. It is determined by
whatever the completion table author put into `group-function`. So
eliding the second term from that equation may be premature.
>> And there's a constant factor in front of that O(N). So that's why I
>> think measurements should be taken, always.
>
> Please go ahead, if you like. I just wanted to make a couple of
> suggestions here.
I don't think we understand each other. If I understand correctly, your
suggestions is to add a re-grouping, meaning grouping on top the current
sorting, under the presumption that it will not significantly slow
things down. That's fine. My suggestion, however, is different. It is
to skip the current sorting for these cases altogether. My suggestion
has an actual implementation in the form of a patch, has been tested by
Kévin and has been benchmarked to show that it speeds up the process.
You suggestion, as far as I can see, has none of these three elements.
So if you or someone else wants to experiment with the re-grouping (with
whichever implemention), then it is you or that someone who should
perform these measurements. I can't imagine or guess what re-grouping
implementation you or anyone else has in mind, and if even I could I
wouldn't be able to take measurements from my imagination.
>> Not to mention that if the table is already "naturally" grouped
>> upfront, your're incurring in both the sorting cost and the grouping
>> cost, when you could just be skipping both with little to no
>> downsides, I would presume.
>
> Right. I just don't think either is costly, most of the time.
Did you read my previous message where I reported that C-x 8 RET takes
currently takes about a second to compute completions and only 0.6
seconds when sorting is removed?
> Maybe I should say: destroys information. One conveyed by the original
> sorting order.
Yes, both the current sorting and your proposed sorting-and-regrouping
implementation will do that.
> Then, at the very least, you will see at the top of the first group
> the best available match for your input. That's useful, I think. Even
> if the remaining items in that group are much worse matches.
I thought we weren't discussing pattern-matching scenarios here, but OK,
this is what currently happens (meaning, you can try it yourself!). As
always with flex the best available match globally is sorted to the top,
along with its group. Icomplete will chose about, say, 10 best matches
to display. If two first ones happen happens to have same group,
Icomplete will shown under the same section. If the third has another
group, another section header. If the fourth global best has again the
same group as the first two, another section header. This is flex doing
its thing.
> icomplete's grouping behavior should probably match the default UI's
> behavior in that regard. Or, if people actually don't like it, see it
> changed in both places.
Anything and everything could be interesting, I guess. If you want to
propose changes to icomplete, propose changes to icomplete, as in with
actual code. Then things can be evaluated against reality
João
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function`
2021-08-19 23:51 ` Dmitry Gutov
2021-08-20 10:35 ` João Távora
@ 2021-08-21 0:24 ` João Távora
1 sibling, 0 replies; 21+ messages in thread
From: João Távora @ 2021-08-21 0:24 UTC (permalink / raw)
To: Dmitry Gutov; +Cc: Daniel Mendler, 48545
Dmitry Gutov <dgutov@yandex.ru> writes:
> On 20.08.2021 02:39, João Távora wrote:
> icomplete's grouping behavior should probably match the default UI's
> behavior in that regard. Or, if people actually don't like it, see it
> changed in both places.
Because it was fairly easy to, i tested the default UI with grouping and
C-x 8 RET. It seems that it doesn't use
completion-all-sorted-completions, and hence doesn't do the normal
alphabetical+length+recency sorting (let's call it a+l+r from now on) at
all by default. It does do the re-grouping though. And it takes a long
time, about 3-4 seconds (when one presses TAB at the prompt) to see the
first page of the completions list.
This is versus Icomplete which about a second (or even less if
you skip the a+l+r).
So whatever the default completion UI does, I don't think Icomplete
should imitate it if it means the same slow behaviour.
The default UI can do some sorting on top of regrouping if you set yet
another variable completions-group-sort, but then it will be only
alphabetical, not a+l+r. No idea why.
However, I've also discovered that my previous assumption that C-x 8 RET
returns naturally grouped chars is also wrong. They are _not_ naturally
grouped.
João
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function`
2021-08-20 10:35 ` João Távora
@ 2021-08-21 2:09 ` Dmitry Gutov
2021-08-21 9:40 ` João Távora
0 siblings, 1 reply; 21+ messages in thread
From: Dmitry Gutov @ 2021-08-21 2:09 UTC (permalink / raw)
To: João Távora; +Cc: Daniel Mendler, 48545
On 20.08.2021 13:35, João Távora wrote:
>> True, but since sorting has higher complexity, for large N it should
>> take much longer, and for small N anything is fast anyway.
>
> This is IME a common misunderstanding, that is usually cleared up by the
> phrase "constant factors matter". <...>
>
> In the particular case we're discussing k2 isn't even under "our"
> (meaning minibuffer.el or "the framework") control. It is determined by
> whatever the completion table author put into `group-function`. So
> eliding the second term from that equation may be premature.
Even if the constant factor is somehow significant (which would be a
surprise, but OK, some pathological cases might turn up), if you do any
kind of grouping at all, you will incur the same cost, won't you?
Unless you only apply the grouping to the first V matches (where it's
the number of lines visible in the minibuffer). But even then my
suggestion can be adapted to this approach. Using the example from the
message I replied to, you would put all the matches in 'xref.el' into
the same group, not two groups.
The cost of the grouping function doesn't matter when making this choice.
>>> And there's a constant factor in front of that O(N). So that's why I
>>> think measurements should be taken, always.
>>
>> Please go ahead, if you like. I just wanted to make a couple of
>> suggestions here.
>
> I don't think we understand each other. If I understand correctly, your
> suggestions is to add a re-grouping, meaning grouping on top the current
> sorting, under the presumption that it will not significantly slow
> things down.
I took an existing example of a grouping UI and suggested a slightly
different one. With no expected difference in performance.
> That's fine. My suggestion, however, is different. It is
> to skip the current sorting for these cases altogether. My suggestion
> has an actual implementation in the form of a patch, has been tested by
> Kévin and has been benchmarked to show that it speeds up the process.
And I offered a reason for why people might still want that sorting.
That reason is not related to performance.
> You suggestion, as far as I can see, has none of these three elements.
> So if you or someone else wants to experiment with the re-grouping (with
> whichever implemention),
Why do you call it re-grouping? Grouping happens after sorting, there is
no prior grouping step.
>>> Not to mention that if the table is already "naturally" grouped
>>> upfront, your're incurring in both the sorting cost and the grouping
>>> cost, when you could just be skipping both with little to no
>>> downsides, I would presume.
>>
>> Right. I just don't think either is costly, most of the time.
>
> Did you read my previous message where I reported that C-x 8 RET takes
> currently takes about a second to compute completions and only 0.6
> seconds when sorting is removed?
I was talking about the grouping step, obviously. Not being costly.
Try disabling grouping. Is completion still slow? Then it's a problem
with sorting speed that needs to be solved separately anyway.
>> Then, at the very least, you will see at the top of the first group
>> the best available match for your input. That's useful, I think. Even
>> if the remaining items in that group are much worse matches.
>
> I thought we weren't discussing pattern-matching scenarios here, but OK,
> this is what currently happens (meaning, you can try it yourself!). As
> always with flex the best available match globally is sorted to the top,
> along with its group. Icomplete will chose about, say, 10 best matches
> to display. If two first ones happen happens to have same group,
> Icomplete will shown under the same section. If the third has another
> group, another section header. If the fourth global best has again the
> same group as the first two, another section header. This is flex doing
> its thing.
Yup. This is what I suggested to change.
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function`
2021-08-21 2:09 ` Dmitry Gutov
@ 2021-08-21 9:40 ` João Távora
2021-08-21 12:01 ` Dmitry Gutov
0 siblings, 1 reply; 21+ messages in thread
From: João Távora @ 2021-08-21 9:40 UTC (permalink / raw)
To: Dmitry Gutov; +Cc: Daniel Mendler, 48545
Dmitry Gutov <dgutov@yandex.ru> writes:
> On 20.08.2021 13:35, João Távora wrote:
> Even if the constant factor is somehow significant (which would be a
> surprise, but OK, some pathological cases might turn up), if you do
> any kind of grouping at all, you will incur the same cost, won't you?
Some tables and grouping strategies, like the xref table, seem to be
"naturally" grouped by the way you harvest candidates. For others, we
could make just make it so that they are. That "make it so" wouldn't
necessarily mean calling `group-function` for every candidate.
> Unless you only apply the grouping to the first V matches (where it's
> the number of lines visible in the minibuffer). But even then my
> suggestion can be adapted to this approach. Using the example from the
> message I replied to, you would put all the matches in 'xref.el' into
> the same group, not two groups.
>
> The cost of the grouping function doesn't matter when making this
> choice.
Yes, I think you see what you mean. But I also imagine it would be
terrifyingly confusing for a user of a scrolling dropdown to see
candidates jump back and forth into their groups as the user scrolls
down to see a new candidate and hide another. If what I imagine isn't
what you mean, maybe you could code something up and show what you mean.
> I took an existing example of a grouping UI and suggested a slightly
> different one. With no expected difference in performance.
As I wrote, that's a fine presumption/intutition, though it is, IMHO,
vunerable to the graces of whatever 'group-function' has been coded by
the completion table author. You should now confirm your intuition with
an actual patch and benchmarks.
My original point about "doing too much work" is that it is almost
impossible that it will somehow make the process _quicker_ than what it
actually is right now. My suggestion to eliminate sorting _does_ makes
it quicker, demonstrably.
But maybe the two suggestions can even coexist: eliminate a+l+r sorting
and add re-grouping. That is likely quicker than the current state.
>> You suggestion, as far as I can see, has none of these three elements.
>> So if you or someone else wants to experiment with the re-grouping (with
>> whichever implemention),
>
> Why do you call it re-grouping? Grouping happens after sorting, there
> is no prior grouping step.
For example, in xref.el the matches provided by the completion table
are, IIUC, already "naturally" grouped, because they are collected file
by file, and the file is the group. That grouping is then completely
destroyed by a+l+r sorting. Your proposal would, I presume, destroy
that sorting to restore grouping. Hence "re-group".
Note that I previously assumed, mistakenly, that the entries in C-x 8
RET were also naturally grouped. They're not. They could very easily
be, and with no performance penalty.
>>>> upfront, your're incurring in both the sorting cost and the grouping
>>>> cost, when you could just be skipping both with little to no
>>>> downsides, I would presume.
>>> Right. I just don't think either is costly, most of the time.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> Did you read my previous message where I reported that C-x 8 RET
>> currently takes about a second to compute completions and only 0.6
>> seconds when sorting is removed?
> I was talking about the grouping step, obviously. Not being costly.
You wrote "I just don't think either is costly".
> Try disabling grouping. Is completion still slow? Then it's a problem
> with sorting speed that needs to be solved separately anyway.
icomplete.el doesn't do any grouping, it merely prints the grouping
information as headers for the few matches that it will print.
completion-all-sorted-completions also doesn't care about grouping. So
there's nothing to disable in that regard.
>> This is flex doing its thing.
> Yup. This is what I suggested to change.
As I explained two or three times now: you can. In a new dmitry-flex
style. That style is only a few lines of code away, I suppose. Or a
defcustom, if you prefer those. The current behaviour for 'flex' is the
correct one. It was conceived like this. flex scoring trumps grouping,
table orders, etc... If you don't like this you can change this, like
everything in Emacs.
João
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function`
2021-08-21 9:40 ` João Távora
@ 2021-08-21 12:01 ` Dmitry Gutov
2021-08-21 12:42 ` João Távora
0 siblings, 1 reply; 21+ messages in thread
From: Dmitry Gutov @ 2021-08-21 12:01 UTC (permalink / raw)
To: João Távora; +Cc: Daniel Mendler, 48545
On 21.08.2021 12:40, João Távora wrote:
> Some tables and grouping strategies, like the xref table, seem to be
> "naturally" grouped by the way you harvest candidates. For others, we
> could make just make it so that they are. That "make it so" wouldn't
> necessarily mean calling `group-function` for every candidate.
Whether it's called for every candidate, is a UI/design choice.
>> The cost of the grouping function doesn't matter when making this
>> choice.
>
> Yes, I think you see what you mean. But I also imagine it would be
> terrifyingly confusing for a user of a scrolling dropdown to see
> candidates jump back and forth into their groups as the user scrolls
> down to see a new candidate and hide another. If what I imagine isn't
> what you mean, maybe you could code something up and show what you mean.
I suppose yes, if you only group candidates that are visible on the
screen, it could lead to jumping. Good point. Then I would suggest to go
back to "global" grouping.
>>> You suggestion, as far as I can see, has none of these three elements.
>>> So if you or someone else wants to experiment with the re-grouping (with
>>> whichever implemention),
>>
>> Why do you call it re-grouping? Grouping happens after sorting, there
>> is no prior grouping step.
>
> For example, in xref.el the matches provided by the completion table
> are, IIUC, already "naturally" grouped, because they are collected file
> by file, and the file is the group. That grouping is then completely
> destroyed by a+l+r sorting. Your proposal would, I presume, destroy
> that sorting to restore grouping. Hence "re-group".
I see.
The order of completions coming from xref is essentially random. Yes,
they are grouped by files (usually), but the files are not coming in any
particular order. So I would prefer not to skip the sorting step.
Of course, there might be different scenarios and preferences in that
regard.
> Note that I previously assumed, mistakenly, that the entries in C-x 8
> RET were also naturally grouped. They're not. They could very easily
> be, and with no performance penalty.
>
>>>>> upfront, your're incurring in both the sorting cost and the grouping
>>>>> cost, when you could just be skipping both with little to no
>>>>> downsides, I would presume.
>>>> Right. I just don't think either is costly, most of the time.
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>> Did you read my previous message where I reported that C-x 8 RET
>>> currently takes about a second to compute completions and only 0.6
>>> seconds when sorting is removed?
>> I was talking about the grouping step, obviously. Not being costly.
>
> You wrote "I just don't think either is costly".
Okay. Sorting seems to indeed be costly in this case (if I trust your
measurements).
Sorting is part of the default completion behavior (with grouping or
not). You want to remove it instead of fixing?
>> Try disabling grouping. Is completion still slow? Then it's a problem
>> with sorting speed that needs to be solved separately anyway.
>
> icomplete.el doesn't do any grouping, it merely prints the grouping
> information as headers for the few matches that it will print.
> completion-all-sorted-completions also doesn't care about grouping. So
> there's nothing to disable in that regard.
That addressed 3 words out of 20.
>>> This is flex doing its thing.
>> Yup. This is what I suggested to change.
>
> As I explained two or three times now: you can. In a new dmitry-flex
> style. That style is only a few lines of code away, I suppose. Or a
> defcustom, if you prefer those. The current behaviour for 'flex' is the
> correct one. It was conceived like this. flex scoring trumps grouping,
> table orders, etc... If you don't like this you can change this, like
> everything in Emacs.
Nothing I suggested should call for a change in completion style.
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function`
2021-08-21 12:01 ` Dmitry Gutov
@ 2021-08-21 12:42 ` João Távora
2021-08-22 13:52 ` Dmitry Gutov
0 siblings, 1 reply; 21+ messages in thread
From: João Távora @ 2021-08-21 12:42 UTC (permalink / raw)
To: Dmitry Gutov; +Cc: Daniel Mendler, 48545
Dmitry Gutov <dgutov@yandex.ru> writes:
> On 21.08.2021 12:40, João Távora wrote:
>> Yes, I think you see what you mean. But I also imagine it would be
>> terrifyingly confusing for a user of a scrolling dropdown to see
>> candidates jump back and forth into their groups as the user scrolls
>> down to see a new candidate and hide another. If what I imagine isn't
>> what you mean, maybe you could code something up and show what you mean.
>
> I suppose yes, if you only group candidates that are visible on the
> screen, it could lead to jumping. Good point. Then I would suggest to
> go back to "global" grouping.
Then do. Go back to that experiment and its drawbacks and actually
prototype it the way you envision it. Then share results here.
> The order of completions coming from xref is essentially random. Yes,
> they are grouped by files (usually), but the files are not coming in
> any particular order. So I would prefer not to skip the sorting step.
> Of course, there might be different scenarios and preferences in that
> regard.
If you sort the groups but not _inside_ the groups, you can skip the
expensive sorting and still keep some order. Though in xref nothing is
particularly expensive anyway.
> Okay. Sorting seems to indeed be costly in this case (if I trust your
> measurements).
You can do them yourself. I posted what I measured from. If it's not
clear, you should let me know.
> Sorting is part of the default completion behavior (with grouping or
> not). You want to remove it instead of fixing?
It's very simple: As I've explained some times already, I contend, and
Kévin at least seems to agree, is that when there grouping the current
slow 'a+l+r' sorting is not particularly useful. At least the "r ===
recently" part seems completely useful there. But the 'a+l' also seem
to be kinda lame, at least for xref and C-x 8 RET.
Now, if one agrees that sorting not particularly useful when there is
grouping and that is significantly slows things down, then there is a
good case for removing it when there is grouping. It's super simple.
>>> Try disabling grouping. Is completion still slow? Then it's a problem
>>> with sorting speed that needs to be solved separately anyway.
>> icomplete.el doesn't do any grouping, it merely prints the grouping
>> information as headers for the few matches that it will print.
>> completion-all-sorted-completions also doesn't care about grouping. So
>> there's nothing to disable in that regard.
>
> That addressed 3 words out of 20.
How in heck could I adress the remaining ones which refer to the first
three if those three were nonsense?
Look, you're asking me to do vaguely worded experiments that you can
perfectly run yourself. If you understand what you mean, go run them
yourself, document your findings and share them here for others to work
from. It'll save us all time.
>>>> This is flex doing its thing.
>>> Yup. This is what I suggested to change.
>> As I explained two or three times now: you can. In a new
>> dmitry-flex
>> style. That style is only a few lines of code away, I suppose. Or a
>> defcustom, if you prefer those. The current behaviour for 'flex' is the
>> correct one. It was conceived like this. flex scoring trumps grouping,
>> table orders, etc... If you don't like this you can change this, like
>> everything in Emacs.
>
> Nothing I suggested should call for a change in completion style.
Then I misunderstood, again. You did suggest changes to the 'flex'
completion style in another bug thread, I naturally though you meant
that. Here, you wrote "this is what I suggested to change" after I
described how the flex completion style worked. You provide no accurate
description or code of what you want changed. If you weren't a
programmer or especially versed in Elisp, I would comprehend. Given
that you are, it is baffling, time-wasting and quite tiring. I'll just
stop answering your hypothetical questions.
João
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function`
2021-08-21 12:42 ` João Távora
@ 2021-08-22 13:52 ` Dmitry Gutov
2021-08-22 15:44 ` João Távora
0 siblings, 1 reply; 21+ messages in thread
From: Dmitry Gutov @ 2021-08-22 13:52 UTC (permalink / raw)
To: João Távora; +Cc: Daniel Mendler, 48545
On 21.08.2021 15:42, João Távora wrote:
> Dmitry Gutov<dgutov@yandex.ru> writes:
>
>> On 21.08.2021 12:40, João Távora wrote:
>>> Yes, I think you see what you mean. But I also imagine it would be
>>> terrifyingly confusing for a user of a scrolling dropdown to see
>>> candidates jump back and forth into their groups as the user scrolls
>>> down to see a new candidate and hide another. If what I imagine isn't
>>> what you mean, maybe you could code something up and show what you mean.
>> I suppose yes, if you only group candidates that are visible on the
>> screen, it could lead to jumping. Good point. Then I would suggest to
>> go back to "global" grouping.
> Then do. Go back to that experiment and its drawbacks and actually
> prototype it the way you envision it. Then share results here.
I don't think I'm obligated to support every trivial suggestion with a
patch and a benchmark.
Or explain, from various POVs, why removing the sorting step "because
it's expensive" is faulty reasoning.
Or why the grouping approach in icomplete mode should match what the
default UI does and what other completion UIs (from which the grouping
feature was extracted) do as well.
Whatever, do what you like. I'm out of this thread.
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function`
2021-08-22 13:52 ` Dmitry Gutov
@ 2021-08-22 15:44 ` João Távora
0 siblings, 0 replies; 21+ messages in thread
From: João Távora @ 2021-08-22 15:44 UTC (permalink / raw)
To: Dmitry Gutov; +Cc: Daniel Mendler, 48545
Dmitry Gutov <dgutov@yandex.ru> writes:
> I don't think I'm obligated to support every trivial suggestion with a
> patch and a benchmark.
Of course you're not obliged to, but the fact that you won't code up
your own "trivial suggestion" is eloquent.
> Or explain, from various POVs, why removing the sorting step "because
> it's expensive" is faulty reasoning.
Could be, if it _were_ the reasoning. But it's not, as is quite easy to
read here.
> Or why the grouping approach in icomplete mode should match what the
> default UI does and what other completion UIs (from which the grouping
> feature was extracted) do as well.
The sorting in the default completion UI is already discrepant to
completions-all-sorted-completions, regardless of grouping. It's also
quite slow, as reported. I doubt we want Icomplete to "match" that (not
to mention the fact that Icomplete is a different type of UI).
> Whatever, do what you like. I'm out of this thread.
I've pushed ba852512f23fdab674086e35d4207e3970dd0912 to fix the
described bugs and wrap this up. Left a TODO in minibuffer.el for
anyone to experiment with "trivial suggestions" (or complex ones at
that).
João
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2021-08-22 15:44 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-05-20 18:56 bug#48545: 28.0.50; `icomplete-vertical-mode` does not support the `group-function` Daniel Mendler
2021-08-17 12:17 ` João Távora
2021-08-18 9:38 ` Kévin Le Gouguec
2021-08-18 9:55 ` João Távora
2021-08-19 11:18 ` João Távora
2021-08-19 12:38 ` Kévin Le Gouguec
2021-08-19 13:29 ` João Távora
2021-08-19 19:36 ` Kévin Le Gouguec
2021-08-19 15:02 ` Dmitry Gutov
2021-08-19 19:41 ` João Távora
2021-08-19 22:37 ` Dmitry Gutov
2021-08-19 23:39 ` João Távora
2021-08-19 23:51 ` Dmitry Gutov
2021-08-20 10:35 ` João Távora
2021-08-21 2:09 ` Dmitry Gutov
2021-08-21 9:40 ` João Távora
2021-08-21 12:01 ` Dmitry Gutov
2021-08-21 12:42 ` João Távora
2021-08-22 13:52 ` Dmitry Gutov
2021-08-22 15:44 ` João Távora
2021-08-21 0:24 ` João Távora
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).