@@ -43,6 +43,11 @@ interface IUndoOptions {
4343 registerName : unknown ;
4444}
4545
46+ export interface ICellContext {
47+ index ?: number ;
48+ cellCount ?: number ;
49+ }
50+
4651export class VimEditorManager {
4752 constructor ( { enabled, userKeybindings } : VimEditorManager . IOptions ) {
4853 this . enabled = enabled ;
@@ -167,21 +172,29 @@ export class VimCellManager extends VimEditorManager {
167172 tracker : INotebookTracker ,
168173 activeCell : Cell < ICellModel > | null
169174 ) : void {
170- this . modifyCell ( activeCell ) . catch ( console . error ) ;
175+ const activeCellContext = {
176+ index : tracker . currentWidget ?. content . activeCellIndex ,
177+ cellCount : tracker . currentWidget ?. content . widgets . length
178+ } as ICellContext ;
179+ this . modifyCell ( activeCell , activeCellContext ) . catch ( console . error ) ;
171180 }
172181
173182 updateLastActive ( ) {
174- if ( ! this . _lastActiveCell ) {
183+ if ( ! this . _lastActiveCell || ! this . _lastActiveCellContext ) {
175184 return ;
176185 }
177- this . modifyCell ( this . _lastActiveCell ) ;
186+ this . modifyCell ( this . _lastActiveCell , this . _lastActiveCellContext ) ;
178187 }
179188
180- async modifyCell ( activeCell : Cell < ICellModel > | null ) : Promise < void > {
181- if ( ! activeCell ) {
189+ async modifyCell (
190+ activeCell : Cell < ICellModel > | null ,
191+ activeCellContext : ICellContext
192+ ) : Promise < void > {
193+ if ( ! activeCell || ! activeCellContext ) {
182194 return ;
183195 }
184196 this . _lastActiveCell = activeCell ;
197+ this . _lastActiveCellContext = activeCellContext ;
185198 await activeCell . ready ;
186199
187200 if ( activeCell . isDisposed ) {
@@ -190,11 +203,14 @@ export class VimCellManager extends VimEditorManager {
190203 }
191204 const wasEnabled = this . modifyEditor ( activeCell . editor ) ;
192205 if ( wasEnabled ) {
193- this . _modifyEdgeNavigation ( activeCell ) ;
206+ this . _modifyEdgeNavigation ( activeCell , activeCellContext ) ;
194207 }
195208 }
196209
197- private _modifyEdgeNavigation ( activeCell : Cell < ICellModel > ) {
210+ private _modifyEdgeNavigation (
211+ activeCell : Cell < ICellModel > ,
212+ activeCellContext : ICellContext
213+ ) {
198214 // Define a function to use as Vim motion
199215 // This replaces the codemirror moveByLines function to
200216 // for jumping between notebook cells.
@@ -254,7 +270,11 @@ export class VimCellManager extends VimEditorManager {
254270 // var key = '';
255271 // `currentCell !== null should not be needed since `activeCell`
256272 // is already check against null (row 61). Added to avoid warning.
257- if ( currentCell !== null && currentCell . model . type === 'markdown' ) {
273+ if (
274+ currentCell !== null &&
275+ currentCell . model . type === 'markdown' &&
276+ ! ( ! motionArgs . forward && activeCellContext . index === 0 )
277+ ) {
258278 if ( ! motionArgs . handleArrow ) {
259279 // markdown cells tends to improperly handle arrow keys movement,
260280 // on the way up the cell is rendered, but down movement is ignored
@@ -368,4 +388,5 @@ export class VimCellManager extends VimEditorManager {
368388
369389 private _commands : CommandRegistry ;
370390 private _lastActiveCell : Cell < ICellModel > | null = null ;
391+ private _lastActiveCellContext : ICellContext | undefined ;
371392}
0 commit comments