mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-15 19:05:11 +00:00
* feat(tui): add pageUp/pageDown key support and selectPageUp/selectPageDown actions * feat(coding-agent): add page-up/down navigation to session selector
147 lines
3.4 KiB
TypeScript
147 lines
3.4 KiB
TypeScript
import { type KeyId, matchesKey } from "./keys.js";
|
|
|
|
/**
|
|
* Editor actions that can be bound to keys.
|
|
*/
|
|
export type EditorAction =
|
|
// Cursor movement
|
|
| "cursorUp"
|
|
| "cursorDown"
|
|
| "cursorLeft"
|
|
| "cursorRight"
|
|
| "cursorWordLeft"
|
|
| "cursorWordRight"
|
|
| "cursorLineStart"
|
|
| "cursorLineEnd"
|
|
// Deletion
|
|
| "deleteCharBackward"
|
|
| "deleteCharForward"
|
|
| "deleteWordBackward"
|
|
| "deleteToLineStart"
|
|
| "deleteToLineEnd"
|
|
// Text input
|
|
| "newLine"
|
|
| "submit"
|
|
| "tab"
|
|
// Selection/autocomplete
|
|
| "selectUp"
|
|
| "selectDown"
|
|
| "selectPageUp"
|
|
| "selectPageDown"
|
|
| "selectConfirm"
|
|
| "selectCancel"
|
|
// Clipboard
|
|
| "copy";
|
|
|
|
// Re-export KeyId from keys.ts
|
|
export type { KeyId };
|
|
|
|
/**
|
|
* Editor keybindings configuration.
|
|
*/
|
|
export type EditorKeybindingsConfig = {
|
|
[K in EditorAction]?: KeyId | KeyId[];
|
|
};
|
|
|
|
/**
|
|
* Default editor keybindings.
|
|
*/
|
|
export const DEFAULT_EDITOR_KEYBINDINGS: Required<EditorKeybindingsConfig> = {
|
|
// Cursor movement
|
|
cursorUp: "up",
|
|
cursorDown: "down",
|
|
cursorLeft: "left",
|
|
cursorRight: "right",
|
|
cursorWordLeft: ["alt+left", "ctrl+left"],
|
|
cursorWordRight: ["alt+right", "ctrl+right"],
|
|
cursorLineStart: ["home", "ctrl+a"],
|
|
cursorLineEnd: ["end", "ctrl+e"],
|
|
// Deletion
|
|
deleteCharBackward: "backspace",
|
|
deleteCharForward: "delete",
|
|
deleteWordBackward: ["ctrl+w", "alt+backspace"],
|
|
deleteToLineStart: "ctrl+u",
|
|
deleteToLineEnd: "ctrl+k",
|
|
// Text input
|
|
newLine: "shift+enter",
|
|
submit: "enter",
|
|
tab: "tab",
|
|
// Selection/autocomplete
|
|
selectUp: "up",
|
|
selectDown: "down",
|
|
selectPageUp: "pageUp",
|
|
selectPageDown: "pageDown",
|
|
selectConfirm: "enter",
|
|
selectCancel: ["escape", "ctrl+c"],
|
|
// Clipboard
|
|
copy: "ctrl+c",
|
|
};
|
|
|
|
/**
|
|
* Manages keybindings for the editor.
|
|
*/
|
|
export class EditorKeybindingsManager {
|
|
private actionToKeys: Map<EditorAction, KeyId[]>;
|
|
|
|
constructor(config: EditorKeybindingsConfig = {}) {
|
|
this.actionToKeys = new Map();
|
|
this.buildMaps(config);
|
|
}
|
|
|
|
private buildMaps(config: EditorKeybindingsConfig): void {
|
|
this.actionToKeys.clear();
|
|
|
|
// Start with defaults
|
|
for (const [action, keys] of Object.entries(DEFAULT_EDITOR_KEYBINDINGS)) {
|
|
const keyArray = Array.isArray(keys) ? keys : [keys];
|
|
this.actionToKeys.set(action as EditorAction, [...keyArray]);
|
|
}
|
|
|
|
// Override with user config
|
|
for (const [action, keys] of Object.entries(config)) {
|
|
if (keys === undefined) continue;
|
|
const keyArray = Array.isArray(keys) ? keys : [keys];
|
|
this.actionToKeys.set(action as EditorAction, keyArray);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if input matches a specific action.
|
|
*/
|
|
matches(data: string, action: EditorAction): boolean {
|
|
const keys = this.actionToKeys.get(action);
|
|
if (!keys) return false;
|
|
for (const key of keys) {
|
|
if (matchesKey(data, key)) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Get keys bound to an action.
|
|
*/
|
|
getKeys(action: EditorAction): KeyId[] {
|
|
return this.actionToKeys.get(action) ?? [];
|
|
}
|
|
|
|
/**
|
|
* Update configuration.
|
|
*/
|
|
setConfig(config: EditorKeybindingsConfig): void {
|
|
this.buildMaps(config);
|
|
}
|
|
}
|
|
|
|
// Global instance
|
|
let globalEditorKeybindings: EditorKeybindingsManager | null = null;
|
|
|
|
export function getEditorKeybindings(): EditorKeybindingsManager {
|
|
if (!globalEditorKeybindings) {
|
|
globalEditorKeybindings = new EditorKeybindingsManager();
|
|
}
|
|
return globalEditorKeybindings;
|
|
}
|
|
|
|
export function setEditorKeybindings(manager: EditorKeybindingsManager): void {
|
|
globalEditorKeybindings = manager;
|
|
}
|