Commit graph

234 commits

Author SHA1 Message Date
Johannes Altmanninger
610338cc70 On undo after execute, restore the cursor position
Ever since 149594f974 (Initial revision, 2005-09-20), we move the
cursor to the end of the commandline just before executing it.

This is so we can move the cursor to the line below the command line,
so moving the cursor is relevant if one presses enter on say, the
first line of a multi-line commandline.

As mentioned in #10838 and others, it can be useful to restore the
cursor position when recalling commandline from history. Make undo
restore the position where enter was pressed, instead of implicitly
moving the cursor to the end. This allows to quickly correct small
mistakes in large commandlines that failed recently.

This requires a new way of moving the cursor below the command line.
Test changes include unrelated cleanup of history.py.
2024-12-21 13:10:34 +01:00
Fabian Boehm
95f4c9c07e One more FreeBSD-only-in-CI 2024-12-15 17:38:37 +01:00
Fabian Boehm
8add30e3bf pexpects: Disable exit on CI Darwin/FreeBSD 2024-12-15 17:33:12 +01:00
Fabian Boehm
cb3fbd3a5c pexpects: Disable 2 only on CI
As the comment says
2024-12-15 17:32:47 +01:00
Peter Ammon
5c8b6adc2c Fix infinite prompt loop if status message is printed in prompt
fish will print messages for some jobs when they exit abnormally, such as
with SIGABRT. If a job exits abnormally inside the prompt, then (prior to
this commit) fish would print the message and re-trigger the prompt, which
could result in an infinite loop. This has existed for a very long time.

Fix it by reaping jobs after running the prompt, and NOT triggering a
redraw based on that reaping. We still print the message but the prompt is
not executed.

Add a test.

Fixes #9796
2024-12-08 18:12:59 -08:00
Peter Ammon
c97b1a992c
Remove some unused code from the tests 2024-12-08 13:57:10 -08:00
Johannes Altmanninger
b89619330b Disable terminal protocols before cancellable operations
The [disambiguate flag](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#disambiguate) means that:

> In particular, ctrl+c will no longer generate the SIGINT signal,
> but instead be delivered as a CSI u escape code.

so cancellation only works while we turn off disambiguation.

Today we turn it off while running external commands that want to
claim the TTY.  Also we do it (only as a workaround for this issue)
while expanding wildcards or while running builtin wait.

However there are other cases where we don't have a workaround,
like in trivial infinite loops or when opening a fifo.

Before we run "while true; end", we put the terminal back in ICANON
mode. This means it's line-buffered, so we won't be able to detect
if the user pressed ctrl-c.

Commit 8164855b7 (Disable terminal protocols throughout evaluation,
2024-04-02) had the right solution: simply disable terminal protocols
whenever we do computations that might take a long time.
eval_node() covers most of that; there are a few others.

As pointed out in #10494, the logic was fairly unsophisticated then:
it toggled terminal protocols many times.  The fix in 29f2da8d1
(Toggle terminal protocols lazily, 2024-05-16) went to the extreme
other end of only toggling protocols when absolutely necessary.

Back out part of that commit by toggling in eval_node() again,
fixing cancellation.  Fortunately, we can keep most of the benefits
of the lazy approach from 29f2da8d1: we toggle only 2 times instead
of 8 times for an empty prompt.

There are only two places left where we call signal_check_cancel()
without necessarily disabling the disambiguate flag
1. open_cloexec() we assume that the files we open outside eval_node()
   are never blocking fifos.
2. fire_delayed(). Judging by commit history, this check is not
   relevant for interactive sessions; we'll soon end up calling
   eval_node() anyway.

In future, we can leave bracketed paste, modifyOtherKeys and
application keypad mode turned on again, until we actually run an
external command.  We really only want to turn off the disambiguate
flag.

Since this is approach is overly complex, I plan to go with either
of these two alternatives in future:
- extend the kitty keyboard protocol to optionally support VINTR,
  VSTOP and friends.  Then we can drop most of these changes.
- poll stdin for ctrl-c. This promises a great simplification,
  because it implies that terminal ownership (term_steal/term_donate)
  will be perfectly synced with us enabling kitty keyboard protocol.
  This is because polling requires us to turn off ICANON.
  I started working on this change; I'm convinced it must work,
  but it's not finished yet. Note that this will also want to
  add stdin polling to builtin wait.

Closes #10864
2024-11-24 16:11:57 +01:00
Fabian Boehm
5e8adb18f4 complete: Sort --keep-order completions smaller
This should make the sort have a strict weak ordering, which rust
requires since 1.81 (or it will panic).

Note: This changes the order, but that's *fine* since the current
order is random weirdness anyway.

Fixes #10763
2024-10-05 13:53:02 +02:00
Fabian Boehm
357eb3cd32 fish_key_reader: use char_to_symbol for verbose output
byte_to_symbol was broken because it didn't iterate by byte, it
iterated by rust-char, which is a codepoint.

So it failed for everything outside of ascii and, because of a
mistaken bound, ascii chars from 0x21 to 0x2F ("!" to "/" - all the punctuation).

char_to_symbol will print printable codepoints as-is and
others escaped. This is okay - something like `decoded from: +` or
`decoded from: ö` is entirely understandable, there is no need to tell
you that "ö" is \xc3\xb6.

This reverts commit 423e5f6c03.
2024-08-13 16:03:47 +02:00
Fabian Boehm
9903eb4c76 Convert ASCII DEL to \x7f
Annoying when you press backspace in fish_key_reader
2024-08-11 14:57:04 +02:00
Mahmoud Al-Qudsi
936f7d9b8d Add pexpect test for commandline --showing-suggestion 2024-07-07 22:34:36 -05:00
Fabian Boehm
652996124d reader: Remove a panic
The special input functions self-insert, self-insert-not-first, and
and or used to be handled by inputter_t::readch, but they aren't
anymore with `commandline -f`.

I am unsure if these *would* have worked, I can't come up with a use.

So, for now, do nothing instead of panicking.
2024-06-10 17:14:13 +02:00
Fabian Boehm
c7d878a8d2 input: Let function_pop_arg return an Option
This would crash if you ran `commandline -f backward-jump`.

The C++ version would read a char (but badly), this doesn't anymore.

So, at least instead of crashing, just do nothing.
2024-06-10 17:02:11 +02:00
ridiculousfish
abf92fcbd1 Fix the bind.py tests
Errant newlines were causing extra prompts.
2024-06-02 15:47:15 -07:00
ridiculousfish
c0766c1844 Fix the histfile.py test
Add missing expect_prompt()
2024-06-02 15:31:19 -07:00
ridiculousfish
cb62ed3e3d Bravely reenable fg.py in CI for Mac 2024-06-02 15:11:51 -07:00
ridiculousfish
96faad247f Fix the fg.py pexpect test 2024-06-02 15:07:23 -07:00
ridiculousfish
25ac5bdb49 Fix the undo pexpect
Add the missing expect_prompts to reflect where we send newlines.
2024-06-02 14:17:36 -07:00
Johannes Altmanninger
d40d2b786f Work around wants_terminal not begin set inside eval
On this binding we fail to disable CSI u

    bind c-t '
        begin
            set -lx FZF_DEFAULT_OPTS --height 40% --bind=ctrl-z:ignore
            eval fzf | while read -l r; echo read $r; end
        end
    '

because for "fzf", ParseExecutionContext::setup_group() returns early with the
parent process group (which should be fish's own) , hence "wants_terminal"
is false. This seems questionable, I don't think the eval should make a
difference here.

For now, don't touch it; use the more accurate way of detecting whether
a process may read keyboard input. In many of such cases "wants_terminal"
is false, like

    echo (echo 1\n2\n3 | fzf)

Fixes #10504
2024-05-18 20:55:06 +02:00
Johannes Altmanninger
29f2da8d18 Toggle terminal protocols lazily
Closes #10494
2024-05-16 12:26:47 +02:00
Fabian Boehm
9e6a661c00 One more sleep 2024-05-08 16:35:00 +02:00
Fabian Boehm
37f0d7c522 Work around more spurious test failures 2024-05-07 17:55:29 +02:00
Fabian Boehm
1d7fde7bf0 tests: Fix apple key "invalid escape sequence" with python 3.12 2024-05-07 17:55:29 +02:00
Fabian Boehm
29f9d3d843 tests/signals.py: Increase a timeout
10ms is *much* too short
2024-05-07 17:55:26 +02:00
ridiculousfish
eba0d56411 Make bind_mode_events.py pass on Mac again 2024-05-06 10:26:32 -07:00
ridiculousfish
f6f1d93df5 Help fg.py test pass more on macOS 2024-05-06 10:26:32 -07:00
ridiculousfish
7b524f6995 Help the torn_escapes test pass on Mac 2024-05-06 10:26:32 -07:00
ridiculousfish
2bbeed157b Further improvements to signals.py test
Get it passing again on macOS.
2024-05-06 10:26:32 -07:00
ridiculousfish
269b18532d Fix Ctrl-C signals test
Prior to this change, signals.py attempted to generate Ctrl-C (SIGINT) by
sending \x03 to stdin. But with the change to use the CSI U sequence, Ctrl-C no
longer generates SIGINT.

Switch to sending SIGINT directly. Also switch up some of the sleep constants so
that a sleep command can't be confused with another one.
2024-05-06 10:26:32 -07:00
Fabian Boehm
c43f7fbe9c tests: Add another sleep 2024-04-30 16:47:44 +02:00
Fabian Boehm
ac8b1db899 tests: More timeout 2024-04-25 21:36:31 +02:00
Fabian Boehm
69583f3030
Allow restricting abbreviations to specific commands (#10452)
This allows making something like

```fish
abbr --add gc --position anywhere --command git back 'reset --hard
HEAD^'
```

to expand "gc" to "reset --hard HEAD^", but only if the command is
git (including "command git gc" or "and git gc").

Fixes #9411
2024-04-24 18:09:04 +02:00
Fabian Boehm
16eeba8f65 pexpects: More timeouts 2024-04-23 21:59:40 +02:00
Fabian Boehm
0bb0934bc2 tests: Remove weird triplicated string
I have no idea why this matches the string thrice when it is entered
once and suggestions are disabled.

I've seen this fail even on my local system, I expect it works because
of some terminal integration.
2024-04-23 19:40:49 +02:00
Johannes Altmanninger
bdd478bbd0 Disable focus reporting on non-tmux again for now
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
2024-04-18 10:38:15 +02:00
Johannes Altmanninger
00432df420 Trigger abbreviations after inserting process separators
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
2024-04-13 20:11:11 +02:00
Johannes Altmanninger
29dc307111 Insert some completions with quotes instead of backslashes
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
2024-04-13 15:34:21 +02:00
Johannes Altmanninger
edb5cb7226 Fix restoring cursor position on redo with edit groups 2024-04-13 14:36:11 +02:00
Johannes Altmanninger
d1a4b4bc73 Fix undo pexpect test
The assertions were satisfied even though we never triggered any undo.
2024-04-13 11:34:36 +02:00
Johannes Altmanninger
13b5322bef Disable failing bind_mode_events.py in FreeBSD for now
I'm pretty sure it's just a timing issue.
2024-04-12 12:34:01 +02:00
Johannes Altmanninger
57d3614fd8 Add missing import to fg.py 2024-04-12 11:41:40 +02:00
Johannes Altmanninger
f062ad3ad6 Try to fix macOS CI by disabling fg.py, signals.py, torn_escapes.py
These work fine AFAICT, just not in CI.
2024-04-12 11:27:55 +02:00
Johannes Altmanninger
a583fe7230 "commandline -f foo" to skip queue and execute immediately
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.
2024-04-09 00:22:41 +02:00
Johannes Altmanninger
f285e85b0c Enable focus reporting only just before reading from stdin
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.
2024-04-06 11:22:19 +02:00
Fabian Boehm
3af849d739 tests/pexpect: Fix \d escape 2024-04-02 22:41:54 +02:00
Fabian Boehm
171869858a tests/histfile.py: Check for no jobs 2024-04-02 22:24:09 +02:00
Fabian Boehm
3d46987cff tests/histfile.py: Try exiting a second time 2024-04-02 22:19:47 +02:00
Johannes Altmanninger
8164855b70 Disable terminal protocols throughout evaluation
Test changes are very hacky, will cleanup later.

Closes #10408
2024-04-02 21:25:47 +02:00
Fabian Boehm
6501f7ab6f tests: Disable terminal.py under asan
We want asan to tell us about memory errors, not randomly fail tests
because it's too slow.
2024-04-02 19:57:57 +02:00
Johannes Altmanninger
8bf8b10f68 Extended & human-friendly keys
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
2024-04-02 14:35:16 +02:00