@theia/debug 1.77.0-next.47 → 1.77.0-next.56
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.
- package/lib/browser/breakpoint/breakpoint-manager.js +1 -1
- package/lib/browser/breakpoint/breakpoint-manager.js.map +1 -1
- package/lib/browser/breakpoint/breakpoint-manager.spec.js +2 -1
- package/lib/browser/breakpoint/breakpoint-manager.spec.js.map +1 -1
- package/lib/browser/console/debug-console-items.d.ts +2 -3
- package/lib/browser/console/debug-console-items.d.ts.map +1 -1
- package/lib/browser/console/debug-console-items.js +21 -10
- package/lib/browser/console/debug-console-items.js.map +1 -1
- package/lib/browser/console/debug-console-session.js +2 -2
- package/lib/browser/console/debug-console-session.js.map +1 -1
- package/lib/browser/console/debug-copy-value.spec.d.ts +2 -0
- package/lib/browser/console/debug-copy-value.spec.d.ts.map +1 -0
- package/lib/browser/console/debug-copy-value.spec.js +123 -0
- package/lib/browser/console/debug-copy-value.spec.js.map +1 -0
- package/lib/browser/debug-configuration-manager.js +1 -1
- package/lib/browser/debug-configuration-manager.js.map +1 -1
- package/lib/browser/debug-frontend-application-contribution.d.ts +5 -0
- package/lib/browser/debug-frontend-application-contribution.d.ts.map +1 -1
- package/lib/browser/debug-frontend-application-contribution.js +13 -3
- package/lib/browser/debug-frontend-application-contribution.js.map +1 -1
- package/lib/browser/debug-package.spec.js +1 -0
- package/lib/browser/debug-package.spec.js.map +1 -1
- package/lib/browser/debug-prefix-configuration.js +1 -1
- package/lib/browser/debug-prefix-configuration.js.map +1 -1
- package/lib/browser/debug-schema-updater.js +1 -1
- package/lib/browser/debug-schema-updater.js.map +1 -1
- package/lib/browser/debug-session-configuration-label-provider.js +1 -1
- package/lib/browser/debug-session-configuration-label-provider.js.map +1 -1
- package/lib/browser/debug-session-manager.js +1 -1
- package/lib/browser/debug-session-manager.js.map +1 -1
- package/lib/browser/debug-session-options.js +1 -1
- package/lib/browser/debug-session-options.js.map +1 -1
- package/lib/browser/debug-session.js +1 -1
- package/lib/browser/debug-session.js.map +1 -1
- package/lib/browser/debug-watch-manager.d.ts +1 -1
- package/lib/browser/debug-watch-manager.d.ts.map +1 -1
- package/lib/browser/editor/debug-breakpoint-widget.js +3 -3
- package/lib/browser/editor/debug-breakpoint-widget.js.map +1 -1
- package/lib/browser/editor/debug-editor-model.js +2 -2
- package/lib/browser/editor/debug-editor-model.js.map +1 -1
- package/lib/browser/editor/debug-editor-service.js +1 -1
- package/lib/browser/editor/debug-editor-service.js.map +1 -1
- package/lib/browser/editor/debug-exception-widget.js +1 -1
- package/lib/browser/editor/debug-exception-widget.js.map +1 -1
- package/lib/browser/editor/debug-expression-provider.js +1 -1
- package/lib/browser/editor/debug-expression-provider.js.map +1 -1
- package/lib/browser/editor/debug-hover-widget.js +1 -1
- package/lib/browser/editor/debug-hover-widget.js.map +1 -1
- package/lib/browser/editor/debug-inline-value-decorator.js +1 -1
- package/lib/browser/editor/debug-inline-value-decorator.js.map +1 -1
- package/lib/browser/model/debug-function-breakpoint.js +2 -1
- package/lib/browser/model/debug-function-breakpoint.js.map +1 -1
- package/lib/browser/model/debug-instruction-breakpoint.js +2 -1
- package/lib/browser/model/debug-instruction-breakpoint.js.map +1 -1
- package/lib/browser/model/debug-source-breakpoint.js +3 -2
- package/lib/browser/model/debug-source-breakpoint.js.map +1 -1
- package/lib/browser/model/debug-source.js +2 -1
- package/lib/browser/model/debug-source.js.map +1 -1
- package/lib/browser/model/debug-stack-frame.js +2 -1
- package/lib/browser/model/debug-stack-frame.js.map +1 -1
- package/lib/browser/view/debug-action.js +2 -1
- package/lib/browser/view/debug-action.js.map +1 -1
- package/lib/browser/view/debug-configuration-select.js +3 -2
- package/lib/browser/view/debug-configuration-select.js.map +1 -1
- package/lib/browser/view/debug-configuration-widget.js +1 -1
- package/lib/browser/view/debug-configuration-widget.js.map +1 -1
- package/lib/browser/view/debug-toolbar-widget.js +1 -1
- package/lib/browser/view/debug-toolbar-widget.js.map +1 -1
- package/lib/browser/view/debug-view-model.js +1 -1
- package/lib/browser/view/debug-view-model.js.map +1 -1
- package/lib/browser/view/debug-watch-expression.d.ts +1 -3
- package/lib/browser/view/debug-watch-expression.d.ts.map +1 -1
- package/lib/browser/view/debug-watch-expression.js +4 -9
- package/lib/browser/view/debug-watch-expression.js.map +1 -1
- package/lib/node/debug-adapter-factory.js +1 -1
- package/lib/node/debug-adapter-factory.js.map +1 -1
- package/package.json +15 -15
- package/src/browser/console/debug-console-items.tsx +19 -10
- package/src/browser/console/debug-copy-value.spec.ts +144 -0
- package/src/browser/debug-frontend-application-contribution.ts +12 -2
- package/src/browser/debug-session-options.ts +1 -1
- package/src/browser/view/debug-watch-expression.tsx +4 -10
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2026 Karthik Harikrishnan and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// http://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
|
|
18
|
+
import { enableJSDOM } from '@theia/core/lib/browser/test/jsdom';
|
|
19
|
+
const disableJSDOM = enableJSDOM();
|
|
20
|
+
FrontendApplicationConfigProvider.set({});
|
|
21
|
+
|
|
22
|
+
import { expect } from 'chai';
|
|
23
|
+
import { DebugProtocol } from '@vscode/debugprotocol';
|
|
24
|
+
import { DebugSession } from '../debug-session';
|
|
25
|
+
import { DebugWatchExpression } from '../view/debug-watch-expression';
|
|
26
|
+
import { DebugVariable, ExpressionContainer } from './debug-console-items';
|
|
27
|
+
|
|
28
|
+
disableJSDOM();
|
|
29
|
+
|
|
30
|
+
interface TestSession extends Pick<DebugSession, 'capabilities' | 'evaluate'> { }
|
|
31
|
+
|
|
32
|
+
class TestDebugWatchExpression extends DebugWatchExpression {
|
|
33
|
+
|
|
34
|
+
setValue(value: string): void {
|
|
35
|
+
this._value = value;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function createVariable(session: TestSession, overrides: Partial<DebugProtocol.Variable> = { evaluateName: 'object.value' }): DebugVariable {
|
|
40
|
+
const sessionProvider = () => session as DebugSession;
|
|
41
|
+
const parent = new ExpressionContainer({ session: sessionProvider, id: 'parent' });
|
|
42
|
+
const variable: DebugProtocol.Variable = {
|
|
43
|
+
name: 'value',
|
|
44
|
+
value: 'truncated',
|
|
45
|
+
variablesReference: 0,
|
|
46
|
+
...overrides
|
|
47
|
+
};
|
|
48
|
+
return new DebugVariable(sessionProvider, variable, parent);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function createWatchExpression(session: TestSession): TestDebugWatchExpression {
|
|
52
|
+
const watchExpression = new TestDebugWatchExpression({
|
|
53
|
+
id: 1,
|
|
54
|
+
expression: 'object.value',
|
|
55
|
+
session: () => session as DebugSession,
|
|
56
|
+
remove: () => undefined,
|
|
57
|
+
onDidChange: () => undefined
|
|
58
|
+
});
|
|
59
|
+
watchExpression.setValue('truncated');
|
|
60
|
+
return watchExpression;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
describe('Debugger Copy Value', () => {
|
|
64
|
+
|
|
65
|
+
it('evaluates a variable using the clipboard context when supported', async () => {
|
|
66
|
+
const evaluations: Array<{ expression: string; context?: string }> = [];
|
|
67
|
+
const session: TestSession = {
|
|
68
|
+
capabilities: { supportsClipboardContext: true },
|
|
69
|
+
evaluate: async (expression, context) => {
|
|
70
|
+
evaluations.push({ expression, context });
|
|
71
|
+
return { result: 'full value', variablesReference: 0 };
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
const value = await createVariable(session).getValueToCopy();
|
|
75
|
+
|
|
76
|
+
expect(evaluations).to.deep.equal([{ expression: 'object.value', context: 'clipboard' }]);
|
|
77
|
+
expect(value).to.equal('full value');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('uses the variables context when the clipboard context is unsupported', async () => {
|
|
81
|
+
const evaluations: Array<{ expression: string; context?: string }> = [];
|
|
82
|
+
const session: TestSession = {
|
|
83
|
+
capabilities: {},
|
|
84
|
+
evaluate: async (expression, context) => {
|
|
85
|
+
evaluations.push({ expression, context });
|
|
86
|
+
return { result: 'full value', variablesReference: 0 };
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const value = await createVariable(session).getValueToCopy();
|
|
90
|
+
|
|
91
|
+
expect(evaluations).to.deep.equal([{ expression: 'object.value', context: 'variables' }]);
|
|
92
|
+
expect(value).to.equal('full value');
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('copies the rendered variable value when evaluateName is unavailable', async () => {
|
|
96
|
+
let evaluated = false;
|
|
97
|
+
const session: TestSession = {
|
|
98
|
+
capabilities: { supportsClipboardContext: true },
|
|
99
|
+
evaluate: async () => {
|
|
100
|
+
evaluated = true;
|
|
101
|
+
return { result: 'full value', variablesReference: 0 };
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const value = await createVariable(session, { evaluateName: undefined }).getValueToCopy();
|
|
105
|
+
|
|
106
|
+
expect(evaluated).to.be.false;
|
|
107
|
+
expect(value).to.equal('truncated');
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('copies the rendered variable value when evaluation fails', async () => {
|
|
111
|
+
const session: TestSession = {
|
|
112
|
+
capabilities: { supportsClipboardContext: true },
|
|
113
|
+
evaluate: async () => { throw new Error('evaluation failed'); }
|
|
114
|
+
};
|
|
115
|
+
const value = await createVariable(session).getValueToCopy();
|
|
116
|
+
|
|
117
|
+
expect(value).to.equal('truncated');
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('evaluates a watch expression using the watch context', async () => {
|
|
121
|
+
const evaluations: Array<{ expression: string; context?: string }> = [];
|
|
122
|
+
const session: TestSession = {
|
|
123
|
+
capabilities: {},
|
|
124
|
+
evaluate: async (expression, context) => {
|
|
125
|
+
evaluations.push({ expression, context });
|
|
126
|
+
return { result: 'full value', variablesReference: 0 };
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
const value = await createWatchExpression(session).getValueToCopy();
|
|
130
|
+
|
|
131
|
+
expect(evaluations).to.deep.equal([{ expression: 'object.value', context: 'watch' }]);
|
|
132
|
+
expect(value).to.equal('full value');
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('copies the rendered watch value when evaluation fails', async () => {
|
|
136
|
+
const session: TestSession = {
|
|
137
|
+
capabilities: { supportsClipboardContext: true },
|
|
138
|
+
evaluate: async () => { throw new Error('evaluation failed'); }
|
|
139
|
+
};
|
|
140
|
+
const value = await createWatchExpression(session).getValueToCopy();
|
|
141
|
+
|
|
142
|
+
expect(value).to.equal('truncated');
|
|
143
|
+
});
|
|
144
|
+
});
|
|
@@ -69,6 +69,7 @@ import {
|
|
|
69
69
|
DebugEditorContextCommands, DebugBreakpointWidgetCommands, nlsEnableBreakpoint, nlsDisableBreakpoint
|
|
70
70
|
} from './debug-commands';
|
|
71
71
|
import { ILogger } from '@theia/core';
|
|
72
|
+
import { ClipboardService } from '@theia/core/lib/browser/clipboard-service';
|
|
72
73
|
|
|
73
74
|
@injectable()
|
|
74
75
|
export class DebugFrontendApplicationContribution extends AbstractViewContribution<DebugWidget>
|
|
@@ -119,6 +120,9 @@ export class DebugFrontendApplicationContribution extends AbstractViewContributi
|
|
|
119
120
|
@inject(ILogger) @named('debug:DebugFrontendApplicationContribution')
|
|
120
121
|
protected readonly logger: ILogger;
|
|
121
122
|
|
|
123
|
+
@inject(ClipboardService)
|
|
124
|
+
protected readonly clipboardService: ClipboardService;
|
|
125
|
+
|
|
122
126
|
constructor() {
|
|
123
127
|
super({
|
|
124
128
|
widgetId: DebugWidget.ID,
|
|
@@ -697,7 +701,7 @@ export class DebugFrontendApplicationContribution extends AbstractViewContributi
|
|
|
697
701
|
isVisible: () => !!this.selectedVariable && this.selectedVariable.supportSetVariable
|
|
698
702
|
});
|
|
699
703
|
registry.registerCommand(DebugCommands.COPY_VARIABLE_VALUE, {
|
|
700
|
-
execute: () => this.
|
|
704
|
+
execute: () => this.copyValue(this.selectedVariable),
|
|
701
705
|
isEnabled: () => !!this.selectedVariable && this.selectedVariable.supportCopyValue,
|
|
702
706
|
isVisible: () => !!this.selectedVariable && this.selectedVariable.supportCopyValue
|
|
703
707
|
});
|
|
@@ -826,7 +830,7 @@ export class DebugFrontendApplicationContribution extends AbstractViewContributi
|
|
|
826
830
|
isVisible: () => !!this.watchExpression
|
|
827
831
|
});
|
|
828
832
|
registry.registerCommand(DebugCommands.COPY_WATCH_EXPRESSION_VALUE, {
|
|
829
|
-
execute: () => this.
|
|
833
|
+
execute: () => this.copyValue(this.watchExpression),
|
|
830
834
|
isEnabled: () => !!this.watchExpression && this.watchExpression.supportCopyValue,
|
|
831
835
|
isVisible: () => !!this.watchExpression && this.watchExpression.supportCopyValue
|
|
832
836
|
});
|
|
@@ -865,6 +869,12 @@ export class DebugFrontendApplicationContribution extends AbstractViewContributi
|
|
|
865
869
|
});
|
|
866
870
|
}
|
|
867
871
|
|
|
872
|
+
protected async copyValue(item: { getValueToCopy(): Promise<string> } | undefined): Promise<void> {
|
|
873
|
+
if (item) {
|
|
874
|
+
await this.clipboardService.writeText(await item.getValueToCopy());
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
|
|
868
878
|
override registerKeybindings(keybindings: KeybindingRegistry): void {
|
|
869
879
|
super.registerKeybindings(keybindings);
|
|
870
880
|
keybindings.registerKeybinding({
|
|
@@ -113,7 +113,7 @@ export namespace InternalDebugSessionOptions {
|
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
/** @deprecated Please use `JSON.parse` to restore previously serialized debug session options. */
|
|
116
|
-
// eslint-disable-next-line
|
|
116
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
117
117
|
export function parseValue(value: string): DebugSessionOptionsData {
|
|
118
118
|
const split = value.split(SEPARATOR);
|
|
119
119
|
if (split.length === 5) {
|
|
@@ -63,7 +63,7 @@ export class DebugWatchExpression extends ExpressionItem {
|
|
|
63
63
|
return <div className='theia-debug-console-variable theia-debug-watch-expression'>
|
|
64
64
|
<div className={TREE_NODE_SEGMENT_GROW_CLASS}>
|
|
65
65
|
<span title={this.type || this._expression} className='name'>{this._expression}:</span>
|
|
66
|
-
<span title={this._value}
|
|
66
|
+
<span title={this._value} className={valueClass}>{this._value}</span>
|
|
67
67
|
</div>
|
|
68
68
|
<div className={codicon('close', true)} title={nls.localizeByDefault('Remove Expression')} onClick={this.options.remove} />
|
|
69
69
|
</div>;
|
|
@@ -93,16 +93,10 @@ export class DebugWatchExpression extends ExpressionItem {
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
get supportCopyValue(): boolean {
|
|
96
|
-
return
|
|
96
|
+
return this.available;
|
|
97
97
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
if (this.valueRef && selection) {
|
|
101
|
-
selection.selectAllChildren(this.valueRef);
|
|
102
|
-
document.execCommand('copy');
|
|
103
|
-
}
|
|
98
|
+
async getValueToCopy(): Promise<string> {
|
|
99
|
+
return this.evaluateForClipboard(this.expression, 'watch', this.value);
|
|
104
100
|
}
|
|
105
|
-
protected valueRef: HTMLSpanElement | undefined;
|
|
106
|
-
protected setValueRef = (valueRef: HTMLSpanElement | null): void => { this.valueRef = valueRef || undefined; };
|
|
107
101
|
|
|
108
102
|
}
|