[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: |
Thu, 02 Nov 2023 22:31:27 +0100 |
User-agent: |
Evolution 3.50.1-1 |
Hey.
On Fri, 2023-10-27 at 15:53 -0400, Chet Ramey wrote:
> > But one thing could indeed work - at least in the sense that it
> > fails
> > more or less "gracefully":
> > Allow to make bindings readonly, i.e. once set in that fashion,
> > they
> > cannot be changed anymore during the lifetime of the shell.
>
> I'm not enthusiastic about that. It flies in the face of one
> essential
> readline feature: the ability to customize any keybinding.
Yes. Just wanted to point out that in principle this would be an
alternative.
> > > > 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).
> > >
> > > Yes, those variables would be in the shell environment, but an
> > > internal
> > > readline function would never modify them.
> > >
> > > The READLINE_* variables are an application-specific way for an
> > > application
> > > using readline (bash) to communicate changes back to readline
> > > about
> > > changes
> > > to the internal line buffer it uses made by a bindable command.
> > > This
> > > function (the one installed by bind -x) is, from readline's
> > > perspective,
> > > just another bindable function that may modify that line buffer.
> > > The
> > > internal readline functions that this new option would execute
> > > would
> > > operate on the internal readline line buffer as they always do.
> >
> > Well that's what I meant, I guess?!
>
> Then you understand that bind -e (or whatever) would not have any
> effect
> on the data held in the READLINE_ variables, and the state of those
> variables wouldn't be reflected back into readline's line buffer
> until
> the function bound by bind -x finished executing.
No, I didn't.
> The basic readline execution loop looks like this:
>
> 1. read characters from the input until they resolve to a readline
> function;
> 2. execute that function, expecting it to update any or all of
> rl_line_buffer, rl_point, rl_mark, and rl_end;
> 3. invoke redisplay to display the new line
>
> So a function invoked by a key sequence bound with bind -x executes
> as step 2, just like readline's `forward-char' bindable command.
I think in the last mail you anyway said that you wouldn't want to
allow -e to do anything else but calling a readline function, which I
thought made sense.
Calling a readline function however makes anyway only sense when one is
either interactively right at the readline, or shell code executes via
bind -x, doesn't it?
So if we had a bind -e, wouldn't it already make sense and work for the
case when it's called from bind -x, i.e. in my naive understanding it
would also be at step 2.
Or is the problem here, that e.g. for bind -e accept-line to work (as
I'd need it in my use case) it would need to finalise steps 2 and 3,
but then continue in 2 with the remaining code for the -x ?
> No, not at least as we're discussing it. Readline's line buffer would
> be
> in the same state it was when it returned the last line to the
> caller. In
> this scenario, readline is not active when bind -e is executed.
>
> It won't be active again until bind finishes executing and bash goes
> back to get another line of input, and that's when it will
> reinitialize
> its line state variables.
>
> What you'd probably see is the same `bind -e' command echoed to the
> display, but I haven't written any code to test, and it's dependent
> on
> what the redisplay code thinks the current state of the displayed
> line is.
>
> So it doesn't appear that something like bind -e would be useful, at
> least not as useful as something like M-x, for this use case.
Well I guess I can only say little to nothing to that. I have no real
clue about the internal workings of bash and readline.
I guess you know what my use-case is and what my idea was to solve it
more cleanly than by the other approaches,... but if you say that's
technically not possible,... well than I guess it's simply like that.
If however, you do see some behaviour that would work and make sense
(whilst still being usable for my use-case), then I'd be of course
interested in it. :-)
> Like I said, I haven't written any code, so maybe? It depends on the
> behavior of accept-line: that it performs an out-of-sequence
> redisplay.
> But if the code sequence bound to ^F modified the READLINE_ variables
> then it's likely that the line readline returns to bash isn't what
> accept-line displays on the screen, which is going to surprise some
> people
> and anger others.
Would there be a way to redraw-current-line or some new function to
also re-evaluate the prompt string?
That would of course only help in my specific use-case, if at all, but
I would imagine that I could then do something like this:
printf '%s\n' "${PS1@P}cd /tmp" # do, as if the user would have typed the
command
history -s "cd -- $newdir" # add it to the history
cd -- $newdir # this would not yet update and prompt,
history or print the command
So far this works of course already now, but at that point, when the
bind -x function returns, the prompt would still be the old one, with
the old CWD.
But I guess the problem with this approach would be, that it's no real
new approach but basically comes back to the same problems that calling
accept-line has, namely either having to trust/hope that some helper
bindings are still as defined, or needing to do hacks as with the DSR
escape sequences.
> > Well I mostly just wrote it, cause I've assumed you wanted a
> > description on what should/could happen under all circumstances.
>
> I do. That's how we figure out whether this is worth the work.
I'm afraid that I probably cannot really contribute that much here :-(
Thanks,
Chris.
- Re: could there be a bash built-in that allows executing readline functions?,
Christoph Anton Mitterer <=