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

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 and 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 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 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:

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.

{
  "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:

{
  "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:

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

Vim-Style Navigation

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

{
  "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:

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:

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:

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 and 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 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 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. 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. Both types are configured in the same keybindings.json file.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →