diff --git a/IPython/html/static/notebook/js/cell.js b/IPython/html/static/notebook/js/cell.js index c8253a6..994f643 100644 --- a/IPython/html/static/notebook/js/cell.js +++ b/IPython/html/static/notebook/js/cell.js @@ -19,6 +19,7 @@ var IPython = (function (IPython) { "use strict"; var utils = IPython.utils; + var keycodes = IPython.keyboard.keycodes; /** * The Base `Cell` class from which to inherit @@ -153,6 +154,59 @@ var IPython = (function (IPython) { }); } }; + + /** + * This method gets called in CodeMirror's onKeyDown/onKeyPress + * handlers and is used to provide custom key handling. + * + * To have custom handling, subclasses should override this method, but still call it + * in order to process the Edit mode keyboard shortcuts. + * + * @method handle_codemirror_keyevent + * @param {CodeMirror} editor - The codemirror instance bound to the cell + * @param {event} event - + * @return {Boolean} `true` if CodeMirror should ignore the event, `false` Otherwise + */ + Cell.prototype.handle_codemirror_keyevent = function (editor, event) { + var that = this; + + if (event.keyCode === keycodes.enter && (event.shiftKey || event.ctrlKey || event.altKey)) { + // Always ignore shift-enter in CodeMirror as we handle it. + return true; + } else if (event.which === keycodes.up && event.type === 'keydown') { + // If we are not at the top, let CM handle the up arrow and + // prevent the global keydown handler from handling it. + if (!that.at_top()) { + event.stop(); + return false; + } else { + return true; + }; + } else if (event.which === keycodes.down && event.type === 'keydown') { + // If we are not at the bottom, let CM handle the down arrow and + // prevent the global keydown handler from handling it. + if (!that.at_bottom()) { + event.stop(); + return false; + } else { + return true; + }; + } else if (event.which === keycodes.esc && event.type === 'keydown') { + if (that.code_mirror.options.keyMap === "vim-insert") { + // vim keyMap is active and in insert mode. In this case we leave vim + // insert mode, but remain in notebook edit mode. + // Let' CM handle this event and prevent global handling. + event.stop(); + return false; + } else { + // vim keyMap is not active. Leave notebook edit mode. + // Don't let CM handle the event, defer to global handling. + return true; + } + } + return false; + }; + /** * Triger typsetting of math by mathjax on current cell element @@ -257,7 +311,6 @@ var IPython = (function (IPython) { var cm = this.code_mirror var cursor = cm.getCursor(); if (cursor.line === 0 && cm.findPosV(cursor, -1, 'line').hitSide) { - console.log('at top'); return true; } else { return false; diff --git a/IPython/html/static/notebook/js/codecell.js b/IPython/html/static/notebook/js/codecell.js index e5753a7..ec1aad8 100644 --- a/IPython/html/static/notebook/js/codecell.js +++ b/IPython/html/static/notebook/js/codecell.js @@ -194,60 +194,26 @@ var IPython = (function (IPython) { this.auto_highlight(); } - if (event.keyCode === keycodes.enter && (event.shiftKey || event.ctrlKey || event.altKey)) { - // Always ignore shift-enter in CodeMirror as we handle it. - return true; - } else if (event.which === keycodes.down && event.type === 'keypress' && IPython.tooltip.time_before_tooltip >= 0) { + if (event.which === keycodes.down && event.type === 'keypress' && IPython.tooltip.time_before_tooltip >= 0) { // triger on keypress (!) otherwise inconsistent event.which depending on plateform // browser and keyboard layout ! // Pressing '(' , request tooltip, don't forget to reappend it // The second argument says to hide the tooltip if the docstring // is actually empty IPython.tooltip.pending(that, true); - } else if (event.which === keycodes.up && event.type === 'keydown') { - // If we are not at the top, let CM handle the up arrow and - // prevent the global keydown handler from handling it. - if (!that.at_top()) { - event.stop(); - return false; - } else { - return true; - } - } else if (event.which === keycodes.esc && event.type === 'keydown') { - // First see if the tooltip is active and if so cancel it. - if (tooltip_closed) { - // The call to remove_and_cancel_tooltip above in L177 doesn't pass - // force=true. Because of this it won't actually close the tooltip - // if it is in sticky mode. Thus, we have to check again if it is open - // and close it with force=true. - if (!IPython.tooltip._hidden) { - IPython.tooltip.remove_and_cancel_tooltip(true); - } - // If we closed the tooltip, don't let CM or the global handlers - // handle this event. - event.stop(); - return true; - } - if (that.code_mirror.options.keyMap === "vim-insert") { - // vim keyMap is active and in insert mode. In this case we leave vim - // insert mode, but remain in notebook edit mode. - // Let' CM handle this event and prevent global handling. - event.stop(); - return false; - } else { - // vim keyMap is not active. Leave notebook edit mode. - // Don't let CM handle the event, defer to global handling. - return true; - } - } else if (event.which === keycodes.down && event.type === 'keydown') { - // If we are not at the bottom, let CM handle the down arrow and - // prevent the global keydown handler from handling it. - if (!that.at_bottom()) { - event.stop(); - return false; - } else { - return true; + } else if ( tooltip_closed && event.which === keycodes.esc && event.type === 'keydown') { + // If tooltip is active, cancel it. + // The call to remove_and_cancel_tooltip above in L177 doesn't pass + // force=true. Because of this it won't actually close the tooltip + // if it is in sticky mode. Thus, we have to check again if it is open + // and close it with force=true. + if (!IPython.tooltip._hidden) { + IPython.tooltip.remove_and_cancel_tooltip(true); } + // If we closed the tooltip, don't let CM or the global handlers + // handle this event. + event.stop(); + return true; } else if (event.keyCode === keycodes.tab && event.type === 'keydown' && event.shiftKey) { if (editor.somethingSelected()){ var anchor = editor.getCursor("anchor"); @@ -275,12 +241,11 @@ var IPython = (function (IPython) { this.completer.startCompletion(); return true; } - } else { - // keypress/keyup also trigger on TAB press, and we don't want to - // use those to disable tab completion. - return false; - } - return false; + } + + // keyboard event wasn't one of those unique to code cells, let's see + // if it's one of the generic ones (i.e. check edit mode shortcuts) + return IPython.Cell.prototype.handle_codemirror_keyevent.apply(this, [editor, event]) }; // Kernel related calls. diff --git a/IPython/html/static/notebook/js/textcell.js b/IPython/html/static/notebook/js/textcell.js index c60dc6c..6bd13fb 100644 --- a/IPython/html/static/notebook/js/textcell.js +++ b/IPython/html/static/notebook/js/textcell.js @@ -113,57 +113,6 @@ var IPython = (function (IPython) { }); }; - /** - * This method gets called in CodeMirror's onKeyDown/onKeyPress - * handlers and is used to provide custom key handling. - * - * Subclass should override this method to have custom handling - * - * @method handle_codemirror_keyevent - * @param {CodeMirror} editor - The codemirror instance bound to the cell - * @param {event} event - - * @return {Boolean} `true` if CodeMirror should ignore the event, `false` Otherwise - */ - TextCell.prototype.handle_codemirror_keyevent = function (editor, event) { - var that = this; - - if (event.keyCode === 13 && (event.shiftKey || event.ctrlKey || event.altKey)) { - // Always ignore shift-enter in CodeMirror as we handle it. - return true; - } else if (event.which === keycodes.up && event.type === 'keydown') { - // If we are not at the top, let CM handle the up arrow and - // prevent the global keydown handler from handling it. - if (!that.at_top()) { - event.stop(); - return false; - } else { - return true; - }; - } else if (event.which === keycodes.down && event.type === 'keydown') { - // If we are not at the bottom, let CM handle the down arrow and - // prevent the global keydown handler from handling it. - if (!that.at_bottom()) { - event.stop(); - return false; - } else { - return true; - }; - } else if (event.which === keycodes.esc && event.type === 'keydown') { - if (that.code_mirror.options.keyMap === "vim-insert") { - // vim keyMap is active and in insert mode. In this case we leave vim - // insert mode, but remain in notebook edit mode. - // Let' CM handle this event and prevent global handling. - event.stop(); - return false; - } else { - // vim keyMap is not active. Leave notebook edit mode. - // Don't let CM handle the event, defer to global handling. - return true; - } - } - return false; - }; - // Cell level actions TextCell.prototype.select = function () {