// change the mode of all current and future CodeMirror instances define([ "base/js/namespace", "notebook/js/cell", "codemirror/lib/codemirror", "codemirror/keymap/emacs", "codemirror/keymap/vim", "codemirror/keymap/sublime", "codemirror/mode/meta", "codemirror/addon/comment/comment", "codemirror/addon/dialog/dialog", "codemirror/addon/edit/closebrackets", "codemirror/addon/edit/matchbrackets", "codemirror/addon/search/searchcursor", "codemirror/addon/search/search", ], function( Jupyter, Cell, CodeMirror // other stuff is loaded, but not used ) { "use_strict"; var previous_mode = ""; var available_keymaps = [ "default", "emacs", "vim", "sublime" ]; /* Values to use for config keys that are note defined in server config */ var default_config = { line_wrap: true, local_storage: true, }; var starting_state = { extraKeys: {}, edit_shortcuts: {}, command_shortcuts: {} }; var cm_default = Cell.Cell.options_default.cm_config; var edit_shortcuts = Jupyter.keyboard_manager.edit_shortcuts; var command_shortcuts = Jupyter.keyboard_manager.command_shortcuts; var mods = { vim: { add: { extraKeys: { "Esc": "leave_current_mode", "Ctrl-[": "leave_current_mode" }, command_shortcuts: { "Ctrl-c": "jupyter-notebook:interrupt-kernel", "Ctrl-z": "jupyter-notebook:restart-kernel", "d,d": "jupyter-notebook:cut-cell", "y,y": "jupyter-notebook:copy-cell", "u": "jupyter-notebook:undo-cell-deletion", "p": "jupyter-notebook:paste-cell-below", "Shift-P": "jupyter-notebook:paste-cell-above", "o": "jupyter-notebook:insert-cell-below", "Shift-O": "jupyter-notebook:insert-cell-above", "i": "jupyter-notebook:enter-edit-mode", "Enter": "jupyter-notebook:enter-edit-mode", "Shift-J": "jupyter-notebook:move-cell-down", "Shift-K": "jupyter-notebook:move-cell-up", "Shift-/": "jupyter-notebook:show-keyboard-shortcuts", "h": "jupyter-notebook:toggle-cell-output-collapsed", "Shift-H": "jupyter-notebook:toggle-cell-output-scrolled", "`": "jupyter-notebook:change-cell-to-code", "0": "jupyter-notebook:change-cell-to-markdown" }, edit_shortcuts: { "Shift-Esc": "jupyter-notebook:enter-command-mode" } }, remove: { edit_shortcuts: ["Esc"] }, custom: function() { disable_keyboard_manager_in_dialog(this); }, custom_teardown: function() { reenable_keyboard_manager_in_dialog(this); } }, emacs: { add: { extraKeys: { "Ctrl-Y": "yank_no_selection" }, command_shortcuts: { "Ctrl-N": "jupyter-notebook:select-next-cell", "Ctrl-P": "jupyter-notebook:select-previous-cell", "Alt-X": "jupyter-notebook:show-command-palette" }, edit_shortcuts: { "Alt-X": "jupyter-notebook:show-command-palette" } }, remove: { edit_shortcuts: ["Ctrl-Shift-Minus"], keyMap: ["Ctrl-V"] }, custom: function() { disable_keyboard_manager_in_dialog(this); }, custom_teardown: function() { reenable_keyboard_manager_in_dialog(this); } } }; function disable_keyboard_manager_in_dialog(_this) { // Disable keyboard manager for code mirror dialogs, handles ':' // triggered ex-mode dialog box in vim mode. // Manager is re-enabled by re-entry into notebook edit mode + // cell normal mode after dialog closes _this.openDialog = CodeMirror.prototype.openDialog; function openDialog_keymap_wrapper(target, template, callback, options) { Jupyter.keyboard_manager.disable(); return target.call(this, template, callback, options); } CodeMirror.defineExtension("openDialog", _.wrap(_this.openDialog, openDialog_keymap_wrapper)); } function reenable_keyboard_manager_in_dialog(_this) { CodeMirror.defineExtension("openDialog", _this.openDialog); } var server_config = Jupyter.notebook.config; // make sure config is loaded before making initial changes var initialize = function () { save_starting_state(); // initialize last stored value or default switch_keymap(get_stored_keymap()); }; function get_config(key) { if (server_config.data.hasOwnProperty("select_keymap_" + key)) { return server_config.data["select_keymap_" + key]; } return default_config[key]; } function get_stored_keymap() { var keymap; if (get_config("local_storage")) { keymap = window.localStorage.getItem("jupyter_keymap"); } else { keymap = server_config.data.stored_keymap; } return keymap || "default"; } function store_keymap(mode) { if (get_config("local_storage")) { window.localStorage.setItem("jupyter_keymap", mode); } else { server_config.update({ stored_keymap: mode }); } } function flatten_shortcuts(shortcut_tree) { var result = {}; for (var p in shortcut_tree) { if (typeof(shortcut_tree[p]) == "string") { result[p] = shortcut_tree[p]; } else { var subresult = flatten_shortcuts(shortcut_tree[p]); for (var subp in subresult) { result[p + "," + subp] = subresult[subp]; } } } return result; } function update_shortcuts(shortcut_manager, updated_shortcuts) { var current_shortcuts = _.invert(flatten_shortcuts(shortcut_manager._shortcuts)); for (var shortcut_action in _.invert(updated_shortcuts)) { if (_.has(current_shortcuts, shortcut_action) && shortcut_manager.get_shortcut(current_shortcuts[shortcut_action])) { shortcut_manager.remove_shortcut(current_shortcuts[shortcut_action]); } } shortcut_manager.add_shortcuts(updated_shortcuts); } // start custom CodeMirror command definitions function leave_current_mode(cm) { if (cm.state.vim.insertMode) { // Move from insert mode into command mode. CodeMirror.keyMap["vim-insert"].call("Esc", cm); } else if (cm.state.vim.visualMode) { // Move from visual mode to command mode. CodeMirror.keyMap["vim"].call("Esc", cm); } else { // Move to notebook command mode. Jupyter.notebook.command_mode(); Jupyter.notebook.focus_cell(); } }; var orig_ctrl_y = CodeMirror.keyMap.emacs["Ctrl-Y"]; function yank_no_selection(cm) { orig_ctrl_y(cm); // remove selection after yank cm.setSelection(cm.getCursor(), cm.getCursor()); }; CodeMirror.commands.yank_no_selection = yank_no_selection; CodeMirror.commands.leave_current_mode = leave_current_mode; // end custom CodeMirror command definitions function create_menu() { var menu = [ "
", "