forked from jupyterlab/extension-examples
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
cbff547
commit be84853
Showing
12 changed files
with
465 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
*.bundle.* | ||
lib/ | ||
node_modules/ | ||
*.egg-info/ | ||
.ipynb_checkpoints | ||
*.tsbuildinfo |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
BSD 3-Clause License | ||
|
||
Copyright (c) 2019, Jeremy Tuloup | ||
Copyright (c) 2019, Jupyter Development Team | ||
All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without | ||
modification, are permitted provided that the following conditions are met: | ||
|
||
1. Redistributions of source code must retain the above copyright notice, this | ||
list of conditions and the following disclaimer. | ||
|
||
2. Redistributions in binary form must reproduce the above copyright notice, | ||
this list of conditions and the following disclaimer in the documentation | ||
and/or other materials provided with the distribution. | ||
|
||
3. Neither the name of the copyright holder nor the names of its | ||
contributors may be used to endorse or promote products derived from | ||
this software without specific prior written permission. | ||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
# Start your extension from the launcher | ||
|
||
In this example, you will learn how to start your extension from the launcher and how to have optional | ||
dependencies to JupyterLab features. | ||
|
||
 | ||
|
||
> Acknowledgement: This example is copied from Jeremy Tuloup [Python file extension](https://github.com/jtpio/jupyterlab-python-file). | ||
In this example, you will add the ability to create an empty Python file. To do so, | ||
your extension will use two commands defined by the [documents manager](https://github.com/jupyterlab/jupyterlab/blob/master/packages/docmanager-extension/src/index.ts#L47-L75) of JupyterLab: | ||
|
||
- `'docmanager:new-untitled'`: Create new untitled document | ||
- `'docmanager:open'`: Open a document | ||
|
||
The command will create a new Python file and then open it: | ||
|
||
```ts | ||
// src/index.ts#L36-L58 | ||
|
||
commands.addCommand(CommandIDs.createNew, { | ||
label: args => (args['isPalette'] ? 'New Python File' : 'Python File'), | ||
caption: 'Create a new Python file', | ||
iconClass: args => (args['isPalette'] ? '' : ICON_CLASS), | ||
execute: async args => { | ||
// Get the directory in which the Python file must be created; | ||
// otherwise take the current filebrowser directory | ||
let cwd = args['cwd'] || browserFactory.defaultBrowser.model.path; | ||
|
||
// Create a new untitled python file | ||
const model = await commands.execute('docmanager:new-untitled', { | ||
path: cwd, | ||
type: 'file', | ||
ext: 'py' | ||
}); | ||
|
||
// Open the newly created file with the 'Editor' | ||
return commands.execute('docmanager:open', { | ||
path: model.path, | ||
factory: FACTORY | ||
}); | ||
} | ||
}); | ||
``` | ||
|
||
To link that command to the JupyterLab launcher, the `ILauncher` interface needs to be passed to the `activate` | ||
extension function. As that interface is provided by the `@jupyterlab/launcher` package, it needs first to be installed: | ||
|
||
```bash | ||
jlpm add @jupyterlab/launcher | ||
``` | ||
|
||
Then you can use it in the extension by importing it: | ||
|
||
```ts | ||
// src/index.ts#L10-L10 | ||
|
||
import { ILauncher } from '@jupyterlab/launcher'; | ||
``` | ||
|
||
And finally you can request it as extension dependency: | ||
|
||
```ts | ||
// src/index.ts#L22-L33 | ||
|
||
const extension: JupyterFrontEndPlugin<void> = { | ||
id: '@jupyterlab-examples/launcher', | ||
autoStart: true, | ||
optional: [ILauncher, IMainMenu, ICommandPalette], | ||
requires: [IFileBrowserFactory], | ||
activate: ( | ||
app: JupyterFrontEnd, | ||
browserFactory: IFileBrowserFactory, | ||
launcher: ILauncher | null, | ||
menu: IMainMenu | null, | ||
palette: ICommandPalette | null | ||
) => { | ||
``` | ||
In this example, the `ILauncher` interface is requested as optional dependency and not as classical dependency. This allow other application without launcher to be able | ||
to use your extension. | ||
If the application is unable to provide an optional interface, it will take a `null` | ||
value. | ||
Therefore before adding the command to the launcher, you need to check if the `launcher` | ||
variable is not `null`: | ||
```ts | ||
// src/index.ts#L60-L67 | ||
|
||
// Add the command to the launcher | ||
if (launcher) { | ||
launcher.add({ | ||
command: CommandIDs.createNew, | ||
category: 'Other', | ||
rank: 1 | ||
}); | ||
} | ||
``` | ||
## Where to Go Next | ||
This example uses a _command_. This is an essential concept of JupyterLab. To know more about it | ||
have a look at the [command example](../commands/README.md). | ||
As seen in this example too, an user can execute a command from other UI elements than the launcher. To | ||
know more about those other possible, you could look at the following examples: | ||
- Add the command to the [command palette](../command-palette/README.md) | ||
- Add the command to a [menu](../main-menu/README.md) | ||
- Add the command to a [context menu](../context-menu/README.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
{ | ||
"name": "@jupyterlab-examples/launcher", | ||
"version": "0.1.0", | ||
"description": "A minimal JupyterLab example using the launcher.", | ||
"keywords": [ | ||
"jupyter", | ||
"jupyterlab", | ||
"jupyterlab-extension" | ||
], | ||
"homepage": "https://github.com/my_name/jupyterlab_myextension", | ||
"bugs": { | ||
"url": "https://github.com/my_name/jupyterlab_myextension/issues" | ||
}, | ||
"license": "BSD-3-Clause", | ||
"author": "my_name", | ||
"files": [ | ||
"lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}", | ||
"style/**/*.{css,eot,gif,html,jpg,json,png,svg,woff2,ttf}" | ||
], | ||
"main": "lib/index.js", | ||
"types": "lib/index.d.ts", | ||
"style": "style/index.css", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/my_name/jupyterlab_myextension.git" | ||
}, | ||
"scripts": { | ||
"build": "tsc", | ||
"clean": "rimraf lib tsconfig.tsbuildinfo", | ||
"link": "jupyter labextension link . --no-build", | ||
"prepare": "jlpm run clean && jlpm run build", | ||
"tslint": "tslint --fix -c tslint.json --project tsconfig.json \"**/*{.ts,.tsx}\"", | ||
"tslint:check": "tslint -c tslint.json --project tsconfig.json \"**/*{.ts,.tsx}\"", | ||
"watch": "tsc -w" | ||
}, | ||
"dependencies": { | ||
"@jupyterlab/application": "^1.0.0", | ||
"@jupyterlab/filebrowser": "^1.2.1", | ||
"@jupyterlab/launcher": "^1.2.1", | ||
"@jupyterlab/mainmenu": "^1.2.1" | ||
}, | ||
"devDependencies": { | ||
"rimraf": "^2.6.1", | ||
"tslint": "^5.20.1", | ||
"tslint-config-prettier": "^1.18.0", | ||
"tslint-plugin-prettier": "^2.0.1", | ||
"tslint-react": "^4.1.0", | ||
"typescript": "~3.5.2" | ||
}, | ||
"sideEffects": [ | ||
"style/*.css" | ||
], | ||
"jupyterlab": { | ||
"extension": true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { | ||
JupyterFrontEnd, | ||
JupyterFrontEndPlugin | ||
} from '@jupyterlab/application'; | ||
|
||
import { ICommandPalette } from '@jupyterlab/apputils'; | ||
|
||
import { IFileBrowserFactory } from '@jupyterlab/filebrowser'; | ||
|
||
import { ILauncher } from '@jupyterlab/launcher'; | ||
|
||
import { IMainMenu } from '@jupyterlab/mainmenu'; | ||
|
||
const FACTORY = 'Editor'; | ||
const ICON_CLASS = 'jp-example-PythonIcon'; | ||
const PALETTE_CATEGORY = 'Text Editor'; | ||
|
||
namespace CommandIDs { | ||
export const createNew = 'launcher:create-new-python-file'; | ||
} | ||
|
||
const extension: JupyterFrontEndPlugin<void> = { | ||
id: '@jupyterlab-examples/launcher', | ||
autoStart: true, | ||
optional: [ILauncher, IMainMenu, ICommandPalette], | ||
requires: [IFileBrowserFactory], | ||
activate: ( | ||
app: JupyterFrontEnd, | ||
browserFactory: IFileBrowserFactory, | ||
launcher: ILauncher | null, | ||
menu: IMainMenu | null, | ||
palette: ICommandPalette | null | ||
) => { | ||
const { commands } = app; | ||
|
||
commands.addCommand(CommandIDs.createNew, { | ||
label: args => (args['isPalette'] ? 'New Python File' : 'Python File'), | ||
caption: 'Create a new Python file', | ||
iconClass: args => (args['isPalette'] ? '' : ICON_CLASS), | ||
execute: async args => { | ||
// Get the directory in which the Python file must be created; | ||
// otherwise take the current filebrowser directory | ||
let cwd = args['cwd'] || browserFactory.defaultBrowser.model.path; | ||
|
||
// Create a new untitled python file | ||
const model = await commands.execute('docmanager:new-untitled', { | ||
path: cwd, | ||
type: 'file', | ||
ext: 'py' | ||
}); | ||
|
||
// Open the newly created file with the 'Editor' | ||
return commands.execute('docmanager:open', { | ||
path: model.path, | ||
factory: FACTORY | ||
}); | ||
} | ||
}); | ||
|
||
// Add the command to the launcher | ||
if (launcher) { | ||
launcher.add({ | ||
command: CommandIDs.createNew, | ||
category: 'Other', | ||
rank: 1 | ||
}); | ||
} | ||
|
||
// Add the command to the palette | ||
if (palette) { | ||
palette.addItem({ | ||
command: CommandIDs.createNew, | ||
args: { isPalette: true }, | ||
category: PALETTE_CATEGORY | ||
}); | ||
} | ||
|
||
// Add the command to the menu | ||
if (menu) { | ||
menu.fileMenu.newMenu.addGroup([{ command: CommandIDs.createNew }], 30); | ||
} | ||
} | ||
}; | ||
|
||
export default extension; |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.jp-example-PythonIcon { | ||
background-image: url('Python-logo-notext.svg'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"compilerOptions": { | ||
"allowSyntheticDefaultImports": true, | ||
"composite": true, | ||
"declaration": true, | ||
"esModuleInterop": true, | ||
"incremental": true, | ||
"jsx": "react", | ||
"module": "esnext", | ||
"moduleResolution": "node", | ||
"noEmitOnError": true, | ||
"noImplicitAny": true, | ||
"noUnusedLocals": true, | ||
"preserveWatchOutput": true, | ||
"resolveJsonModule": true, | ||
"outDir": "lib", | ||
"rootDir": "src", | ||
"strict": true, | ||
"strictNullChecks": false, | ||
"target": "es2017", | ||
"types": [] | ||
}, | ||
"include": ["src/*"] | ||
} |
Oops, something went wrong.