fix(vim): vim support that feels (more) complete (#18755)

Co-authored-by: Tommaso Sciortino <sciortino@gmail.com>
This commit is contained in:
Philippe
2026-02-13 01:22:39 +01:00
committed by GitHub
parent 55ec0f043c
commit 5b4884692b
7 changed files with 1241 additions and 115 deletions

View File

@@ -1657,8 +1657,9 @@ export type TextBufferAction =
| { type: 'vim_change_big_word_end'; payload: { count: number } }
| { type: 'vim_delete_line'; payload: { count: number } }
| { type: 'vim_change_line'; payload: { count: number } }
| { type: 'vim_delete_to_end_of_line' }
| { type: 'vim_change_to_end_of_line' }
| { type: 'vim_delete_to_end_of_line'; payload: { count: number } }
| { type: 'vim_delete_to_start_of_line' }
| { type: 'vim_change_to_end_of_line'; payload: { count: number } }
| {
type: 'vim_change_movement';
payload: { movement: 'h' | 'j' | 'k' | 'l'; count: number };
@@ -1688,6 +1689,11 @@ export type TextBufferAction =
| { type: 'vim_move_to_last_line' }
| { type: 'vim_move_to_line'; payload: { lineNumber: number } }
| { type: 'vim_escape_insert_mode' }
| { type: 'vim_delete_to_first_nonwhitespace' }
| { type: 'vim_change_to_start_of_line' }
| { type: 'vim_change_to_first_nonwhitespace' }
| { type: 'vim_delete_to_first_line'; payload: { count: number } }
| { type: 'vim_delete_to_last_line'; payload: { count: number } }
| {
type: 'toggle_paste_expansion';
payload: { id: string; row: number; col: number };
@@ -2437,6 +2443,7 @@ function textBufferReducerLogic(
case 'vim_delete_line':
case 'vim_change_line':
case 'vim_delete_to_end_of_line':
case 'vim_delete_to_start_of_line':
case 'vim_change_to_end_of_line':
case 'vim_change_movement':
case 'vim_move_left':
@@ -2463,6 +2470,11 @@ function textBufferReducerLogic(
case 'vim_move_to_last_line':
case 'vim_move_to_line':
case 'vim_escape_insert_mode':
case 'vim_delete_to_first_nonwhitespace':
case 'vim_change_to_start_of_line':
case 'vim_change_to_first_nonwhitespace':
case 'vim_delete_to_first_line':
case 'vim_delete_to_last_line':
return handleVimAction(state, action as VimAction);
case 'toggle_paste_expansion': {
@@ -2945,12 +2957,36 @@ export function useTextBuffer({
dispatch({ type: 'vim_change_line', payload: { count } });
}, []);
const vimDeleteToEndOfLine = useCallback((): void => {
dispatch({ type: 'vim_delete_to_end_of_line' });
const vimDeleteToEndOfLine = useCallback((count: number = 1): void => {
dispatch({ type: 'vim_delete_to_end_of_line', payload: { count } });
}, []);
const vimChangeToEndOfLine = useCallback((): void => {
dispatch({ type: 'vim_change_to_end_of_line' });
const vimDeleteToStartOfLine = useCallback((): void => {
dispatch({ type: 'vim_delete_to_start_of_line' });
}, []);
const vimChangeToEndOfLine = useCallback((count: number = 1): void => {
dispatch({ type: 'vim_change_to_end_of_line', payload: { count } });
}, []);
const vimDeleteToFirstNonWhitespace = useCallback((): void => {
dispatch({ type: 'vim_delete_to_first_nonwhitespace' });
}, []);
const vimChangeToStartOfLine = useCallback((): void => {
dispatch({ type: 'vim_change_to_start_of_line' });
}, []);
const vimChangeToFirstNonWhitespace = useCallback((): void => {
dispatch({ type: 'vim_change_to_first_nonwhitespace' });
}, []);
const vimDeleteToFirstLine = useCallback((count: number): void => {
dispatch({ type: 'vim_delete_to_first_line', payload: { count } });
}, []);
const vimDeleteToLastLine = useCallback((count: number): void => {
dispatch({ type: 'vim_delete_to_last_line', payload: { count } });
}, []);
const vimChangeMovement = useCallback(
@@ -3510,7 +3546,13 @@ export function useTextBuffer({
vimDeleteLine,
vimChangeLine,
vimDeleteToEndOfLine,
vimDeleteToStartOfLine,
vimChangeToEndOfLine,
vimDeleteToFirstNonWhitespace,
vimChangeToStartOfLine,
vimChangeToFirstNonWhitespace,
vimDeleteToFirstLine,
vimDeleteToLastLine,
vimChangeMovement,
vimMoveLeft,
vimMoveRight,
@@ -3592,7 +3634,13 @@ export function useTextBuffer({
vimDeleteLine,
vimChangeLine,
vimDeleteToEndOfLine,
vimDeleteToStartOfLine,
vimChangeToEndOfLine,
vimDeleteToFirstNonWhitespace,
vimChangeToStartOfLine,
vimChangeToFirstNonWhitespace,
vimDeleteToFirstLine,
vimDeleteToLastLine,
vimChangeMovement,
vimMoveLeft,
vimMoveRight,
@@ -3832,12 +3880,38 @@ export interface TextBuffer {
vimChangeLine: (count: number) => void;
/**
* Delete from cursor to end of line (vim 'D' command)
* With count > 1, deletes to end of current line plus (count-1) additional lines
*/
vimDeleteToEndOfLine: () => void;
vimDeleteToEndOfLine: (count?: number) => void;
/**
* Delete from start of line to cursor (vim 'd0' command)
*/
vimDeleteToStartOfLine: () => void;
/**
* Change from cursor to end of line (vim 'C' command)
* With count > 1, changes to end of current line plus (count-1) additional lines
*/
vimChangeToEndOfLine: () => void;
vimChangeToEndOfLine: (count?: number) => void;
/**
* Delete from cursor to first non-whitespace character (vim 'd^' command)
*/
vimDeleteToFirstNonWhitespace: () => void;
/**
* Change from cursor to start of line (vim 'c0' command)
*/
vimChangeToStartOfLine: () => void;
/**
* Change from cursor to first non-whitespace character (vim 'c^' command)
*/
vimChangeToFirstNonWhitespace: () => void;
/**
* Delete from current line to first line (vim 'dgg' command)
*/
vimDeleteToFirstLine: (count: number) => void;
/**
* Delete from current line to last line (vim 'dG' command)
*/
vimDeleteToLastLine: (count: number) => void;
/**
* Change movement operations (vim 'ch', 'cj', 'ck', 'cl' commands)
*/