How to: Get Sublime Text style editing in the IPython/Jupyter notebook
So, I really like the Jupyter notebook (formerly known as the IPython notebook), but I often find myself missing the ‘fancy’ features that ‘proper’ editors have. I particularly miss the amazing multiple cursor functionality of editors like Sublime Text and Atom.
I’ve known for a while that you can edit a cell in your default $EDITOR
by running %%edit
at the top of the cell – but I’ve recently found out that you can configure Jupyter to use Sublime Text-style keyboard shortcuts when editing cells in the notebook – all thanks to CodeMirror, the javascript-based text editor component that the Jupyter notebook uses. Brilliantly, this also brings with it the multiple-cursor functionality! So, you can get something like this:
So, how do you do this? It’s really simple.
- Find your Jupyter configuration folder by running
jupyter --config-dir
- Open the
custom.js
file in thecustom
sub-folder in your favourite editor - Add the following lines to the bottom of the file
require(["codemirror/keymap/sublime", "notebook/js/cell", "base/js/namespace"], function(sublime_keymap, cell, IPython) { // setTimeout(function(){ // uncomment line to fake race-condition cell.Cell.options_default.cm_config.keyMap = 'sublime'; var cells = IPython.notebook.get_cells(); for(var cl=0; cl< cells.length ; cl++){ cells[cl].code_mirror.setOption('keyMap', 'sublime'); } // }, 1000)// uncomment line to fake race condition } );
That should be it – if you start a notebook now all of the Sublime Text shortcuts should be working!
If you found this post useful, please consider buying me a coffee.
This post originally appeared on Robin's Blog.
Categorised as: Programming, Python
In the for loop, I believe
cells.code_mirror.setOption(‘keyMap’, ‘sublime’);
should be
cells[c].code_mirror.setOption(‘keyMap’, ‘sublime’);
Weirdly, the
[c]
was in the code, but wasn’t rendering properly. I’ve changed the variable name tocl
and it works fine. Weird – but thanks for pointing it out!I’ve tried this and it works fine, with one small hitch: ctrl+enter, which executes the cell in Jupyter, is also a keyboard shortcut for “insert a new line after the current one” in the sublime keymap, so now every time I run a cell, I get a new blank line. Have you encountered this problem?
Ahh, good point! I hadn’t come across that myself, as I don’t use Ctrl-Enter to execute the cell (I’m on a Mac so use Cmd-Enter) – although I believe Ctrl-Enter does do something on Macs too. I can see that would be very frustrating though!
All I can suggest is getting in touch with the IPython people and asking if there is a way to make the IPython shortcut take precedence – or alternatively to ‘turn off’ the Ctrl-Enter Sublime shortcut. If you do find out how to do it then please let me know!
I’d love to get this going. I’m on Jupyter 4.1 (was on 4.0.4) but my .jupyter folder is basically empty. I have a file “migrated” that looks to have a timestamp of when I first installed jupyter.
Searches for custom.js suggest this is an old ipython remnant that exists in some other form now in jupyter.
Am I barking up the wrong tree?
I think this may be a IPython to Jupyter migration problem. First, I’d try running
jupyter migrate
in a terminal and see if that creates some more files there. If it doesn’t, then I’d have a look at this migration guide. Hope that helps![JupyterMigrate] Found nothing to migrate.
Curious. This is a relatively new machine to me. I never did have iPython notebook on it. I just installed Jupyter from the getgo. Any possibility it could it be related to that? Maybe custom.js was a part of ipython?
I can’t find any current reference to it in read the docs.
I’m not using Conda… any chance it’s tied to that?
It definitely shouldn’t be related to conda. It seems like it is still in use, but a blank file may not be created automatically nowadays. Try using the example code at
http://jupyter-notebook.readthedocs.org/en/latest/examples/Notebook/JavaScript%20Notebook%20Extensions.html#custom.js
to check where your Jupyter config directory is, and create acustom.js
file there code in it, and see if it works. (If not, then you can try the ‘Exercise’ listed on that page – and you’ll definitely be able to find out if it works!)Ay carumba! Thanks.
First of all, my fault on all of it. I can read, but apparently I can’t READ!
jupyter –config-dir shows me to the .jupyter folder. You clearly then say IN THE `custom` FOLDER, which I didn’t have, but glossed over. So every attempt I made at making a custom.js in that root folder didn’t take.
The little snippets in read the docs helped clearly bash me over the head that I didn’t have a custom.js and showed that it was looking in my nonexistent custom folder. Making one and placing it there and it all works swell now. Thanks for pointing me there.
Now… why can I not search for custom.js in read the docs? eh? It doesn’t like periods search and I can’t seem to escape them. That’s why I couldn’t find any of that when I searched for custom.js. And searches for custom or js only did whole word searches. Sheesh.
Thanks so much for your help and patience!
Really glad to hear you got it working 🙂
The issue with searching the docs might be worth raising as an issue (either on Github or on the mailing list), as I imagine others may run into the same problem.
This only partly works for me. I can do column select, but other key strokes don’t work as expected. CMD-D deletes the selected lines for example.
Like Alan, this doesn’t seem to work. Cmd-D still deltes the line. I did the verification-step and got the alert, but no Sublime multi-select goodness.
Hmm, that’s weird. I’m not sure what’s going wrong.
I’ll have a play on another machine and see if I can replicate the error: I wonder if it is a version-related issue or something.
@Adam, I had to restart the server in order to get it working
Thanks! I’ve made an addition to your script that will leave the Ctrl-Enter & Shift-Enter keys unchanged (as these are used by jupyter to execute cells). This prevents both the jupyter AND the sublime actions happening:
“`
console.log(‘loaded sublime custom.js’);
require([“codemirror/keymap/sublime”, “notebook/js/cell”, “base/js/namespace”],
function(sublime_keymap, cell, IPython) {
cell.Cell.options_default.cm_config.keyMap = ‘sublime’;
cell.Cell.options_default.cm_config.extraKeys[‘Cmd-Enter’] = function(){console.log(‘cmd-enter’)};
cell.Cell.options_default.cm_config.extraKeys[‘Ctrl-Enter’] = function(){console.log(‘ctrl-enter’)};
cell.Cell.options_default.cm_config.extraKeys[‘Shift-Enter’] = function(){};
var cells = IPython.notebook.get_cells();
for(var cl=0; cl< cells.length ; cl++){
cells[cl].code_mirror.setOption('extraKeys',
{
"Cmd-Enter": function(){},
"Ctrl-Enter": function(){}
}
);
cells[cl].code_mirror.setOption('keyMap', 'sublime');
}
}
);
“`
Thanks a lot!!!
Is there a way to get this to work in Jupyter Lab?
Using the built-in Sublime Text option in Lab doesn’t seem to work, or at least it doesn’t capture all Sublime shortcuts (ctrl D, deletes a line, instead of selecting next instance).
That’s a good question Jay – I don’t know. I’ve just installed the latest version of Jupyter Lab myself, and I’ll have a play and post here if I find anything.
Did you get anywhere with Jupyter Lab?
No, sorry, I haven’t had chance.
Maybe try the Jupyter mailing list and see if anyone can help? I’d love to hear your answer if you manage to work it out!
Looks like somebody has to write an extension. It already exists for vim style keymaps.
https://github.com/jupyterlab/jupyterlab/issues/4310
To fix the ctrl-Enter problem on windows:
Use:
require([“codemirror/keymap/sublime”, “notebook/js/cell”, “base/js/namespace”],
function(sublime_keymap, cell, IPython) {
cell.Cell.options_default.cm_config.keyMap = ‘sublime’;
cell.Cell.options_default.cm_config.extraKeys[“Ctrl-Enter”] = function(cm) {}
var cells = IPython.notebook.get_cells();
for(var cl=0; cl< cells.length ; cl++){
cells[cl].code_mirror.setOption('keyMap', 'sublime');
cells[cl].code_mirror.setOption("extraKeys", {
"Ctrl-Enter": function(cm) {}
});
}
}
);
Genius, thank you!
The modification by Santas_little_helper works fine on Windows after replacing the typographical quotes with regular double (or simple) quotes. WordPress being overeager again.
You also have to reload the workbook in the browser (I also restarted the server, but you may not actually have to do that).
This is great! Thanks a lot… will really speed up my workflow. Now just to get it working in JupyterLab.
Moving line up/down with Ctrl+Shit+Up/Down does not work.