Make Esc always switch to Command mode
update: this problem should be fixed in the recent version of navigation-hotkeys
.
If you use a very handy jupyter_contrib_nbextensions/nbextensions/navigation-hotkeys
it introduces a very bad idea of changing the behavior of Esc to always switch to the opposite mode, making Esc unreliable as a precursor for a command mode shortcut call. Which leads to a lot of unpredictable behavior. So the following takes the goodness of the navigation-hotkeys
extension and avoids the undesirable.
- disable
navigation-hotkeys
- add to ~/.jupyter/custom/custom.js the following:
/* start a custom version of jupyter_contrib_nbextensions/nbextensions/navigation-hotkeys to remove Esc=> Edit mode toggle as it interferes with the workflow - Esc needs to be deterministic - switches to Command mode */
var add_command_shortcuts = {
'home' : {
help : 'go to top',
help_index : 'ga',
handler : function() {
IPython.notebook.select(0);
IPython.notebook.scroll_to_top();
return false;
}
},
'end' : {
help : 'go to bottom',
help_index : 'ga',
handler : function() {
var ncells = IPython.notebook.ncells();
IPython.notebook.select(ncells-1);
IPython.notebook.scroll_to_bottom();
return false;
}
},
'pageup' : {
help : 'page up',
help_index : 'aa',
handler : function() {
var wh = 0.6 * $(window).height();
var cell = IPython.notebook.get_selected_cell();
var h = 0;
/* loop until we have enough cells to span the size of the notebook window (= one page) */
do {
h += cell.element.height();
IPython.notebook.select_prev();
cell = IPython.notebook.get_selected_cell();
} while ( h < wh );
var cp = cell.element.position();
var sp = $('body').scrollTop();
if ( cp.top < sp) {
IPython.notebook.scroll_to_cell(IPython.notebook.get_selected_index(), 0);
}
cell.focus_cell();
return false;
}
},
'pagedown' : {
help : 'page down',
help_index : 'aa',
handler : function() {
/* jump to bottom if we are already in the last cell */
var ncells = IPython.notebook.ncells();
if ( IPython.notebook.get_selected_index()+1 == ncells) {
IPython.notebook.scroll_to_bottom();
return false;
}
var wh = 0.6*$(window).height();
var cell = IPython.notebook.get_selected_cell();
var h = 0;
/* loop until we have enough cells to span the size of the notebook window (= one page) */
do {
h += cell.element.height();
IPython.notebook.select_next();
cell = IPython.notebook.get_selected_cell();
} while ( h < wh );
cell.focus_cell();
return false;
}
}
};
var add_edit_shortcuts = {
'alt-add' : {
help : 'split cell',
help_index : 'eb',
handler : function() {
IPython.notebook.split_cell();
IPython.notebook.edit_mode();
return false;
}
},
'alt-subtract' : {
help : 'merge cell',
help_index : 'eb',
handler : function() {
var i = IPython.notebook.get_selected_index();
if (i > 0) {
var l = IPython.notebook.get_cell(i-1).code_mirror.lineCount();
IPython.notebook.merge_cell_above();
IPython.notebook.get_selected_cell().code_mirror.setCursor(l,0);
}
}
},
'shift-enter' : {
help : 'run cell, select next codecell',
help_index : 'bb',
handler : function() {
IPython.notebook.execute_cell_and_select_below();
var rendered = IPython.notebook.get_selected_cell().rendered;
var ccell = IPython.notebook.get_selected_cell().cell_type;
if (rendered === false || ccell === 'code') IPython.notebook.edit_mode();
return false;
}
},
'ctrl-enter' : {
help : 'run cell',
help_index : 'bb',
handler : function() {
var cell = IPython.notebook.get_selected_cell();
var mode = cell.mode;
cell.execute();
if (mode === "edit") IPython.notebook.edit_mode();
return false;
}
},
'alt-n' : {
help : 'toggle line numbers',
help_index : 'xy',
handler : function() {
var cell = IPython.notebook.get_selected_cell();
cell.toggle_line_numbers();
return false;
}
},
'pagedown' : {
help : 'page down',
help_index : 'xy',
handler : function() {
var ic = IPython.notebook.get_selected_index();
var cells = IPython.notebook.get_cells();
var i, h=0;
for (i=0; i < ic; i ++) {
h += cells[i].element.height();
}
var cur = cells[ic].code_mirror.getCursor();
h += cells[ic].code_mirror.defaultTextHeight() * cur.line;
IPython.notebook.element.animate({scrollTop:h}, 0);
return false;
}
},
'pageup' : {
help : 'page down',
help_index : 'xy',
handler : function() {
var ic = IPython.notebook.get_selected_index();
var cells = IPython.notebook.get_cells();
var i, h=0;
for (i=0; i < ic; i ++) {
h += cells[i].element.height();
}
var cur =cells[ic].code_mirror.getCursor();
h += cells[ic].code_mirror.defaultTextHeight() * cur.line;
IPython.notebook.element.animate({scrollTop:h}, 0);
return false;
}
},
'ctrl-y' : {
help : 'toggle markdown/code',
handler : function() {
var cell = IPython.notebook.get_selected_cell();
var cur = cell.code_mirror.getCursor();
if (cell.cell_type == 'code') {
IPython.notebook.command_mode();
IPython.notebook.to_markdown();
IPython.notebook.edit_mode();
cell = IPython.notebook.get_selected_cell();
cell.code_mirror.setCursor(cur);
} else if (cell.cell_type == 'markdown') {
IPython.notebook.command_mode();
IPython.notebook.to_code();
IPython.notebook.edit_mode();
cell = IPython.notebook.get_selected_cell();
cell.code_mirror.setCursor(cur);
}
return false;
}
}
};
Jupyter.keyboard_manager.edit_shortcuts.add_shortcuts(add_edit_shortcuts);
Jupyter.keyboard_manager.command_shortcuts.add_shortcuts(add_command_shortcuts);
/* end a custom version of jupyter_contrib_nbextensions/nbextensions/navigation-hotkeys */