@jupyterlab/debugger-extension 4.5.0-alpha.4 → 4.5.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,42 @@
1
+ import { IConsoleCellExecutor } from '@jupyterlab/console';
2
+ import { IDebugger } from '@jupyterlab/debugger';
3
+ import { ExecutionCount, IDisplayData } from '@jupyterlab/nbformat';
4
+ import { TranslationBundle } from '@jupyterlab/translation';
5
+ /**
6
+ * Custom console cell executor that uses debugger evaluation.
7
+ */
8
+ export declare class DebugConsoleCellExecutor implements IConsoleCellExecutor {
9
+ constructor(options: DebugConsoleCellExecutor.IOptions);
10
+ /**
11
+ * Create an IDisplayData object with the given text content.
12
+ */
13
+ private createDisplayData;
14
+ evaluateWithDebugger(options: {
15
+ code: string;
16
+ executionCount: ExecutionCount;
17
+ }): Promise<IDisplayData | null>;
18
+ /**
19
+ * Execute a cell using debugger evaluation.
20
+ */
21
+ runCell(options: IConsoleCellExecutor.IRunCellOptions): Promise<boolean>;
22
+ private _debuggerService;
23
+ private _trans;
24
+ }
25
+ /**
26
+ * A namespace for DebugConsoleCellExecutor statics.
27
+ */
28
+ export declare namespace DebugConsoleCellExecutor {
29
+ /**
30
+ * The instantiation options for a DebugConsoleCellExecutor.
31
+ */
32
+ interface IOptions {
33
+ /**
34
+ * The debugger service for evaluating expressions in debug context.
35
+ */
36
+ debuggerService: IDebugger;
37
+ /**
38
+ * The translation bundle for internationalization.
39
+ */
40
+ trans: TranslationBundle;
41
+ }
42
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Custom console cell executor that uses debugger evaluation.
3
+ */
4
+ export class DebugConsoleCellExecutor {
5
+ constructor(options) {
6
+ this._debuggerService = options.debuggerService;
7
+ this._trans = options.trans;
8
+ }
9
+ /**
10
+ * Create an IDisplayData object with the given text content.
11
+ */
12
+ createDisplayData(text, executionCount) {
13
+ return {
14
+ output_type: 'display_data',
15
+ data: {
16
+ 'text/plain': text
17
+ },
18
+ metadata: {
19
+ execution_count: executionCount
20
+ }
21
+ };
22
+ }
23
+ async evaluateWithDebugger(options) {
24
+ const { code, executionCount } = options;
25
+ try {
26
+ // Check if debugger has stopped threads (required for evaluation)
27
+ if (!this._debuggerService.hasStoppedThreads()) {
28
+ return this.createDisplayData(this._trans.__('Debugger does not have stopped threads - cannot evaluate'), executionCount);
29
+ }
30
+ // Evaluate the code using the debugger service
31
+ const reply = await this._debuggerService.evaluate(code);
32
+ if (!reply) {
33
+ return this.createDisplayData(this._trans.__('Evaluation resulted in an error'), executionCount);
34
+ }
35
+ // Convert reply to IDisplayData format
36
+ return this.createDisplayData(reply.result, executionCount);
37
+ }
38
+ catch (error) {
39
+ console.error('Error evaluating code with debugger:', error);
40
+ return this.createDisplayData(`Error: ${error}`, executionCount);
41
+ }
42
+ }
43
+ /**
44
+ * Execute a cell using debugger evaluation.
45
+ */
46
+ async runCell(options) {
47
+ const { cell } = options;
48
+ const code = cell.model.sharedModel.getSource();
49
+ const executionCount = cell.model.sharedModel.execution_count;
50
+ const outputDisplayData = await this.evaluateWithDebugger({
51
+ code,
52
+ executionCount
53
+ });
54
+ if (!outputDisplayData) {
55
+ const errorOutputData = this.createDisplayData(this._trans.__('Could not display output data'), executionCount);
56
+ cell.model.outputs.add(errorOutputData);
57
+ return false;
58
+ }
59
+ cell.model.outputs.add(outputDisplayData);
60
+ return true;
61
+ }
62
+ }
63
+ //# sourceMappingURL=debug-console-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-console-executor.js","sourceRoot":"","sources":["../src/debug-console-executor.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,MAAM,OAAO,wBAAwB;IACnC,YAAY,OAA0C;QACpD,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;QAChD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAC9B,CAAC;IAED;;OAEG;IACK,iBAAiB,CACvB,IAAY,EACZ,cAA8B;QAE9B,OAAO;YACL,WAAW,EAAE,cAAc;YAC3B,IAAI,EAAE;gBACJ,YAAY,EAAE,IAAI;aACnB;YACD,QAAQ,EAAE;gBACR,eAAe,EAAE,cAAc;aAChC;SACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,OAG1B;QACC,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;QAEzC,IAAI,CAAC;YACH,kEAAkE;YAClE,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,EAAE,CAAC;gBAC/C,OAAO,IAAI,CAAC,iBAAiB,CAC3B,IAAI,CAAC,MAAM,CAAC,EAAE,CACZ,0DAA0D,CAC3D,EACD,cAAc,CACf,CAAC;YACJ,CAAC;YAED,+CAA+C;YAC/C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAEzD,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,IAAI,CAAC,iBAAiB,CAC3B,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,iCAAiC,CAAC,EACjD,cAAc,CACf,CAAC;YACJ,CAAC;YAED,uCAAuC;YACvC,OAAO,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAC9D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;YAC7D,OAAO,IAAI,CAAC,iBAAiB,CAAC,UAAU,KAAK,EAAE,EAAE,cAAc,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CACX,OAA6C;QAE7C,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;QAEzB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC;QAChD,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,eAAe,CAAC;QAC9D,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC;YACxD,IAAI;YACJ,cAAc;SACf,CAAC,CAAC;QAEH,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvB,MAAM,eAAe,GAAG,IAAI,CAAC,iBAAiB,CAC5C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,+BAA+B,CAAC,EAC/C,cAAc,CACf,CAAC;YACF,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YACxC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;CAIF"}
@@ -0,0 +1,30 @@
1
+ import type { CompletionTriggerKind, ICompletionContext, ICompletionProvider } from '@jupyterlab/completer';
2
+ import type { CompletionHandler } from '@jupyterlab/completer';
3
+ import { IDebugger } from '@jupyterlab/debugger';
4
+ import { ITranslator } from '@jupyterlab/translation';
5
+ /**
6
+ * Completion provider that uses debugger evaluation for suggestions.
7
+ */
8
+ export declare class DebuggerCompletionProvider implements ICompletionProvider {
9
+ protected options: DebuggerCompletionProvider.IOptions;
10
+ readonly identifier = "DebuggerCompletionProvider";
11
+ readonly name: string;
12
+ readonly rank = 1000;
13
+ constructor(options: DebuggerCompletionProvider.IOptions);
14
+ /**
15
+ * Check if this completion provider is applicable to the given context.
16
+ */
17
+ isApplicable(context: ICompletionContext): Promise<boolean>;
18
+ /**
19
+ * Fetch completion suggestions using debugger evaluation.
20
+ */
21
+ fetch(request: CompletionHandler.IRequest, context: ICompletionContext, trigger?: CompletionTriggerKind): Promise<CompletionHandler.ICompletionItemsReply>;
22
+ private _trans;
23
+ private _debuggerService;
24
+ }
25
+ export declare namespace DebuggerCompletionProvider {
26
+ interface IOptions {
27
+ debuggerService: IDebugger;
28
+ translator?: ITranslator;
29
+ }
30
+ }
@@ -0,0 +1,146 @@
1
+ // Copyright (c) Jupyter Development Team.
2
+ // Distributed under the terms of the Modified BSD License.
3
+ import { nullTranslator } from '@jupyterlab/translation';
4
+ /**
5
+ * Completion provider that uses debugger evaluation for suggestions.
6
+ */
7
+ export class DebuggerCompletionProvider {
8
+ constructor(options) {
9
+ this.options = options;
10
+ this.identifier = 'DebuggerCompletionProvider';
11
+ this.rank = 1000;
12
+ const translator = options.translator || nullTranslator;
13
+ this._trans = translator.load('jupyterlab');
14
+ this.name = this._trans.__('Debugger');
15
+ this._debuggerService = options.debuggerService;
16
+ }
17
+ /**
18
+ * Check if this completion provider is applicable to the given context.
19
+ */
20
+ async isApplicable(context) {
21
+ var _a, _b, _c;
22
+ try {
23
+ const spec = await ((_c = (_b = (_a = this._debuggerService.session) === null || _a === void 0 ? void 0 : _a.connection) === null || _b === void 0 ? void 0 : _b.kernel) === null || _c === void 0 ? void 0 : _c.spec);
24
+ return (spec === null || spec === void 0 ? void 0 : spec.language) === 'python';
25
+ }
26
+ catch (error) {
27
+ return false;
28
+ }
29
+ }
30
+ /**
31
+ * Fetch completion suggestions using debugger evaluation.
32
+ */
33
+ async fetch(request, context, trigger) {
34
+ var _a, _b;
35
+ let items = [];
36
+ let parsedResult;
37
+ try {
38
+ const { text, offset } = request;
39
+ const pyCode = `
40
+ from IPython.core.completer import provisionalcompleter as _provisionalcompleter
41
+ from IPython.core.completer import rectify_completions as _rectify_completions
42
+ from IPython.core.completer import IPCompleter
43
+ _EXPERIMENTAL_KEY_NAME = "_jupyter_types_experimental"
44
+
45
+ def getCompletionsForDebugger(code, cursor_pos):
46
+ ip = get_ipython()
47
+
48
+ # Access the current debugger frame
49
+ import inspect
50
+ current_frame = inspect.currentframe()
51
+
52
+ # Get the frame that called this function (the debugger's target frame)
53
+ caller_frame = current_frame.f_back if current_frame else None
54
+
55
+ # Get the debugger's frame variables
56
+ if caller_frame:
57
+ frame_locals = caller_frame.f_locals
58
+ frame_globals = caller_frame.f_globals
59
+ else:
60
+ frame_locals = locals()
61
+ frame_globals = globals()
62
+
63
+ local_completer = IPCompleter(shell=ip, namespace=frame_locals, global_namespace=frame_globals, parent=ip)
64
+
65
+ with _provisionalcompleter():
66
+ raw_completions = local_completer.completions(code, cursor_pos)
67
+ completions = list(_rectify_completions(code, raw_completions))
68
+
69
+ comps = []
70
+ for comp in completions:
71
+ comps.append(
72
+ dict(
73
+ start=comp.start,
74
+ end=comp.end,
75
+ text=comp.text,
76
+ type=comp.type,
77
+ signature=comp.signature,
78
+ )
79
+ )
80
+
81
+ if completions:
82
+ s = completions[0].start
83
+ e = completions[0].end
84
+ matches = [c.text for c in completions]
85
+ types = [c.type for c in completions]
86
+ else:
87
+ s = cursor_pos
88
+ e = cursor_pos
89
+ matches = []
90
+ types = []
91
+
92
+ result = {
93
+ "matches": matches,
94
+ "types": types,
95
+ "cursor_end": e,
96
+ "cursor_start": s,
97
+ "status": "ok",
98
+ }
99
+
100
+ return result
101
+ `;
102
+ // create method
103
+ await this._debuggerService.evaluate(pyCode);
104
+ const debuggerCompletions = `getCompletionsForDebugger(${JSON.stringify(text)}, ${offset})`;
105
+ const evalReply = await this._debuggerService.evaluate(debuggerCompletions);
106
+ if (!evalReply) {
107
+ return { start: 0, end: 0, items: [] };
108
+ }
109
+ const matches = evalReply.result;
110
+ // Replace single quotes with double quotes in matches string for JSON parsing
111
+ let correctedMatches = matches.replace(/'/g, '"');
112
+ // TODO - Investigate truncation
113
+ // The eval reply from kernel truncates the result string (a string representation
114
+ // of an array containing completion results). Anything after a certain number of
115
+ // matches (19 for ipykernel) is replaced by ellipses, which needs to be removed to parse into JSON.
116
+ correctedMatches = correctedMatches.replace(/, \.\.\./g, '');
117
+ try {
118
+ parsedResult = JSON.parse(correctedMatches);
119
+ }
120
+ catch (error) {
121
+ console.error('Failed to parse corrected matches:', error);
122
+ return { start: 0, end: 0, items: [] };
123
+ }
124
+ // Parse completions into completion items
125
+ const parsedCompletions = parsedResult.matches.map((match, index) => {
126
+ var _a;
127
+ return ({
128
+ label: match,
129
+ insertText: match,
130
+ type: ((_a = parsedResult.types) === null || _a === void 0 ? void 0 : _a[index]) || undefined
131
+ });
132
+ });
133
+ items = [...parsedCompletions];
134
+ }
135
+ catch (error) {
136
+ console.warn('Error fetching debugger completions:', error);
137
+ // Return empty items on error
138
+ return { start: 0, end: 0, items: [] };
139
+ }
140
+ // Extract cursor positions from the parsed result if available
141
+ const start = (_a = parsedResult.cursor_start) !== null && _a !== void 0 ? _a : 0;
142
+ const end = (_b = parsedResult.cursor_end) !== null && _b !== void 0 ? _b : 0;
143
+ return { start, end, items };
144
+ }
145
+ }
146
+ //# sourceMappingURL=debugger-completion-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debugger-completion-provider.js","sourceRoot":"","sources":["../src/debugger-completion-provider.ts"],"names":[],"mappings":"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"}
package/lib/index.js CHANGED
@@ -5,19 +5,21 @@
5
5
  * @module debugger-extension
6
6
  */
7
7
  import { ILabShell, ILayoutRestorer } from '@jupyterlab/application';
8
- import { Clipboard, Dialog, ICommandPalette, InputDialog, ISessionContextDialogs, IThemeManager, MainAreaWidget, SessionContextDialogs, showDialog, WidgetTracker } from '@jupyterlab/apputils';
9
- import { CodeCell } from '@jupyterlab/cells';
8
+ import { Clipboard, Dialog, ICommandPalette, InputDialog, ISanitizer, ISessionContextDialogs, IThemeManager, MainAreaWidget, SessionContextDialogs, showDialog } from '@jupyterlab/apputils';
10
9
  import { IEditorServices } from '@jupyterlab/codeeditor';
11
10
  import { ConsolePanel, IConsoleTracker } from '@jupyterlab/console';
12
11
  import { PageConfig, PathExt } from '@jupyterlab/coreutils';
13
12
  import { Debugger, IDebugger, IDebuggerConfig, IDebuggerHandler, IDebuggerSidebar, IDebuggerSources, IDebuggerSourceViewer } from '@jupyterlab/debugger';
14
13
  import { DocumentWidget } from '@jupyterlab/docregistry';
15
14
  import { FileEditor, IEditorTracker } from '@jupyterlab/fileeditor';
16
- import { ILoggerRegistry } from '@jupyterlab/logconsole';
17
15
  import { INotebookTracker, NotebookActions, NotebookPanel } from '@jupyterlab/notebook';
18
16
  import { standardRendererFactories as initialFactories, IRenderMimeRegistry, RenderMimeRegistry } from '@jupyterlab/rendermime';
19
17
  import { ISettingRegistry } from '@jupyterlab/settingregistry';
20
18
  import { ITranslator, nullTranslator } from '@jupyterlab/translation';
19
+ import { ICompletionProviderManager } from '@jupyterlab/completer';
20
+ import { WidgetTracker } from '@jupyterlab/apputils';
21
+ import { DebugConsoleCellExecutor } from './debug-console-executor';
22
+ import { DebuggerCompletionProvider } from './debugger-completion-provider';
21
23
  function notifyCommands(commands) {
22
24
  Object.values(Debugger.CommandIDs).forEach(command => {
23
25
  if (commands.hasCommand(command)) {
@@ -261,7 +263,7 @@ const sources = {
261
263
  });
262
264
  }
263
265
  };
264
- /*
266
+ /**
265
267
  * A plugin to open detailed views for variables.
266
268
  */
267
269
  const variables = {
@@ -661,17 +663,23 @@ const sourceViewer = {
661
663
  const main = {
662
664
  id: '@jupyterlab/debugger-extension:main',
663
665
  description: 'Initialize the debugger user interface.',
664
- requires: [IDebugger, IDebuggerSidebar, IEditorServices, ITranslator],
666
+ requires: [
667
+ IDebugger,
668
+ IDebuggerSidebar,
669
+ IEditorServices,
670
+ ITranslator,
671
+ ConsolePanel.IContentFactory,
672
+ IConsoleTracker
673
+ ],
665
674
  optional: [
666
675
  ICommandPalette,
667
676
  IDebuggerSourceViewer,
668
677
  ILabShell,
669
678
  ILayoutRestorer,
670
- ILoggerRegistry,
671
679
  ISettingRegistry
672
680
  ],
673
681
  autoStart: true,
674
- activate: async (app, service, sidebar, editorServices, translator, palette, sourceViewer, labShell, restorer, loggerRegistry, settingRegistry) => {
682
+ activate: async (app, service, sidebar, editorServices, translator, consolePanelContentFactory, consoleTracker, palette, sourceViewer, labShell, restorer, settingRegistry) => {
675
683
  var _a;
676
684
  const trans = translator.load('jupyterlab');
677
685
  const { commands, shell, serviceManager } = app;
@@ -692,63 +700,6 @@ const main = {
692
700
  return;
693
701
  }
694
702
  }
695
- // get the mime type of the kernel language for the current debug session
696
- const getMimeType = async () => {
697
- var _a, _b, _c;
698
- const kernel = (_b = (_a = service.session) === null || _a === void 0 ? void 0 : _a.connection) === null || _b === void 0 ? void 0 : _b.kernel;
699
- if (!kernel) {
700
- return '';
701
- }
702
- const info = (await kernel.info).language_info;
703
- const name = info.name;
704
- const mimeType = (_c = editorServices.mimeTypeService.getMimeTypeByLanguage({ name })) !== null && _c !== void 0 ? _c : '';
705
- return mimeType;
706
- };
707
- const rendermime = new RenderMimeRegistry({ initialFactories });
708
- commands.addCommand(CommandIDs.evaluate, {
709
- label: trans.__('Evaluate Code'),
710
- caption: trans.__('Evaluate Code'),
711
- icon: Debugger.Icons.evaluateIcon,
712
- isEnabled: () => service.hasStoppedThreads(),
713
- execute: async () => {
714
- var _a, _b, _c;
715
- const mimeType = await getMimeType();
716
- const result = await Debugger.Dialogs.getCode({
717
- title: trans.__('Evaluate Code'),
718
- okLabel: trans.__('Evaluate'),
719
- cancelLabel: trans.__('Cancel'),
720
- mimeType,
721
- contentFactory: new CodeCell.ContentFactory({
722
- editorFactory: options => editorServices.factoryService.newInlineEditor(options)
723
- }),
724
- rendermime
725
- });
726
- const code = result.value;
727
- if (!result.button.accept || !code) {
728
- return;
729
- }
730
- const reply = await service.evaluate(code);
731
- if (reply) {
732
- const data = reply.result;
733
- const path = (_b = (_a = service === null || service === void 0 ? void 0 : service.session) === null || _a === void 0 ? void 0 : _a.connection) === null || _b === void 0 ? void 0 : _b.path;
734
- const logger = path ? (_c = loggerRegistry === null || loggerRegistry === void 0 ? void 0 : loggerRegistry.getLogger) === null || _c === void 0 ? void 0 : _c.call(loggerRegistry, path) : undefined;
735
- if (logger) {
736
- // print to log console of the notebook currently being debugged
737
- logger.log({ type: 'text', data, level: logger.level });
738
- }
739
- else {
740
- // fallback to printing to devtools console
741
- console.debug(data);
742
- }
743
- }
744
- },
745
- describedBy: {
746
- args: {
747
- type: 'object',
748
- properties: {}
749
- }
750
- }
751
- });
752
703
  commands.addCommand(CommandIDs.debugContinue, {
753
704
  label: () => {
754
705
  return service.hasStoppedThreads()
@@ -968,6 +919,227 @@ const main = {
968
919
  }
969
920
  }
970
921
  };
922
+ /**
923
+ * A plugin that provides debugger-based completions.
924
+ */
925
+ const debuggerCompletions = {
926
+ id: '@jupyterlab/debugger-extension:completions',
927
+ description: 'Provides debugger-based completions.',
928
+ autoStart: true,
929
+ requires: [IDebugger, ICompletionProviderManager],
930
+ optional: [ITranslator],
931
+ activate: (app, debuggerService, completionManager, translator) => {
932
+ // Create and register the debugger completion provider
933
+ const provider = new DebuggerCompletionProvider({
934
+ debuggerService: debuggerService,
935
+ translator: translator || nullTranslator
936
+ });
937
+ // Register the provider with the completion manager
938
+ completionManager.registerProvider(provider);
939
+ }
940
+ };
941
+ /**
942
+ * A plugin that provides the debug console functionality.
943
+ */
944
+ const debugConsole = {
945
+ id: '@jupyterlab/debugger-extension:debug-console',
946
+ description: 'Debugger console to enable evaluation in debugger context.',
947
+ autoStart: true,
948
+ requires: [
949
+ IDebugger,
950
+ ConsolePanel.IContentFactory,
951
+ IEditorServices,
952
+ ICompletionProviderManager,
953
+ ISanitizer,
954
+ ITranslator
955
+ ],
956
+ optional: [ILabShell],
957
+ activate: (app, service, consolePanelContentFactory, editorServices, manager, sanitizer, translator, labShell) => {
958
+ const CommandIDs = Debugger.CommandIDs;
959
+ const trans = translator.load('jupyterlab');
960
+ // Create our own tracker for debug consoles
961
+ const debugConsoleTracker = new WidgetTracker({
962
+ namespace: 'debugger-debug-console'
963
+ });
964
+ // Global debug console widget variable for toggling
965
+ let debugConsoleWidget = null;
966
+ // Create the console
967
+ const createDebugConsole = async () => {
968
+ const rendermime = new RenderMimeRegistry({ initialFactories });
969
+ const debugExecutor = new DebugConsoleCellExecutor({
970
+ debuggerService: service,
971
+ trans
972
+ });
973
+ debugConsoleWidget = new ConsolePanel({
974
+ manager: app.serviceManager,
975
+ name: trans.__('Debug Console'),
976
+ contentFactory: consolePanelContentFactory,
977
+ rendermime,
978
+ executor: debugExecutor,
979
+ mimeTypeService: editorServices.mimeTypeService,
980
+ kernelPreference: { shouldStart: false, canStart: false }
981
+ });
982
+ debugConsoleWidget.title.label = trans.__('Debug Console');
983
+ debugConsoleWidget.title.icon = Debugger.Icons.evaluateIcon;
984
+ // Add a specific class to distinguish debug console from regular consoles
985
+ debugConsoleWidget.addClass('jp-DebugConsole');
986
+ debugConsoleWidget.console.addClass('jp-DebugConsole-widget');
987
+ // Close console when debugger is terminated
988
+ service.eventMessage.connect((_, event) => {
989
+ if (labShell && event.event === 'terminated') {
990
+ debugConsoleWidget === null || debugConsoleWidget === void 0 ? void 0 : debugConsoleWidget.dispose();
991
+ }
992
+ });
993
+ const notifyCommands = () => {
994
+ app.commands.notifyCommandChanged(CommandIDs.evaluate);
995
+ app.commands.notifyCommandChanged(CommandIDs.executeConsole);
996
+ app.commands.notifyCommandChanged(CommandIDs.invokeConsole);
997
+ app.commands.notifyCommandChanged(CommandIDs.selectConsole);
998
+ };
999
+ debugConsoleWidget.disposed.connect(() => {
1000
+ debugConsoleWidget = null;
1001
+ });
1002
+ app.shell.add(debugConsoleWidget, 'main', {
1003
+ mode: 'split-bottom',
1004
+ activate: true,
1005
+ type: 'Debugger console'
1006
+ });
1007
+ void debugConsoleTracker.add(debugConsoleWidget);
1008
+ app.shell.activateById(debugConsoleWidget.id);
1009
+ await updateCompleter(undefined, debugConsoleWidget);
1010
+ debugConsoleWidget === null || debugConsoleWidget === void 0 ? void 0 : debugConsoleWidget.update();
1011
+ notifyCommands();
1012
+ };
1013
+ // Set up completer
1014
+ const updateCompleter = async (_, consolePanel) => {
1015
+ var _a, _b;
1016
+ const completerContext = {
1017
+ editor: (_b = (_a = consolePanel.console.promptCell) === null || _a === void 0 ? void 0 : _a.editor) !== null && _b !== void 0 ? _b : null,
1018
+ session: consolePanel.console.sessionContext.session,
1019
+ widget: consolePanel
1020
+ };
1021
+ await manager.updateCompleter(completerContext);
1022
+ consolePanel.console.promptCellCreated.connect((codeConsole, cell) => {
1023
+ const newContext = {
1024
+ editor: cell.editor,
1025
+ session: codeConsole.sessionContext.session,
1026
+ widget: consolePanel,
1027
+ sanitizer: sanitizer
1028
+ };
1029
+ manager.updateCompleter(newContext).catch(console.error);
1030
+ });
1031
+ consolePanel.console.sessionContext.sessionChanged.connect(() => {
1032
+ var _a, _b;
1033
+ const newContext = {
1034
+ editor: (_b = (_a = consolePanel.console.promptCell) === null || _a === void 0 ? void 0 : _a.editor) !== null && _b !== void 0 ? _b : null,
1035
+ session: consolePanel.console.sessionContext.session,
1036
+ widget: consolePanel,
1037
+ sanitizer: sanitizer
1038
+ };
1039
+ manager.updateCompleter(newContext).catch(console.error);
1040
+ });
1041
+ };
1042
+ debugConsoleTracker.widgetAdded.connect(updateCompleter);
1043
+ manager.activeProvidersChanged.connect(() => {
1044
+ debugConsoleTracker.forEach(consoleWidget => {
1045
+ updateCompleter(undefined, consoleWidget).catch(e => console.error(e));
1046
+ });
1047
+ });
1048
+ // Add commands
1049
+ app.commands.addCommand(CommandIDs.invokeConsole, {
1050
+ label: trans.__('Display the tab completion widget.'),
1051
+ execute: () => {
1052
+ const id = debugConsoleTracker.currentWidget &&
1053
+ debugConsoleTracker.currentWidget.id;
1054
+ if (id) {
1055
+ return manager.invoke(id);
1056
+ }
1057
+ },
1058
+ describedBy: {
1059
+ args: {
1060
+ type: 'object',
1061
+ properties: {}
1062
+ }
1063
+ }
1064
+ });
1065
+ app.commands.addCommand(CommandIDs.selectConsole, {
1066
+ label: trans.__('Select the completion suggestion.'),
1067
+ execute: () => {
1068
+ const id = debugConsoleTracker.currentWidget &&
1069
+ debugConsoleTracker.currentWidget.id;
1070
+ if (id) {
1071
+ return manager.select(id);
1072
+ }
1073
+ },
1074
+ describedBy: {
1075
+ args: {
1076
+ type: 'object',
1077
+ properties: {}
1078
+ }
1079
+ }
1080
+ });
1081
+ // Add the debugger console execute command
1082
+ app.commands.addCommand(CommandIDs.executeConsole, {
1083
+ label: trans.__('Execute the current line in debug console.'),
1084
+ execute: async () => {
1085
+ const currentWidget = debugConsoleTracker.currentWidget;
1086
+ if (currentWidget && currentWidget.console) {
1087
+ await currentWidget.console.execute(true);
1088
+ // Ensure focus stays on the console prompt after execution
1089
+ const promptCell = currentWidget.console.promptCell;
1090
+ if (promptCell && promptCell.editor) {
1091
+ promptCell.editor.focus();
1092
+ }
1093
+ }
1094
+ },
1095
+ describedBy: {
1096
+ args: {
1097
+ type: 'object',
1098
+ properties: {}
1099
+ }
1100
+ }
1101
+ });
1102
+ app.commands.addCommand(CommandIDs.evaluate, {
1103
+ label: trans.__('Evaluate Code'),
1104
+ caption: trans.__('Evaluate Code'),
1105
+ icon: Debugger.Icons.evaluateIcon,
1106
+ isEnabled: () => { var _a; return !!((_a = service.session) === null || _a === void 0 ? void 0 : _a.isStarted); },
1107
+ execute: async () => {
1108
+ if (debugConsoleWidget) {
1109
+ debugConsoleWidget.dispose();
1110
+ }
1111
+ else {
1112
+ void createDebugConsole();
1113
+ }
1114
+ },
1115
+ isToggled: () => {
1116
+ return debugConsoleWidget !== null;
1117
+ },
1118
+ describedBy: {
1119
+ args: {
1120
+ type: 'object',
1121
+ properties: {}
1122
+ }
1123
+ }
1124
+ });
1125
+ // Add the keybindings
1126
+ app.commands.addKeyBinding({
1127
+ command: CommandIDs.selectConsole,
1128
+ keys: ['Enter'],
1129
+ selector: '.jp-ConsolePanel.jp-DebugConsole .jp-DebugConsole-widget .jp-mod-completer-active'
1130
+ });
1131
+ app.commands.addKeyBinding({
1132
+ command: CommandIDs.invokeConsole,
1133
+ keys: ['Tab'],
1134
+ selector: '.jp-ConsolePanel.jp-DebugConsole .jp-DebugConsole-widget .jp-CodeConsole-promptCell .jp-mod-completer-enabled:not(.jp-mod-at-line-beginning)'
1135
+ });
1136
+ app.commands.addKeyBinding({
1137
+ command: CommandIDs.executeConsole,
1138
+ keys: ['Shift Enter'],
1139
+ selector: '.jp-ConsolePanel.jp-DebugConsole .jp-DebugConsole-widget .jp-CodeConsole-promptCell'
1140
+ });
1141
+ }
1142
+ };
971
1143
  /**
972
1144
  * Export the plugins as default.
973
1145
  */
@@ -981,7 +1153,9 @@ const plugins = [
981
1153
  main,
982
1154
  sources,
983
1155
  sourceViewer,
984
- configuration
1156
+ configuration,
1157
+ debuggerCompletions,
1158
+ debugConsole
985
1159
  ];
986
1160
  export default plugins;
987
1161
  //# sourceMappingURL=index.js.map