Selectrum: Require-match does not implement confirm and confirm-after-completion

Created on 10 Feb 2021  路  33Comments  路  Source: raxod502/selectrum

~~~
REQUIRE-MATCH can take the following values:

  • t means that the user is not allowed to exit unless the input is (or
    completes to) an element of COLLECTION or is null.
  • nil means that the user can exit with any input.
  • confirm means that the user can exit with any input, but she needs
    to confirm her choice if the input is not an element of COLLECTION.
  • confirm-after-completion means that the user can exit with any
    input, but she needs to confirm her choice if she called
    minibuffer-complete right before minibuffer-complete-and-exit
    and the input is not an element of COLLECTION.
  • anything else behaves like t except that typing RET does not exit if it
    does non-null completion.
    ~~~

Most helpful comment

But reading the docs again we should also treat any non-nil value but confirm and confirm-after-completion as t.

Agree

With Selectrum RET will always submit the selected candidate so this kind of accidental submission can't happen, I think an additional safe guard would probably be more annoying than it helps.

I am not sure. I wonder which commands actually use this feature. But let's assume that it is used in a german air traffic control system of the 90s, then I would probably appreciate the annoying double RET ;)

All 33 comments

I looked into this and the other values seem to make most sense for the default UI. We already don't allow exit with the prompt when the value is t and in the other cases you either have to intentionally select the prompt or it is visually indicated that is selected so the RET can be seen as the confirmation already. With default completion that is not the case as you don't have a selection there and RET can also do completion there. Maybe we should keep things like they are in this case?

I didn't really consider it makes sense to do anything here. I just thought about reporting this when I saw the completing-read documentation.

After reading the documentation again I think the Selectrum behavior is insufficient. If I am using require-match=t, I cannot return the input when it does not match a candidate. But with 'confirm option this should be possible? Now if I am using require-match=nil I can return an arbitrary value, but having only selected the prompt is not sufficient confirmation. There should be a second step.

EDIT: If one uses 'confirm, Selectrum behaves like nil, right? Then I guess it is okay, but I am missing a bit the second confirmation step. Maybe it is unnecessary. Hmm.

EDIT2: With default completion, when doing (consult--read '(a b c) :require-match 'confirm) I have to press RET twice. This is different from Selectrum, there I only have to press RET once.

If one uses 'confirm, Selectrum behaves like nil, right? Then I guess it is okay, but I am missing a bit the second confirmation step. Maybe it is unnecessary. Hmm.

Yes, we only block the t all other ones are treated like nil.

With default completion, when doing (consult--read '(a b c) :require-match 'confirm) I have to press RET twice. This is different from Selectrum, there I only have to press RET once.

With default completion you have no idea if RET will submit of complete so it makes more sense to have a separate step to avoid accidental submission. With Selectrum RET will always submit the selected candidate so this kind of accidental submission can't happen, I think an additional safe guard would probably be more annoying than it helps.

But reading the docs again we should also treat any non-nil value but confirm and confirm-after-completion as t.

But reading the docs again we should also treat any non-nil value but confirm and confirm-after-completion as t.

Agree

With Selectrum RET will always submit the selected candidate so this kind of accidental submission can't happen, I think an additional safe guard would probably be more annoying than it helps.

I am not sure. I wonder which commands actually use this feature. But let's assume that it is used in a german air traffic control system of the 90s, then I would probably appreciate the annoying double RET ;)

On Mon, Mar 22 2021, Daniel Mendler wrote:

After reading the documentation again I think the Selectrum behavior
is insufficient. If I am using require-match=t, I cannot return the
input when it does not match a candidate. But with 'confirm option
this should be possible? Now if I am using require-match=nil I can
return an arbitrary value, but having only selected the prompt is not
sufficient confirmation. There should be a second step.

[Apologies in advance if this is not related with what you're discussing
here, but it sounds as it might]

Today, i was playing with the new quick-keys in the context of a
consult-lines invocation, with orderless in my completion-styles. With
that configuration, the content of a line might not match itself (e.g.,
the line has a portion that looks like a regexp that doesn't match the
line); so, when you select the line you want with a quick key and
therefore move its contents to selectrum's prompt, you cannot select it
(i.e., jump to it by pressing RET) because require-match is t. A quick
workaround is to add orderess-literal to orderless-matching-styles, but
i am not sure i want that everywhere (and it's not a default macthing
style in orderless).

@jaor I don't see this behavior. If a line matches a candidate exactly it is selected as far as I know. Could you give a more precise example?

EDIT: Ah now I got it, you do the insertion first as @clemera remarked. @clemera why does this not work? Maybe this should really be fixed at the level of the completion style, such that exact matches are always accepted? Considering the built-in styles, basic, substring, flex will all work naturally I guess.

@jaor On another note why do you insert the line first and not directly select it using M-m?

On Mon, Mar 22 2021, Daniel Mendler wrote:

@jaor I don't see this behavior. If a line matches a candidate exactly
it is selected as far as I know. Could you give a more precise
example?

  • Go to any buffer, e.g. scratch
  • Insert these lines:

    line a [1 xd]
    line b [2 bc]
    line x [3 bd]

  • M-x consult-line

  • Narrow the candidates by typing, say line

  • Now M-i will assign to line 3 the character d

  • My expectation is that pressing d i'll jump to the third
    line. Instead, line x [3 bd] is inserted at my prompt

  • That value doesn't match any line in the buffer (because orderless is
    matching using either a regexp or initialisms), so pressing RET or
    C-j won't jump to the desired line (one gets an error, Match required,
    instead).

Isn't that what you see?

On Mon, Mar 22 2021, Clemens Radermacher wrote:

@jaor On another note why do you insert the line first and not
directly select it using M-m?

because i'm an idiot that doesn't read the documentation :) i was
imagining M-i was supposed to do what M-m does. sorry about the noise!

@jaor I see what you see. I just assumed blindly that you had problems when using the quick select (and not the quick insert). I think for the quick insert the issue you are observing is expected and should be solved at the level of the completion style (orderless?), if it should even be solved at all.

On Mon, Mar 22 2021, Daniel Mendler wrote:

@jaor I see what you see. I just assumed blindly that you had problems
when using the quick select (and not the quick insert).

Right. I was just oblivious of the existence of quick select, and
thought i had to go through insert.

I think for the quick insert the issue you are observing is expected
and should be solved at the level of the completion style
(orderless?), if it should even be solved at all.

Agreed. Maybe @oantolin could consider adding orderless-literal to the
default value of orderless-matching-styles, to minimize surprises for
newcomers. I am trying to imagine a case where i would want an exact
duplicate of what i'm completing for not to match it, and finding only
rather esoteric use cases.

I thought the consult-async commands meant we were all comfortable with the idea that completion candidates can't be relied on to match themselves! 馃槢

Agreed. Maybe @oantolin could consider adding orderless-literal to the
default value of orderless-matching-styles, to minimize surprises for
newcomers. I am trying to imagine a case where i would want an exact
duplicate of what i'm completing for not to match it, and finding only
rather esoteric use cases.

@jaor I am not sure. Even if you add literal to the defaults, Orderless still splits the input string at spaces and possibly matches more than the exact candidate you are interested in. So I think it is justified to just keep things as is.

If you want to force the exact matching you can combine orderless with substring:

~ elisp
(setq completion-styles '(substring orderless))
~

But this has other bad effects, because substring is used first and then you don't get initialism matching directly or whatever you have configured in orderless.

I thought the consult-async commands meant we were all comfortable with the idea that completion candidates can't be relied on to match themselves! stuck_out_tongue

@oantolin I agree with this :)

On Mon, Mar 22 2021, Daniel Mendler wrote:

@jaor I am not sure. Even if you add literal to the defaults,
Orderless still splits the input string at spaces and possibly matches
more than the exact candidate you are interested in. So I think it is
justified to just keep things as is.

I won't insist, but, at first blush, seeing more than one candidate is to
me less awkward than inserting the exact line i'm looking for and being
told that it doesn't exist!

@jaor I agree that it you it would be good to fix this, though it is an edge case which isn't that important but it would be good to have open a separate issue for it to keep track of it.

This issue got fixed by #510.

I agree that it you it would be good to fix this, though it is an edge case which isn't that important but it would be good to have open a separate issue for it to keep track of it.

I tried to "fix this" by setting (setq orderless-matching-styles '(orderless-regexp orderless-literal orderless-initialism)) but this does not work. However (setq orderless-matching-styles '(orderless-literal orderless-initialism)) gives the desired result at the great cost of not allowing regexps by default anymore. @oantolin Is literal somehow incompatible with regexp?

That's weird, adding orderless-literal anywhere in the orderless-matching-styles list should definitely work (unless, of course you have dispatchers that do something else). It also does seem to work here. Do you have a test case where it didn't work, @minad?

Maybe my problem was due to dispatchers. I have to investigate this better.

Just for the record, the mystery in the last couple of comments was elucidated over at oantolin/orderless#42.

On Tue, Mar 23 2021, Omar Antol铆n Camarena wrote:

That's weird, adding orderless-literal anywhere in the
orderless-matching-styles list should definitely work

it does indeed work for me.

@clemera

This commit also seems to have changed how find-file works. Now I have to confirm before making a new-file using the find-file interface? I'm not sure whether there's an option to disable this although I'd really appreciate one.

Reproduction instructions:

  1. find-file
  2. Enter and select the name of a file that doesn't exist.
  3. selectrum asks to confirm before accepting it.

@clemera @mohkale I cannot reproduce this. I don't have to confirm for new files?!

The behavior of find-file depends on the Emacs option confirm-nonexistent-file-or-buffer. Generally there is not equivalent for confirm-after-completion in Selectrum, I decided to treat it the same as confirm but looking at this it seems it might be better to not do that and treat it like nil instead?

@clemera Thank you for letting me know about this option. I think treating confirm-after-completion like confirm is correct in the context of Selectrum. Confirm means confirm, so it should happen at some point (Remember the air traffic control?).

And just recently - maybe they had their steering system running on Emacs?

image

Maybe I should also respect the setting in consult-buffer?

@clemera What is weird. On my Emacs confirm-nonexistent-file-or-buffer is set to after-completion, but the documentation of completing-read mentions confirm-after-completion. Do both symbols mean the same? Do we treat only one as confirm?

:laughing: Yes, who knows what else runs on Emacs. The symbol after-completion is treated like confirm-after-completion in this context, see the function confirm-nonexistent-file-or-buffer.

I think treating confirm-after-completion like confirm is correct in the context of Selectrum. Confirm means confirm, so it should happen at some point (Remember the air traffic control?).

I thought the same but when using find-file with confirm-after-completion/after-completion in emacs -Q you can type a non existent file name and don't need to confirm, the behavior for Selectrum is different for this case.

@clemera Great. I think I was running on and old version of Selectrum. Now it works and asks me to confirm. Regarding the treatment of after-completion, I don't really understand what this is supposed to do. I think in Selectrum it is not bad like this, asking for an additional confirmation (and one can always turn this off). But on both default completion and Icomplete setting after-completion for new files does nothing.

EDIT: Yes, we wrote at the same time.

EDIT2: I think the after-completion setting is a remnant of the past. It does not make sense anymore since it has something to do if you do TAB completion. Or did I misunderstand this? But if something is nonexistant, I cannot complete, so what does this mean? We can either err on the safe side (treat it as confirm) or ignore the setting (treat it as nil).

EDIT3: I must say, I like the additional confirmation. Since usually I don't open new files/new buffers. It is good to have this kind of interrupt. But I could also set confirm-nonexistent-file-or-buffer to confirm I guess, if I want it that badly.

The option also does not make sense to me, I don't see why pressing TAB before makes confirmation more desirable in this case. As there is no equivalent to trigger completion help/try-completion action with TAB and to match the default behavior it is probably okay to ignore it as you say you can adjust confirm-nonexistent-file-or-buffer to always get the confirmation.

@clemera

Thanks unsetting confirm-nonexistent-file-or-buffer fixed the issue for me.

@mohkale Note you don't need to unset if after a7130ca. Only need to set it to confirm (or any other non-nil value but after-completion) if you want the confirmation.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

piranha picture piranha  路  7Comments

mohkale picture mohkale  路  11Comments

grolongo picture grolongo  路  10Comments

clemera picture clemera  路  8Comments

tinglycraniumplacidly picture tinglycraniumplacidly  路  13Comments