@@ -3,6 +3,7 @@ import type { createVimState, VimSnapshot } from "./vim-state"
33import type { TextareaRenderable } from "@opentui/core"
44import { vimScroll , type VimScroll } from "./vim-scroll"
55import { vimJump , type VimJump } from "./vim-motion-jump"
6+ import { vimWindowNavigation , type VimWindowNavigation } from "./vim-motion-window-navigation.ts"
67import {
78 appendAfterCursor ,
89 appendLineEnd ,
@@ -49,6 +50,7 @@ import {
4950} from "./vim-motions"
5051
5152export type VimEvent = {
53+
5254 name ?: string
5355 shift ?: boolean
5456 ctrl ?: boolean
@@ -66,9 +68,11 @@ export function createVimHandler(input: {
6668 submit : ( ) => void
6769 scroll : ( action : VimScroll ) => void
6870 jump : ( action : VimJump ) => void
71+ navigate : ( action : VimWindowNavigation ) => void
6972 copy ?: ( action : VimCopyMove ) => void
7073 copyVisual ?: ( mode : "char" | "line" ) => void
7174 copyExitVisual ?: ( ) => void
75+ copyExit ?: ( scrollToBottom ?: boolean ) => void
7276 copyYank ?: ( ) => void
7377 copyCopy ?: ( ) => void
7478 copyIsVisual ?: ( ) => boolean
@@ -182,6 +186,16 @@ export function createVimHandler(input: {
182186 return true
183187 }
184188
189+ const navigation = vimWindowNavigation ( event , input . state ) ;
190+ if ( navigation . handled ) {
191+ if ( navigation . action ) {
192+ input . state . clearPending ( ) ;
193+ input . navigate ( navigation . action ) ;
194+ }
195+ event . preventDefault ( )
196+ return true
197+ }
198+
185199 if ( key === "escape" ) {
186200 if ( input . state . isVisual ( ) ) {
187201 clearSelection ( input . textarea ( ) )
@@ -715,8 +729,15 @@ export function createVimHandler(input: {
715729 return true
716730 }
717731
732+ // window navigation
733+ if ( key === "w" && hasModifier ( event ) ) {
734+ input . state . setPending ( "w" ) ;
735+ event . preventDefault ( ) ;
736+ return true ;
737+ }
738+
718739 return false
719- }
740+ }
720741
721742 function copyMotion ( offset : number ) {
722743 input . setCopyCol ?.( offset )
@@ -740,6 +761,40 @@ export function createVimHandler(input: {
740761 return true
741762 }
742763
764+ if ( key === "i" ) {
765+ if ( input . copyIsVisual ?.( ) ) {
766+ input . copyExitVisual ?.( )
767+ event . preventDefault ( )
768+ return true
769+ }
770+ input . state . setSkipExitOnModeChange ( true )
771+ input . state . setExitScrollToBottom ( false )
772+ input . state . setMode ( "insert" )
773+ event . preventDefault ( )
774+ input . copyExit ?.( false )
775+ return true
776+ }
777+
778+ if ( event . ctrl && input . state . pending ( ) === "w" && key === "j" ) {
779+ if ( input . copyIsVisual ?.( ) ) {
780+ input . copyExitVisual ?.( )
781+ event . preventDefault ( )
782+ return true
783+ }
784+ input . state . setSkipExitOnModeChange ( true )
785+ input . state . setExitScrollToBottom ( false )
786+ input . state . setMode ( "normal" )
787+ event . preventDefault ( )
788+ input . copyExit ?.( false )
789+ return true
790+ }
791+
792+ if ( key === "w" && hasModifier ( event ) ) {
793+ input . state . setPending ( "w" )
794+ event . preventDefault ( )
795+ return true
796+ }
797+
743798 const scroll = vimScroll ( event )
744799 if ( scroll ) {
745800 input . scroll ( scroll )
@@ -964,6 +1019,7 @@ export function createVimHandler(input: {
9641019 return true
9651020 }
9661021
1022+
9671023 // repeat find
9681024 if ( key === ";" ) {
9691025 const last = input . state . lastFind ( )
0 commit comments