---
slug: "pi-zed-shift-enter"
source_type: "readme"
source_url: "https://cdn.jsdelivr.net/gh/illusivejosiah/pi-zed-shift-enter@main/README.md"
repo: "https://github.com/illusivejosiah/pi-zed-shift-enter"
source_file: "README.md"
branch: "main"
---
# pi-zed-shift-enter

Fixes **Shift+Enter** not creating newlines in [pi](https://github.com/badlogic/pi-mono) when running inside [Zed](https://zed.dev)'s built-in terminal.

## Preferred fix (no extension) — Zed keybinding

The most robust fix is a **Zed terminal keybinding** that sends a real CSI-u
Shift+Enter, which pi already binds to newline (`tui.input.newLine`). This works in
direct pi, inside tmux, **and inside [herdr](https://herdr.dev) panes** — none of
which the byte-intercept extension can fully cover once another terminal layer
(tmux/herdr) re-encodes the keys.

Add to `~/.config/zed/keymap.json` (macOS: `~/Library/Application Support/Zed/keymap.json`):

```json
{
  "context": "Terminal",
  "bindings": {
    "shift-enter": ["terminal::SendText", "\u001b[13;2u"]
  }
}
```

Do **not** use `\u001b\r` (ESC+CR) — that is Alt+Enter, which pi treats as
"queue follow-up", and tmux/herdr re-encode it into yet another Alt+Enter form. The
canonical Shift+Enter is CSI-u `\u001b[13;2u`.

**This extension remains a fallback** for environments where you cannot change the
Zed keymap (or want a byte-level intercept). It handles the raw and tmux CSI-u
forms; the Zed keybinding above is preferred because it also works through herdr.

## Install

```bash
pi install git:github.com/illusivejosiah/pi-zed-shift-enter
```

Or manually copy `extension.ts` to `~/.pi/agent/extensions/zed-shift-enter.ts`.

## Problem

Zed's terminal does not support the [Kitty keyboard protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/) ([zed#29756](https://github.com/zed-industries/zed/discussions/29756)). When you press Shift+Enter in pi inside Zed's terminal, it queues a follow-up message instead of inserting a newline.

**Ctrl+J** works as an alternative newline key without this extension.

## Root Cause

| Key | Bytes sent by Zed | Pi interprets as |
|-----|-------------------|-----------------|
| Enter | `\x0d` (CR) | Enter — submit |
| Shift+Enter | `\x1b\x0d` (ESC+CR) | Alt+Enter — follow-up (wrong) |
| Shift+Enter (tmux) | `\x1b[13;3u` (CSI-u Alt+Enter) | Alt+Enter — follow-up (wrong) |
| Ctrl+J | `\x0a` (LF) | Newline (correct) |

Without Kitty protocol, pi treats the ESC prefix as an Alt modifier, so `ESC+CR` becomes Alt+Enter instead of Shift+Enter.

This extension intercepts `\x1b\x0d` and converts it to `\x0a` (bare LF), which pi's editor recognizes as a newline.

## When is this no longer needed?

This extension becomes unnecessary when either:

- **Zed** implements the Kitty keyboard protocol ([zed#29756](https://github.com/zed-industries/zed/discussions/29756))
- **Pi** adds `\x1b\x0d` as a recognized Shift+Enter variant in the editor's newline detection

## License

MIT
