When a terminal sends \x1ba, that could be either escape,a or alt-a.
Historically we've handled this with an escape delay that defaults to 30
milliseconds. If we read nothing for that time, it's escape. Otherwise it's
an alt modifier (or an escape sequence).
As a side effect of 8bf8b10f6 (Extended & human-friendly keys, 2024-03-30) we
added a new way of disambiguating escape: whenever we read the escape byte,
we immediately try another (nonblocking) read. If it succeeds, we treat it
as modifier, else it's escape. Before that commit, we didn't have a concept
of modifiers.
The new way works fine for disambiguating escape,a from alt-a (as pressed
by the user) because only for alt-a the data is sent in the same packet.
So we no longer need the escape delay to disambiguate the alt from the
escape key. Let's simplify things by not using it by default.
The escape delay as set by fish_escape_delay_ms also serves another purpose;
it allows to disambiguate "escape,a" from "escape (pause) a". For that use
case we want to keep it.
Commit 8164855b7 (Disable terminal protocols throughout evaluation, 2024-04-02)
changed where we output control sequences (to enable bracketed paste and CSI).
Likewise, f285e85b0 (Enable focus reporting only just before reading from
stdin, 2024-04-06) added control sequence output just before we read().
This output causes problems because it invalidates our stdout/stderr
timestamps, which causes us to think that a rogue background process wrote
to the terminal; we react by abandoning the current line and redrawing the
prompt below. Our fix was to refresh the TTY timestamps after we run a bind
command that might add stdout (#3481).
Since commit c3cd68dda (Process shell commands from bindings like regular
char events, 2024-03-02), this timestamp refresh logic is in the wrong place;
shell commands are run later now; we could move it but wait -
... we also need to make sure to refresh timestamps after outputting control
sequences. Since bracketed paste is enabled after CSI u, we can skip the
latter. Additionally, since we currently output control sequences before
every single top-level interactive command, we no longer need to separately
refresh timestamps in between commands.
Fixes#10409
Some terminals send the focus-in sequences ("^[I") whenever focus reporting is
enabled. We enable focus reporting whenever we are finished running a command.
If we run two commands without reading in between, the focus sequences
will show up on the terminal.
Fix this by enabling focus-reporting as late as possible.
This fixes the problem with `^[I` showing up when running "cat" in
gnome-terminal https://github.com/fish-shell/fish-shell/issues/10411.
This begs the question if we should do the same for CSI u and bracketed paste.
It's difficult to answer that; let's hope we find motivating test cases.
If we enable CSI u too late, we might misinterpret key presses, so for now
we still enable those as early as possible.
Also, since we now read immediately after enabling focus events, we can get
rid of the hack where we defer enabling them until after the first prompt.
When I start a fresh terminal, the ^[I no longer shows up.
See the changelog additions for user-visible changes.
Since we enable/disable terminal protocols whenever we pass terminal ownership,
tests can no longer run in parallel on the same terminal.
For the same reason, readline shortcuts in the gdb REPL will not work anymore.
As a remedy, use gdbserver, or lobby for CSI u support in libreadline.
Add sleep to some tests, otherwise they fall (both in CI and locally).
There are two weird failures on FreeBSD remaining, disable them for now
https://github.com/fish-shell/fish-shell/pull/10359/checks?check_run_id=23330096362
Design and implementation borrows heavily from Kakoune.
In future, we should try to implement more of the kitty progressive
enhancements.
Closes#10359
This binding is akin to ForwardSingleChar but it is "passive" in that is not
intended to affect the meta state of the shell: autocompletions are not accepted
if the cursor is at the end of input and it does not have any effect in the
completions pager.
A long standing issue is that bindings cannot mix special input functions
and shell commands. For example,
bind x end-of-line "commandline -i x"
silently does nothing. Instead we have to do lift everything to shell commands
bind x "commandline -f end-of-line; commandline -i x"
for no good reason.
Additionally, there is a weird ordering difference between special input
functions and shell commands. Special input functions are pushed into the
the queue whereas shell commands are executed immediately.
This weird ordering means that the above "bind x" still doesn't work as
expected, because "commandline -i" is processed before "end-of-line".
Finally, this is all implemented via weird hack to allow recursive use of
a mutable reference to the reader state.
Fix all of this by processing shell commands the same as both special input
functions and regular chars. Hopefully this doesn't break anything.
Fixes#8186Fixes#10360Closes#9398
Unlike C++, Rust requires "char" to be a valid Unicode code point. As a
workaround, we take the raw (probably UTF-8-encoded) input and convert each
input byte to a char representation from the private use area (see commit
3b15e995e (str2wcs: encode invalid Unicode characters in the private use
area, 2023-04-01)). We convert back whenever we output the string, which
is correct as long as the encoding didn't change since the data was input.
We also need to convert keyboard input; do that.
Quick testing shows that our reader drops PUA characters. Since this patch
converts both invalid Unicode input as well as PUA input into a safe PUA
representation, there's no longer a reason to not add PUA characters to
the commandline, so let's do that to restore traditional behavior.
Render them as � (REPLACEMENT CHARACTER); unfortunately we show one per
input byte instead of one per code point. To fix this we probably need our
own char type.
While at it, remove some special cases that try to prevent insertion of
control characters. I don't think they are necessary. Could be wrong..