bug-readline
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: rl_complete(0, '?') should never insert into the line buffer


From: Pip Cet
Subject: Re: rl_complete(0, '?') should never insert into the line buffer
Date: Thu, 23 May 2024 20:41:12 +0000

On Thu, May 23, 2024 at 3:48 PM Chet Ramey <chet.ramey@case.edu> wrote:
Please forgive me for reordering your email a little, but I think it's
best if we start with this:

> The appropriate fix is to separate the behavior of
> `possible-completions' and consecutive invocations of `complete' so that
> using M-? doesn't result in a completion being inserted.
> That will be
> in the next version of bash/readline, and it's in the respective devel
> git branches now. I'm not sure that's going to help your particular use
> case, though.

If M-? is fixed never to insert text, that addresses this bug. There
appears to be a separate and very recent readline bug which makes TAB
after a failed completion list completions rather than insert a unique
completion, but I hadn't even noticed that one; it doesn't appear with
my system version of readline, and it doesn't appear with the devel
branch of readline, but it does appear with the master branch of
readline.

I think you're saying both the bug I reported and the separate bug
introduced in readline fairly recently will be fixed? That's great! If
that's true, please feel free to disregard the rest of this email.

> On 5/22/24 8:03 AM, Pip Cet wrote:
> > x x BACKSPACE x x
> >
> > with automatic completions before and after the BACKSPACE, will result
> > in the line buffer showing "xyz xx". The expected output is "xxx".
> >
> > It's this code in complete.c:
> >
> >      case '?':
> >        /* Let's try to insert a single match here if the last completion 
> > failed
> >       but this attempt returned a single match. */
> >        if (saved_last_completion_failed && matches[0] && *matches[0] &&
> > matches[1] == 0)
> >      {
> >        insert_match (matches[0], start, matches[1] ? MULT_MATCH :
> > SINGLE_MATCH, &quote_char);
> >        append_to_match (matches[0], delimiter, quote_char, nontrivial_lcd);
> >        break;
> >      }
> >
> > The code in question seems extremely questionable to me: '?' is meant
> > to LIST completions (non-destructively), not insert a completion.
> > Again, with most applications, it's valid and useful to continue
> > typing in something that doesn't match a completion.
>
> Consider the case that this is designed to address:

Can you expand that example a little? I think there's a
misunderstanding here somewhere, and I strongly suspect it's on my
part.

Here are the two interpretations I have of what you describe, using
bash and default key bindings:

1. user is in a directory with no x* files.
2. user enters c a t > x TAB
3. no completions appear
4. user goes to another window and creates "xyz"
5. user enters TAB again
6. The command line now reads "cat>xyz"

That interpretation works with and without the code in question, using
my system version of readline and bash. It appears to fail with the
current master branch of readline, but that's a separate bug entirely.

The other one is:

1. user is in a directory with no x* files.
2. user enters c a t > x TAB
3. no completions appear
4. user goes to another window and creates "xyz"
5. user enters M-?
6. The command line now reads "cat>xyz"

> They then go off to another window and fix whatever the problem was, and
> come back and try completion again.

Except they don't "try completion": they invoke a command specifically
documented to LIST available completions, not insert them at point.
Using default key bindings, they made the choice not to use the TAB
key, but to hit M-? instead.

> Since the last readline command was
> attempted completion,
> the default behavior is to list possible completions,

the behavior of TAB or M-? ? The code I referenced does not depend in
any way on what the last readline command was, it just checks the last
completion command, which may have been a while ago, failed.

Consider this:

0. you're in a fresh shell (this is important)
1. you're in a directory containing a single file called "xyz"
2. you enter c a t SPACE a b c RET
3. the file doesn't exist and an error message is printed
4. you enter c a t SPACE x M-?
5. you see a single completion listed, "xyz"
6. the command line still reads "cat x"

versus this:

1. you're in a directory containing a single file called "xyz"
2. you enter c a t SPACE a b c TAB RET
3. the file doesn't exist and an error message is printed
4. you enter c a t SPACE x M-?
5. you see no completions
6. the command line reads "cat abc xyz"

So to know what M-? does, the user has to remember the result of the
last attempted completion, no matter how long ago that was, and how
many intervening completion-free commands were executed.

> but in this case, listing a single completion that the user knows is there
> is pretty hostile.

I struggle to follow this. Maybe it's the default keybindings
confusing me, but I assume most users who have M-? rebound to TAB
specifically decided they don't want TAB to insert a completion, ever.

> It's better to just insert the single completion, since
> there is one, and go on.

It may lead to the production of a command line which would remove or
modify a file you never intended to, which is why you used M-?, not
TAB. I fail to see how that is better, in general.

> > Let's just remove this special case: it's undocumented, violates the
> > distinction between text-modifying and non-destructive calls of
> > rl_complete, it's useless for applications where non-completed words
> > are still valid input, and it complicates things.
>
> No, it's valuable.

You're saying it's valuable for M-? to insert completions at point?
That's the behavior I want to remove.

I did briefly try the devel version of readline, but it didn't work at
all for my application, most likely because I'm doing something wrong,
so I couldn't check whether the bug still existed there.

Thanks!
Pip



reply via email to

[Prev in Thread] Current Thread [Next in Thread]