minad / consult

:mag: consult.el - Consulting completing-read
GNU General Public License v3.0
1.23k stars 103 forks source link

Add category to consult-history #486

Closed abcdw closed 2 years ago

abcdw commented 2 years ago

Hi!

Could you add a category to consult-history command, please?

consult-history seems ok to me as a value for this field.

minad commented 2 years ago

We should use more fine grained categories. Currently in the minibuffer the category command is used. What do you need this for?

abcdw commented 2 years ago

I try out mct.el and found one quite interesting workflow with it:

In most cases I show the completion buffer inside current window, so nothing jumps around, but for some commands (mostly the ones with preview functionality) like imenu or consult-line/yank/history I would like to have them in other window than current one.

So I pick the window for displaying completion buffer based on category.

https://git.sr.ht/~abcdw/rde/tree/ba1eaf883f98ef994099da080c135735ba042157/rde/features/emacs.scm#L1316

(mct--completion-category) returns nil, when I invoke consult-history and I can't handle completion buffer placement properly.

minad commented 2 years ago

Yes, the ugly jumping is certainly an appealing reason to use a buffer for completion instead of the minibuffer. The underlying problem is that Emacs ensures that the cursor in other windows stays visible always. At some point I spent quite a bit of time to see if there are ways to avoid the jumping when the minibuffer pops up, but it would all lead to ugly hacks with an unacceptable amount of advices. I consider the Emacs feature to keep the cursor in other windows visible a bit of a misfeature. But this is probably just me - I don't use a blinking cursor and I also hide the cursor in other windows. As you found the alternative is to use a buffer or a child frame. In Vertico I use vertico-posframe and vertico-buffer for that, but I also dislike the non-uniformity in behavior - so in the end I just accept the jumping :shrug:

While I am generally in favor of using completion categories to distinguish behavior (Embark and Marginalia use the categories exclusively), it does not seem to be a good fit here. Note that Mct generally seems to tune the behavior per command (mct-completion-passlist, etc.), so I suggest you do the same for the consult-history command and the window tuning. As I mentioned, in the minibuffer consult-history already uses the command category when completing commands and I would rather refine this further and use different categories for the different histories. The category should reflect the items which are being completed, not the command name itself. Only in some cases there is an overlap of command and category.

I hope this helps. If you disagree with me regarding the category assignment there is an easy escape hatch ~if you also use Marginalia. You can overwrite the categories via Marginalia, see marginalia-command-categories and marginalia-prompt-categories. This mechanism is part of Marginalia since it allows us to add categories to existing built-in commands which do not specify a category out of the box.~ (EDIT: Rather use consult-customize for the override).

minad commented 2 years ago

Oh, I forgot the easier override mechanism which is already part of Consult:

(consult-customize consult-history :category 'consult-history)
abcdw commented 2 years ago

Yep, consult-customize works flawlessly. Thank you very much, I forgot about it.

I think that category is more apropriate than exact command, because the rule for consult-grep should also apply to consult-ripgrep, however maybe it also good idea to check if the command has a preview function, but this heuristic can fail from time to time. Anyway, consult-customize solved my issue and I'll keep current solution with categories for now.

BTW, I succesfully use vertico with mini-frame and it works quite good, but the thing, which bothers me is that child frame hides part of the buffer I work with, it is especially important with consult-line/imenu and some other commands with preview. Also, with commands like consult-imenu/outline and some others I would like to see as long list of candidates as possible to see the structure of document/module. It seems current experimental setup with mct solves it, but there are other issues/UX problems I need to figure out how to fix.

abcdw commented 2 years ago

One more question: I did (setq completion-in-region-function 'consult-completion-in-region) and now want to get category annotation.

I tried:

(consult-customize consult-completion-in-region :category 'consult-completion)
(add-to-list 'marginalia-command-categories
             ;; '(completion-in-region . consult-completion)
             ;; '(consult-completion-in-region . consult-completion)
             '(completion-at-point . consult-completion))

but only this worked:

(add-to-list 'marginalia-prompt-categories
             '("\\<completion\\>" . consult-completion))

Feels a little hacky, maybe there is a better and more perciese way to assign a category to consult-completion-in-region?

minad commented 2 years ago

It does not make sense to assign a single category to consult-completion-in-region since you complete candidates of different categories. completion-in-region is comparable to completing-read. This would be as if you assign a single category to all completions. But you can use Marginalia to still forcibly override the category. I don't recommend that though.

abcdw commented 2 years ago

Yep, probably semantically it doesn't make too much sense.

One of the reasons why I use categories: I don't know how else to understand which function I'm currently displaying completion buffer for.

minad commented 2 years ago

BTW, I succesfully use vertico with mini-frame and it works quite good, but the thing, which bothers me is that child frame hides part of the buffer I work with, it is especially important with consult-line/imenu and some other commands with preview. Also, with commands like consult-imenu/outline and some others I would like to see as long list of candidates as possible to see the structure of document/module. It seems current experimental setup with mct solves it, but there are other issues/UX problems I need to figure out how to fix.

I am also not a fan of mini-frame or child-frames. In my experience they have robustness issues, sometimes flicker and overlapping the content hurts usability. However I like to use child frames for in-buffer popups like Corfu or Company. In-buffer completion is also the only place where I use child frames in my setup in the form of my Corfu package. I prefer these popups in comparison to real buffers or the minibuffer (via consult-completion-in-region) since it feels less intrusive. There are people who argue that widget-like UIs are unEmacsy since you cannot interact with them in the same way as you can interact with buffers. They are right of course, but for me it is less important to stay 100% pure to the original Emacs interaction models as long as the components are overall non-intrusive and fit well into the ecosystem. For me the advantage of these widget like UIs is that they are specifically optimized for the task at hand.

This is also where I see the main difference between @protesilaos' Mct and Vertico. Mct offers a buffer display which allows full buffer interaction (isearch, rectangular selection etc), while Vertico is a widget (independent from where it is displayed, in buffer, child frame or minibuffer). Vertico only allows you to interact with it in the special way it has been designed. If you want to do more, use embark-collect-snapshot and go from there. The downsides are obvious and the advantage is that the workflow and performance are slightly optimized for the common case. Another advantage of Mct is that it can be operated in an even less obtrusive way by enabling it only on demand.

Anyways, your comments here inspired me to fiddle a bit around with Vertico and create the vertico-multiform extension. This solves an issue I had for quite some time: There was no easy and clean way to enable the vertico-grid/vertico-buffer/vertico-flat extensions per command or per completion category.

protesilaos commented 2 years ago

On 2021-12-26, 06:06 -0800, Daniel Mendler @.***> wrote:

Anyways, your comments here inspired me to fiddle a bit around with Vertico and create the vertico-multiform extension. This solves an issue I had for quite some time: There was no easy and clean way to enable the vertico-grid/vertico-buffer/vertico-flat extensions per command or per completion category.

Sounds great!

@abcdw I think vertico+extensions (and maybe some custom code on top) will cover all of your needs. Mct with its current limited scope is nice for experimentation or simple usage, but the more you try to push the boundaries, the more you realise that either (i) emacs.git needs to be patched extensively, or (ii) mct must change direction to basically do what vertico already does. The former is tricky. The latter would be a waste of resources.

-- Protesilaos Stavrou https://protesilaos.com

minad commented 2 years ago

Hey Prot,

Thank you!

I would like to note that my work on vertico-multiform should not imply that Andrew should drop Mct or that Vertico is better. Andrew's comment motivated me to finally solve the issue with enabling the special Vertico display configurations per command and per completion category. People had asked me before about per-command/per-category tuning and I had been aware of this deficiency.

As I mentioned I see Mct (see also @karthink's Elmo) and Vertico as occupying two different niches: Mct offers a buffer to interact with while Vertico is a widget, which has a much more restricted interaction model. Some people may like this, some may not. I think Vertico is beginner friendly and optimizes for the common usage patterns. But more experienced users like to interact more freely with the completions buffers (rectangular selection, isearch, avy etc). Personally I haven't seen the need for this but the motivation is understandable.

I don't think moving Vertico and Mct closer together is desirable. The main issue of Mct is that it can be slow for many candidates. But this is a price one necessarily has to pay with default completion/Mct. Mct has to display all candidates to allow the free form interaction and Isearch. In contrast, Vertico limits the flexibility of the user by only displaying a subset of the candidates in the buffer at once. Let's assume one would implement an optimized Completions buffer which lazily displays only a subset of candidates - then you are right, one would waste resources since Vertico is basically already that and second one looses the main advantage - the buffer would be incomplete and would not reflect the entire completion state anymore.

protesilaos commented 2 years ago

On 2021-12-26, 07:22 -0800, Daniel Mendler @.***> wrote:

I would like to note that my work on vertico-multiform should not imply that Andrew should drop Mct or that Vertico is better.

Agreed! Just to clarify that I did not imply otherwise. I simply stated my opinion earlier, which relates to the fact that mct is limited by how the "Completions" work and, by extension, most major improvements to it will have to come from changes to minibuffer.el and/or simple.el.

-- Protesilaos Stavrou https://protesilaos.com

abcdw commented 2 years ago

On 2021-12-26 10:57, Protesilaos Stavrou wrote:

On 2021-12-26, 07:22 -0800, Daniel Mendler @.***> wrote:

I would like to note that my work on vertico-multiform should not imply that Andrew should drop Mct or that Vertico is better.

Agreed! Just to clarify that I did not imply otherwise. I simply stated my opinion earlier, which relates to the fact that mct is limited by how the "Completions" work and, by extension, most major improvements to it will have to come from changes to minibuffer.el and/or simple.el.

To sum up all the things:

My primary completion UI is vertico, in rde project I implemented an experimental support for mct for people who prefer a closer to vanilla experience. Also, with mct I was trying out the workflow I described before, which turned out to be very nice BTW)

I implemented the same workflow with vertico and it works great. I stay with vertico, cause of more polished experience and performance, keep feature-emacs-mct as an alternative to feature-emacs-vertico in rde project, really like the idea of cadidates list being a normal buffer with all the normal things available.

Thank you very much both of you for the work and help!)

-- Best regards, Andrew Tropin

minad commented 2 years ago

@abcdw Regarding the performance - as Prot mentioned, the issue is that Mct would have to replace more of the core facilities, while I implement my own faster sorting, grouping and lazy highlighting in Vertico. If the core functionality would be fast enough I could also reuse it in Vertico, but unfortunately that's not the case. Vertico has stricter performance requirements since it updates more often in comparison to Mct which uses a delay. Could you be more specific about the polishing? Such feedback is helpful to improve Mct. I agree that having a normal buffer available is a nice feature. Another distinction which I haven't mentioned before is that Mct operates initially from the minibuffer prompt, while Vertico immediately selects a candidate. In Mct you have the ability to expand the completion input via completion-try-completion (TAB completion), which is close to the original completion mechanism of Emacs (even pre completion styles, where Emacs only had shell-like prefix expansion). This feature is lost by default in Vertico, since TAB in Vertico replaces the input with the currently selected candidate (this is relevant for find-file for example). With the orderless completion style the completion-try-completion feature is arguably less important, since orderless does not support prefix expansion. Nevertheless this feature can be restored in Vertico.

abcdw commented 2 years ago

On 2021-12-28 03:29, Daniel Mendler wrote:

@abcdw Regarding the performance - as Prot mentioned, the issue is that Mct would have to replace more of the core facilities, while I implement my own faster sorting, grouping and lazy highlighting in Vertico. If the core functionality would be fast enough I could also reuse it in Vertico, but unfortunately that's not the case. Vertico has stricter performance requirements since it updates more often in comparison to Mct which uses a delay. Could you be more specific about the polishing? Such feedback is helpful to improve Mct.

Sure, I already share my thought with Protesilaos in the "Split out completion UI features" thread in @.*** mailing list.

I agree that having a normal buffer available is a nice feature. Another distinction which I haven't mentioned before is that Mct operates initially from the minibuffer prompt, while Vertico immediately selects a candidate. In Mct you have the ability to expand the completion input via completion-try-completion (TAB completion), which is close to the original completion mechanism of Emacs (even pre completion styles, where Emacs only had shell-like prefix expansion). This feature is lost by default in Vertico, since TAB in Vertico replaces the input with the currently selected candidate (this is relevant for find-file for example). With the orderless completion style the completion-try-completion feature is arguably less important, since orderless does not support prefix expansion. Nevertheless this feature can be restored in Vertico.

-- Best regards, Andrew Tropin

karthink commented 2 years ago

Anyways, your comments here inspired me to fiddle a bit around with Vertico and create the vertico-multiform extension.

Wow, this is great. I had a bunch of advice set up to turn various vertico extensions on and off depending on the command, this is much simpler to use!

minad commented 2 years ago

Wow, this is great. I had a bunch of advice set up to turn various vertico extensions on and off depending on the command, this is much simpler to use!

Thanks! Please let me know how it works for you.

abcdw commented 2 years ago

On 2021-12-26 06:06, Daniel Mendler wrote:

Anyways, your comments here inspired me to fiddle a bit around with Vertico and create the vertico-multiform extension. This solves an issue I had for quite some time: There was no easy and clean way to enable the vertico-grid/vertico-buffer/vertico-flat extensions per command or per completion category.

I was playing with vertico-multiform for some time and finally commited it to rde: https://git.sr.ht/~abcdw/rde/commit/e068ec9f82d7cba4b319d006ccbaddf0c57354ee

I still have thoughts about using child frames in some cases, not sure if I implement it soon, but will keep you updated on this.

Thank you very much for making a plugin, works flawlessly.

-- Best regards, Andrew Tropin