[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [bug] Bind + readline state corruption
From: |
Chet Ramey |
Subject: |
Re: [bug] Bind + readline state corruption |
Date: |
Fri, 8 Jul 2022 16:50:02 -0400 |
User-agent: |
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:91.0) Gecko/20100101 Thunderbird/91.10.0 |
On 7/5/22 1:37 PM, Hans Kristian Otnes Berge wrote:
Bash Version: 5.1
Patch Level: 16
Release Status: release
Description:
When modifying READLINE_LINE the substitution works but when returned
to the command line, either bash or the tty has lost its state so further
attempts to edit the command results in literal control characters being
output (self-inserted) without having any other effect. A good state is
restored on the following command line. I have found a work-around so the
problem can be investigated by observing the difference in state.
It has nothing to do with modifying READLINE_LINE; the issue is calling
readline recursively from a subshell while readline is active, and having
the two instances dueling over which terminal settings are active. The
scenario goes something like this:
readline0 changes the terminal settings
read -e gets called in a subshell
readline1 notes the terminal settings have already been changed and doesn't
readline1 reads a line
readline1 restores the terminal settings to what they were initially
(when readline0 started up)
readline0 doesn't know the terminal settings have been restored
Readline doesn't restore the terminal settings to the original values when
dispatching a command bound to a key sequence. In this case, that means
that commands bound with bind -x execute in the same environment as any
other readline command (because they're readline commands).
The following seems to fix the issue for me.
bind -m vi-insert -x '"\C-b": BINDX_TTY_STATE=$(stty -g);
_RLL="${READLINE_LINE}"; _RLP="${READLINE_POINT}"; _RES=$(read -e -p "Text
to insert: " text ; echo ${text});
READLINE_LINE="${_RLL:0:${_RLP}}${_RES}${_RLL:${_RLP}}"; READLINE_POINT=$((
${#_RES} + ${_RLP} )); stty $BINDX_TTY_STATE; unset BINDX_TTY_STATE;';
I'm glad your solution -- saving and restoring the terminal settings
yourself -- works. The effect is that readline0 has the settings it
expects.
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU chet@case.edu http://tiswww.cwru.edu/~chet/