# How to Customize Keyboard Keybindings in pi-ai: Complete Configuration Guide

> Easily customize keyboard keybindings in pi-ai by editing the keybindings.json file. Learn how to tailor shortcuts to your workflow for a more efficient coding experience.

- Repository: [Mario Zechner/pi-mono](https://github.com/badlogic/pi-mono)
- Tags: how-to-guide
- Published: 2026-02-16

---

**You can customize keyboard keybindings in pi-ai by editing the `~/.pi/agent/keybindings.json` file, which merges your overrides with built-in defaults defined in [`packages/coding-agent/src/core/keybindings.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/keybindings.ts) and [`packages/tui/src/keybindings.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/tui/src/keybindings.ts).**

The pi-ai coding agent from the `badlogic/pi-mono` repository provides a flexible JSON-based configuration system for keyboard shortcuts. This approach allows you to override specific actions without redefining the entire keymap, ensuring your customizations persist across updates while maintaining access to default editor and application behaviors.

## Understanding the Keybinding Architecture

The keybinding system in pi-ai operates through a merge-based hierarchy that combines user preferences with hardcoded defaults.

### Configuration File Location

All user-defined shortcuts reside in `~/.pi/agent/keybindings.json`. The coding-agent layer reads this file during startup and merges it with internal defaults. If the file does not exist, the system falls back to an empty object and uses only the built-in definitions.

### Default Application Actions

Application-level actions control pi-ai behaviors like interrupting requests or cycling models. These defaults are defined in [`packages/coding-agent/src/core/keybindings.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/keybindings.ts) within the `KeybindingsManager` class. Key actions include:

- `interrupt`: Stops the current LLM request (default: `escape`)
- `clear`: Clears the conversation (default: `ctrl+c`)
- `cycleModelForward`: Switches to the next model (default: `ctrl+p`)
- `toggleThinking`: Toggles reasoning display (default: `ctrl+t`)
- `expandTools`: Expands the tools panel (default: `ctrl+o`)

### Default Editor Actions

Editor actions handle text input and cursor movement within the TUI interface. These are defined in [`packages/tui/src/keybindings.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/tui/src/keybindings.ts) and include:

- `cursorUp` / `cursorDown`: Arrow key navigation
- `deleteCharBackward`: Backspace functionality
- `newLine`: Insert line breaks (default: `shift+enter`)

## How to Customize Keyboard Keybindings in pi-ai

Customizing shortcuts requires editing the JSON configuration file and restarting the agent.

### Step 1: Create or Edit the Configuration File

Open `~/.pi/agent/keybindings.json` in your preferred text editor. If the directory does not exist, create it:

```bash
mkdir -p ~/.pi/agent
touch ~/.pi/agent/keybindings.json

```

### Step 2: Define Your Overrides

Add only the actions you want to change. The system merges your definitions with defaults, so unspecified actions retain their original bindings.

```json
{
  "interrupt": "ctrl+space",
  "cycleModelForward": ["ctrl+p", "alt+m"],
  "cursorUp": "k",
  "cursorDown": "j"
}

```

### Step 3: Restart the Agent

Save the file and restart pi-ai. The new bindings take effect immediately upon startup when the `KeybindingsManager` loads and merges the configuration.

## Advanced Keybinding Techniques

The pi-ai system supports sophisticated customization patterns beyond simple key remapping.

### Multiple Bindings for Single Actions

You can assign multiple keys to the same action using JSON arrays. This is useful for providing both ergonomic and traditional shortcuts:

```json
{
  "newLine": ["alt+enter", "shift+enter"],
  "interrupt": ["escape", "ctrl+space"]
}

```

### Disabling Default Shortcuts

To completely disable a built-in shortcut, set its value to an empty array. This prevents the action from triggering on any key combination:

```json
{
  "clear": [],
  "expandTools": []
}

```

### Vim-Style Navigation

Remap cursor movement to vi-style keys by overriding the editor actions:

```json
{
  "cursorUp": "k",
  "cursorDown": "j",
  "cursorLeft": "h",
  "cursorRight": "l"
}

```

## Programmatic Access to Keybindings

Developers extending pi-ai can interact with the keybinding system programmatically through the exposed managers.

### Retrieving Current Bindings

Access the active keybindings to display hints or build help menus:

```typescript
import { getEditorKeybindings } from "@mariozechner/pi-tui";
import { KeybindingsManager } from "@mariozechner/pi-coding-agent";

const appKB = new KeybindingsManager();
const editorKB = getEditorKeybindings();

const interruptKeys = appKB.getKeys("interrupt");
const upKeys = editorKB.getKeys("cursorUp");

```

### Checking Key Presses in Components

Validate user input against configured shortcuts within TUI components:

```typescript
import { matchesKey } from "@mariozechner/pi-tui";
import { KeybindingsManager } from "@mariozechner/pi-coding-agent";

function onKey(data: string) {
  const kb = new KeybindingsManager();
  if (kb.matches(data, "interrupt")) {
    // Handle interruption logic
  }
}

```

### In-Memory Configuration Overrides

Create temporary keybinding configurations for specific sessions without modifying the user config file:

```typescript
import { KeybindingsManager } from "@mariozechner/pi-coding-agent";

const custom = KeybindingsManager.inMemory({
  interrupt: "ctrl+space",
  cursorUp: "k"
});

```

## Summary

- **Configuration location**: Edit `~/.pi/agent/keybindings.json` to customize keyboard keybindings in pi-ai.
- **Merge behavior**: Your settings merge with defaults from [`packages/coding-agent/src/core/keybindings.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/keybindings.ts) and [`packages/tui/src/keybindings.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/tui/src/keybindings.ts), so you only override what you need.
- **Action types**: Distinguish between **application actions** (interrupt, cycleModelForward) and **editor actions** (cursorUp, newLine).
- **Advanced features**: Support multiple keys per action, disable shortcuts with empty arrays, and use programmatic APIs via `KeybindingsManager` and `EditorKeybindingsManager`.

## Frequently Asked Questions

### Where does pi-ai store its keyboard configuration?

pi-ai stores user-specific keyboard shortcuts in `~/.pi/agent/keybindings.json`. This file is created automatically when you first customize a shortcut, or you can create it manually. The configuration is read at startup and merged with the built-in defaults defined in the source code.

### Can I use multiple keys for the same action in pi-ai?

Yes, pi-ai supports multiple keybindings for a single action. In your [`keybindings.json`](https://github.com/badlogic/pi-mono/blob/main/keybindings.json) file, specify an array of strings instead of a single string. For example: `"interrupt": ["escape", "ctrl+space"]` allows you to stop the current operation using either the Escape key or Ctrl+Space.

### How do I disable a default keyboard shortcut in pi-ai?

To disable a built-in shortcut, set its value to an empty array `[]` in your [`keybindings.json`](https://github.com/badlogic/pi-mono/blob/main/keybindings.json) file. For example, adding `"clear": []` prevents the `ctrl+c` shortcut from clearing the conversation. This is useful when you want to prevent accidental triggers or free up keys for other purposes.

### What is the difference between application actions and editor actions in pi-ai?

Application actions control the coding-agent behavior, such as `interrupt` (stop LLM generation), `cycleModelForward` (switch models), or `toggleThinking`. These are defined in [`packages/coding-agent/src/core/keybindings.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/keybindings.ts). Editor actions control text input and cursor movement within the terminal UI, such as `cursorUp`, `newLine`, or `deleteCharBackward`, defined in [`packages/tui/src/keybindings.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/tui/src/keybindings.ts). Both types are configured in the same [`keybindings.json`](https://github.com/badlogic/pi-mono/blob/main/keybindings.json) file.