How to add keyboard shortcuts permanently to Jupyter (ipython) notebook? - ipython

I have the following configuration for shortcuts, that works after running it in the cell of Jupiter notebook:
%%javascript
IPython.keyboard_manager.command_shortcuts.add_shortcut('ctrl-q', {
help: 'Clear all output', // This text will show up on the help page (CTRL-M h or ESC h)
handler: function (event) { // Function that gets invoked
if (IPython.notebook.mode == 'command') {
IPython.notebook.clear_all_output();
return false;
}
return true;
}
});
How can I setup Jupiter notebook to make this initialization automatically on startup?
I tried adding the same code (without %%javascript) to C:\Users\<username>\.ipython\profile_default\static\custom\custom.js but it didn't work.
I have only one profile, created with ipython profile create, Python 3.3, Windows 7.
Thanks in advance.

In the new version of Jupyter notebook (update it either with pip install --upgrade notebook or if you use conda conda upgrade notebook), you can customize them from the notebook itself.
To do this Help -> Edit keyboard shortcuts

custom.js is the correct place for this code. Try wrapping it as follows (don't forget the return true before the end of the block):
$([IPython.events]).on("app_initialized.NotebookApp", function () {
<your code>
return true;
});

1. For changing command mode shortcuts: refer Salvador's answer
2. For changing edit mode shortcuts:
Edit the file, ~/.jupyter/nbconfig/notebook.json as explained on https://jupyter-notebook.readthedocs.io/en/stable/extending/keymaps.html
For example, after replacing the control-enter shortcut to execute code, with command-enter on macOS, the file looks like this:
{
"Notebook": {
"Toolbar": true,
"Header": true
},
"Cell": {
"cm_config": {
"lineNumbers": true
}
},
"keys": {
"command": {
"unbind": [
"ctrl-enter"
],
"bind": {
"cmdtrl-enter": "jupyter-notebook:run-cell"
}
},
"edit": {
"unbind": [
"ctrl-enter"
],
"bind": {
"cmdtrl-enter": "jupyter-notebook:run-cell"
}
}
}
}

Adding hotkeys the easy way with nbextensions
Install nbextensions.
pip install jupyter_contrib_nbextensions
Then launch jupyter notebook.
The the intro page will have a new tab called nbextensions click it and enable Keyboard Shortcut Editor.
Now open any notebook click help>keyboard shortcuts
Each shortcut will have a pencil icon next to it if you click on it then you can set the shortcut to whatever you want.

Related

why hover doesn't work on Linux using VSCode after the latest release of VSCode(1.59.1)?

I am actually trying to make a VSCode extension that will provide hover functionality. I had managed to make it work but since the last release of VSCode (1.59.1) it doesn't work anymore on Linux computers (have tested on Ubuntu and CentOs), but still works on Windows and MacOS. Here is my client js file (./client/extension.js):
const vscode = require('vscode');
function activate(context) {
console.log('Congratulations, your extension of YALES2 is now active!');
console.warn('Congratulations, your extension of YALES2 is now active!')
let disposable = vscode.commands.registerCommand('extension.mamar', () => {
vscode.window.showInformationMessage("Hover");
});
context.subscriptions.push(disposable);
disposable = vscode.languages.registerHoverProvider('yales2test', {
provideHover(document, position, token) {
const range = document.getWordRangeAtPosition(position);
const word = document.getText(range);
if (word=="ABSORBING_BOUNDARIES") {
return new vscode.Hover({ language: "yales2test", value: 'Message to show on Hover'});
}
}
});
context.subscriptions.push(disposable)
}
function deactivate() { }
module.exports = {
activate,
deactivate
}
And on my package.json I have:
"activationEvents": [
"onCommand:extension.mamar",
"onLanguage:yales2test"
],
"main": "./client/extension.js",
"contributes": {
"capabilities": {
"hoverProvider": "true"
}
I also tried to downgrade VSCode to 1.58.2 and there the hover works!
Would anyone know why it doesn't work anymore on Linux when using VSCode 1.59.1, please?
The problem was the length of my extension.js since it had a huge number of if ... else if... resulting to an exceed of memory! So always think to optimize your code!

Create duplicate tab of an already open file [duplicate]

We can use the "split editor" option to make two views into one file.
I'm looking for an option to open the same file in separated tabs like I can do in Sublime Text (open new view of file). Is that possible?
Note: I want to do this without splitting the view, so there should be two tabs for the same file within the same view container.
I couldn't find anything built-in that lets you do this, nor an existing extension in the marketplace. I thought it should be quite trivial to implement a "Duplicate Tab" command yourself in a custom extension, but it turns out VSCode only allows the same resource to be opened once within the same view column.
It's still possible to do this on Windows or macOS, but only by abusing this bug:
Issues with not case/fragment-normalizing file paths (macOS, Windows) #12448
Here's what the code for the extension looks like:
'use strict';
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
vscode.commands.registerCommand("duplicateTab", () => {
var activeEditor = vscode.window.activeTextEditor;
if (activeEditor == null) {
return;
}
// HACK!
const sameFileNameButDifferent = activeEditor.document.fileName.toUpperCase();
vscode.workspace.openTextDocument(sameFileNameButDifferent).then(document => {
vscode.window.showTextDocument(document, {preview: false});
});
});
}
In package.json:
"contributes": {
"commands": [
{
"title": "Duplicate Tab",
"command": "duplicateTab"
}
]
},

How do I contribute a command to the VS Code explorer title bar or command palette that is only active when my webview is focused?

I'm writing an extension that uses VS Code's webview api. My extension also registers a refresh preview command that updates the webview's content. How can I make it so that:
The refresh preview command only shows up in the command palette when my webview is focused?
The refresh preview command shows in the webview's editor title bar?
First, create a custom context key that tracks when your webview is focused. Use VS Code's setContext command to make this context key track when your webview is focused:
const myWebview = ...;
// Make the context key track when one of your webviews is focused
myWebview.onDidChangeViewState(({ webviewPanel }) => {
vscode.commands.executeCommand('setContext',
'myWebviewFocused',
webviewPanel.active);
});
Then use your context key in the when clauses of your extension's menus contribution point
For a command with the id myExtension.refreshPreview, to ensure that command only shows up in the command palette when your webview is focused, use the following contribution:
{
"contributes": {
"menus": {
"commandPalette": [
{
"command": "myExtension.refreshPreview",
"when": "myWebviewFocused",
}
]
}
}
}
For adding a command (possible with icon) to the editor title bar of your webview, use the editor/title contribution point:
{
"contributes": {
"menus": {
"editor/title": [
{
"command": "myExtension.refreshPreview",
"when": "myWebviewFocused",
}
]
}
}
}
Check out VS Code's built-in markdown extension for a more advanced example of this.

How to prevent commands from being displayed if the extension is not active?

I am writing an extension and I'm providing a custom command, declare in the package.json as:
{
"contributes": {
"commands": [
{
"command": "myext.doSomething",
"title": "Do something"
}
]
}
}
I'm am then registering it in the extension, when it activates:
commands.registerCommand("myext.doSomething", () => console.log("hi"))
This works, but the Do Something command is present in the command palette even if the extension is not active.
This means that if the user selects the command when the extension is not active, an error along the lines of
command myext.doSomething not found
Is there a way to prevent custom commands to be displayed in the command palette unless the extension has been activated?
Instead of not showing your command when the extension is not active, you can just add it to the activationEvents like this in your package.json. In your case:
{
"activationEvents": [
"onCommand:myext.doSomething"
]
}
This will run the exported activate function of your extension before the command is invoked.
Also the when keyword could be an option for you. I answered a similar question on that topic here.
Edit:
You can control a command's visibility in the command pallette by additionally contributing a contextual menu (docs). Then you can for instance only display the command when the editor's file has a specific language id.
Example:
{
"menus": {
"commandPalette": [
{
"command": "myext.doSomething",
"when": "editorLangId==scala"
}
]
}
}

Adding keyboard shortcuts for move cell up and move cell down

I am trying to add the Cntl+K and Cntl+J shortcuts to move cells up and down quickly. I viewed the issue on Github here for adding the shortcuts and found what looked to be a workable answer:
"For those (like me) who liked this shortcut, add this to your ~/.ipython/profile_default/static/custom/custom.js:
$([IPython.events]).on("app_initialized.NotebookApp", function () {
IPython.keyboard_manager.command_shortcuts.add_shortcut('ctrl-k', function (event) {
IPython.notebook.move_cell_up();
return false;
});
IPython.keyboard_manager.command_shortcuts.add_shortcut('ctrl-j', function (event) {
IPython.notebook.move_cell_down();
return false;
});
});
"
But my users/{my name}/.ipython/profile_default directory did not have a static folder. I tried adding the missing folders and custom.js file, and reopened Anaconda prompt, but this did not add the missing shortcuts.
Another answer had the same issue:
"Use the following:
$ cat ~/.jupyter/custom/custom.js
define(["base/js/namespace"], function(Jupyter){
console.info('Binding Ctrl-J/K to move cell up/down');
Jupyter.keyboard_manager.command_shortcuts.add_shortcut('Ctrl-k','jupyter-notebook:move-cell-up');
Jupyter.keyboard_manager.command_shortcuts.add_shortcut('Ctrl-j','jupyter-notebook:move-cell-down');
});
"
This answer also did not work (adding the missing folder and custom.js file did not work).
As proposed in the official doc (got with the "Help>Notebook" menu action),
you could try first in a live notebook. The browser javascript console helps too.
I tried:
%%javascript
IPython.keyboard_manager.command_shortcuts.add_shortcut('Ctrl-k','jupyter-notebook:move-cell-up');
// replacing IPython with Jupyter should work as well:
Jupyterkeyboard_manager.command_shortcuts.add_shortcut('Ctrl-j','jupyter-notebook:move-cell-down');
It works but, just as when clicking on the corresponding toolbar button, the console warns about deprecation
in favor of IPython.notebook.move_selection_up() .
The string "jupyter-notebook:move-cell-up" refers to the same action.
So I suppose a reasonnable thing to do is to redefine it from scratch:
IPython.keyboard_manager.command_shortcuts.add_shortcut('Ctrl-k', {
help : 'move up selected cells',
help_index : 'jupyter-notebook:move-selection-up',
handler : function (event) {
IPython.notebook.move_selection_up();
return false;
}}
);
IPython.keyboard_manager.command_shortcuts.add_shortcut('Ctrl-j', {
help : 'move down selected cells',
help_index : 'jupyter-notebook:move-selection-down',
handler : function (event) {
IPython.notebook.move_selection_down();
return false;
}}
);
After executing the notbook cell (or the code in your browser console), it should
be active and you can experiment with it.
Once happy, check the path of your jupyter profile with !jupyter --config, and from there
you'd know where to copy your code : <profile>/static/custom/custom.js
so that it would be active in next jupyter sessions.