ux(polish) autocomplete in the input prompt (#18181)

This commit is contained in:
Jacob Richman
2026-02-05 12:38:29 -08:00
committed by GitHub
parent 9ca7300c90
commit 8efae719ee
11 changed files with 927 additions and 210 deletions

View File

@@ -44,10 +44,16 @@ vi.mock('./text-buffer.js', () => {
);
}
}),
setText: vi.fn((newText) => {
setText: vi.fn((newText, cursorPosition) => {
mockTextBuffer.text = newText;
mockTextBuffer.viewportVisualLines = [newText];
mockTextBuffer.visualCursor[1] = newText.length;
if (typeof cursorPosition === 'number') {
mockTextBuffer.visualCursor[1] = cursorPosition;
} else if (cursorPosition === 'start') {
mockTextBuffer.visualCursor[1] = 0;
} else {
mockTextBuffer.visualCursor[1] = newText.length;
}
}),
};
@@ -92,10 +98,16 @@ describe('TextInput', () => {
);
}
}),
setText: vi.fn((newText) => {
setText: vi.fn((newText, cursorPosition) => {
buffer.text = newText;
buffer.viewportVisualLines = [newText];
buffer.visualCursor[1] = newText.length;
if (typeof cursorPosition === 'number') {
buffer.visualCursor[1] = cursorPosition;
} else if (cursorPosition === 'start') {
buffer.visualCursor[1] = 0;
} else {
buffer.visualCursor[1] = newText.length;
}
}),
};
mockBuffer = buffer as unknown as TextBuffer;

View File

@@ -1596,8 +1596,13 @@ function generatePastedTextId(
}
export type TextBufferAction =
| { type: 'set_text'; payload: string; pushToUndo?: boolean }
| { type: 'insert'; payload: string; isPaste?: boolean }
| {
type: 'set_text';
payload: string;
pushToUndo?: boolean;
cursorPosition?: 'start' | 'end' | number;
}
| { type: 'add_pasted_content'; payload: { id: string; text: string } }
| { type: 'backspace' }
| {
@@ -1709,12 +1714,29 @@ function textBufferReducerLogic(
.replace(/\r\n?/g, '\n')
.split('\n');
const lines = newContentLines.length === 0 ? [''] : newContentLines;
const lastNewLineIndex = lines.length - 1;
let newCursorRow: number;
let newCursorCol: number;
if (typeof action.cursorPosition === 'number') {
[newCursorRow, newCursorCol] = offsetToLogicalPos(
action.payload,
action.cursorPosition,
);
} else if (action.cursorPosition === 'start') {
newCursorRow = 0;
newCursorCol = 0;
} else {
// Default to 'end'
newCursorRow = lines.length - 1;
newCursorCol = cpLen(lines[newCursorRow] ?? '');
}
return {
...nextState,
lines,
cursorRow: lastNewLineIndex,
cursorCol: cpLen(lines[lastNewLineIndex] ?? ''),
cursorRow: newCursorRow,
cursorCol: newCursorCol,
preferredCol: null,
pastedContent: action.payload === '' ? {} : nextState.pastedContent,
};
@@ -2838,9 +2860,12 @@ export function useTextBuffer({
dispatch({ type: 'redo' });
}, []);
const setText = useCallback((newText: string): void => {
dispatch({ type: 'set_text', payload: newText });
}, []);
const setText = useCallback(
(newText: string, cursorPosition?: 'start' | 'end' | number): void => {
dispatch({ type: 'set_text', payload: newText, cursorPosition });
},
[],
);
const deleteWordLeft = useCallback((): void => {
dispatch({ type: 'delete_word_left' });
@@ -3638,7 +3663,7 @@ export interface TextBuffer {
* Replaces the entire buffer content with the provided text.
* The operation is undoable.
*/
setText: (text: string) => void;
setText: (text: string, cursorPosition?: 'start' | 'end' | number) => void;
/**
* Insert a single character or string without newlines.
*/