Skip to content
This repository has been archived by the owner on Jan 26, 2022. It is now read-only.

Commit

Permalink
Merge pull request #533 from mnowacki-b/custom_panel
Browse files Browse the repository at this point in the history
Adding an optional custom panel to the sidebar
  • Loading branch information
jtpio committed Sep 29, 2020
2 parents a28beb8 + 3a991e3 commit d1adea2
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 55 deletions.
111 changes: 66 additions & 45 deletions src/index.ts
Expand Up @@ -46,12 +46,19 @@ import { DebuggerHandler } from './handler';

import { EditorHandler } from './handlers/editor';

import { IDebugger, IDebuggerConfig, IDebuggerSources } from './tokens';
import {
IDebugger,
IDebuggerConfig,
IDebuggerSources,
IDebuggerSidebar
} from './tokens';

import { ReadOnlyEditorFactory } from './panels/sources/factory';

import { VariablesBodyGrid } from './panels/variables/grid';

export { IDebugger, IDebuggerSidebar } from './tokens';

/**
* The command IDs used by the debugger plugin.
*/
Expand Down Expand Up @@ -352,30 +359,76 @@ const variables: JupyterFrontEndPlugin<void> = {
}
};

/**
* Debugger sidebar provider plugin.
*/
const sidebar: JupyterFrontEndPlugin<IDebugger.ISidebar> = {
id: '@jupyterlab/debugger-extension:sidebar',
provides: IDebuggerSidebar,
requires: [IDebugger, IEditorServices],
optional: [IThemeManager, ISettingRegistry],
autoStart: true,
activate: async (
app: JupyterFrontEnd,
service: IDebugger,
editorServices: IEditorServices,
themeManager: IThemeManager | null,
settingRegistry: ISettingRegistry | null
): Promise<IDebugger.ISidebar> => {
const { commands } = app;

const callstackCommands = {
registry: commands,
continue: CommandIDs.debugContinue,
terminate: CommandIDs.terminate,
next: CommandIDs.next,
stepIn: CommandIDs.stepIn,
stepOut: CommandIDs.stepOut
};

const sidebar = new Debugger.Sidebar({
service,
callstackCommands,
editorServices,
themeManager
});

if (settingRegistry) {
const setting = await settingRegistry.load(main.id);
const updateSettings = (): void => {
const filters = setting.get('variableFilters').composite as {
[key: string]: string[];
};
const kernel = service.session?.connection?.kernel?.name ?? '';
if (kernel && filters[kernel]) {
sidebar.variables.filter = new Set<string>(filters[kernel]);
}
};
updateSettings();
setting.changed.connect(updateSettings);
service.sessionChanged.connect(updateSettings);
}

return sidebar;
}
};

/**
* The main debugger UI plugin.
*/
const main: JupyterFrontEndPlugin<void> = {
id: '@jupyterlab/debugger:main',
requires: [IDebugger, IEditorServices],
optional: [
ILabShell,
ILayoutRestorer,
ICommandPalette,
ISettingRegistry,
IThemeManager,
IDebuggerSources
],
requires: [IDebugger, IEditorServices, IDebuggerSidebar],
optional: [ILabShell, ILayoutRestorer, ICommandPalette, IDebuggerSources],
autoStart: true,
activate: async (
app: JupyterFrontEnd,
service: IDebugger,
editorServices: IEditorServices,
sidebar: IDebugger.ISidebar,
labShell: ILabShell | null,
restorer: ILayoutRestorer | null,
palette: ICommandPalette | null,
settingRegistry: ISettingRegistry | null,
themeManager: IThemeManager | null,
debuggerSources: IDebugger.ISources | null
): Promise<void> => {
const { commands, shell, serviceManager } = app;
Expand Down Expand Up @@ -459,39 +512,6 @@ const main: JupyterFrontEndPlugin<void> = {
}
});

const callstackCommands = {
registry: commands,
continue: CommandIDs.debugContinue,
terminate: CommandIDs.terminate,
next: CommandIDs.next,
stepIn: CommandIDs.stepIn,
stepOut: CommandIDs.stepOut
};

const sidebar = new Debugger.Sidebar({
service,
callstackCommands,
editorServices,
themeManager
});

if (settingRegistry) {
const setting = await settingRegistry.load(main.id);
const updateSettings = (): void => {
const filters = setting.get('variableFilters').composite as {
[key: string]: string[];
};
const list = filters[service.session?.connection?.kernel?.name];
if (list) {
sidebar.variables.filter = new Set<string>(list);
}
};

updateSettings();
setting.changed.connect(updateSettings);
service.sessionChanged.connect(updateSettings);
}

service.eventMessage.connect((_, event): void => {
commands.notifyCommandChanged();
if (labShell && event.event === 'initialized') {
Expand Down Expand Up @@ -611,6 +631,7 @@ const plugins: JupyterFrontEndPlugin<any>[] = [
files,
notebooks,
variables,
sidebar,
main,
sources,
configuration
Expand Down
59 changes: 49 additions & 10 deletions src/sidebar.ts
Expand Up @@ -22,7 +22,7 @@ import { IDebugger } from './tokens';
/**
* A debugger sidebar.
*/
export class DebuggerSidebar extends Panel {
export class DebuggerSidebar extends Panel implements IDebugger.ISidebar {
/**
* Instantiate a new Debugger.Sidebar
*
Expand All @@ -31,7 +31,7 @@ export class DebuggerSidebar extends Panel {
constructor(options: DebuggerSidebar.IOptions) {
super();
this.id = 'jp-debugger-sidebar';
this.title.iconRenderer = bugIcon;
this.title.icon = bugIcon;
this.addClass('jp-DebuggerSidebar');

const {
Expand Down Expand Up @@ -73,16 +73,50 @@ export class DebuggerSidebar extends Panel {
header.title.label = title;
});

const body = new SplitPanel();
this._body = new SplitPanel();
this._body.orientation = 'vertical';
this._body.addClass('jp-DebuggerSidebar-body');
this.addWidget(this._body);

body.orientation = 'vertical';
body.addWidget(this.variables);
body.addWidget(this.callstack);
body.addWidget(this.breakpoints);
body.addWidget(this.sources);
body.addClass('jp-DebuggerSidebar-body');
this.addItem(this.variables);
this.addItem(this.callstack);
this.addItem(this.breakpoints);
this.addItem(this.sources);
}

this.addWidget(body);
/**
* Add an item at the end of the sidebar.
*
* @param widget - The widget to add to the sidebar.
*
* #### Notes
* If the widget is already contained in the sidebar, it will be moved.
* The item can be removed from the sidebar by setting its parent to `null`.
*/
addItem(widget: Widget): void {
this._body.addWidget(widget);
}

/**
* Insert an item at the specified index.
*
* @param index - The index at which to insert the widget.
*
* @param widget - The widget to insert into to the sidebar.
*
* #### Notes
* If the widget is already contained in the sidebar, it will be moved.
* The item can be removed from the sidebar by setting its parent to `null`.
*/
insertItem(index: number, widget: Widget): void {
this._body.insertWidget(index, widget);
}

/**
* A read-only array of the sidebar items.
*/
get items(): readonly Widget[] {
return this._body.widgets;
}

/**
Expand Down Expand Up @@ -119,6 +153,11 @@ export class DebuggerSidebar extends Panel {
* The sources widget.
*/
readonly sources: SourcesPanel;

/**
* Container for sidebar items.
*/
private _body: SplitPanel;
}

/**
Expand Down
29 changes: 29 additions & 0 deletions src/tokens.ts
Expand Up @@ -11,6 +11,8 @@ import { IObservableDisposable } from '@lumino/disposable';

import { ISignal, Signal } from '@lumino/signaling';

import { Widget } from '@lumino/widgets';

import { DebugProtocol } from 'vscode-debugprotocol';

/**
Expand Down Expand Up @@ -484,6 +486,26 @@ export namespace IDebugger {
}
}

/**
* Debugger sidebar interface.
*/
export interface ISidebar extends Widget {
/**
* Add item at the end of the sidebar.
*/
addItem(widget: Widget): void;

/**
* Insert item at a specified index.
*/
insertItem(index: number, widget: Widget): void;

/**
* Return all items that were added to sidebar.
*/
readonly items: readonly Widget[];
}

/**
* A utility to find text editors used by the debugger.
*/
Expand Down Expand Up @@ -741,3 +763,10 @@ export const IDebuggerConfig = new Token<IDebugger.IConfig>(
export const IDebuggerSources = new Token<IDebugger.ISources>(
'@jupyterlab/debugger:IDebuggerSources'
);

/**
* The debugger sidebar token.
*/
export const IDebuggerSidebar = new Token<IDebugger.ISidebar>(
'@jupyterlab/debugger:IDebuggerSidebar'
);

0 comments on commit d1adea2

Please sign in to comment.