Skip to content

Commit 8bf8b10

Browse files
committed
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
1 parent 8ada027 commit 8bf8b10

File tree

180 files changed

+2208
-1309
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

180 files changed

+2208
-1309
lines changed

CHANGELOG.rst

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ fish 3.8.0 (released ???)
1212
10198 10200 10201 10204 10210 10214 10219 10223 10227 10232 10235 10237 10243 10244 10245
1313
10246 10251 10260 10267 10281 10347 10366 10368 10370 10371 10263 10270 10272 10276 10277
1414
10278 10279 10291 10293 10305 10306 10309 10316 10317 10327 10328 10329 10330 10336 10340
15-
10345 10346 10353 10354 10356 10372 10373 3299 10360
15+
10345 10346 10353 10354 10356 10372 10373 3299 10360 10359
1616
1717
The entirety of fish's C++ code has been ported to Rust (:issue:`9512`).
1818
This means a large change in dependencies and how to build fish.
@@ -21,6 +21,24 @@ Packagers should see the :ref:`For Distributors <rust-packaging>` section at the
2121
Notable backwards-incompatible changes
2222
--------------------------------------
2323

24+
- Fish now decodes keyboard input into human-readable key names.
25+
To make this for for a wide range of terminals, fish asks terminals to speak several keyboard protocols,
26+
including CSI u, XTerm's ``modifyOtherKeys`` and some progressive enhancements from the [kitty keyboard protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/).
27+
Depending on terminal support, this allows to bind a lot more key combinations,
28+
including arbitrary combinations of modifiers ``ctrl``, ``alt`` and ``shift``.
29+
30+
This comes with a new syntax for specifying keys to builtin ``bind``.
31+
The new syntax introduces modifier names and names for some keys that don't have an obvious and printable Unicode code point.
32+
The old syntax remains mostly supported but the new one is preferred.
33+
- Existing bindings that use the new names have a different meaning now.
34+
For example
35+
- ``bind up 'do something'`` binds the up arrow key instead of a two-key sequence.
36+
- ``bind ctrl-x,alt-c 'do something'`` binds a sequence of two keys.
37+
Since ``,`` and ``-`` act as separators, there are some cases where they need to be written as ``comma`` and ``minus`` respectively.
38+
- To minimize gratuitous breakage, the key argument to ``bind`` is parsed using the old syntax in two cases:
39+
- If key starts with a raw escape character (``\e``) or a raw ASCII control character (``\c``).
40+
- If key consists of exactly two characters, contains none of ``,`` or ``-`` and is not a named key.
41+
2442
- ``random`` now uses a different random number generator and so the values you get even with the same seed have changed.
2543
Notably, it will now work much more sensibly with very small seeds.
2644
The seed was never guaranteed to give the same result across systems,
@@ -39,7 +57,7 @@ Notable backwards-incompatible changes
3957
Notable improvements and fixes
4058
------------------------------
4159
- New function ``fish_should_add_to_history`` can be overridden to decide whether a command should be added to the history (:issue:`10302`).
42-
- :kbd:`Control-C` during command input no longer prints ``^C`` and a new prompt but merely clears the command line. This restores the behavior from version 2.2. To revert to the old behavior use ``bind \cc __fish_cancel_commandline`` (:issue:`10213`).
60+
- :kbd:`Control-C` during command input no longer prints ``^C`` and a new prompt but merely clears the command line. This restores the behavior from version 2.2. To revert to the old behavior use ``bind ctrl-c __fish_cancel_commandline`` (:issue:`10213`).
4361
- The :kbd:`Control-R` history search now uses glob syntax (:issue:`10131`).
4462
- The :kbd:`Control-R` history search now operates only on the line at cursor, making it easier to quickly compose a multi-line commandline by recalling previous commands.
4563

@@ -48,6 +66,12 @@ Deprecations and removed features
4866

4967
- ``commandline --tokenize`` (short option ``-o``) has been deprecated in favor of ``commandline --tokens-expanded`` (short option ``-x``) which expands variables and other shell expressions, removing the need to use "eval" in custom completions (:issue:`10212`).
5068
- A new feature flag, ``remove-percent-self`` (see ``status features``) disables PID expansion of ``%self`` which has been supplanted by ``$fish_pid`` (:issue:`10262`).
69+
- Specifying key names as terminfo name (``bind -k``) is deprecated and may be removed in a future version.
70+
- Flow control -- which if enabled by ``stty ixon ixoff`` allows to pause terminal input with ``ctrl-s`` and resume it with ``ctrl-q`` -- now works only while fish is executing an external command.
71+
- When a terminal pastes text into fish using bracketed paste, fish used to switch to a special ``paste`` bind mode.
72+
This bind mode has been removed. The behavior on paste is currently not meant to be configurable.
73+
- When fish is stopped or terminated by a signal that cannot be caught (SIGSTOP or SIGKILL), it may leave the terminal in a state where keypresses with modifiers are sent as CSI u sequences instead of traditional control characters or escape sequecnes (that are recognized by bash/readline). If this happens, you can use the ``reset`` command from ``ncurses`` to restore the terminal state.
74+
- ``fish_key_reader --verbose`` is now ignored, so it no longer shows raw byte values or timing information. Since fish now decodes keys, this should no longer be necessary.
5175

5276
Scripting improvements
5377
----------------------
@@ -78,13 +102,14 @@ Interactive improvements
78102

79103
New or improved bindings
80104
^^^^^^^^^^^^^^^^^^^^^^^^
81-
- Bindings can now mix special input functions and shell commands, so ``bind \cg expand-abbr "commandline -i \n"`` works as expected (:issue:`8186`).
105+
- Bindings can now mix special input functions and shell commands, so ``bind ctrl-g expand-abbr "commandline -i \n"`` works as expected (:issue:`8186`).
82106
- When the cursor is on a command that resolves to an executable script, :kbd:`Alt-O` will now open that script in your editor (:issue:`10266`).
83107
- Two improvements to the :kbd:`Alt-E` binding which edits the commandline in an external editor:
84108
- The editor's cursor position is copied back to fish. This is currently supported for Vim and Kakoune.
85109
- Cursor position synchronization is only supported for a set of known editors. This has been extended by also resolving aliases. For example use ``complete --wraps my-vim vim`` to synchronize cursors when `EDITOR=my-vim`.
86110
- ``backward-kill-path-component`` and friends now treat ``#`` as part of a path component (:issue:`10271`).
87111
- The ``E`` binding in vi mode now correctly handles the last character of the word, by jumping to the next word (:issue:`9700`).
112+
- If the terminal supports shifted key codes from the [kitty keyboard protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/), ``shift-enter`` now inserts a newline instead of executing the command line.
88113
- Vi mode has seen some improvements but continues to suffer from the lack of people working on it.
89114
- Insert-mode :kbd:`Control-N` accepts autosuggestions (:issue:`10339`).
90115
- Outside insert mode, the cursor will no longer be placed beyond the last character on the commandline.
@@ -103,6 +128,8 @@ Completions
103128
Improved terminal support
104129
^^^^^^^^^^^^^^^^^^^^^^^^^
105130
- Fish now sets the terminal window title unconditionally (:issue:`10037`).
131+
- Focus reporting is enabled unconditionally, not just inside tmux.
132+
To use it, define functions that handle events ``fish_focus_in`` and ``fish_focus_out``.
106133

107134
Other improvements
108135
------------------

build_tools/pexpect_helper.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,12 @@ def get_prompt_re(counter):
3434
"""Return a regular expression for matching a with a given prompt counter."""
3535
return re.compile(
3636
r"""(?:\r\n?|^) # beginning of line
37-
(?:\x1b[\d\[KB(m]*)* # optional colors
37+
(?:\x1b[\d[KB(m]*)* # optional colors
38+
(?:\x1b[\?2004h) # Bracketed paste
39+
(?:\x1b[>4;1m) # XTerm's modifyOtherKeys
40+
(?:\x1b[>5u) # CSI u with kitty progressive enhancement
41+
(?:\x1b=) # set application keypad mode, so the keypad keys send unique codes
42+
(?:\x1b[\?1004h)? # enable focus notify
3843
(?:\[.\]\ )? # optional vi mode prompt
3944
"""
4045
+ (r"prompt\ %d>" % counter) # prompt with counter

cmake/Tests.cmake

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
11
# This adds ctest support to the project
22
enable_testing()
33

4-
# By default, ctest runs tests serially
5-
if(NOT CTEST_PARALLEL_LEVEL)
6-
include(ProcessorCount)
7-
ProcessorCount(CORES)
8-
set(CTEST_PARALLEL_LEVEL ${CORES})
9-
endif()
10-
114
# Put in a tests folder to reduce the top level targets in IDEs.
125
set(CMAKE_FOLDER tests)
136

@@ -24,16 +17,14 @@ set(SKIP_RETURN_CODE 125)
2417
# running `make test` does not require any of the binaries to be built before testing.
2518
# * The only way to have a test depend on a binary is to add a fake test with a name like
2619
# "build_fish" that executes CMake recursively to build the `fish` target.
27-
# * It is not possible to set top-level CTest options/settings such as CTEST_PARALLEL_LEVEL from
28-
# within the CMake configuration file.
2920
# * Circling back to the point about individual tests not being actual Makefile targets, CMake does
3021
# not offer any way to execute a named test via the `make`/`ninja`/whatever interface; the only
3122
# way to manually invoke test `foo` is to to manually run `ctest` and specify a regex matching
3223
# `foo` as an argument, e.g. `ctest -R ^foo$`... which is really crazy.
3324

3425
# The top-level test target is "fish_run_tests".
3526
add_custom_target(fish_run_tests
36-
COMMAND env CTEST_PARALLEL_LEVEL=${CTEST_PARALLEL_LEVEL} FISH_FORCE_COLOR=1
27+
COMMAND env FISH_FORCE_COLOR=1
3728
FISH_SOURCE_DIR=${CMAKE_SOURCE_DIR}
3829
${CMAKE_CTEST_COMMAND} --force-new-ctest-process # --verbose
3930
--output-on-failure --progress

doc_src/cmds/bind.rst

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,49 +7,67 @@ Synopsis
77

88
.. synopsis::
99

10-
bind [(-M | --mode) MODE] [(-m | --sets-mode) NEW_MODE] [--preset | --user] [-s | --silent] [-k | --key] SEQUENCE COMMAND ...
11-
bind [(-M | --mode) MODE] [-k | --key] [--preset] [--user] SEQUENCE
12-
bind (-K | --key-names) [-a | --all] [--preset] [--user]
10+
bind [(-M | --mode) MODE] [(-m | --sets-mode) NEW_MODE] [--preset | --user] [-s | --silent] KEYS COMMAND ...
11+
bind [(-M | --mode) MODE] [--preset] [--user] [KEYS]
12+
bind [-a | --all] [--preset] [--user]
1313
bind (-f | --function-names)
1414
bind (-L | --list-modes)
15-
bind (-e | --erase) [(-M | --mode) MODE] [--preset] [--user] [-a | --all] | [-k | --key] SEQUENCE ...
15+
bind (-e | --erase) [(-M | --mode) MODE] [--preset] [--user] [-a | --all] | KEYS ...
1616

1717
Description
1818
-----------
1919

20-
``bind`` manages bindings.
20+
``bind`` manages key bindings.
2121

22-
It can add bindings if given a SEQUENCE of characters to bind to. These should be written as :ref:`fish escape sequences <escapes>`. The most important of these are ``\c`` for the control key, and ``\e`` for escape, and because of historical reasons also the Alt key (sometimes also called "Meta").
22+
If both ``KEYS`` and ``COMMAND`` are given, ``bind`` adds (or replaces) a binding in ``MODE``.
23+
If only ``KEYS`` is given, any existing binding in the given ``MODE`` will be printed.
2324

24-
For example, :kbd:`Alt`\ +\ :kbd:`W` can be written as ``\ew``, and :kbd:`Control`\ +\ :kbd:`X` (^X) can be written as ``\cx``. Note that Alt-based key bindings are case sensitive and Control-based key bindings are not. This is a constraint of text-based terminals, not ``fish``.
25+
``KEYS`` is a comma-separated list of key names.
26+
Modifier keys can be specified by prefixing a key name with a combination of ``ctrl-``, ``alt-`` and ``shift-``.
27+
For example, :kbd:`Alt`\ +\ :kbd:`w` is written as ``alt-w``.
28+
Key names are case-sensitive; for example ``alt-W`` is the same as ``alt-shift-w``.
2529

26-
The generic key binding that matches if no other binding does can be set by specifying a ``SEQUENCE`` of the empty string (``''``). For most key bindings, it makes sense to bind this to the ``self-insert`` function (i.e. ``bind '' self-insert``). This will insert any keystrokes not specifically bound to into the editor. Non-printable characters are ignored by the editor, so this will not result in control sequences being inserted.
30+
Some keys have names, usually because they don't have an obvious printable character representation.
31+
They are:
2732

28-
If the ``-k`` switch is used, the name of a key (such as 'down', 'up' or 'backspace') is used instead of a sequence. The names used are the same as the corresponding curses variables, but without the 'key\_' prefix. (See ``terminfo(5)`` for more information, or use ``bind --key-names`` for a list of all available named keys). Normally this will print an error if the current ``$TERM`` entry doesn't have a given key, unless the ``-s`` switch is given.
33+
``plus`` (``+``),
34+
``minus`` (``-``),
35+
``comma`` (``,``),
36+
``backspace``,
37+
``delete``,
38+
``escape``,
39+
``enter``,
40+
the arrow keys ``up``, ``down``, ``left`` and ``right``,
41+
``pageup``,
42+
``pagedown``,
43+
``home``,
44+
``end``,
45+
``insert``,
46+
``tab``,
47+
``space`` and
48+
``F1`` through ``F12``.
2949

30-
To find out what sequence a key combination sends, you can use :doc:`fish_key_reader <fish_key_reader>`.
50+
An empty value (``''``) for ``KEYS`` designates the generic binding. For most bind modes, it makes sense to bind this to the ``self-insert`` function (i.e. ``bind '' self-insert``). This will insert any keystrokes not specifically bound to into the editor. Non-printable characters are ignored by the editor, so this will not result in control sequences being inserted.
51+
52+
To find the name of a key combination you can use :doc:`fish_key_reader <fish_key_reader>`.
3153

3254
``COMMAND`` can be any fish command, but it can also be one of a set of special input functions. These include functions for moving the cursor, operating on the kill-ring, performing tab completion, etc. Use ``bind --function-names`` or :ref:`see below <special-input-functions>` for a list of these input functions.
3355

3456
.. note::
3557
If a script changes the commandline, it should finish by calling the ``repaint`` special input function.
3658

37-
If no ``SEQUENCE`` is provided, all bindings (or just the bindings in the given ``MODE``) are printed. If ``SEQUENCE`` is provided but no ``COMMAND``, just the binding matching that sequence is printed.
59+
If no ``KEYS`` argument is provided, all bindings (in the given ``MODE``) are printed. If ``KEYS`` is provided but no ``COMMAND``, just the binding matching that sequence is printed.
3860

3961
Key bindings may use "modes", which mimics vi's modal input behavior. The default mode is "default". Every key binding applies to a single mode; you can specify which one with ``-M MODE``. If the key binding should change the mode, you can specify the new mode with ``-m NEW_MODE``. The mode can be viewed and changed via the ``$fish_bind_mode`` variable. If you want to change the mode from inside a fish function, use ``set fish_bind_mode MODE``.
4062

63+
To bind a sequence of keys, separate them with ``,``.
64+
4165
To save custom key bindings, put the ``bind`` statements into :ref:`config.fish <configuration>`. Alternatively, fish also automatically executes a function called ``fish_user_key_bindings`` if it exists.
4266

4367
Options
4468
-------
4569
The following options are available:
4670

47-
**-k** or **--key**
48-
Specify a key name, such as 'left' or 'backspace' instead of a character sequence
49-
50-
**-K** or **--key-names**
51-
Display a list of available key names. Specifying **-a** or **--all** includes keys that don't have a known mapping
52-
5371
**-f** or **--function-names**
5472
Display a list of available input functions
5573

@@ -69,7 +87,7 @@ The following options are available:
6987
Specifying **-a** or **--all** without **-M** or **--mode** erases all binds in all modes regardless of sequence.
7088

7189
**-a** or **--all**
72-
See **--erase** and **--key-names**
90+
See **--erase**
7391

7492
**--preset** and **--user**
7593
Specify if bind should operate on user or preset bindings.
@@ -349,7 +367,7 @@ Examples
349367

350368
Exit the shell when :kbd:`Control`\ +\ :kbd:`D` is pressed::
351369

352-
bind \cd 'exit'
370+
bind ctrl-d 'exit'
353371

354372
Perform a history search when :kbd:`Page Up` is pressed::
355373

doc_src/cmds/fish_key_reader.rst

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,11 @@ Description
1515

1616
:program:`fish_key_reader` is used to explain how you would bind a certain key sequence. By default, it prints the :doc:`bind <bind>` command for one key sequence read interactively over standard input.
1717

18-
If the character sequence matches a special key name (see ``bind --key-names``), both ``bind CHARS ...`` and ``bind -k KEYNAME ...`` usage will be shown. In verbose mode (enabled by passing ``--verbose``), additional details about the characters received, such as the delay between chars, are written to standard error.
19-
2018
The following options are available:
2119

2220
**-c** or **--continuous**
2321
Begins a session where multiple key sequences can be inspected. By default the program exits after capturing a single key sequence.
2422

25-
**-V** or **--verbose**
26-
Tells fish_key_reader to output timing information and explain the sequence in more detail.
27-
2823
**-h** or **--help**
2924
Displays help about using this command.
3025

@@ -34,8 +29,6 @@ The following options are available:
3429
Usage Notes
3530
-----------
3631

37-
In verbose mode, the delay in milliseconds since the previous character was received is included in the diagnostic information written to standard error. This information may be useful to determine the optimal ``fish_escape_delay_ms`` setting or learn the amount of lag introduced by tools like ``ssh``, ``mosh`` or ``tmux``.
38-
3932
``fish_key_reader`` intentionally disables handling of many signals. To terminate ``fish_key_reader`` in ``--continuous`` mode do:
4033

4134
- press :kbd:`Control`\ +\ :kbd:`C` twice, or
@@ -51,12 +44,4 @@ Example
5144
> fish_key_reader
5245
Press a key:
5346
# press up-arrow
54-
bind \e\[A 'do something'
55-
56-
> fish_key_reader --verbose
57-
Press a key:
58-
# press alt+enter
59-
hex: 1B char: \e
60-
( 0.027 ms) hex: D char: \cM (or \r)
61-
bind \e\r 'do something'
62-
47+
bind up 'do something'

0 commit comments

Comments
 (0)