fix(keybindings): migrate to namespaced ids closes #2391
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { getEditorKeybindings } from "../keybindings.js";
|
||||
import { getKeybindings } from "../keybindings.js";
|
||||
import { Loader } from "./loader.js";
|
||||
|
||||
/**
|
||||
@@ -27,8 +27,8 @@ export class CancellableLoader extends Loader {
|
||||
}
|
||||
|
||||
handleInput(data: string): void {
|
||||
const kb = getEditorKeybindings();
|
||||
if (kb.matches(data, "selectCancel")) {
|
||||
const kb = getKeybindings();
|
||||
if (kb.matches(data, "tui.select.cancel")) {
|
||||
this.abortController.abort();
|
||||
this.onAbort?.();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { AutocompleteProvider, CombinedAutocompleteProvider } from "../autocomplete.js";
|
||||
import { getEditorKeybindings } from "../keybindings.js";
|
||||
import { getKeybindings } from "../keybindings.js";
|
||||
import { decodeKittyPrintable, matchesKey } from "../keys.js";
|
||||
import { KillRing } from "../kill-ring.js";
|
||||
import { type Component, CURSOR_MARKER, type Focusable, type TUI } from "../tui.js";
|
||||
@@ -517,12 +517,12 @@ export class Editor implements Component, Focusable {
|
||||
}
|
||||
|
||||
handleInput(data: string): void {
|
||||
const kb = getEditorKeybindings();
|
||||
const kb = getKeybindings();
|
||||
|
||||
// Handle character jump mode (awaiting next character to jump to)
|
||||
if (this.jumpMode !== null) {
|
||||
// Cancel if the hotkey is pressed again
|
||||
if (kb.matches(data, "jumpForward") || kb.matches(data, "jumpBackward")) {
|
||||
if (kb.matches(data, "tui.editor.jumpForward") || kb.matches(data, "tui.editor.jumpBackward")) {
|
||||
this.jumpMode = null;
|
||||
return;
|
||||
}
|
||||
@@ -566,29 +566,29 @@ export class Editor implements Component, Focusable {
|
||||
}
|
||||
|
||||
// Ctrl+C - let parent handle (exit/clear)
|
||||
if (kb.matches(data, "copy")) {
|
||||
if (kb.matches(data, "tui.input.copy")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Undo
|
||||
if (kb.matches(data, "undo")) {
|
||||
if (kb.matches(data, "tui.editor.undo")) {
|
||||
this.undo();
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle autocomplete mode
|
||||
if (this.autocompleteState && this.autocompleteList) {
|
||||
if (kb.matches(data, "selectCancel")) {
|
||||
if (kb.matches(data, "tui.select.cancel")) {
|
||||
this.cancelAutocomplete();
|
||||
return;
|
||||
}
|
||||
|
||||
if (kb.matches(data, "selectUp") || kb.matches(data, "selectDown")) {
|
||||
if (kb.matches(data, "tui.select.up") || kb.matches(data, "tui.select.down")) {
|
||||
this.autocompleteList.handleInput(data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (kb.matches(data, "tab")) {
|
||||
if (kb.matches(data, "tui.input.tab")) {
|
||||
const selected = this.autocompleteList.getSelectedItem();
|
||||
if (selected && this.autocompleteProvider) {
|
||||
const shouldChainSlashArgumentAutocomplete = this.shouldChainSlashArgumentAutocompleteOnTabSelection();
|
||||
@@ -615,7 +615,7 @@ export class Editor implements Component, Focusable {
|
||||
return;
|
||||
}
|
||||
|
||||
if (kb.matches(data, "selectConfirm")) {
|
||||
if (kb.matches(data, "tui.select.confirm")) {
|
||||
const selected = this.autocompleteList.getSelectedItem();
|
||||
if (selected && this.autocompleteProvider) {
|
||||
this.pushUndoSnapshot();
|
||||
@@ -644,68 +644,68 @@ export class Editor implements Component, Focusable {
|
||||
}
|
||||
|
||||
// Tab - trigger completion
|
||||
if (kb.matches(data, "tab") && !this.autocompleteState) {
|
||||
if (kb.matches(data, "tui.input.tab") && !this.autocompleteState) {
|
||||
this.handleTabCompletion();
|
||||
return;
|
||||
}
|
||||
|
||||
// Deletion actions
|
||||
if (kb.matches(data, "deleteToLineEnd")) {
|
||||
if (kb.matches(data, "tui.editor.deleteToLineEnd")) {
|
||||
this.deleteToEndOfLine();
|
||||
return;
|
||||
}
|
||||
if (kb.matches(data, "deleteToLineStart")) {
|
||||
if (kb.matches(data, "tui.editor.deleteToLineStart")) {
|
||||
this.deleteToStartOfLine();
|
||||
return;
|
||||
}
|
||||
if (kb.matches(data, "deleteWordBackward")) {
|
||||
if (kb.matches(data, "tui.editor.deleteWordBackward")) {
|
||||
this.deleteWordBackwards();
|
||||
return;
|
||||
}
|
||||
if (kb.matches(data, "deleteWordForward")) {
|
||||
if (kb.matches(data, "tui.editor.deleteWordForward")) {
|
||||
this.deleteWordForward();
|
||||
return;
|
||||
}
|
||||
if (kb.matches(data, "deleteCharBackward") || matchesKey(data, "shift+backspace")) {
|
||||
if (kb.matches(data, "tui.editor.deleteCharBackward") || matchesKey(data, "shift+backspace")) {
|
||||
this.handleBackspace();
|
||||
return;
|
||||
}
|
||||
if (kb.matches(data, "deleteCharForward") || matchesKey(data, "shift+delete")) {
|
||||
if (kb.matches(data, "tui.editor.deleteCharForward") || matchesKey(data, "shift+delete")) {
|
||||
this.handleForwardDelete();
|
||||
return;
|
||||
}
|
||||
|
||||
// Kill ring actions
|
||||
if (kb.matches(data, "yank")) {
|
||||
if (kb.matches(data, "tui.editor.yank")) {
|
||||
this.yank();
|
||||
return;
|
||||
}
|
||||
if (kb.matches(data, "yankPop")) {
|
||||
if (kb.matches(data, "tui.editor.yankPop")) {
|
||||
this.yankPop();
|
||||
return;
|
||||
}
|
||||
|
||||
// Cursor movement actions
|
||||
if (kb.matches(data, "cursorLineStart")) {
|
||||
if (kb.matches(data, "tui.editor.cursorLineStart")) {
|
||||
this.moveToLineStart();
|
||||
return;
|
||||
}
|
||||
if (kb.matches(data, "cursorLineEnd")) {
|
||||
if (kb.matches(data, "tui.editor.cursorLineEnd")) {
|
||||
this.moveToLineEnd();
|
||||
return;
|
||||
}
|
||||
if (kb.matches(data, "cursorWordLeft")) {
|
||||
if (kb.matches(data, "tui.editor.cursorWordLeft")) {
|
||||
this.moveWordBackwards();
|
||||
return;
|
||||
}
|
||||
if (kb.matches(data, "cursorWordRight")) {
|
||||
if (kb.matches(data, "tui.editor.cursorWordRight")) {
|
||||
this.moveWordForwards();
|
||||
return;
|
||||
}
|
||||
|
||||
// New line
|
||||
if (
|
||||
kb.matches(data, "newLine") ||
|
||||
kb.matches(data, "tui.input.newLine") ||
|
||||
(data.charCodeAt(0) === 10 && data.length > 1) ||
|
||||
data === "\x1b\r" ||
|
||||
data === "\x1b[13;2~" ||
|
||||
@@ -722,7 +722,7 @@ export class Editor implements Component, Focusable {
|
||||
}
|
||||
|
||||
// Submit (Enter)
|
||||
if (kb.matches(data, "submit")) {
|
||||
if (kb.matches(data, "tui.input.submit")) {
|
||||
if (this.disableSubmit) return;
|
||||
|
||||
// Workaround for terminals without Shift+Enter support:
|
||||
@@ -739,7 +739,7 @@ export class Editor implements Component, Focusable {
|
||||
}
|
||||
|
||||
// Arrow key navigation (with history support)
|
||||
if (kb.matches(data, "cursorUp")) {
|
||||
if (kb.matches(data, "tui.editor.cursorUp")) {
|
||||
if (this.isEditorEmpty()) {
|
||||
this.navigateHistory(-1);
|
||||
} else if (this.historyIndex > -1 && this.isOnFirstVisualLine()) {
|
||||
@@ -752,7 +752,7 @@ export class Editor implements Component, Focusable {
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (kb.matches(data, "cursorDown")) {
|
||||
if (kb.matches(data, "tui.editor.cursorDown")) {
|
||||
if (this.historyIndex > -1 && this.isOnLastVisualLine()) {
|
||||
this.navigateHistory(1);
|
||||
} else if (this.isOnLastVisualLine()) {
|
||||
@@ -763,31 +763,31 @@ export class Editor implements Component, Focusable {
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (kb.matches(data, "cursorRight")) {
|
||||
if (kb.matches(data, "tui.editor.cursorRight")) {
|
||||
this.moveCursor(0, 1);
|
||||
return;
|
||||
}
|
||||
if (kb.matches(data, "cursorLeft")) {
|
||||
if (kb.matches(data, "tui.editor.cursorLeft")) {
|
||||
this.moveCursor(0, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Page up/down - scroll by page and move cursor
|
||||
if (kb.matches(data, "pageUp")) {
|
||||
if (kb.matches(data, "tui.editor.pageUp")) {
|
||||
this.pageScroll(-1);
|
||||
return;
|
||||
}
|
||||
if (kb.matches(data, "pageDown")) {
|
||||
if (kb.matches(data, "tui.editor.pageDown")) {
|
||||
this.pageScroll(1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Character jump mode triggers
|
||||
if (kb.matches(data, "jumpForward")) {
|
||||
if (kb.matches(data, "tui.editor.jumpForward")) {
|
||||
this.jumpMode = "forward";
|
||||
return;
|
||||
}
|
||||
if (kb.matches(data, "jumpBackward")) {
|
||||
if (kb.matches(data, "tui.editor.jumpBackward")) {
|
||||
this.jumpMode = "backward";
|
||||
return;
|
||||
}
|
||||
@@ -1149,10 +1149,10 @@ export class Editor implements Component, Focusable {
|
||||
}
|
||||
}
|
||||
|
||||
private shouldSubmitOnBackslashEnter(data: string, kb: ReturnType<typeof getEditorKeybindings>): boolean {
|
||||
private shouldSubmitOnBackslashEnter(data: string, kb: ReturnType<typeof getKeybindings>): boolean {
|
||||
if (this.disableSubmit) return false;
|
||||
if (!matchesKey(data, "enter")) return false;
|
||||
const submitKeys = kb.getKeys("submit");
|
||||
const submitKeys = kb.getKeys("tui.input.submit");
|
||||
const hasShiftEnter = submitKeys.includes("shift+enter") || submitKeys.includes("shift+return");
|
||||
if (!hasShiftEnter) return false;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getEditorKeybindings } from "../keybindings.js";
|
||||
import { getKeybindings } from "../keybindings.js";
|
||||
import { decodeKittyPrintable } from "../keys.js";
|
||||
import { KillRing } from "../kill-ring.js";
|
||||
import { type Component, CURSOR_MARKER, type Focusable } from "../tui.js";
|
||||
@@ -82,69 +82,69 @@ export class Input implements Component, Focusable {
|
||||
return;
|
||||
}
|
||||
|
||||
const kb = getEditorKeybindings();
|
||||
const kb = getKeybindings();
|
||||
|
||||
// Escape/Cancel
|
||||
if (kb.matches(data, "selectCancel")) {
|
||||
if (kb.matches(data, "tui.select.cancel")) {
|
||||
if (this.onEscape) this.onEscape();
|
||||
return;
|
||||
}
|
||||
|
||||
// Undo
|
||||
if (kb.matches(data, "undo")) {
|
||||
if (kb.matches(data, "tui.editor.undo")) {
|
||||
this.undo();
|
||||
return;
|
||||
}
|
||||
|
||||
// Submit
|
||||
if (kb.matches(data, "submit") || data === "\n") {
|
||||
if (kb.matches(data, "tui.input.submit") || data === "\n") {
|
||||
if (this.onSubmit) this.onSubmit(this.value);
|
||||
return;
|
||||
}
|
||||
|
||||
// Deletion
|
||||
if (kb.matches(data, "deleteCharBackward")) {
|
||||
if (kb.matches(data, "tui.editor.deleteCharBackward")) {
|
||||
this.handleBackspace();
|
||||
return;
|
||||
}
|
||||
|
||||
if (kb.matches(data, "deleteCharForward")) {
|
||||
if (kb.matches(data, "tui.editor.deleteCharForward")) {
|
||||
this.handleForwardDelete();
|
||||
return;
|
||||
}
|
||||
|
||||
if (kb.matches(data, "deleteWordBackward")) {
|
||||
if (kb.matches(data, "tui.editor.deleteWordBackward")) {
|
||||
this.deleteWordBackwards();
|
||||
return;
|
||||
}
|
||||
|
||||
if (kb.matches(data, "deleteWordForward")) {
|
||||
if (kb.matches(data, "tui.editor.deleteWordForward")) {
|
||||
this.deleteWordForward();
|
||||
return;
|
||||
}
|
||||
|
||||
if (kb.matches(data, "deleteToLineStart")) {
|
||||
if (kb.matches(data, "tui.editor.deleteToLineStart")) {
|
||||
this.deleteToLineStart();
|
||||
return;
|
||||
}
|
||||
|
||||
if (kb.matches(data, "deleteToLineEnd")) {
|
||||
if (kb.matches(data, "tui.editor.deleteToLineEnd")) {
|
||||
this.deleteToLineEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
// Kill ring actions
|
||||
if (kb.matches(data, "yank")) {
|
||||
if (kb.matches(data, "tui.editor.yank")) {
|
||||
this.yank();
|
||||
return;
|
||||
}
|
||||
if (kb.matches(data, "yankPop")) {
|
||||
if (kb.matches(data, "tui.editor.yankPop")) {
|
||||
this.yankPop();
|
||||
return;
|
||||
}
|
||||
|
||||
// Cursor movement
|
||||
if (kb.matches(data, "cursorLeft")) {
|
||||
if (kb.matches(data, "tui.editor.cursorLeft")) {
|
||||
this.lastAction = null;
|
||||
if (this.cursor > 0) {
|
||||
const beforeCursor = this.value.slice(0, this.cursor);
|
||||
@@ -155,7 +155,7 @@ export class Input implements Component, Focusable {
|
||||
return;
|
||||
}
|
||||
|
||||
if (kb.matches(data, "cursorRight")) {
|
||||
if (kb.matches(data, "tui.editor.cursorRight")) {
|
||||
this.lastAction = null;
|
||||
if (this.cursor < this.value.length) {
|
||||
const afterCursor = this.value.slice(this.cursor);
|
||||
@@ -166,24 +166,24 @@ export class Input implements Component, Focusable {
|
||||
return;
|
||||
}
|
||||
|
||||
if (kb.matches(data, "cursorLineStart")) {
|
||||
if (kb.matches(data, "tui.editor.cursorLineStart")) {
|
||||
this.lastAction = null;
|
||||
this.cursor = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (kb.matches(data, "cursorLineEnd")) {
|
||||
if (kb.matches(data, "tui.editor.cursorLineEnd")) {
|
||||
this.lastAction = null;
|
||||
this.cursor = this.value.length;
|
||||
return;
|
||||
}
|
||||
|
||||
if (kb.matches(data, "cursorWordLeft")) {
|
||||
if (kb.matches(data, "tui.editor.cursorWordLeft")) {
|
||||
this.moveWordBackwards();
|
||||
return;
|
||||
}
|
||||
|
||||
if (kb.matches(data, "cursorWordRight")) {
|
||||
if (kb.matches(data, "tui.editor.cursorWordRight")) {
|
||||
this.moveWordForwards();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getEditorKeybindings } from "../keybindings.js";
|
||||
import { getKeybindings } from "../keybindings.js";
|
||||
import type { Component } from "../tui.js";
|
||||
import { truncateToWidth, visibleWidth } from "../utils.js";
|
||||
|
||||
@@ -110,26 +110,26 @@ export class SelectList implements Component {
|
||||
}
|
||||
|
||||
handleInput(keyData: string): void {
|
||||
const kb = getEditorKeybindings();
|
||||
const kb = getKeybindings();
|
||||
// Up arrow - wrap to bottom when at top
|
||||
if (kb.matches(keyData, "selectUp")) {
|
||||
if (kb.matches(keyData, "tui.select.up")) {
|
||||
this.selectedIndex = this.selectedIndex === 0 ? this.filteredItems.length - 1 : this.selectedIndex - 1;
|
||||
this.notifySelectionChange();
|
||||
}
|
||||
// Down arrow - wrap to top when at bottom
|
||||
else if (kb.matches(keyData, "selectDown")) {
|
||||
else if (kb.matches(keyData, "tui.select.down")) {
|
||||
this.selectedIndex = this.selectedIndex === this.filteredItems.length - 1 ? 0 : this.selectedIndex + 1;
|
||||
this.notifySelectionChange();
|
||||
}
|
||||
// Enter
|
||||
else if (kb.matches(keyData, "selectConfirm")) {
|
||||
else if (kb.matches(keyData, "tui.select.confirm")) {
|
||||
const selectedItem = this.filteredItems[this.selectedIndex];
|
||||
if (selectedItem && this.onSelect) {
|
||||
this.onSelect(selectedItem);
|
||||
}
|
||||
}
|
||||
// Escape or Ctrl+C
|
||||
else if (kb.matches(keyData, "selectCancel")) {
|
||||
else if (kb.matches(keyData, "tui.select.cancel")) {
|
||||
if (this.onCancel) {
|
||||
this.onCancel();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { fuzzyFilter } from "../fuzzy.js";
|
||||
import { getEditorKeybindings } from "../keybindings.js";
|
||||
import { getKeybindings } from "../keybindings.js";
|
||||
import type { Component } from "../tui.js";
|
||||
import { truncateToWidth, visibleWidth, wrapTextWithAnsi } from "../utils.js";
|
||||
import { Input } from "./input.js";
|
||||
@@ -174,17 +174,17 @@ export class SettingsList implements Component {
|
||||
}
|
||||
|
||||
// Main list input handling
|
||||
const kb = getEditorKeybindings();
|
||||
const kb = getKeybindings();
|
||||
const displayItems = this.searchEnabled ? this.filteredItems : this.items;
|
||||
if (kb.matches(data, "selectUp")) {
|
||||
if (kb.matches(data, "tui.select.up")) {
|
||||
if (displayItems.length === 0) return;
|
||||
this.selectedIndex = this.selectedIndex === 0 ? displayItems.length - 1 : this.selectedIndex - 1;
|
||||
} else if (kb.matches(data, "selectDown")) {
|
||||
} else if (kb.matches(data, "tui.select.down")) {
|
||||
if (displayItems.length === 0) return;
|
||||
this.selectedIndex = this.selectedIndex === displayItems.length - 1 ? 0 : this.selectedIndex + 1;
|
||||
} else if (kb.matches(data, "selectConfirm") || data === " ") {
|
||||
} else if (kb.matches(data, "tui.select.confirm") || data === " ") {
|
||||
this.activateItem();
|
||||
} else if (kb.matches(data, "selectCancel")) {
|
||||
} else if (kb.matches(data, "tui.select.cancel")) {
|
||||
this.onCancel();
|
||||
} else if (this.searchEnabled && this.searchInput) {
|
||||
const sanitized = data.replace(/ /g, "");
|
||||
|
||||
Reference in New Issue
Block a user