help-bash
[Top][All Lists]
Advanced

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

Re: could there be a bash built-in that allows executing readline functi


From: Christoph Anton Mitterer
Subject: Re: could there be a bash built-in that allows executing readline functions?
Date: Tue, 24 Oct 2023 21:16:41 +0200
User-agent: Evolution 3.50.0-1

Hey.


On Tue, 2023-10-24 at 12:06 -0400, Chet Ramey wrote:
> If there were a key binding that was, by default, bound to something
> like execute-named-command, wouldn't it be the user's responsibility
> if
> they bound it to something else?

I would say that for the \ec I've used in my examples - that is the one
where the user says: use that keyseq to run that widget in my bash.

But not for any helper keyseqs that are in principle only needed
internally.

Sure, we can now simply define the others as being in the user's
responsibility, too. But I don't think it's feasible for the user in
the real world to check all these things.

Take the example of fzf's integration scripts:
- They use the \e[5n -> \e[0n trick, but there is no warning anywhere
  that this is needed. And let's be honest, even if there were, how
  would care?
- They also assume numerous other keyseqs to be in their default state:
  
https://github.com/junegunn/fzf/blob/b1a0ab8086f061640948299b9ed90a6b0c61c143/shell/key-bindings.bash#L131


I think it should not be the users responsibility to check whether all
such tools work nicely together.
At least not, if it's in principle possible that the tool assures that
on its own


> >    That it works itself (and doesn't break anything else) depends
> > fully
> >    on the likeliness that one uses keyseqs that no-one else use.
> 
> How likely do you think this is?

If I were to use \e[5n it seems already quite likely (e.g. fzf uses it
too) and if I'd follow Koichi's recommendation of using invalid
overlong UTF-8 encodings,... well it seems still somewhat possible.

When there was the pandemic and we had to give some of our lectures via
remote (and also hold the exams via remote)... the best way of catching
cheating students was because they literally copied the same mistakes.

And even if it was super unlikely, ... the risk of executing some
arbitrary command seems still too much.


> >    Chances may be small, yes, but still seems a risk I wouldn't
> > want to
> >    be responsible for.
> 
> Even if you were to document the bindings this approach uses (which
> may
> be an arbitrary number of characters)?

As said before,... do you really think that people will read this and
then have the time to thoroughly check? TBH, I wouldn't ^^
And even if they'd do for my tool, there's no guarantee that no other
such tool they use, doesn't do any such documentation but still breaks
it.

> 
> > 
> > - "my" approach:
> >       bind -x '"\ec":    store_and_set'
> >       bind    '"\e[0n":  "\xC0\r\xC0\a"'
> >       bind    '"\xC0\r": accept-line'
> >       bind -x '"\xC0\a": restore_and_set'
> >     with store_and_set and set eventually printing \e[5n ...
> >     has the advantage that it can set all binds other than the main
> > one
> >     (\ec) in store_and_set, where it also removes all other
> > bindings to
> >     make sure that nothing is in the queue right after \ec and with
> >     some tricks one can IMO even prevent any bigger damage in case
> > any
> >     of the 3 other bindings were in the queue.
> >     By restoring the original bindings, the shell should never see
> >     any other binding than the one for \ec, so one can avoid to
> >     accidentally break other stuff.
> 
> This seems to be the key concern.

But really in both directions: me not breaking anything else, nothing
else being able to break mine.


> > Both suffer from the problem, that PROMPT_COMMAND or PS1 (and
> > perhaps
> > even by other means I'm not aware of) the bindings may be broken
> > again,
> > after the accept-line.
> 
> If the user does this, how can your code be responsible? Anyone can
> override any readline keybinding, and I don't feel responsible if
> someone binds something new to, say, ^A.

Admittedly, the case with PROMPT_COMMAND or PS1 is really awkward.
But still... one doesn't know what people do (without knowing what they
do).

Take that nice piece of code from Koichi:
https://lists.gnu.org/archive/html/help-bash/2022-02/msg00023.html

A user may take it, only want it to be active when e.g. working in some
project dirctory, and thus set and unset it via PROMPT_COMMAND,
depending on the CWD.
If I were now to use the very same keyseqs... it could already cause
troubles.

And I don't think it's necessarily immediately available for the user,
that this may cause troubles.
The user just wants some nice tool to get working (I mean that's how I
got now into all this without being a bash expert, cause I wanted fzf
integration, but the upstream one is limited).


> > My hope was - and of course I may be totally wrong - that a built-
> > in
> > that allows me to execute the accept-line from the function would
> > make
> > all the voodoo unnecessary and be safe in all cases, like that:
> >    bind -x '"\ec": dir="$(find) | fzf)"; store_current_readline;
> > READLINE_LINE="$dir";   magic_built_in accept-line;  
> > restore_old_readline'
> > 
> > No multiple bindings needed, no fragile functions, no awk, sed,
> > whatsoever.
> 
> It might make some things easier. I'm not convinced about the safety
> concerns.

Well it's anyway just a question whether it could be done. :-)



> > Before I've ended up asking on help-bash for help, I did of course
> > search for solutions on stackoverflow and the likes.
> > Seems, that there were quite some questions like "how can one
> > execute
> > two readline functions in a row".
> 
> Using a macro with key bindings?

You mean Koichi's approach like in the:
   bind '"\ec":"\xC0\a\xC0\r\xC0\n"'
being the "staring point" and further bindings doing the actual stuff?

Well... works, but AFAIU it always depends on the assumption that there
are no usage collisions of the same keyseqs, which IMO one can assume
to be save if everyone writes all his bashrc code himself, but no
longer to be 100% safe, when one uses other frameworks like bash-
completion, copied code snippets or tools like what I'm working on.


> Let's conduct a thought experiment. Say I added some new option to
> `bind'
> for this (this clearly does not deserve its own builtin). Under what
> conditions should it execute? What should it assume about readline's
> state or the state of the objects readline exports (line buffer,
> etc.)?
> The executing part is easy: take a string, look up a function, and
> execute it.

Uhm, difficult to say. As you may have noticed, I'm far from being a
bash/shell expert.

I would have naively assumed it to be similar like bind -x ... just
that it doesn't set up a new binding but execute either a keyseq macro
or a readline function.
So let's call it bind -e (for "e"xecute macro/function).

So presumably it would also see the READLINE_* vars, just as the code
from -x does? And if called via -x (as it would be the case in my
example) it would of course see the READLINE_* from that (which is
anyway the same).

It would also see any other bindings as they are at the point of being
executed.
So I guess when one would execute:
  bind -e "foobar"
it would be as if someone just typed foobar (obviously one would need a
way to differentiate between macros and functions).


> But how do you want to guarantee it executes on something
> reasonable?

You mean when this would be executed e.g. from a script and there is no
readline? Uhm not sure...

Aren't there two things?
1. executing some macro, like the \xC0\a\xC0\r\xC0\n
2. executing some readline function

(1) would just behave as if the user has typed those keyseqs, so
regardless of where (on the readline, during a function) (1) would be
executed, it would always be some defined state.

(2) would then probably only make sense if one is either live on the
readline OR while executing bind -x code?
If neither is the case... I don't know... it should probably lead to an
error? But perhaps there are people with uses cases that want that to
be queued up for until the next time readline is back in control?



On Tue, 2023-10-24 at 14:32 -0400, Chet Ramey wrote:
> Should this mode run multiple readline commands per invocation?

I'm not sure whether I understand this.
You mean that I could do in the case (2):
   bind -e "accept-line, redraw-current-line"

And get those executed in sequence? I guess it would make sense, but I
probably don't understand all implications.


> How
> about numeric arguments?

Uhm, no idea ^^



Thanks,
Chris.



reply via email to

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