Add readline-like keybindings to the input prompts. (#354)

New keybindings in the main input prompt (when auto-suggestions are not active):

  - `Ctrl+L`: Clears the entire screen.
  - `Ctrl+A`: Moves the cursor to the beginning of the current input line.
  - `Ctrl+E`: Moves the cursor to the end of the current input line.
  - `Ctrl+P`: Navigates to the previous command in the input history.
  - `Ctrl+N`: Navigates to the next command in the input history.

In the multiline text editor (e.g., when editing a previous message):
   - `Ctrl+K`: Deletes text from the current cursor position to the end of the line ("kill line right").
This commit is contained in:
DeWitt Clinton
2025-05-14 17:33:37 -07:00
committed by GitHub
parent ff36c93733
commit aec6c0861e
4 changed files with 127 additions and 5 deletions

View File

@@ -24,6 +24,8 @@ interface InputPromptProps {
userMessages: readonly string[];
navigateSuggestionUp: () => void;
navigateSuggestionDown: () => void;
setEditorState: (updater: (prevState: EditorState) => EditorState) => void;
onClearScreen: () => void;
}
export interface EditorState {
@@ -44,6 +46,8 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
navigateSuggestionUp,
navigateSuggestionDown,
resetCompletion,
setEditorState,
onClearScreen,
}) => {
const handleSubmit = useCallback(
(submittedValue: string) => {
@@ -106,7 +110,12 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
);
const inputPreprocessor = useCallback(
(input: string, key: Key) => {
(
input: string,
key: Key,
_currentText?: string,
_cursorOffset?: number,
) => {
if (showSuggestions) {
if (key.upArrow) {
navigateSuggestionUp();
@@ -136,6 +145,31 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
resetCompletion();
return true;
}
} else {
// Keybindings when suggestions are not shown
if (key.ctrl && input === 'a') {
setEditorState((s) => ({ key: s.key + 1, initialCursorOffset: 0 }));
return true;
}
if (key.ctrl && input === 'e') {
setEditorState((s) => ({
key: s.key + 1,
initialCursorOffset: query.length,
}));
return true;
}
if (key.ctrl && input === 'l') {
onClearScreen();
return true;
}
if (key.ctrl && input === 'p') {
inputHistory.navigateUp();
return true;
}
if (key.ctrl && input === 'n') {
inputHistory.navigateDown();
return true;
}
}
return false;
},
@@ -149,6 +183,9 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
resetCompletion,
activeSuggestionIndex,
handleSubmit,
inputHistory,
setEditorState,
onClearScreen,
],
);