62 Commits

Author SHA1 Message Date
Sean Reifschneider
eb535322d0 Fix cW Vi mode regression deleting trailing space
Missed in 02c0455 (Fix Vi mode cw deleting trailing whitespace, 2026-02-12),

Closes #12790
Closes #12791
2026-05-31 07:38:44 +08:00
Johannes Altmanninger
01ee6f968d Support backward-word-end when cursor is past end
Closes #12581
2026-03-30 13:57:27 +08:00
Johannes Altmanninger
b5c367f8bf Bounds check backward-word-end
While at it, narrow the bounds check for forward movements,
no need to check for impossible cases.

Fixes #12555
2026-03-25 17:36:21 +08:00
Johannes Altmanninger
02c04550fd Fix Vi mode cw deleting trailing whitespace
Fixes 38e633d49b (fish_vi_key_bindings: add support for count,
2025-12-16).

Fixes #12443
2026-02-12 14:11:26 +11:00
Johannes Altmanninger
cc1ae25c3a Fix kill-a-word kill-inner-word bounds checks if at end of command line
These commands are meant to be used in Vi mode when the cursor is on
a valid character, so there's not much reason to try to make them do
something when the cursor is past-end.  Do nothing, like we already
do for the empty commandline.

Reported in #12430
2026-02-08 13:12:41 +11:00
Johannes Altmanninger
d25965afba Vi mode: hack in support for df and friends
Commit 38e633d49b (fish_vi_key_bindings: add support for count,
2025-12-16) introduced an operator mode which kind of makes a lot of
sense for today's fish.  If we end up needing more flexibility and
tighter integration, we might want to move some of this into core.

Unfortunately the change is at odds with our cursed forward-jump
implementation.  The forward-jump special input function works by
magically reading the next key from stdin, which causes problems when
we are executing a script:

	commandline -f begin-selection
	commandline -f forward-jump
	commandline -f end-selection

here end-selection will be executed immediately
and forward-jump fails to wait for a keystroke.

We should get rid of forward-jump implementation.

For now, replace only the broken thing with a dedicated bind mode
for each of f/F/t/T.

Fixes #12417
2026-02-06 15:38:50 +11:00
SharzyL
bbb2f0de8d feat(vi-mode): make word movements vi-compliant
- The behavior of `{,d}{w,W}`, `{,d}{,g}{e,E}` bindings in vi-mode is
  now more compatible with vim, except that the underscore is not a
  keyword (which can be achieved by setting `set iskeyword-=_` in vim).

- Add commands `{forward,kill}-{word,bigword}-vi`,
  `{forward,backward,kill,backward-kill}-{word,bigword}-end` and
  `kill-{a,inner}-{word,bigword}` corresponding to above-mentioned
  bindings.

- Closes #10393.

Closes #12269

Co-authored-by: Johannes Altmanninger <aclopte@gmail.com>
2026-01-11 21:12:40 +01:00
Heitor Augusto
38e633d49b fish_vi_key_bindings: add support for count
Closes #12170
2026-01-11 18:37:14 +01:00
Johannes Altmanninger
af3b49bf9c Fix kill-selection crash when selection start is out-of-bounds
This part of the code could use some love; when we happen to clear the
selected text, we should end the selection.

But that's not how it works today. This is fine for Vi mode, because Vi
mode never deletes in visual mode.

Let's fix the crash for now.

Fixes #11367
2025-04-11 15:11:22 +02:00
Johannes Altmanninger
c94e30293a Fix crash when history pager is closed before search
With

	bind ctrl-r 'sleep 1' history-pager

typing ctrl-r,escape crashes fish in the history pager completion callback,
because the history pager has already been closed.

Prior to 55fd43d86c (Port reader, 2023-12-22), the completion callback
would not crash open a pager -- which causes weird races with the
user input.

Apparently this crash as been triggered by running "playwright",
and -- while that's running typing ctrl-r ligh escape.
Those key strokes were received while the kitty keyboard protocol
was active, possibly a race.

Fixes #11355
2025-04-04 14:34:11 +02:00
Johannes Altmanninger
fb2d427a45 Remove "bind -k" terminfo key names, update "bind --key-names"
I don't think there's a relevant terminal where the "bind -k" notation is
still needed. The remaining reason to keep it is backwards compatibility.

But "bind -k" is already subtly broken on terminals that implement either
of modifyOtherKeys, application keypad mode or the kitty keyboard protocol,
since those alter the byte sequences (see #11278).

Having it randomly not work might do more harm than good. Remove it.

This is meant go into 4.1, which means that users who switch back and forth
between 4.1 and 4.0 can already use the new notation.

If someone wants to use the bind config for a wider range of versions they
could use "bind -k 2>/dev/null" etc.

While at it, use the new key names in "bind --key-names", and sort it like
we do in "bind --function-names".

Closes #11342
2025-04-02 01:05:51 +02:00
Peter Ammon
f2dde229aa Revert changes to restore cursor position after undo
This feature is nice and desirable, but it was implemented in a intrusive way
by modifying the sequence of bytes we emit when running a command; this in
turn requires changing a bunch of tests.

This sequence hasn't changed in decades and the consequences of changing it
are hard to predict, given that it is likely terminal dependent; we've
already found a regression.

It's fine to reintroduce this but it should be done in a less intrusive way
(conceptually that seems straightforward - we're just remembering the cursor
position).

Revert "Fix spurious blank lines when executing scrolled commandline"

This reverts commit 0e512f8033.

Revert "On undo after execute, restore the cursor position "

This reverts commit 610338cc70.
2025-03-05 17:57:48 -08:00
Łukasz Wieczorek
82750bbaec Reformat with black. 2025-02-12 22:59:27 +08:00
Fabian Boehm
8ddb078db8 reader: Only maintain cursor position in non-empty prefix search
Otherwise this would always move the cursor to the beginning.

Fixes #11133

(cherry picked from commit db244e0492)
2025-02-05 22:14:47 +01:00
Fabian Boehm
f4f786633d pexpects/bind: Add missing expect_prompt 2025-01-08 19:10:38 +01:00
Johannes Altmanninger
83b0294fc9 ctrl-l to scroll content instead of erasing screen
On ctrl-l we send `\e[2J` (Erase in Display).  Some terminals interpret
this to scroll the screen content instead of clearing it. This happens
on VTE-based terminals like gnome-terminal for example.

The traditional behavior of ctrl-l erasing the screen (but not the
rest of the scrollback) is weird because:

1. `ctrl-l` is the easiest and most portable way to push the prompt
   to the top (and repaint after glitches I guess). But it's also a
   destructive action, truncating scrollback. I use it for scrolling
   and am frequently surprised when my scroll back is missing
   information.
2. the amount of lines erased depends on the window size.
   It would be more intuitive to erase by prompts, or erase the text
   in the terminal selection.

Let's use scrolling behavior on all terminals.

The new command could also be named "push-to-scrollback", for
consistency with others. But if we anticipate a want to add other
scrollback-related commands, "scrollback-push" is better.

This causes tests/checks/tmux-history-search.fish to fail; that test
seems pretty broken; M-d (alt-d) is supposed to delete the current
search match but there is a rogue "echo" that is supposed to invalidate
the search match.  I'm not sure how that ever worked.

Also, pexepect doesn't seem to support cursor position reporting,
so work around that.

Ref: https://codeberg.org/dnkl/foot/wiki#how-do-i-make-ctrl-l-scroll-the-content-instead-of-erasing-it
as of wiki commit b57489e298f95d037fdf34da00ea60a5e8eafd6d

Closes #10934
2024-12-30 10:50:38 +01:00
Johannes Altmanninger
69f0d960cf Fix off-by-one error in Vi-style upcase-word at commandline end
cursor_selection_mode=inclusive means the commandline position is
bounded by the last character. Fix a loop that fails to account
for this.

Fixes d51f669647 (Vi mode: avoid placing cursor beyond last character,
2024-02-14).

This change looks very odd because if the commandline is like

	echo foo.

it makes us try to uppercase the trailing period even though that's
not part of word range.  Hopefully this is harmless.

Note that there seem to be more issues remaining, for example Vi-mode
paste leaves the cursor in an out-of-bounds odd position.

Fixes #10952
Closes #10953

Reported-by: Lzu Tao <taolzu@gmail.com>
2024-12-30 10:50:01 +01:00
Johannes Altmanninger
ca28d0a78f Add missing test for Vi mode $
PR #10953 reports missing coverage for the change to update_buff_pos()
in d51f669647 (Vi mode: avoid placing cursor beyond last character,
2024-02-14).

Add a case demonstrating how $ should not move the cursor past the
last character. Goes without saying that it's really ugly that we
update_buff_pos() must be so defensive here, ideally we wouldn't pass
it out-of-bounds positions.
2024-12-30 10:50:01 +01:00
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
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
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
8164855b70 Disable terminal protocols throughout evaluation
Test changes are very hacky, will cleanup later.

Closes #10408
2024-04-02 21:25:47 +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
Fabian Boehm
34c09b1816 reader: Fix infinite loop for up/downcase bindings
This could *probably* be rewritten nicer with a for-loop

Fixes #10222
2024-01-16 18:13:18 +01:00
Fabian Boehm
1fdbac3320 tests: Lengthen a timeout
This fails on ASAN a bunch now, let's see if it's just slower
2024-01-02 22:42:19 +01:00
Fabian Boehm
9f5f34267d key delay: Add tests
I already forsee these being annoying on CI, because they involve a timeout.
2023-08-30 23:13:10 +02:00
Fabian Boehm
ff800c68e8 tests: Increase one more timeout
Example output from a Cirrus bionic-asan-clang run:

```
fish: Unknown command: man
/tmp/cirrus-ci-build/share/functions/__fish_man_page.fish (line 30):
        if man "$maincmd" &>/dev/null
           ^~^
in function '__fish_man_page'
�

[I] prompt 9>echo TEXT
[I] prompt 9>echo TEXThrAi
[I] prompt 9>echo TEXThrAi
TEXThrAi
```

Yes, this detected escape, waiting *300ms* and then "h" as being below
the escape timeout of 120ms.
2022-12-23 12:18:20 +01:00
Fabian Boehm
d920610f96 Fix special readline functions after and/or
Here we needed to handle self-insert immediately, but we ended up
returning it.

Fixes #9051
2022-07-02 09:23:11 +02:00
Fabian Boehm
8f08fe80fd Restyle codebase
Not a lot of changes, tbh
2022-06-16 18:43:28 +02:00
Fabian Homborg
aa470e12b2 Defer escape bindings as well
This allows rebinding escape in the user list without breaking e.g.
arrow keys (which send escape and then `[A` and similar, so escape is
a prefix of them).

Fixes #8428.
2021-11-10 20:40:21 +01:00
Fabian Homborg
3b74f6e0c6 tests/bind: Disable one flakey test
This one annoys the living fudge out of me, and I've never seen it
fail in earnest.
2021-09-24 20:41:09 +02:00
Fabian Homborg
2b0b0fe042 tests/bind: Skip on Github macOS
This just fails too much to be of any use.
2021-05-23 19:46:04 +02:00
Fabian Homborg
735105e33f bind tests: One more attempt to increase the timeouts
This is the last time I'm doing this before I rip these particular
tests out.

As far as I know there is no actual *problem* here, this is just
failing through a combination of macOS and Github Actions being slow
as molasses.

So it is wasting our time and therefore worse than not having these
tests at all, especially since they very rarely fail for good reasons.

We would leave some escape delay tests intact with generous timeouts, which would provide 90%
of the coverage with 10% of the hassle.
2021-05-03 12:13:18 +02:00
Fabian Homborg
ae561c3702 bind tests: Sleep shorter, more often
We still wait 5s, but with higher resolution.

This allows that test to succeed within 100ms, instead of within 1s.
2021-05-03 11:26:41 +02:00
Fabian Homborg
d8c3d667d7 bind tests: More slack
As always, increase one escape delay and wait for a bit to enter
insert mode
2021-05-03 11:26:27 +02:00
ridiculousfish
0c79a8d3af Correct time.sleep to just sleep in bind.py
time was not imported, so this was raising an exception.
2021-05-02 11:25:33 -07:00
Fabian Homborg
202e5e53d5 Handle exit in keybindings immediately
This simply checks if the parser requested exit after running any
binding scripts (in read_normal_chars).

I think this means we no longer need the `exit` bind function.

Fixes #7967.
2021-05-02 20:27:08 +02:00
ridiculousfish
fc0dd49842 Attempt to fix the bind test on MacOS
Wait for the command line to "catch up" to what is sent.
Use expect_str rather than hard-coded delays.
Fixes #7942
2021-04-22 13:15:40 -07:00
Fabian Homborg
4ac9924088 tests: Deactivate that one bind test that still keeps failing
This test has never failed for me in earnest, it's only when CI is too
slow that I've ever seen it fail.

So it's a net-negative and should be removed
2021-01-26 07:07:51 +01:00
Fabian Homborg
20741007c8 tests: Increase one more timeout
Alright, maybe it's the mode switch in this case.
2021-01-22 21:49:40 +01:00
Fabian Homborg
a57f7a8653 tests/pexpects/bind: Increase a timeout
Last attempt, if this keeps failing on CI (specifically macOS seems to
be affected), I'm removing the test as it's more noise than use.
2020-12-13 14:57:37 +01:00
Fabian Homborg
78173cf541 tests/bind: Rationalize delays
This increases a 100ms timeout to 200ms, because we've hit it on
Github Actions:

```
 INPUT    3904.65 ms (Line 223): set -g fish_escape_delay_ms 100\n
OUTPUT      +1.74 ms (Line 224): \rprompt 25>
 INPUT      +0.71 ms (Line 230): echo abc def
 INPUT      +0.57 ms (Line 231): \x1b
 INPUT      +0.57 ms (Line 232): t\r
OUTPUT      +2.41 ms (Line 234): \r\ndef abc\r\n
OUTPUT      +1.63 ms (Line 234): \rprompt 26>
 INPUT      +0.75 ms (Line 239): echo ghi jkl
 INPUT      +0.57 ms (Line 240): \x1b
 INPUT    +134.98 ms (Line 242): t\r
```

In other places it decreases sleeps where we just wait for a timeout to elapse, in which case we don't need much longer than the timeout.
2020-12-10 16:25:57 +01:00
ridiculousfish
21e2b39fa8 Add a sleep to bind.py
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.
2020-11-23 19:36:39 -08:00
Fabian Homborg
2e55e34544 Reformat 2020-11-22 14:39:48 +01:00
Fabian Homborg
25823d2900 And another delay change
Monty Python this ain't.
2020-11-11 19:57:29 +01:00
Fabian Homborg
ae0c68ec7e Tests: Yet another delay change
Now this failed because the CI added 90ms of delay.

*sigh*
2020-11-11 19:20:55 +01:00
Fabian Homborg
eed70d719a tests: More slack
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.
2020-11-09 19:56:53 +01:00