mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-17 08:00:59 +00:00
feat: make session selector keybindings configurable (#948)
I lost my ability to select up and down in the session selector because of some hardcoded keybindings again... So, I am adding these configurable keybindings so I can `ctrl+p` to select up :-) ### Changes Adds 4 new keybinding actions for the session picker (/resume): - `toggleSessionPath` (ctrl+p) - toggle path display - `toggleSessionSort` (ctrl+r) - toggle sort mode - `deleteSession` (ctrl+d) - delete selected session - `deleteSessionNoninvasive` (ctrl+backspace) - delete when query empty Refactors session-selector to use `kb.matches()` instead of hardcoded key checks.
This commit is contained in:
parent
4bb21b7f5f
commit
225fcb3830
3 changed files with 27 additions and 10 deletions
|
|
@ -435,6 +435,11 @@ All keyboard shortcuts can be customized via `~/.pi/agent/keybindings.json`. Eac
|
||||||
| `selectDown` | `down` | Move selection down in lists |
|
| `selectDown` | `down` | Move selection down in lists |
|
||||||
| `selectConfirm` | `enter` | Confirm selection |
|
| `selectConfirm` | `enter` | Confirm selection |
|
||||||
| `selectCancel` | `escape`, `ctrl+c` | Cancel selection |
|
| `selectCancel` | `escape`, `ctrl+c` | Cancel selection |
|
||||||
|
| `toggleSessionPath` | `ctrl+p` | Toggle path display in session picker |
|
||||||
|
| `toggleSessionSort` | `ctrl+s` | Toggle sort mode in session picker |
|
||||||
|
| `renameSession` | `ctrl+r` | Rename selected session |
|
||||||
|
| `deleteSession` | `ctrl+d` | Delete selected session |
|
||||||
|
| `deleteSessionNoninvasive` | `ctrl+backspace` | Delete session (when query empty) |
|
||||||
|
|
||||||
**Example (Emacs-style):**
|
**Example (Emacs-style):**
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import {
|
||||||
import type { SessionInfo, SessionListProgress } from "../../../core/session-manager.js";
|
import type { SessionInfo, SessionListProgress } from "../../../core/session-manager.js";
|
||||||
import { theme } from "../theme/theme.js";
|
import { theme } from "../theme/theme.js";
|
||||||
import { DynamicBorder } from "./dynamic-border.js";
|
import { DynamicBorder } from "./dynamic-border.js";
|
||||||
import { keyHint, rawKeyHint } from "./keybinding-hints.js";
|
import { keyHint } from "./keybinding-hints.js";
|
||||||
import { filterAndSortSessions, type SortMode } from "./session-selector-search.js";
|
import { filterAndSortSessions, type SortMode } from "./session-selector-search.js";
|
||||||
|
|
||||||
type SessionScope = "current" | "all";
|
type SessionScope = "current" | "all";
|
||||||
|
|
@ -153,12 +153,12 @@ class SessionSelectorHeader implements Component {
|
||||||
const sep = theme.fg("muted", " · ");
|
const sep = theme.fg("muted", " · ");
|
||||||
const hint1 = keyHint("tab", "scope") + sep + theme.fg("muted", 're:<pattern> regex · "phrase" exact');
|
const hint1 = keyHint("tab", "scope") + sep + theme.fg("muted", 're:<pattern> regex · "phrase" exact');
|
||||||
const hint2Parts = [
|
const hint2Parts = [
|
||||||
rawKeyHint("ctrl+s", "sort"),
|
keyHint("toggleSessionSort", "sort"),
|
||||||
rawKeyHint("ctrl+d", "delete"),
|
keyHint("deleteSession", "delete"),
|
||||||
rawKeyHint("ctrl+p", `path ${pathState}`),
|
keyHint("toggleSessionPath", `path ${pathState}`),
|
||||||
];
|
];
|
||||||
if (this.showRenameHint) {
|
if (this.showRenameHint) {
|
||||||
hint2Parts.push(rawKeyHint("ctrl+r", "rename"));
|
hint2Parts.push(keyHint("renameSession", "rename"));
|
||||||
}
|
}
|
||||||
const hint2 = hint2Parts.join(sep);
|
const hint2 = hint2Parts.join(sep);
|
||||||
hintLine1 = truncateToWidth(hint1, width, "…");
|
hintLine1 = truncateToWidth(hint1, width, "…");
|
||||||
|
|
@ -383,20 +383,20 @@ class SessionList implements Component, Focusable {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matchesKey(keyData, "ctrl+s")) {
|
if (kb.matches(keyData, "toggleSessionSort")) {
|
||||||
this.onToggleSort?.();
|
this.onToggleSort?.();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ctrl+P: toggle path display
|
// Ctrl+P: toggle path display
|
||||||
if (matchesKey(keyData, "ctrl+p")) {
|
if (kb.matches(keyData, "toggleSessionPath")) {
|
||||||
this.showPath = !this.showPath;
|
this.showPath = !this.showPath;
|
||||||
this.onTogglePath?.(this.showPath);
|
this.onTogglePath?.(this.showPath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ctrl+D: initiate delete confirmation (useful on terminals that don't distinguish Ctrl+Backspace from Backspace)
|
// Ctrl+D: initiate delete confirmation (useful on terminals that don't distinguish Ctrl+Backspace from Backspace)
|
||||||
if (matchesKey(keyData, "ctrl+d")) {
|
if (kb.matches(keyData, "deleteSession")) {
|
||||||
this.startDeleteConfirmationForSelectedSession();
|
this.startDeleteConfirmationForSelectedSession();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -412,7 +412,7 @@ class SessionList implements Component, Focusable {
|
||||||
|
|
||||||
// Ctrl+Backspace: non-invasive convenience alias for delete
|
// Ctrl+Backspace: non-invasive convenience alias for delete
|
||||||
// Only triggers deletion when the query is empty; otherwise it is forwarded to the input
|
// Only triggers deletion when the query is empty; otherwise it is forwarded to the input
|
||||||
if (matchesKey(keyData, "ctrl+backspace")) {
|
if (kb.matches(keyData, "deleteSessionNoninvasive")) {
|
||||||
if (this.searchInput.getValue().length > 0) {
|
if (this.searchInput.getValue().length > 0) {
|
||||||
this.searchInput.handleInput(keyData);
|
this.searchInput.handleInput(keyData);
|
||||||
this.filterSessions(this.searchInput.getValue());
|
this.filterSessions(this.searchInput.getValue());
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,13 @@ export type EditorAction =
|
||||||
// Undo
|
// Undo
|
||||||
| "undo"
|
| "undo"
|
||||||
// Tool output
|
// Tool output
|
||||||
| "expandTools";
|
| "expandTools"
|
||||||
|
// Session
|
||||||
|
| "toggleSessionPath"
|
||||||
|
| "toggleSessionSort"
|
||||||
|
| "renameSession"
|
||||||
|
| "deleteSession"
|
||||||
|
| "deleteSessionNoninvasive";
|
||||||
|
|
||||||
// Re-export KeyId from keys.ts
|
// Re-export KeyId from keys.ts
|
||||||
export type { KeyId };
|
export type { KeyId };
|
||||||
|
|
@ -95,6 +101,12 @@ export const DEFAULT_EDITOR_KEYBINDINGS: Required<EditorKeybindingsConfig> = {
|
||||||
undo: "ctrl+-",
|
undo: "ctrl+-",
|
||||||
// Tool output
|
// Tool output
|
||||||
expandTools: "ctrl+o",
|
expandTools: "ctrl+o",
|
||||||
|
// Session
|
||||||
|
toggleSessionPath: "ctrl+p",
|
||||||
|
toggleSessionSort: "ctrl+s",
|
||||||
|
renameSession: "ctrl+r",
|
||||||
|
deleteSession: "ctrl+d",
|
||||||
|
deleteSessionNoninvasive: "ctrl+backspace",
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue