Keyboard#
A terminal sends bytes to a program, and the same bytes can mean different keys. The classic encoding sends the same byte for Enter and for SHIFT+Enter. A full-screen program (a TUI) can ask the terminal for an extended encoding that separates the two. A shell cannot.
Nash handles both cases with the ShiftEnterOrNewline action. This page
explains what the action does, where it stops, and how to change it. It also
describes how Nash treats the Kitty keyboard protocol when a program resets it.
The tab-related key changes in Nash 0.9.0 (SUPER+9 and SUPER+0) are on the Tabs page.
To jump between panes, hold Ctrl+Alt+Super (Control+Option+Command on macOS) and type a pane number. See Quick Pane Navigation for configuration, folded panes, and shortcut conflicts. Open the Command Palette to find other actions.
SHIFT+Enter#
Nash 0.9.0 or newer binds SHIFT+Enter to ShiftEnterOrNewline in its bundled
key configuration. For each key press the action looks at the pane that has
focus:
- If the pane can tell SHIFT+Enter from Enter, Nash sends the real SHIFT+Enter key, with its modifiers.
- If not, Nash sends
ESC CR, the same bytes that Alt+Enter sends. A shell that readsESC CRas "insert a newline" lets you write a command over more than one line without running it. In the default keymap of zsh,ESC CRis bound toself-insert-unmeta, which does this. Check the binding of your own shell if SHIFT+Enter does not insert a newline.
The result is that a shell still gets its multiline key, and a TUI that asks for SHIFT+Enter gets SHIFT+Enter and not Alt+Enter.
What the program receives#
| The pane is in this state | The program receives for SHIFT+Enter |
|---|---|
| No extended keyboard mode is on | ESC CR |
The program turned on the Kitty keyboard protocol, and enable_kitty_keyboard = true | The key event ESC [ 13 ; 2 u, and release events if the program asked for them |
The program turned on xterm modifyOtherKeys | The key event ESC [ 27 ; 2 ; 13 ~ |
You set enable_csi_u_key_encoding = true | The key event ESC [ 13 ; 2 u |
On Windows, Win32 input mode is active and allow_win32_input_mode is on | The key event in the Win32 input encoding |
The Kitty keyboard protocol is off by default. To let programs use it, put
this in ~/.config/nash/custom.lua:
return { enable_kitty_keyboard = true }
Since Nash 0.11.5, mux-server panes also report their Kitty, Win32, and
other keyboard modes to the GUI. This includes [mux] enabled = true, unix and
TLS domains, and SSH domains using Nash multiplexing. To use Kitty, set
enable_kitty_keyboard = true in both the GUI and server configuration; it
remains opt-in. Mode changes can take a network trip to reach the GUI, so
SHIFT+Enter chooses using the latest state it knows.
Limits#
The action works in direct key bindings only. It does not work from a
command palette command, from Multiple, or from a Lua window:perform_action
call. Nash does not list it in the palette.
Before Nash 0.11.5, mux-client panes always sent ESC CR. Since that
release, direct bindings of ShiftEnterOrNewline follow the server pane's
reported mode and can send native SHIFT+Enter, as in a GUI-owned pane.
Tmux control-mode domains still always send ESC CR: they do not expose the
program's keyboard mode.
A pane that runs tmux inside a normal pane is different. Nash sees the modes
that tmux negotiated, not the modes of the program inside tmux. If tmux has
extended keys on, SHIFT+Enter can pass through, and a plain shell inside tmux
then receives Enter instead of a newline key. Test this with your own shell
before you rely on it.
An SSH session without Nash multiplexing is a normal pane and follows the rules in the table.
Change or remove the binding#
Bindings that you add to nash.toml or keys.lua come after the bundled
bindings, so your binding for the same key wins. If you added a SHIFT+Enter
binding before Nash 0.9.0, for example one that always sends ESC CR, remove it
so that programs get the real key. Since Nash 0.11.5, this also applies to
mux-client panes. Tmux control-mode panes may still need their workaround.
To always send ESC CR:
[[keys]] key = "Return" mods = "SHIFT" action = "SendString" text = '\u001b\r'
To remove the binding, so that SHIFT+Enter has no special action:
[[keys]] key = "Return" mods = "SHIFT" action = "DisableDefaultAssignment"
Programs that tell Alt+Enter from SHIFT+Enter need the real SHIFT+Enter key. An
unconditional ESC CR for SHIFT+Enter removes that difference.
Kitty keyboard protocol reset#
A program turns on Kitty keyboard modes by pushing flags onto a stack. A program or a shell can later set the flags to zero. In Nash 0.9.0 or newer, a flag value of zero restores the legacy encoding for all keys.
- The keyboard stack and the replies to a keyboard capability query (
CSI ? u) stay as they were. Only the key encoding goes back to legacy. - Nash keeps the keyboard state separately for the normal screen and the alternate screen.
- Explicit settings still apply. If you set
enable_csi_u_key_encoding = true, or a program turns onmodifyOtherKeys, those encodings stay active.
This matters for SHIFT+Enter. When a program that used the Kitty protocol exits
and resets the flags to zero, your shell gets ESC CR for SHIFT+Enter again.