Prior to this fix, when key binding is a script command (i.e. not a
readline command), fish would run that key binding using fish's shell
tty modes. Switch to using the external tty modes. This re-fixes
issue #2214.
With the upcoming fix to place the tty in external-proc mode, add a sleep
which resolves a race between emitting a newline and restoring it to shell
mode.
Prior to this change, when a process resumes because it is brought back
to the foreground, we would reset the terminal attributes to shell mode.
This fixed#2114 but subtly introduced #7483.
This backs out 9fd9f70346, re-introducing #2114 and re-fixing #7483.
A followup fix will re-fix #2114; these are broken out separately for
bisecting purposes.
Fixes#7483.
I *think* this might sometimes (on CI) be eating the prompt, so that the actual `prompt`
part of `expect_prompt` doesn't find anything.
On Github Actions we see things like:
```
Testing file pexpects/generic.py ... Failed to match pattern: prompt 5
generic.py:35: timeout from expect_prompt("echo .history.*")
[...]
OUTPUT +1.08 ms (Line 31): \rprompt 4>
INPUT +0.35 ms (Line 34): echo $history[1]\n
OUTPUT +1.58 ms (Line 35): echo $history[1]\r\necho $history[1]\r\n⏎ \r⏎ \r\rprompt 5>
```
so the prompt *is* printed, it's just not correctly matched.
Apparently on macOS SIGTSTP (from control-Z) causes `read()` to return
EINTR.
This means `cat | cat` will exit as soon as it's backgrounded and
brought back.
So instead we use `sleep`, which won't read(), and therefore is
impervious to these puny attacks.
See discussion in #7447.
The classic mistake: Some of these have a bit of a delay, but it's supposed to
be *under* the timeout, so it needs to be *shorter* not longer to
increase the slack.
We just had the following output on Github Actions:
INPUT +0.94 ms (Line 34): echo ghi jkl
INPUT +0.72 ms (Line 35): \x1b
INPUT +63.12 ms (Line 37): t\r
The default escape delay is 30ms, that had 60ms between an escape and
a tab, so it missed it.
So: We have to increase the delay for CI's benefit. Let's try with
80ms, because otherwise we'd have to bump up other timeouts and the
bind tests take long enough as it is.
Github Action's macOS builds are even more resource-starved (even tho
they use the same provider?) than
Travis, but Travis is unusable to us now, so....
In some cases the completion we come up with may be unexpected, e.g.
if you have files like
/etc/realfile
and
/etc/wrongfile
and enter "/etc/gile", it will accept "wrongfile" because "g" and
"ile" are in there - it's a substring insertion match.
The underlying cause was a typo, so it should be easy to go back.
So we do a bit of magic and let "cancel" undo, but only right after a
completion was accepted via complete or complete-and-search.
That means that just reflexively pressing escape would, by default, get you back to
the old token and let you fix your mistake.
We don't do this when the completion was accepted via the pager,
because 1. there's more of a chance to see the problem there and 2.
it's harder to redo in that case.
Fixes#7433.
This was typically overridden by "too many/few arguments", but it's
actually incorrect:
sin(55
has the correct number of arguments to `sin`, but it's lacking
the closing `)`.
We've heard news of this regressing, so let's add the test that should
have been there already (mea culpa!).
Because we now use POSIX_VDISABLE, this should also work in tandem
with ctrl-space (which sends NUL), but we can't test *that* because
some systems might not have POSIX_VDISABLE.
This switch is no longer necessary when only one command is given.
Internally completions are stored separately for each command,
so we only every print one command name per "complete" line anyway.
These aliases seem to be common, see #7389 and others. This prevents
recursion on that example, so `alias ssh "env TERM=screen ssh"` will just
have the same completions as ssh.
Checking the last token is a heuristic which hopefully works for most
cases. Users are encouraged to use functions instead of aliases.
Ensure that the increment= param is set via keyword, not via positional arg.
This mistake was masking a bug where the "^a b c" match was not being tested,
because it was being set as the value for increment!
This switches the 'increment' param from "after" to "before." Instead
of expect_prompt saying if the next prompt will be incremented, each
call site says if it should have been incremented sinec the last prompt.
I am not sure why this worked, actually.
These tests did not have $fish set anywhere, and on my fresh OpenBSD
VM it ended up calling whatever that calls "fish" (I think it's that
"Go fish!" game?).
If the padding is not divisible by the char's width without remainder,
we pad the remainder with spaces, so the total width of the output is correct.
Also add completions, changelog entry, adjust documentation, add examples
with emoji and some tests. Apply some minor style nitpicks and avoid extra
allocations of the input strings.
Prior to this change, tab completing with a variable assignment like
`VAR=val cmd<tab>` would parse out and apply VAR=val, then recursively
invoke completions. This caused some awkwardness around the wrap chain -
if a wrapped command had a variable completion we risked infinite
recursion. A secondary problem is that we would run any command
substitutions inside variable assignment, which the user does not expect
to run until pressing enter.
With this change, we explicitly track variable assignments encountered
during tab completion, including both those explicitly given on the
command line and those found during wrap chain walk. We then apply them
while suppressing command substitutions.
In preparation for applying variable assignments (VAR=VAL cmd), separate
them out from the command when performing completions. This includes both
those that the user typed, and any that come about through
completion --wraps.
The "wrap chain" refers to a sequence of commands which wrap other
commands, for completion purposes. One possibility is that a wrap chain
will produce a combinatorial explosion or even an infinite loop, so there
needs to be logic to prevent that. Part of that logic is encapsulated in a
visited set (wrap_chain_visited_set_t) to prevent exploring the same item
twice.
Prior to this change, we stored pairs (command, wrapped_command). But we
only really need to store the wrapped command. Switch to that.
One consequence is that if a command wraps another command in more than
one way, we won't explore both ways. This seems unlikely in practice.
Detect recursive calls to builtin complete and the internal completion in
the same place.
In 0a0149cc2 (Prevent infinite recursion when completion wraps variable assignment)
we don't print an error when completing certain aliases like:
alias vim "A=B vim"
But we also gave no completions.
We could make this case work, but I think that trying to salvage situations
like this one is way too complex. Instead, let the user know by printing an
error. Not sure if the style of the error fits.
We could add some heuristic to alias to not add --wraps in some cyclic cases.