|
@@ -4,24 +4,34 @@
|
|
|
import {
|
|
|
ILayoutRestorer,
|
|
|
JupyterFrontEnd,
|
|
|
- JupyterFrontEndPlugin
|
|
|
+ JupyterFrontEndPlugin,
|
|
|
+ LabShell
|
|
|
} from '@jupyterlab/application';
|
|
|
|
|
|
+import { ICommandPalette } from '@jupyterlab/apputils';
|
|
|
+
|
|
|
import { WidgetTracker, MainAreaWidget } from '@jupyterlab/apputils';
|
|
|
|
|
|
-import { IConsoleTracker } from '@jupyterlab/console';
|
|
|
+import { IConsoleTracker, ConsolePanel } from '@jupyterlab/console';
|
|
|
|
|
|
import { IStateDB } from '@jupyterlab/coreutils';
|
|
|
|
|
|
import { IEditorTracker } from '@jupyterlab/fileeditor';
|
|
|
|
|
|
-import { INotebookTracker } from '@jupyterlab/notebook';
|
|
|
+import { INotebookTracker, NotebookPanel } from '@jupyterlab/notebook';
|
|
|
|
|
|
import { Debugger } from './debugger';
|
|
|
|
|
|
+import { IDebugger, IDebuggerSidebar } from './tokens';
|
|
|
+
|
|
|
+import { DebuggerNotebookHandler } from './handlers/notebook';
|
|
|
+
|
|
|
+import { DebuggerConsoleHandler } from './handlers/console';
|
|
|
+
|
|
|
import { DebuggerSidebar } from './sidebar';
|
|
|
|
|
|
-import { IDebugger, IDebuggerSidebar } from './tokens';
|
|
|
+import { SessionTypes } from './breakpoints';
|
|
|
+import { DebugSession } from './session';
|
|
|
|
|
|
/**
|
|
|
* The command IDs used by the debugger plugin.
|
|
@@ -42,14 +52,22 @@ export namespace CommandIDs {
|
|
|
const consoles: JupyterFrontEndPlugin<void> = {
|
|
|
id: '@jupyterlab/debugger:consoles',
|
|
|
autoStart: true,
|
|
|
- requires: [IDebugger],
|
|
|
- optional: [IConsoleTracker],
|
|
|
- activate: (_, debug, tracker: IConsoleTracker | null) => {
|
|
|
- if (!tracker) {
|
|
|
- console.log(`${consoles.id} load failed. There is no console tracker.`);
|
|
|
- return;
|
|
|
- }
|
|
|
- console.log(`${consoles.id} has not been implemented.`, debug);
|
|
|
+ requires: [IDebugger, IDebuggerSidebar, IConsoleTracker],
|
|
|
+ activate: (
|
|
|
+ _,
|
|
|
+ debug: IDebugger,
|
|
|
+ sidebar: IDebuggerSidebar,
|
|
|
+ tracker: IConsoleTracker
|
|
|
+ ) => {
|
|
|
+ debug.currentChanged.connect((_, update) => {
|
|
|
+ if (update) {
|
|
|
+ update.content.model.sidebar = sidebar;
|
|
|
+ new DebuggerConsoleHandler({
|
|
|
+ debuggerModel: update.content.model,
|
|
|
+ consoleTracker: tracker
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -59,8 +77,27 @@ const consoles: JupyterFrontEndPlugin<void> = {
|
|
|
const files: JupyterFrontEndPlugin<void> = {
|
|
|
id: '@jupyterlab/debugger:files',
|
|
|
autoStart: true,
|
|
|
- optional: [IEditorTracker],
|
|
|
- activate: (app: JupyterFrontEnd, tracker: IEditorTracker | null) => {
|
|
|
+ requires: [IEditorTracker, IDebugger, INotebookTracker],
|
|
|
+ activate: (
|
|
|
+ app: JupyterFrontEnd,
|
|
|
+ tracker: IEditorTracker | null,
|
|
|
+ debug: IDebugger,
|
|
|
+ notebook: INotebookTracker
|
|
|
+ ) => {
|
|
|
+ const shell = app.shell;
|
|
|
+ (shell as LabShell).currentChanged.connect((sender, update) => {
|
|
|
+ const newWidget = update.newValue;
|
|
|
+ const session =
|
|
|
+ newWidget && (newWidget as NotebookPanel | ConsolePanel).session
|
|
|
+ ? (newWidget as NotebookPanel | ConsolePanel).session
|
|
|
+ : false;
|
|
|
+ if (session && debug.currentWidget) {
|
|
|
+ const debugModel: Debugger.Model = debug.currentWidget.content.model;
|
|
|
+ debugModel.session = new DebugSession({ client: session });
|
|
|
+ debugModel.sidebar.breakpoints.model.type = session.type as SessionTypes;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
app.commands.addCommand(CommandIDs.debugFile, {
|
|
|
execute: async _ => {
|
|
|
if (!tracker || !tracker.currentWidget) {
|
|
@@ -68,8 +105,8 @@ const files: JupyterFrontEndPlugin<void> = {
|
|
|
}
|
|
|
if (tracker.currentWidget) {
|
|
|
// TODO: Find if the file is backed by a kernel or attach it to one.
|
|
|
- const widget = await app.commands.execute(CommandIDs.create);
|
|
|
- app.shell.add(widget, 'main');
|
|
|
+ // const widget = await app.commands.execute(CommandIDs.create);
|
|
|
+ // app.shell.add(widget, 'main');
|
|
|
}
|
|
|
}
|
|
|
});
|
|
@@ -82,14 +119,43 @@ const files: JupyterFrontEndPlugin<void> = {
|
|
|
const notebooks: JupyterFrontEndPlugin<void> = {
|
|
|
id: '@jupyterlab/debugger:notebooks',
|
|
|
autoStart: true,
|
|
|
- requires: [IDebugger],
|
|
|
- optional: [INotebookTracker],
|
|
|
- activate: (_, debug, tracker: INotebookTracker | null) => {
|
|
|
- if (!tracker) {
|
|
|
- console.log(`${notebooks.id} load failed. There is no notebook tracker.`);
|
|
|
- return;
|
|
|
- }
|
|
|
- console.log(`${notebooks.id} has not been implemented.`, debug);
|
|
|
+ requires: [IDebugger, IDebuggerSidebar],
|
|
|
+ optional: [INotebookTracker, ICommandPalette],
|
|
|
+ activate: (
|
|
|
+ app: JupyterFrontEnd,
|
|
|
+ debug: IDebugger,
|
|
|
+ sidebar: IDebuggerSidebar,
|
|
|
+ notebook: INotebookTracker,
|
|
|
+ palette: ICommandPalette
|
|
|
+ ) => {
|
|
|
+ // 1. Keep track of any new notebook that is created.
|
|
|
+ // 2. When the *active* notebook changes, hook it up to the debugger.
|
|
|
+ // 3. If a notebook is closed, dispose the debugger session.
|
|
|
+
|
|
|
+ debug.currentChanged.connect((_, update) => {
|
|
|
+ if (update) {
|
|
|
+ update.content.model.sidebar = sidebar;
|
|
|
+ new DebuggerNotebookHandler({
|
|
|
+ debuggerModel: update.content.model,
|
|
|
+ notebookTracker: notebook
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // // Debugger model:
|
|
|
+ // // LIST of editors that it currently cares about.
|
|
|
+ // // Manages life cycle signal connections.
|
|
|
+ // // Manages variables
|
|
|
+ // });
|
|
|
+
|
|
|
+ // this exist only for my test in futre will be removed
|
|
|
+ const command: string = CommandIDs.debugNotebook;
|
|
|
+ app.commands.addCommand(command, {
|
|
|
+ label: 'test',
|
|
|
+ execute: () => {}
|
|
|
+ });
|
|
|
+
|
|
|
+ palette.addItem({ command, category: 'dev test' });
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -99,6 +165,7 @@ const notebooks: JupyterFrontEndPlugin<void> = {
|
|
|
const sidebar: JupyterFrontEndPlugin<IDebuggerSidebar> = {
|
|
|
id: '@jupyterlab/debugger:sidebar',
|
|
|
optional: [ILayoutRestorer],
|
|
|
+ provides: IDebuggerSidebar,
|
|
|
autoStart: true,
|
|
|
activate: (
|
|
|
app: JupyterFrontEnd,
|
|
@@ -108,11 +175,9 @@ const sidebar: JupyterFrontEndPlugin<IDebuggerSidebar> = {
|
|
|
const label = 'Environment';
|
|
|
const namespace = 'jp-debugger-sidebar';
|
|
|
const sidebar = new DebuggerSidebar(null);
|
|
|
-
|
|
|
sidebar.id = namespace;
|
|
|
sidebar.title.label = label;
|
|
|
shell.add(sidebar, 'right', { activate: false });
|
|
|
-
|
|
|
if (restorer) {
|
|
|
restorer.add(sidebar, sidebar.id);
|
|
|
}
|
|
@@ -126,7 +191,7 @@ const sidebar: JupyterFrontEndPlugin<IDebuggerSidebar> = {
|
|
|
*/
|
|
|
const tracker: JupyterFrontEndPlugin<IDebugger> = {
|
|
|
id: '@jupyterlab/debugger:tracker',
|
|
|
- optional: [ILayoutRestorer, IDebuggerSidebar],
|
|
|
+ optional: [ILayoutRestorer, IDebuggerSidebar, ICommandPalette],
|
|
|
requires: [IStateDB],
|
|
|
provides: IDebugger,
|
|
|
autoStart: true,
|
|
@@ -134,49 +199,61 @@ const tracker: JupyterFrontEndPlugin<IDebugger> = {
|
|
|
app: JupyterFrontEnd,
|
|
|
state: IStateDB,
|
|
|
restorer: ILayoutRestorer | null,
|
|
|
- sidebar: IDebuggerSidebar | null
|
|
|
+ sidebar: IDebuggerSidebar | null,
|
|
|
+ palette: ICommandPalette
|
|
|
): IDebugger => {
|
|
|
const tracker = new WidgetTracker<MainAreaWidget<Debugger>>({
|
|
|
namespace: 'debugger'
|
|
|
});
|
|
|
|
|
|
- app.commands.addCommand(CommandIDs.create, {
|
|
|
+ tracker.widgetUpdated.connect((_, update) => {
|
|
|
+ update;
|
|
|
+ });
|
|
|
+
|
|
|
+ const command = CommandIDs.create;
|
|
|
+
|
|
|
+ app.commands.addCommand(command, {
|
|
|
+ label: 'Debugger',
|
|
|
execute: args => {
|
|
|
const id = (args.id as string) || '';
|
|
|
-
|
|
|
if (id) {
|
|
|
console.log('Debugger ID: ', id);
|
|
|
}
|
|
|
|
|
|
- if (tracker.find(widget => id === widget.content.model.id)) {
|
|
|
+ const existedWidget = tracker.find(
|
|
|
+ widget => id === widget.content.model.id
|
|
|
+ );
|
|
|
+
|
|
|
+ if (existedWidget) {
|
|
|
+ app.shell.add(existedWidget, 'main');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
const widget = new MainAreaWidget({
|
|
|
- content: new Debugger({ connector: state, id })
|
|
|
+ content: new Debugger({
|
|
|
+ connector: state,
|
|
|
+ id: id
|
|
|
+ })
|
|
|
});
|
|
|
|
|
|
void tracker.add(widget);
|
|
|
+ app.shell.add(widget, 'main');
|
|
|
|
|
|
return widget;
|
|
|
}
|
|
|
});
|
|
|
|
|
|
+ palette.addItem({ command, category: 'Debugger' });
|
|
|
+
|
|
|
if (restorer) {
|
|
|
// Handle state restoration.
|
|
|
void restorer.restore(tracker, {
|
|
|
- command: CommandIDs.create,
|
|
|
+ command: command,
|
|
|
args: widget => ({ id: widget.content.model.id }),
|
|
|
name: widget => widget.content.model.id
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- if (sidebar) {
|
|
|
- tracker.currentChanged.connect((_, current) => {
|
|
|
- sidebar.model = current ? current.content.model : null;
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
return tracker;
|
|
|
}
|
|
|
};
|
|
@@ -184,6 +261,7 @@ const tracker: JupyterFrontEndPlugin<IDebugger> = {
|
|
|
/**
|
|
|
* Export the plugins as default.
|
|
|
*/
|
|
|
+
|
|
|
const plugins: JupyterFrontEndPlugin<any>[] = [
|
|
|
consoles,
|
|
|
files,
|
|
@@ -191,5 +269,5 @@ const plugins: JupyterFrontEndPlugin<any>[] = [
|
|
|
sidebar,
|
|
|
tracker
|
|
|
];
|
|
|
-const plugin: JupyterFrontEndPlugin<any> = plugins[3];
|
|
|
-export default plugin;
|
|
|
+
|
|
|
+export default plugins;
|