-
Notifications
You must be signed in to change notification settings - Fork 5.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make keyboard shortcuts declarative #1234
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,3 +12,4 @@ override the notebook's defaults with your own custom behavior. | |
contents | ||
savehooks | ||
handlers | ||
keymaps |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
Customize keymaps | ||
================= | ||
|
||
.. note:: | ||
|
||
DEclarative Custom Keymaps is a provisional feature with unstable API which is not | ||
guarantied to be keep in future versions odf the notebook, and can be | ||
removed or changed without warnings. | ||
|
||
The notebook shortcuts that are defined by jupyter both in edit mode an command | ||
mode are configurable in the frontend configuration file | ||
``~/.jupyter/nbconfig/notebook.json``. The modification of Keyboard shortcut | ||
suffer of several limitations, mainly that your Browser and OS might prevent | ||
certain shortcut to work correctly. If this is the case, there are | ||
unfortunately not much than can be done. The second issue can arise with | ||
keyboard that have a layout different than US English. Again even if we are | ||
aware of the issue, there is not much we can do about that. | ||
|
||
Shortcut are also limited by the underlying library that handle code and text | ||
edition: CodeMirror. If some Keyboard shortcuts are conflicting, the method | ||
describe below might not work to create new keyboard shortcuts, especially in | ||
the ``edit`` mode of the notebook. | ||
|
||
|
||
The 4 sections of interest in ``~/.jupyter/nbconfig/notebook.json`` are the following: | ||
|
||
- ``keys.command.unbind`` | ||
- ``keys.edit.unbind`` | ||
- ``keys.command.bind`` | ||
- ``keys.edit.bind`` | ||
|
||
The first two section describe which default keyboard shortcut not to register | ||
at notebook startup time. These are mostly useful if you need to ``unbind`` a | ||
default keyboard shortcut before binding it to a new ``command``. | ||
|
||
These two first sections apply respectively to the ``command`` and ``edit`` | ||
mode of the notebook. They take a list of shortcut to ``unbind``. | ||
|
||
For example, to unbind the shortcut to split a cell at the position of the | ||
cursor (``Ctrl-Shift-Minus``)use the following: | ||
|
||
.. code:: javascript | ||
|
||
// file ~/.jupyter/nbconfig/notebook.json | ||
|
||
{ | ||
"keys": { | ||
"edit": { | ||
"unbind": [ | ||
"Ctrl-Shift-Minus" | ||
] | ||
}, | ||
}, | ||
} | ||
|
||
|
||
|
||
|
||
The last two section describe which new keyboard shortcut to register | ||
at notebook startup time, and which actions they trigger. | ||
|
||
These two last sections apply respectively to the ``command`` and ``edit`` mode of the notebook. | ||
They take a dictionary with shortcuts as ``keys`` and ``commands`` name as value. | ||
|
||
For example, to bind the shortcut ``G,G,G`` (Press G three time in a row) in | ||
command mode, to the command that restart the kernel and run all cells, use the | ||
following: | ||
|
||
|
||
.. code:: javascript | ||
|
||
// file ~/.jupyter/nbconfig/notebook.json | ||
|
||
{ | ||
"keys": { | ||
"command": { | ||
"bind": { | ||
"G,G,G":"jupyter-notebook:restart-kernel-and-run-all-cells" | ||
} | ||
} | ||
}, | ||
} | ||
|
||
|
||
|
||
|
||
The name of the available ``commands`` can be find by hovering the right end of | ||
a row in the command palette. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -396,6 +396,10 @@ define([ | |
* Remove the binding of shortcut `sortcut` with its action. | ||
* throw an error if trying to remove a non-exiting shortcut | ||
**/ | ||
if(!shortcut){ | ||
console.warn('trying to remove empty shortcut'); | ||
return; | ||
} | ||
shortcut = normalize_shortcut(shortcut); | ||
if( typeof(shortcut) === 'string'){ | ||
shortcut = shortcut.split(','); | ||
|
@@ -404,8 +408,8 @@ define([ | |
* The shortcut error should be explicit here, because it will be | ||
* seen by users. | ||
*/ | ||
try | ||
{ | ||
var that = this; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I might be missing something but it doesn't look like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, yeah, just had an experiment here that I removed. |
||
try { | ||
this._remove_leaf(shortcut, this._shortcuts); | ||
if (!suppress_help_update) { | ||
// update the keyboard shortcuts notebook help | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -76,4 +76,4 @@ | |
"notebookApp['" + modulePath + "']});`"].join(' ')); | ||
return notebookApp[modulePath]; | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,6 +42,46 @@ define([ | |
this.edit_shortcuts = new keyboard.ShortcutManager(undefined, options.events, this.actions, this.env); | ||
this.edit_shortcuts.add_shortcuts(this.get_default_common_shortcuts()); | ||
this.edit_shortcuts.add_shortcuts(this.get_default_edit_shortcuts()); | ||
|
||
|
||
this.config = options.config; | ||
var that = this; | ||
|
||
this.config.loaded.then(function(){ | ||
var edit_unbind; | ||
|
||
try { | ||
edit_unbind = that.config.data.keys.edit.unbind; | ||
} catch (e) { | ||
if (e instanceof TypeError) { | ||
edit_unbind = []; | ||
} else { | ||
throw e; | ||
} | ||
} | ||
|
||
edit_unbind.forEach(function(u){that.edit_shortcuts.remove_shortcut(u);}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this be shorted to:
? and for the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, I actually tried, and it was calling the prototype in the wrong context, telling me that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, you're right. I think it's because a function has the scope of the object it was defined on, so by default ES6 gives a very concise way to get around most There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I know. We could think of using es6 transpiler as now we use webpack.... we might be able to use:
So I'll be in favor of something obvious. |
||
|
||
var command_unbind; | ||
|
||
try { | ||
command_unbind = that.config.data.keys.command.unbind; | ||
} catch (e) { | ||
if (e instanceof TypeError) { | ||
command_unbind = []; | ||
} else { | ||
throw e; | ||
} | ||
} | ||
|
||
command_unbind.forEach(function(u){that.command_shortcuts.remove_shortcut(u);}); | ||
|
||
that.command_shortcuts.add_shortcuts( ((that.config.data.keys||{}).command||{}).bind); | ||
that.edit_shortcuts.add_shortcuts( ((that.config.data.keys||{}).edit ||{}).bind); | ||
|
||
} | ||
); | ||
|
||
Object.seal(this); | ||
}; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spelling nits: