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: 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.



reply via email to

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