Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/cli/src/config/keyBindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export type KeyBindingConfig = {
export const defaultKeyBindings: KeyBindingConfig = {
// Basic Controls
[Command.RETURN]: [{ key: 'return' }],
[Command.ESCAPE]: [{ key: 'escape' }],
[Command.ESCAPE]: [{ key: 'escape' }, { key: '[', ctrl: true }],
[Command.QUIT]: [{ key: 'c', ctrl: true }],
[Command.EXIT]: [{ key: 'd', ctrl: true }],

Expand Down
30 changes: 23 additions & 7 deletions packages/cli/src/ui/hooks/vim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,14 @@ export function useVim(buffer: TextBuffer, onSubmit?: (value: string) => void) {
return false; // Let InputPrompt handle completion
}

// Let InputPrompt handle Ctrl+U (kill line left) and Ctrl+K (kill line right)
if (
normalizedKey.ctrl &&
(normalizedKey.name === 'u' || normalizedKey.name === 'k')
) {
return false;
}

// Let InputPrompt handle Ctrl+V for clipboard image pasting
if (normalizedKey.ctrl && normalizedKey.name === 'v') {
return false; // Let InputPrompt handle clipboard functionality
Expand Down Expand Up @@ -698,7 +706,10 @@ export function useVim(buffer: TextBuffer, onSubmit?: (value: string) => void) {
}

case '$': {
// Move to end of line
// Move to end of line (with count, move down count-1 lines first)
if (repeatCount > 1) {
buffer.vimMoveDown(repeatCount - 1);
}
buffer.vimMoveToLineEnd();
dispatch({ type: 'CLEAR_COUNT' });
return true;
Expand All @@ -713,14 +724,18 @@ export function useVim(buffer: TextBuffer, onSubmit?: (value: string) => void) {

case 'g': {
if (state.pendingOperator === 'g') {
// Second 'g' - go to first line (gg command)
buffer.vimMoveToFirstLine();
// Second 'g' - go to line N (gg command), or first line if no count
if (state.count > 0) {
buffer.vimMoveToLine(state.count);
} else {
buffer.vimMoveToFirstLine();
}
dispatch({ type: 'SET_PENDING_OPERATOR', operator: null });
dispatch({ type: 'CLEAR_COUNT' });
} else {
// First 'g' - wait for second g
// First 'g' - wait for second g (don't clear count yet)
dispatch({ type: 'SET_PENDING_OPERATOR', operator: 'g' });
}
dispatch({ type: 'CLEAR_COUNT' });
return true;
}

Expand Down Expand Up @@ -811,12 +826,13 @@ export function useVim(buffer: TextBuffer, onSubmit?: (value: string) => void) {
}
Comment thread
ppgranger marked this conversation as resolved.
Resolved

case '.': {
// Repeat last command
// Repeat last command (use current count if provided, otherwise use original count)
if (state.lastCommand) {
const cmdData = state.lastCommand;
const count = state.count > 0 ? state.count : cmdData.count;

// All repeatable commands are now handled by executeCommand
executeCommand(cmdData.type, cmdData.count);
executeCommand(cmdData.type, count);
}

dispatch({ type: 'CLEAR_COUNT' });
Expand Down