lambdalisue / jupyter-vim-binding

Jupyter meets Vim. Vimmer will fall in love.
2.1k stars 136 forks source link

Customization help #63

Open clearissimple opened 8 years ago

clearissimple commented 8 years ago

Summary

Request for some additional explanation regarding customization

Environment

I am not familiar with JavaScript, its libraries and the technology surrounding it. Advice on how to organize customization code would be very helpful. Thanks in advance.

Order of loading

If I understand correctly, customization Code should be run after the vim-bindig extension has been loaded. But it's not clear to me how to achieve a certain order. From what I can see, custom.js is executed first, then extensions are loaded.

I tried following this guide http://akuederle.com/customize-ipython-keymap to create an extension for additional key bindings and force it to load after vim-binding. The following code in my custom.js produces the desired order most of the time.

require(['base/js/utils'],
function(utils) {
    utils.load_extensions('vim_binding/vim_binding');
    setTimeout(function() {
        console.log("additional");
        utils.load_extensions('additional_shortcuts');
}, 3000);
});

What's the correct way to do it?

Customizing the design by putting code into ~/.jupyter/custom/custom.css has no effect. I assume it's because those settings are overridden once the vim-binding is loaded.

CodeMirror Vim Mode

I would also like to ask for help with customizing the CodeMirror's Vim Mode. My additional_shortcuts.js contains

require(['nbextensions/vim_binding/vim_binding'], function() {
    CodeMirror.Vim.defineOperator("comment_op",
                                  function(cm) { cm.toggleComment(); });
    CodeMirror.Vim.mapCommand("gc", "operator", "comment_op", {});
});

which works fine to toggle comments on a selection or a text object. Is there a way to add a mapping gcc that would toggle comments on current line, or is the common prefix gc a problem? I tried with map and defineAction but they we not called.

How to provide a Ctrl-c insert mode mapping to return to normal mode? This does not work.

CodeMirror.Vim.map("<C-c>", "<Esc>", "insert");
lambdalisue commented 8 years ago

Order of loading

If I understand correctly, customization Code should be run after the vim-bindig extension has been loaded.

Yes. That's why codes in Wiki are enclosed by

require([
  'nbextensions/vim_binding/vim_binding',   // depends your installation
], function() {
  // Code here is executed after vim_binding has loaded.
});

So what exactly would you like to do?

Customizing the design by putting code into ~/.jupyter/custom/custom.css has no effect. I assume it's because those settings are overridden once the vim-binding is loaded.

Hum... maybe a bug. Can I see your custom.css and expected behavior?

CodeMirror Vim mode

which works fine to toggle comments on a selection or a text object. Is there a way to add a mapping gcc that would toggle comments on current line, or is the common prefix gc a problem? I tried with map and defineAction but they we not called.

I'm sorry but I'm not really familiar with customizing CodeMirror. My knowledge comes from them documentation so you probably need to ask how to do such kind of things to CodeMirror developers.

How to provide a Ctrl-c insert mode mapping to return to normal mode? This does not work.

I'm not really sure but jupyter-vim-binding disable <C-c> mapping to enable browser's default copy mapping. It may overwrite your setting.

clearissimple commented 8 years ago

Thanks @lambdalisue, your hints helped me along. I installed vim-binding via jupyter nbextension enable and could simplify the custom.js code to

require(['base/js/utils',
         'nbextensions/vim_binding/vim_binding'], function(utils) {
    utils.load_extensions('additional_shortcuts');
});

and now the customization code is run correctly after vim-binding loads.

You were right about the 'Ctrl-C' mapping. I removed that property form the extraKeys option with this:

var cm_config = require("notebook/js/cell").Cell.options_default.cm_config;
delete cm_config.extraKeys['Ctrl-C'];
Jupyter.notebook.get_cells().map(function(cell) {
    var cm = cell.code_mirror;
    if (cm) {
        delete cm.getOption('extraKeys')['Ctrl-C'];
    }
});

and the CodeMirror.Vim.map("<C-c>", "<Esc>", "insert"); mapping works now.

The customisations I made are a couple of vim mappings and redefinitions of run cell actions to include scrolling a cell to the top automatically, because the output is often off screen.

Jupyter.keyboard_manager.actions.register({
    'help': 'run selected cells',
    'handler': function(env, event) {
        env.notebook.command_mode();
        var actions = Jupyter.keyboard_manager.actions;
        actions.call('jupyter-notebook:run-cell', event, env);
        actions.call('jupyter-notebook:scroll-cell-top', event, env);
        env.notebook.edit_mode();
    }
}, 'run-cell', 'vim-binding');

The ~/.jupyter/custom/custom.css is

/* Jupyter cell is in normal mode when code mirror */
.edit_mode .cell.selected .CodeMirror-focused.cm-fat-cursor {
  background-color: #F5F6EB;
}
/* Jupyter cell is in insert mode when code mirror */
.edit_mode .cell.selected .CodeMirror-focused:not(.cm-fat-cursor) {
  /* background-color: #F6EBF1; */
  background-color: #F5F6EB;
}

I simply don't want the color to change when I switch modes. In the Web Console, I don't see a request for custom.css. Do I have to explicitly state that it's required?

lambdalisue commented 8 years ago

and now the customization code is run correctly after vim-binding loads.

So did you really need to use utils.load_extensions? The code in the document used to work but I add a lot of modifications so it may break customization codes.... If it is required, I need to re-write documents.

You were right about the 'Ctrl-C' mapping. I removed that property form the extraKeys option with this:

The customisations I made are a couple of vim mappings and redefinitions of run cell actions to include scrolling a cell to the top automatically, because the output is often off screen.

Cool. Could you write those tips on the wiki in case someone want similar behaviour?

I simply don't want the color to change when I switch modes. In the Web Console, I don't see a request for custom.css. Do I have to explicitly state that it's required?

I'm not really sure but could you try ~/.jupyter/static/custom/custom.css instead? Found in https://github.com/jupyter/notebook/search?utf8=%E2%9C%93&q=custom.css

clearissimple commented 8 years ago

As far as I can tell, installing extensions via jupyter nbextensions install modifies ~/.jupyter/nbconfig/notebook.json but when these extensions are loaded it happens apparently in no particular order. That's why I used the utils.load_extensions() function to make vim-binding load first.

Putting the file in the static directory, as you suggested, did not work. I added code from the require_css (vim_binding.js) to load the custom.css file. And that file gets loaded after vim_binding.css but it does not seem to have an effect. Maybe the css-Code does not override or replace values as it is supposed to.

I'll gladly add those snippets to the wiki.

sysid commented 7 years ago

Got the same problem on windows. Python 3.5.2 |Anaconda 4.1.1 (64-bit) Any ideas appreciated:

jgors commented 7 years ago

Likewise, I am having the same problem with getting custom.css code to work. I was wanting the same thing as @gyphub -- in that I just wanted the code background to stay the same when in either normal or insert mode.

However, as a super hacky solution, if I hard-code a change in the vim_binding package code directly, in ~/.local/share/jupyter/nbextensions/vim_binding/vim_binding.css, then the css changes do take effect. (Note, this assumes pip package installs with --user flag).

-Python 3.5 -Ubuntu 16.10

lambdalisue commented 7 years ago

Thanks for sharing your tips and sorry for inconvenience... Actually I don't use custom.css so I'm waiting someone to fix and sending me a PR.