jupyterlab-contrib / jupyterlab-vim

Vim notebook cell bindings for JupyterLab
https://jupyterlab-contrib.github.io/jupyterlab-vim.html
MIT License
691 stars 43 forks source link

Make insert the default mode of Notebook cells. #13

Closed gordonrust closed 2 years ago

gordonrust commented 4 years ago

Presently, when I jump to a notebook cell, I always end up in the normal mode, even if that cell was in insert mode previously. Do you think it is possible to make the cell remember their states.

ianhi commented 4 years ago

This extension works by listening to every time you switch cells and when you do it runs all of the vim initialization code on the cell you've switched to: https://github.com/axelfahy/jupyterlab-vim/blob/c4e43f940ef4be4c961608b6192412d2f3a33d1f/src/index.ts#L61-L64

My guess is that doing this is resetting the mode. I wonder if adding an if statement checking if the cell is already in vim mode, and if so not setting the keymap would prevent this.

ianhi commented 4 years ago

Follow up. That is indeed true. You can get the behavior you want if you only set the cell keymap on creation. This is the default in my pr to jupyterlab adding notebook vim to core https://github.com/jupyterlab/jupyterlab/pull/9068 which uses a different method of setting the cells to be vim.

gordonrust commented 3 years ago

And how do i check if the cell is already in vim mode? I looked into src/index.ts and couldn't find this done anywhere and am completely unaware of the codemirror api (or even javascript :-))

gordonrust commented 3 years ago

I got ur suggestion working on my end by using a count variable that runs the vim-mode initialistion only if the count is 0.

But now I am unable to move between cells using j-k in the normal mode (i have to use up-down only.)

Any ideas?

ianhi commented 3 years ago

And how do i check if the cell is already in vim mode?

I think the easiest way will look somethign like this: (untested but I htink this is will wokr)

if (editor.getOption('keymap') === 'vim'){
   return
}else {
// whatever is currently done
}

completely unaware of the codemirror api (or even javascript :-))

This was me no so long ago :).

Codemirror vim api here: https://codemirror.net/doc/manual.html#vimapi

ianhi commented 3 years ago

But now I am unable to move between cells using j-k in the normal mode (i have to use up-down only.)

This is after the changes you made? Or is that a bug in the version of the extension you installed?

gordonrust commented 3 years ago

But now I am unable to move between cells using j-k in the normal mode (i have to use up-down only.)

This is after the changes you made? Or is that a bug in the version of the extension you installed?

I was able to debug the issue with you approach.

Somehow this function which is responsible for motions definign switching between cell using j-k is not called if I do not reinitialise the cell . (Line 85 ; src/index.ts) lvim.defineMotion('moveByLinesOrCell', (cm: any, head: any, motionArgs: any, vim : any) => `

(line 84) I tries creating the cells with insert mode itself changing (CodeMirror as any).Vim.handleKey(editor.editor, '<Esc>'); to (CodeMirror as any).Vim.handleKey(editor.editor, 'i'); but then if i use j--k motion to move into a new cell, i land in the insert mode of this cell an type a lot of j's or k's .

Any ideas??

gordonrust commented 3 years ago

@ianhi I was actually able to configure the following behaviour:

  1. If I use mouse click to go to a cell , I land in the insert mode.
  2. If I use j-k to go to a cell, I land in the insert mode.

The way I did this is :

  1. I create an indicator variable whose default value changes when we are about to jump to next cell.
  2. The cell reintializes using either of (CodeMirror as any).Vim.handleKey(editor.editor, '<Esc>'); or (CodeMirror as any).Vim.handleKey(editor.editor, 'i'); based on the indicator variable.

Something I am perplexed about is that the indicator variable is initialised to default value in the constructor.

If all the cells are different objects of the class VimCell how does the value of the indicator variable propagates when we switch to a different cell??

I can share my code if you want.

Thanks

gordonrust commented 2 years ago

So I was able to make the default mode of code-mirror to be insert mode by simply changing (CodeMirror as any).Vim.handleKey(editor.editor, '<Esc>'); to (CodeMirror as any).Vim.handleKey(editor.editor, 'i'); This is to be changed in the src/codemirrorCommands.ts file in the function modifyCell . This works with jupyterlab 3 (3.4.7 o be exact)

You would need to make a development install. Make sure that nodejs version is recent( I was getting from conda nodejs 6.63 and had to update the nodejs to get the local install working.