This is similar to f7dac82ed (Escape separators (colon and equals) to improve
completion, 2019-08-23) except we only escape : and = if they are the result of
file completions. This way we avoid issues with custom completions like dd.
This also means that it won't work for things like __fish_complete_suffix
[*] but that can be fixed later, once we can serialize the DONT_ESCAPE flag.
By moving the escaping step earlier, this causes some unit test changes
which should not result in actual behavior change.
See also #6099
[*]: The new \: and \= does not leak from "complete -C" because that command
unescapes its output -- unless --escape is given.
Another consequence of a583fe723 ("commandline -f foo" to skip queue
and execute immediately, 2024-04-08) is that "commandline -f repaint"
will paint the prompt with the current value of $status which might be
set from a shell command in a the currently executing binding, instead of
waiting for the top-level status. This is wrong, at least historically. It
surfaces in bindings like alt-w which always paint a status value of [1]
when on single-lines commandlines.
Another regression is that a redundant repaint in a signal handler outputs
an extra prompt.
Fix both by making repaint commands go over the input queue again. This way,
they are always run with a good commandline state. There is no need to
repaint immediately because I don't think anyone has a data dependency on it
(we currently don't expose the prompt string), it's only for rendering.
We sometimes leak ^[[I and ^[[O focus reporting events when run from VSCode's
"Run python file" button in the top right corner. To reproduce I installed
the ms-python extension set the VSCode default shell to fish and repeatedly
ran a script that does "time.sleep(1)". I believe VSCode synthesizes keys
and triggers a race condition.
We can probably fix this but I'm not sure when I'll get to it (given how
relatively unimportant this feature is).
So let's go back to the old behavior of only enabling focus reporting in tmux.
I believe that tmux is affected by the same VSCode issue (also on 3.7.1 I
think) but I haven't been able to get tmux to emit focus reporting sequences
yet. Still, keep it to not regress cursor shape (#4788). So far this is
the only motivation for focus reporting and I believe it is only relevant
for terminals that can split windows (though there are a bunch that do).
Closes#10448
While it does need to store the string, we also need to use the string after
storing it, so we aren't getting any advantage from passing by value. Just pass
by reference to simplify the call sites.
This is another problem that has been bothering me for years: as mentioned
in 1dd901e52 (Maintain cursor in history prefix search, 2024-04-12), up-arrow
search highlights search matches but the contrast is really bad, especially in
command position, because the search matches --background=brblack is combined
with whatever foreground syntax highlighting the command has. The history
pager had a similar problem (for the selected history item) but circumented
it by disabling syntax highlighting altogether for the selected item.
fish_color_search_match's foreground component is ignored.
Let's use it instead of syntax highlighting.
This fixes the contrast on some default colorschemes but the bryellow
foreground looks weirdly like an error/warning on some terminals. Change it
to white. This needs a hack because we don't have a canonical way to tell
if a uvar has been set by the user. Fortunately the foreground component
hasn't been used at all so far, so we're not so much changing it as much as
initializing it.
On Konsole with
function my-bindings
bind --preset --erase escape
bind escape,i 'echo escape i'
end
set fish_key_bindings my-bindings
the "escape,i" binding doesn't trigger. This is because of our special
handling of the escape key prefix. Other multi-key bindings like "bind j,k"
wait indefinitely for the second character. But not "escape,i"; that one
has historically had a low timeout (fish_escape_delay_ms). The motivation
is probably that we have a "escape" binding as well that shouldn't wait
indefinitely.
We can distinguish between the case of raw escape sequence binding like "\e123"
and a binding that talks about the actual escape key like "escape,i". For the
latter we don't need the special treatment of having a low timeout, so make it
fall back to "fish_sequence_key_delay_ms" which waits indefinitely by default.
When we read bytes like \xfc that don't produce a Unicode code point,
we encode them in a Unicode private use area.
This encoding should be transparent to the user.
We accidentally add it to uvar files as \uf6fc in this case. When reading
it back, read_unquoted_escape() will fail at the "fish_reserved_codepoint(c)"
check. This check is to avoid external input being misinterpreted
as one of our in-band signalling characters like ANY_CHAR (for *).
For encoded raw bytes, this check probably doesn't really matter in terms of
security because the only thing we do with these bytes is convert them back
to raw. So we could allow unescaping them at this point, thus supporting
old uvar files.
However that seems like the wrong direction. PUA encoding should never leak.
So let's instead make sure to serialize it as \xfc instead of \f6fc going
forward.
Fixes#10313
Popular operating systems support shift-delete to delete the selected item
in an autocompletion widgets. We already support this in the history pager.
Let's do the same for up-arrow history search.
Related discussion: https://github.com/fish-shell/fish-shell/pull/9515
On
a;
we don't expand the abbreviation because the cursor is right of semicolon,
not on the command token. Fix this by making sure that we call expand-abbr
with the cursor on the semicolon which is the end of the command token.
(Now that our bind command execution order is less surprising, this is doable.)
This means that we need to fix the cursor after successfully expanding
an abbreviation. Do this by setting the position explicitly even when no
--set-position is in effect.
An earlier version of this patch used
bind space self-insert backward-char expand-abbr or forward-char
The problem with that (as a failing test shows) was that given "abbr m
myabbr", after typing "m space ctrl-z", the cursor would be after the "m",
not after the space. The second space removes the space, not changing the
cursor position, which is weird. I initially tried to fix this by adding
a hack to the undo group logic, to always restore the cursor position from
when begin-undo-group was used.
bind space self-insert begin-undo-group backward-char expand-abbr end-undo-group or forward-char
However this made test_torn_escapes.py fail for mysterious reasons.
I believe this is because that test registers and triggers a SIGUSR1 handler;
since the signal handler will rearrange char events, that probably messes
with the undo group guards.
I resorted to adding a tailor-made readline cmd. We could probably remove
it and give the new behavior to expand-abbr, not sure.
Fixes#9730
File names that have lots of spaces look quite ugly when inserted as
completions because every space will have a backslash.
Add an initial heuristic to decide when to use quotes instead of
backslash escapes.
Quote when
1. it's not an autosuggestion
2. we replace the token or insert a fresh one
3. we will add a space at the end
In future we could relax some of these requirements.
Requirement 2 means we don't quote when appending to an existing token.
Need to find a natural behavior here.
Re 3, if the completion adds no space, users will probably want to add more
characters, which looks a bit weird if the token has a trailing quote.
We could relax this requirement for directory completions, so «ls so»
completes to «ls 'some dir with spaces'/».
Closes#5433
On Konsole, given
bind escape,i 'echo escape i'
bind alt-i 'echo alt-i'
pressing alt-i triggers the wrong binding. This is because we treat "escape
followed by i" as "alt-i". This is to support raw sequences like "\ei"
which are probably meant as "alt-i" -- we match such inputs to both mappings.
This double matching is not necessary for new-style bindings which
unambiguously describe the key presses, so let's activate this sequence
matching only for bindings specified as raw sequences.
Conversely, we currently fail to match an XTerm raw binding for ctrl-enter:
echo 'XTerm.vt100.formatOtherKeys: 0' | xrdb
xterm -e fish
bind \e\[27\;5\;13~ execute
because we decode this to a single char; we match the leading CSI but not
the entire sequence. So this is a raw binding where we accidentally
match full, modified keys. Fix that too (two birds with one stone).
I think commit 8386088b3 (Update commandline state changes eagerly as well,
2024-04-11) broke the alt-s binding.
This is because we update the commandline state snapshot (which is consumed
by builtin commandline and others) only at key points. This seems like a
dubious optimization. With the new streamlined bind execution semantics,
this doesn't really work anymore; any shell command can run any number of
commands like "commandline -i foo" which should synchronize.
Do the simple thing of calculating the snapshot whenever needed.
The search term highlighting looks looks really bad on the default theme
because the command is highlighted as dark blue and the search term adds
a dark background. If this new feature motivates us to finally fix this,
that would be great.
Closes#10430
The new reader_execute_readline_cmd() runs apply_commandline_state_changes()
to make sure that given
bind x "commandline --insert foo; commandline -f backward-char"
the backward-char command knows about the insertion of "foo". This
causes problems when running "sleep 1&" and typing some characters -
the commandline will be cleared when the job finishes. This is because
apply_commandline_state_changes() works with stale information in this case.
Let's call it as soon as we know it's needed. This is less messy and fits
better with the new bind function semantics ("execute things in the order
they are written").
This makes them more convenient to use interactively, similar to the existing
\c and \a versions. The resulting bind output keeps using the canonical
ctrl/alt version.
Not sure about s- because that's somewhat ambiguous, it could be "super".
See the parent commit for some context. Turns out that 8bf8b10f6 (Extended &
human-friendly keys, 2024-03-30) broke this for terminals that speak CSI u.
This is pretty complex, probably not worth it.
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.
As mentioned in 8a7c3ceec (Don't abandon line after writing control sequences,
2024-04-06) we need to freshed stdout timestamps after writing to stdout
but before we might redraw, in particular when writing control sequences.
Commit a583fe723 ("commandline -f foo" to skip queue and execute immediately,
2024-04-08) made "commandline -f repaint" redraw immediately, while still
executing the bound shell command; at that time we have written "disabling"
sequences but not refreshed timestamps yet, so do that.
This is probably not needed for commands outside the repaint family.
Needless to say that this is messy, maybe we can simplify things in future.
Ref https://github.com/fish-shell/fish-shell/issues/10409#issuecomment-2044863817
If a key's codepoint is in the PUA1 range, it could
be either from our own named keys (like key::Space)
or from a CSI u key that we haven't assigned a name yet
https://sw.kovidgoyal.net/kitty/keyboard-protocol/#functional-key-definitions
(The latter can still be bound using the \u1234 or the equivalent \e[4660u
raw CSI u sequence.)
It doesn't make sense to insert a PUA character into the commandline when
the user presses PrintScreen; ignore them silently.
This partially reverts b77d1d0e2 (Stop crashing on invalid Unicode input,
2024-02-27). That commit did:
1. convert input byte sequences that map to a PUA codepoint into several
characters, using our on-char-per-byte PUA encoding.
2. do the same for inputs that are codepoints outside the valid Unicode range.
3. render them as replacement character (one per input byte)
In future, we should probably remove these features altogether, and simply
ignore invalid Unicode code points.
Commit c3cd68dda (Process shell commands from bindings like regular char
events, 2024-03-02) mentions a "weird ordering difference".
The issue is that "commandline -f foo" goes through the input
queue while other commands are executed directly.
For example
bind ctrl-g "commandline -f end-of-line; commandline -i x"
is executed in the wrong order. Fix that.
This doesn't yet work for "commandline -f exit" but that can be fixed easily.
It's hard to imagine anyone would rely on the existing behavior. "commandline
-f" in bindings is mostly used for repainting the commandline.
If a binding was input starting with "\e", it's usually a raw control sequence.
Today we display the canonical version like:
bind --preset alt-\[,1,\;,5,C foo
even if the input is
bind --preset \e\[1\;5C foo
Make it look like the input again. This looks more familiar and less
surprising (especially since we canonicalize CSI to "alt-[").
Except that we use the \x01 representation instead of \ca because the
"control" part can be confusing. We're inside an escape sequence so it seems
highly unlikely that an ASCII control character actually comes from the user
holding the control key.
The downside is that this hides the canonical version; it might be surprising
that a raw-escape-sequence binding can be erased using the new syntax and
vice versa.