This makes it so code like
```fish
echo foo
echo bar
```
is collapsed into
```fish
echo foo
echo bar
```
One empty line is allowed, more is overkill.
We could also allow more than one for e.g. function endings.
Commit e5b34d5cd (Suppress autosuggesting during backspacing like browsers do,
2012-02-06) disabled autosuggestion when backspacing. Autosuggestions are
re-enabled whenever we insert anything in the command line. Undo uses a
different code path to insert into the command line, which does not re-enable
autosuggestion.
Fix that.
Also re-enable autosuggestion when undo erases from the command line.
This seems like the simplest approach. It's not clear if there's a better
behavior; browsers don't agree on one in any case.
This is the last remnant of the old percent expansion.
It has the downsides of it, in that it is annoying to combine with
anything:
```fish
echo %self/foo
```
prints "%self/foo", not fish's pid.
We have introduced $fish_pid in 3.0, which is much easier to use -
just like a variable, because it is one.
If you need backwards-compatibility for < 3.0, you can use the
following shim:
```fish
set -q fish_pid
or set -g fish_pid %self
```
So we introduce a feature-flag called "remove-percent-self" to turn it
off.
"%self" will simply not be special, e.g. `echo %self` will print
"%self".
This stops you from doing e.g.
```fish
set pager command less
echo foo | $pager
```
Currently, it would run the command *builtin*, which can only do
`--search` and similar, and would most likely end up printing its own
help.
That means it very very likely won't work, and the code is misguided -
it is trying to defeat function resolution in a way that won't do what
the author wants it to.
The alternative would be to make the command *builtin* execute the
command, *but*
1. That would require rearchitecting and rewriting a bunch of it and
the parser
2. It would be a large footgun, in that `set EDITOR command foo` will
only ever work inside fish, but $EDITOR is also used outside.
I don't want to add a feature that we would immediately have to discourage.
Commit b768b9d3f (Use fuzzy subsequence completion for options names as well,
2024-01-27) allowed completing "oa" to "--foobar", which is a false positive,
especially because it hides other valid completions of non-option arguments.
Let's at least require a leading dash again before completing option names.
Version 2.1.0 introduced subsequence matching for completions but as the
changelog entry mentions, "This feature [...] is not yet implemented for
options (like ``--foobar``)". Add it. Seems like a strict improvement,
pretty much.
Issue #10194 reports Cobra completions do
set -l args (commandline -opc)
eval $args[1] __complete $args[2..] (commandline -ct | string escape)
The intent behind "eval" is to expand variables and tildes in "$args".
Fair enough. Several of our own completions do the same, see the next commit.
The problem with "commandline -o" + "eval" is that the former already
removes quotes that are relevant for "eval". This becomes a problem if $args
contains quoted () or {}, for example this command will wrongly execute a
command substituion:
git --work-tree='(launch-missiles)' <TAB>
It is possible to escape the string the tokens before running eval, but
then there will be no expansion of variables etc. The problem is that
"commandline -o" only unescapes tokens so they end up in a weird state
somewhere in-between what the user typed and the expanded version.
Remove the need for "eval" by introducing "commandline -x" which expands
things like variables and braces. This enables custom completion scripts to
be aware of shell variables without eval, see the added test for completions
to "make -C $var/some/dir ".
This means that essentially all third party scripts should migrate from
"commandline -o" to "commandline -x". For example
set -l tokens
if commandline -x >/dev/null 2>&1
set tokens (commandline -xpc)
else
set tokens (commandline -opc)
end
Since this is mainly used for completions, the expansion skips command
substitutions. They are passed through as-is (instead of cancelling or
expanding to nothing) to make custom completion scripts work reasonably well
in the common case. Of course there are cases where we would want to expand
command substitutions here, so I'm not sure.
Commit 5f849d0 changed control-C to print an inverted ^C and then a newline.
The original motivation was
> In bash if you type something and press ctrl-c then the content of the line
> is preserved and the cursor is moved to a new line. In fish the ctrl-c just
> clears the line. For me the behaviour of bash is a bit better, because it
> allows me to type something then press ctrl-c and I have the typed string
> in the log for further reference.
This sounds like a valid use case in some scenarios but I think that most
abandoned commands are noise. After all, the user erased them. Also, now that
we have undo that can be used to get back a limited set of canceled commands.
I believe the original motivation for existing behavior (in other shells) was
that TERM=dumb does not support erasing characters. Similarly, other shells
like to leave behind other artifacts, for example when using tab-completion
or in their interactive menus but we generally don't.
Control-C is the obvious way to quickly clear a multi-line commandline.
IPython does the same. For the other behavior we have Alt-# although that's
probably not very well-known.
Restore the old Control-C behavior of simply clearing the command line.
Our unused __fish_cancel_commandline still prints the ^C. For folks who
have explicitly bound ^C to that, it's probably better to keep the existing
behavior, so let's leave this one.
Previous attempt at #4713 fizzled.
Closes#10213
The C++ code implicitly relied on wrapping behavior.
There are probably more cases like this. Maybe we should disable
"overflow-checks" in release mode.
This would crash from the highlighter for something like
`PATH={$PATH[echo " "`
The underlying cause is that we use "char_at" which panics on
overread.
So instead this implements try_char_at and then just returns None.
This would misname `\e\x7F` as "backspace":
bind -k backspace 'do something'
bind \e\x7F 'do something'
because it would check if there was any key *in there*.
This was probably meant for continuous mode, but it simply doesn't
work right. It's preferable to not give a key when one would work over
giving one when it's not correct.
This was an issue with "--no-execute", which has no variables and
therefore no $HOME:
```fish
fish --no-execute /path/to/file
```
would say the error is in `~/path/to/file`.
Instead, since this is just for a message, we simply return the
filename without doing the replacement.
Fixes#10171