123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- // Copyright (c) Jupyter Development Team.
- // Distributed under the terms of the Modified BSD License.
- import {
- ILayoutRestorer, JupyterLab, JupyterLabPlugin
- } from '@jupyterlab/application';
- import {
- ICommandPalette, IMainMenu, InstanceTracker
- } from '@jupyterlab/apputils';
- import {
- ILauncher
- } from '@jupyterlab/launcher';
- import {
- ServiceManager
- } from '@jupyterlab/services';
- import {
- Terminal, ITerminalTracker
- } from '@jupyterlab/terminal';
- import {
- Menu
- } from '@phosphor/widgets';
- /**
- * The command IDs used by the terminal plugin.
- */
- namespace CommandIDs {
- export
- const createNew = 'terminal:create-new';
- export
- const open = 'terminal:open';
- export
- const refresh = 'terminal:refresh';
- export
- const increaseFont = 'terminal:increase-font';
- export
- const decreaseFont = 'terminal:decrease-font';
- export
- const toggleTheme = 'terminal:toggle-theme';
- };
- /**
- * The class name for the terminal icon in the default theme.
- */
- const TERMINAL_ICON_CLASS = 'jp-TerminalIcon';
- /**
- * The default terminal extension.
- */
- const plugin: JupyterLabPlugin<ITerminalTracker> = {
- activate,
- id: 'jupyter.extensions.terminal',
- provides: ITerminalTracker,
- requires: [
- IMainMenu, ICommandPalette, ILayoutRestorer
- ],
- optional: [ILauncher],
- autoStart: true
- };
- /**
- * Export the plugin as default.
- */
- export default plugin;
- /**
- * Activate the terminal plugin.
- */
- function activate(app: JupyterLab, mainMenu: IMainMenu, palette: ICommandPalette, restorer: ILayoutRestorer, launcher: ILauncher | null): ITerminalTracker {
- const { commands, serviceManager } = app;
- const category = 'Terminal';
- const namespace = 'terminal';
- const tracker = new InstanceTracker<Terminal>({ namespace });
- // Bail if there are no terminals available.
- if (!serviceManager.terminals.isAvailable()) {
- console.log('Disabling terminals plugin because they are not available on the server');
- return tracker;
- }
- // Handle state restoration.
- restorer.restore(tracker, {
- command: CommandIDs.createNew,
- args: widget => ({ name: widget.session.name }),
- name: widget => widget.session && widget.session.name
- });
- // Update the command registry when the terminal state changes.
- tracker.currentChanged.connect(() => {
- if (tracker.size <= 1) {
- commands.notifyCommandChanged(CommandIDs.refresh);
- }
- });
- addCommands(app, serviceManager, tracker);
- // Add command palette and menu items.
- let menu = new Menu({ commands });
- menu.title.label = category;
- [
- CommandIDs.createNew,
- CommandIDs.refresh,
- CommandIDs.increaseFont,
- CommandIDs.decreaseFont,
- CommandIDs.toggleTheme
- ].forEach(command => {
- palette.addItem({ command, category });
- if (command !== CommandIDs.createNew) {
- menu.addItem({ command });
- }
- });
- mainMenu.addMenu(menu, {rank: 40});
- // Add a launcher item if the launcher is available.
- if (launcher) {
- launcher.add({
- displayName: 'Terminal',
- category: 'Other',
- rank: 0,
- iconClass: TERMINAL_ICON_CLASS,
- callback: () => {
- return commands.execute(CommandIDs.createNew);
- }
- });
- }
- app.contextMenu.addItem({command: CommandIDs.refresh, selector: '.jp-Terminal', rank: 1});
- return tracker;
- }
- /**
- * Add the commands for the terminal.
- */
- export
- function addCommands(app: JupyterLab, services: ServiceManager, tracker: InstanceTracker<Terminal>) {
- let { commands, shell } = app;
- /**
- * Whether there is an active terminal.
- */
- function hasWidget(): boolean {
- return tracker.currentWidget !== null;
- }
- // Add terminal commands.
- commands.addCommand(CommandIDs.createNew, {
- label: 'New Terminal',
- caption: 'Start a new terminal session',
- execute: args => {
- let name = args ? args['name'] as string : '';
- let term = new Terminal();
- term.title.closable = true;
- term.title.icon = TERMINAL_ICON_CLASS;
- term.title.label = '...';
- shell.addToMainArea(term);
- let promise = name ?
- services.terminals.connectTo(name)
- : services.terminals.startNew();
- return promise.then(session => {
- term.session = session;
- tracker.add(term);
- shell.activateById(term.id);
- return term;
- }).catch(() => { term.dispose(); });
- }
- });
- commands.addCommand(CommandIDs.open, {
- execute: args => {
- const name = args['name'] as string;
- // Check for a running terminal with the given name.
- const widget = tracker.find(value => {
- return value.session && value.session.name === name || false;
- });
- if (widget) {
- shell.activateById(widget.id);
- } else {
- // Otherwise, create a new terminal with a given name.
- return commands.execute(CommandIDs.createNew, { name });
- }
- }
- });
- commands.addCommand(CommandIDs.refresh, {
- label: 'Refresh Terminal',
- caption: 'Refresh the current terminal session',
- execute: () => {
- let current = tracker.currentWidget;
- if (!current) {
- return;
- }
- shell.activateById(current.id);
- return current.refresh().then(() => {
- if (current) {
- current.activate();
- }
- });
- },
- isEnabled: () => tracker.currentWidget !== null
- });
- commands.addCommand('terminal:increase-font', {
- label: 'Increase Terminal Font Size',
- execute: () => {
- let options = Terminal.defaultOptions;
- if (options.fontSize < 72) {
- options.fontSize++;
- tracker.forEach(widget => { widget.fontSize = options.fontSize; });
- }
- },
- isEnabled: hasWidget
- });
- commands.addCommand('terminal:decrease-font', {
- label: 'Decrease Terminal Font Size',
- execute: () => {
- let options = Terminal.defaultOptions;
- if (options.fontSize > 9) {
- options.fontSize--;
- tracker.forEach(widget => { widget.fontSize = options.fontSize; });
- }
- },
- isEnabled: hasWidget
- });
- commands.addCommand('terminal:toggle-theme', {
- label: 'Toggle Terminal Theme',
- caption: 'Switch Terminal Theme',
- execute: () => {
- tracker.forEach(widget => {
- if (widget.theme === 'dark') {
- widget.theme = 'light';
- } else {
- widget.theme = 'dark';
- }
- });
- },
- isEnabled: hasWidget
- });
- }
|