| 127 | * @returns Object with vim state and input handler |
| 128 | */ |
| 129 | export function useVim(buffer: TextBuffer, onSubmit?: (value: string) => void) { |
| 130 | const { vimEnabled, vimMode, setVimMode } = useVimMode(); |
| 131 | const [state, dispatch] = useReducer(vimReducer, initialVimState); |
| 132 | |
| 133 | // Sync vim mode from context to local state |
| 134 | useEffect(() => { |
| 135 | dispatch({ type: 'SET_MODE', mode: vimMode }); |
| 136 | }, [vimMode]); |
| 137 | |
| 138 | // Helper to update mode in both reducer and context |
| 139 | const updateMode = useCallback( |
| 140 | (mode: VimMode) => { |
| 141 | setVimMode(mode); |
| 142 | dispatch({ type: 'SET_MODE', mode }); |
| 143 | }, |
| 144 | [setVimMode], |
| 145 | ); |
| 146 | |
| 147 | // Helper functions using the reducer state |
| 148 | const getCurrentCount = useCallback( |
| 149 | () => state.count || DEFAULT_COUNT, |
| 150 | [state.count], |
| 151 | ); |
| 152 | |
| 153 | /** Executes common commands to eliminate duplication in dot (.) repeat command */ |
| 154 | const executeCommand = useCallback( |
| 155 | (cmdType: string, count: number) => { |
| 156 | switch (cmdType) { |
| 157 | case CMD_TYPES.DELETE_WORD_FORWARD: { |
| 158 | buffer.vimDeleteWordForward(count); |
| 159 | break; |
| 160 | } |
| 161 | |
| 162 | case CMD_TYPES.DELETE_WORD_BACKWARD: { |
| 163 | buffer.vimDeleteWordBackward(count); |
| 164 | break; |
| 165 | } |
| 166 | |
| 167 | case CMD_TYPES.DELETE_WORD_END: { |
| 168 | buffer.vimDeleteWordEnd(count); |
| 169 | break; |
| 170 | } |
| 171 | |
| 172 | case CMD_TYPES.CHANGE_WORD_FORWARD: { |
| 173 | buffer.vimChangeWordForward(count); |
| 174 | updateMode('INSERT'); |
| 175 | break; |
| 176 | } |
| 177 | |
| 178 | case CMD_TYPES.CHANGE_WORD_BACKWARD: { |
| 179 | buffer.vimChangeWordBackward(count); |
| 180 | updateMode('INSERT'); |
| 181 | break; |
| 182 | } |
| 183 | |
| 184 | case CMD_TYPES.CHANGE_WORD_END: { |
| 185 | buffer.vimChangeWordEnd(count); |
| 186 | updateMode('INSERT'); |