From 8ab55aaa44aa6fa1ab6a8ec3c5cf4fd6a43cf97e Mon Sep 17 00:00:00 2001 From: Maciej Nowacki Date: Wed, 26 Aug 2020 19:16:47 -0700 Subject: [PATCH 1/6] Adding an optional custom panel to the sidebar --- src/index.ts | 16 ++++++++++++---- src/sidebar.ts | 18 +++++++++++++++++- src/tokens.ts | 16 +++++++++++++++- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/index.ts b/src/index.ts index 9312d17d..7547b8a5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -46,7 +46,12 @@ import { DebuggerHandler } from './handler'; import { EditorHandler } from './handlers/editor'; -import { IDebugger, IDebuggerConfig, IDebuggerSources } from './tokens'; +import { + IDebugger, + IDebuggerConfig, + IDebuggerSources, + IDebuggerSidebarCustomPanel +} from './tokens'; import { ReadOnlyEditorFactory } from './panels/sources/factory'; @@ -364,7 +369,8 @@ const main: JupyterFrontEndPlugin = { ICommandPalette, ISettingRegistry, IThemeManager, - IDebuggerSources + IDebuggerSources, + IDebuggerSidebarCustomPanel ], autoStart: true, activate: async ( @@ -376,7 +382,8 @@ const main: JupyterFrontEndPlugin = { palette: ICommandPalette | null, settingRegistry: ISettingRegistry | null, themeManager: IThemeManager | null, - debuggerSources: IDebugger.ISources | null + debuggerSources: IDebugger.ISources | null, + customPanel: IDebuggerSidebarCustomPanel | null ): Promise => { const { commands, shell, serviceManager } = app; const { kernelspecs } = serviceManager; @@ -469,9 +476,10 @@ const main: JupyterFrontEndPlugin = { }; const sidebar = new Debugger.Sidebar({ - service, callstackCommands, + customPanel, editorServices, + service, themeManager }); diff --git a/src/sidebar.ts b/src/sidebar.ts index 66c8c708..356c6ec3 100644 --- a/src/sidebar.ts +++ b/src/sidebar.ts @@ -17,7 +17,7 @@ import { Sources as SourcesPanel } from './panels/sources'; import { Variables as VariablesPanel } from './panels/variables'; -import { IDebugger } from './tokens'; +import { IDebugger, IDebuggerSidebarCustomPanel } from './tokens'; /** * A debugger sidebar. @@ -37,12 +37,15 @@ export class DebuggerSidebar extends Panel { const { callstackCommands, editorServices, + customPanel = null, service, themeManager } = options; const model = service.model; + this.customPanel = customPanel; + this.variables = new VariablesPanel({ model: model.variables, commands: callstackCommands.registry, @@ -76,6 +79,9 @@ export class DebuggerSidebar extends Panel { const body = new SplitPanel(); body.orientation = 'vertical'; + if (this.customPanel) { + body.addWidget(this.customPanel); + } body.addWidget(this.variables); body.addWidget(this.callstack); body.addWidget(this.breakpoints); @@ -100,6 +106,11 @@ export class DebuggerSidebar extends Panel { super.dispose(); } + /** + * An optional custom sidebar panel + */ + readonly customPanel?: IDebuggerSidebarCustomPanel | null; + /** * The variables widget. */ @@ -147,6 +158,11 @@ export namespace DebuggerSidebar { * An optional application theme manager to detect theme changes. */ themeManager?: IThemeManager | null; + + /** + * An optional info panel + */ + customPanel?: IDebuggerSidebarCustomPanel | null; } /** diff --git a/src/tokens.ts b/src/tokens.ts index 928f7671..072b447e 100644 --- a/src/tokens.ts +++ b/src/tokens.ts @@ -7,10 +7,12 @@ import { KernelMessage, Session } from '@jupyterlab/services'; import { Token } from '@lumino/coreutils'; -import { IObservableDisposable } from '@lumino/disposable'; +import { IObservableDisposable, IDisposable } from '@lumino/disposable'; import { ISignal, Signal } from '@lumino/signaling'; +import { Panel } from '@lumino/widgets'; + import { DebugProtocol } from 'vscode-debugprotocol'; /** @@ -723,6 +725,11 @@ export namespace IDebugger { } } +/** + * An interface describing an optional custom sidebar panel. + */ +export interface IDebuggerSidebarCustomPanel extends Panel, IDisposable {} +s; /** * The visual debugger token. */ @@ -741,3 +748,10 @@ export const IDebuggerConfig = new Token( export const IDebuggerSources = new Token( '@jupyterlab/debugger:IDebuggerSources' ); + +/** + * An optional info panel token. + */ +export const IDebuggerSidebarCustomPanel = new Token< + IDebuggerSidebarCustomPanel +>('@jupyterlab/debugger:IDebuggerSidebarCustomPanel'); From ac9a9f651285b8912476715fa74ebe08c9391efd Mon Sep 17 00:00:00 2001 From: Maciej Nowacki Date: Thu, 27 Aug 2020 08:24:50 -0700 Subject: [PATCH 2/6] Fix typos --- src/sidebar.ts | 4 ++-- src/tokens.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sidebar.ts b/src/sidebar.ts index 356c6ec3..e25b7a22 100644 --- a/src/sidebar.ts +++ b/src/sidebar.ts @@ -107,7 +107,7 @@ export class DebuggerSidebar extends Panel { } /** - * An optional custom sidebar panel + * An optional sidebar custom panel */ readonly customPanel?: IDebuggerSidebarCustomPanel | null; @@ -160,7 +160,7 @@ export namespace DebuggerSidebar { themeManager?: IThemeManager | null; /** - * An optional info panel + * An optional sidebar custom panel */ customPanel?: IDebuggerSidebarCustomPanel | null; } diff --git a/src/tokens.ts b/src/tokens.ts index 072b447e..4cca00f7 100644 --- a/src/tokens.ts +++ b/src/tokens.ts @@ -726,10 +726,10 @@ export namespace IDebugger { } /** - * An interface describing an optional custom sidebar panel. + * An interface describing an optional sidebar custom panel. */ export interface IDebuggerSidebarCustomPanel extends Panel, IDisposable {} -s; + /** * The visual debugger token. */ @@ -750,7 +750,7 @@ export const IDebuggerSources = new Token( ); /** - * An optional info panel token. + * An optional sidebar custom panel token. */ export const IDebuggerSidebarCustomPanel = new Token< IDebuggerSidebarCustomPanel From 5bff72ef4f8555d70f43b7dbada44a81ced20a23 Mon Sep 17 00:00:00 2001 From: Maciej Nowacki Date: Mon, 28 Sep 2020 09:36:43 -0700 Subject: [PATCH 3/6] Revert "Fix typos" This reverts commit ac9a9f651285b8912476715fa74ebe08c9391efd. --- src/sidebar.ts | 4 ++-- src/tokens.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sidebar.ts b/src/sidebar.ts index e25b7a22..356c6ec3 100644 --- a/src/sidebar.ts +++ b/src/sidebar.ts @@ -107,7 +107,7 @@ export class DebuggerSidebar extends Panel { } /** - * An optional sidebar custom panel + * An optional custom sidebar panel */ readonly customPanel?: IDebuggerSidebarCustomPanel | null; @@ -160,7 +160,7 @@ export namespace DebuggerSidebar { themeManager?: IThemeManager | null; /** - * An optional sidebar custom panel + * An optional info panel */ customPanel?: IDebuggerSidebarCustomPanel | null; } diff --git a/src/tokens.ts b/src/tokens.ts index 4cca00f7..072b447e 100644 --- a/src/tokens.ts +++ b/src/tokens.ts @@ -726,10 +726,10 @@ export namespace IDebugger { } /** - * An interface describing an optional sidebar custom panel. + * An interface describing an optional custom sidebar panel. */ export interface IDebuggerSidebarCustomPanel extends Panel, IDisposable {} - +s; /** * The visual debugger token. */ @@ -750,7 +750,7 @@ export const IDebuggerSources = new Token( ); /** - * An optional sidebar custom panel token. + * An optional info panel token. */ export const IDebuggerSidebarCustomPanel = new Token< IDebuggerSidebarCustomPanel From 4909f41b0ea2828d4be827f72d8f9dbf30bef0f9 Mon Sep 17 00:00:00 2001 From: Maciej Nowacki Date: Mon, 28 Sep 2020 09:37:06 -0700 Subject: [PATCH 4/6] Revert "Adding an optional custom panel to the sidebar" This reverts commit 8ab55aaa44aa6fa1ab6a8ec3c5cf4fd6a43cf97e. --- src/index.ts | 16 ++++------------ src/sidebar.ts | 18 +----------------- src/tokens.ts | 16 +--------------- 3 files changed, 6 insertions(+), 44 deletions(-) diff --git a/src/index.ts b/src/index.ts index 7547b8a5..9312d17d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -46,12 +46,7 @@ import { DebuggerHandler } from './handler'; import { EditorHandler } from './handlers/editor'; -import { - IDebugger, - IDebuggerConfig, - IDebuggerSources, - IDebuggerSidebarCustomPanel -} from './tokens'; +import { IDebugger, IDebuggerConfig, IDebuggerSources } from './tokens'; import { ReadOnlyEditorFactory } from './panels/sources/factory'; @@ -369,8 +364,7 @@ const main: JupyterFrontEndPlugin = { ICommandPalette, ISettingRegistry, IThemeManager, - IDebuggerSources, - IDebuggerSidebarCustomPanel + IDebuggerSources ], autoStart: true, activate: async ( @@ -382,8 +376,7 @@ const main: JupyterFrontEndPlugin = { palette: ICommandPalette | null, settingRegistry: ISettingRegistry | null, themeManager: IThemeManager | null, - debuggerSources: IDebugger.ISources | null, - customPanel: IDebuggerSidebarCustomPanel | null + debuggerSources: IDebugger.ISources | null ): Promise => { const { commands, shell, serviceManager } = app; const { kernelspecs } = serviceManager; @@ -476,10 +469,9 @@ const main: JupyterFrontEndPlugin = { }; const sidebar = new Debugger.Sidebar({ + service, callstackCommands, - customPanel, editorServices, - service, themeManager }); diff --git a/src/sidebar.ts b/src/sidebar.ts index 356c6ec3..66c8c708 100644 --- a/src/sidebar.ts +++ b/src/sidebar.ts @@ -17,7 +17,7 @@ import { Sources as SourcesPanel } from './panels/sources'; import { Variables as VariablesPanel } from './panels/variables'; -import { IDebugger, IDebuggerSidebarCustomPanel } from './tokens'; +import { IDebugger } from './tokens'; /** * A debugger sidebar. @@ -37,15 +37,12 @@ export class DebuggerSidebar extends Panel { const { callstackCommands, editorServices, - customPanel = null, service, themeManager } = options; const model = service.model; - this.customPanel = customPanel; - this.variables = new VariablesPanel({ model: model.variables, commands: callstackCommands.registry, @@ -79,9 +76,6 @@ export class DebuggerSidebar extends Panel { const body = new SplitPanel(); body.orientation = 'vertical'; - if (this.customPanel) { - body.addWidget(this.customPanel); - } body.addWidget(this.variables); body.addWidget(this.callstack); body.addWidget(this.breakpoints); @@ -106,11 +100,6 @@ export class DebuggerSidebar extends Panel { super.dispose(); } - /** - * An optional custom sidebar panel - */ - readonly customPanel?: IDebuggerSidebarCustomPanel | null; - /** * The variables widget. */ @@ -158,11 +147,6 @@ export namespace DebuggerSidebar { * An optional application theme manager to detect theme changes. */ themeManager?: IThemeManager | null; - - /** - * An optional info panel - */ - customPanel?: IDebuggerSidebarCustomPanel | null; } /** diff --git a/src/tokens.ts b/src/tokens.ts index 072b447e..928f7671 100644 --- a/src/tokens.ts +++ b/src/tokens.ts @@ -7,12 +7,10 @@ import { KernelMessage, Session } from '@jupyterlab/services'; import { Token } from '@lumino/coreutils'; -import { IObservableDisposable, IDisposable } from '@lumino/disposable'; +import { IObservableDisposable } from '@lumino/disposable'; import { ISignal, Signal } from '@lumino/signaling'; -import { Panel } from '@lumino/widgets'; - import { DebugProtocol } from 'vscode-debugprotocol'; /** @@ -725,11 +723,6 @@ export namespace IDebugger { } } -/** - * An interface describing an optional custom sidebar panel. - */ -export interface IDebuggerSidebarCustomPanel extends Panel, IDisposable {} -s; /** * The visual debugger token. */ @@ -748,10 +741,3 @@ export const IDebuggerConfig = new Token( export const IDebuggerSources = new Token( '@jupyterlab/debugger:IDebuggerSources' ); - -/** - * An optional info panel token. - */ -export const IDebuggerSidebarCustomPanel = new Token< - IDebuggerSidebarCustomPanel ->('@jupyterlab/debugger:IDebuggerSidebarCustomPanel'); From 5951282c4fa9f4a1a1b03d90f1b9c2368697ab6b Mon Sep 17 00:00:00 2001 From: Maciej Nowacki Date: Mon, 28 Sep 2020 09:33:22 -0700 Subject: [PATCH 5/6] Porting changes from Jupyter core. PR: https://github.com/jupyterlab/jupyterlab/pull/9007 --- src/index.ts | 111 +++++++++++++++++++++++++++++-------------------- src/sidebar.ts | 59 +++++++++++++++++++++----- src/tokens.ts | 29 +++++++++++++ 3 files changed, 144 insertions(+), 55 deletions(-) diff --git a/src/index.ts b/src/index.ts index 9312d17d..ea7f5c34 100644 --- a/src/index.ts +++ b/src/index.ts @@ -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. */ @@ -352,30 +359,76 @@ const variables: JupyterFrontEndPlugin = { } }; +/** + * Debugger sidebar provider plugin. + */ +const sidebar: JupyterFrontEndPlugin = { + 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 => { + 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(filters[kernel]); + } + }; + updateSettings(); + setting.changed.connect(updateSettings); + service.sessionChanged.connect(updateSettings); + } + + return sidebar; + } +}; + /** * The main debugger UI plugin. */ const main: JupyterFrontEndPlugin = { 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 => { const { commands, shell, serviceManager } = app; @@ -459,39 +512,6 @@ const main: JupyterFrontEndPlugin = { } }); - 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(list); - } - }; - - updateSettings(); - setting.changed.connect(updateSettings); - service.sessionChanged.connect(updateSettings); - } - service.eventMessage.connect((_, event): void => { commands.notifyCommandChanged(); if (labShell && event.event === 'initialized') { @@ -611,6 +631,7 @@ const plugins: JupyterFrontEndPlugin[] = [ files, notebooks, variables, + sidebar, main, sources, configuration diff --git a/src/sidebar.ts b/src/sidebar.ts index 66c8c708..a03860ba 100644 --- a/src/sidebar.ts +++ b/src/sidebar.ts @@ -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 * @@ -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 { @@ -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) { + 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) { + this._body.insertWidget(index, widget); + } + + /** + * A read-only array of the sidebar items. + */ + get items(): readonly Widget[] { + return this._body.widgets; } /** @@ -119,6 +153,11 @@ export class DebuggerSidebar extends Panel { * The sources widget. */ readonly sources: SourcesPanel; + + /** + * Container for sidebar items. + */ + private _body: SplitPanel; } /** diff --git a/src/tokens.ts b/src/tokens.ts index 928f7671..ab9d0204 100644 --- a/src/tokens.ts +++ b/src/tokens.ts @@ -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'; /** @@ -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. */ @@ -741,3 +763,10 @@ export const IDebuggerConfig = new Token( export const IDebuggerSources = new Token( '@jupyterlab/debugger:IDebuggerSources' ); + +/** + * The debugger sidebar token. + */ +export const IDebuggerSidebar = new Token( + '@jupyterlab/debugger:IDebuggerSidebar' +); From 3a991e3c69c4f7cecd0debcef0c387a37878536e Mon Sep 17 00:00:00 2001 From: Maciej Nowacki Date: Mon, 28 Sep 2020 09:48:31 -0700 Subject: [PATCH 6/6] Add return type --- src/sidebar.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sidebar.ts b/src/sidebar.ts index a03860ba..88e9fa47 100644 --- a/src/sidebar.ts +++ b/src/sidebar.ts @@ -93,7 +93,7 @@ export class DebuggerSidebar extends Panel implements IDebugger.ISidebar { * 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) { + addItem(widget: Widget): void { this._body.addWidget(widget); } @@ -108,7 +108,7 @@ export class DebuggerSidebar extends Panel implements IDebugger.ISidebar { * 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) { + insertItem(index: number, widget: Widget): void { this._body.insertWidget(index, widget); }