@theia/plugin-ext 1.76.0-next.4 → 1.76.0-next.42
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/common/plugin-api-rpc.d.ts +14 -0
- package/lib/common/plugin-api-rpc.d.ts.map +1 -1
- package/lib/common/plugin-api-rpc.js +1 -1
- package/lib/common/plugin-api-rpc.js.map +1 -1
- package/lib/hosted/browser/hosted-plugin.d.ts +2 -0
- package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
- package/lib/hosted/browser/hosted-plugin.js +8 -2
- package/lib/hosted/browser/hosted-plugin.js.map +1 -1
- package/lib/hosted/browser/worker/worker-main.js +3 -1
- package/lib/hosted/browser/worker/worker-main.js.map +1 -1
- package/lib/hosted/browser/worker/worker-plugin-module.d.ts.map +1 -1
- package/lib/hosted/browser/worker/worker-plugin-module.js +2 -0
- package/lib/hosted/browser/worker/worker-plugin-module.js.map +1 -1
- package/lib/hosted/node/plugin-host-module.d.ts.map +1 -1
- package/lib/hosted/node/plugin-host-module.js +2 -0
- package/lib/hosted/node/plugin-host-module.js.map +1 -1
- package/lib/hosted/node/plugin-host-rpc.d.ts +3 -0
- package/lib/hosted/node/plugin-host-rpc.d.ts.map +1 -1
- package/lib/hosted/node/plugin-host-rpc.js +9 -3
- package/lib/hosted/node/plugin-host-rpc.js.map +1 -1
- package/lib/main/browser/editors-and-documents-main.d.ts +7 -0
- package/lib/main/browser/editors-and-documents-main.d.ts.map +1 -1
- package/lib/main/browser/editors-and-documents-main.js +19 -9
- package/lib/main/browser/editors-and-documents-main.js.map +1 -1
- package/lib/main/browser/editors-and-documents-main.spec.d.ts +2 -0
- package/lib/main/browser/editors-and-documents-main.spec.d.ts.map +1 -0
- package/lib/main/browser/editors-and-documents-main.spec.js +117 -0
- package/lib/main/browser/editors-and-documents-main.spec.js.map +1 -0
- package/lib/main/browser/languages-main.d.ts +7 -0
- package/lib/main/browser/languages-main.d.ts.map +1 -1
- package/lib/main/browser/languages-main.js +31 -9
- package/lib/main/browser/languages-main.js.map +1 -1
- package/lib/main/browser/languages-main.spec.d.ts +2 -0
- package/lib/main/browser/languages-main.spec.d.ts.map +1 -0
- package/lib/main/browser/languages-main.spec.js +82 -0
- package/lib/main/browser/languages-main.spec.js.map +1 -0
- package/lib/main/browser/main-context.d.ts.map +1 -1
- package/lib/main/browser/main-context.js +3 -0
- package/lib/main/browser/main-context.js.map +1 -1
- package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts +5 -0
- package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts.map +1 -1
- package/lib/main/browser/menus/vscode-theia-menu-mappings.js +5 -0
- package/lib/main/browser/menus/vscode-theia-menu-mappings.js.map +1 -1
- package/lib/main/browser/plugin-ext-frontend-module.d.ts.map +1 -1
- package/lib/main/browser/plugin-ext-frontend-module.js +1 -0
- package/lib/main/browser/plugin-ext-frontend-module.js.map +1 -1
- package/lib/main/browser/telemetry-main.d.ts +20 -0
- package/lib/main/browser/telemetry-main.d.ts.map +1 -0
- package/lib/main/browser/telemetry-main.js +43 -0
- package/lib/main/browser/telemetry-main.js.map +1 -0
- package/lib/main/browser/telemetry-main.spec.d.ts +2 -0
- package/lib/main/browser/telemetry-main.spec.d.ts.map +1 -0
- package/lib/main/browser/telemetry-main.spec.js +66 -0
- package/lib/main/browser/telemetry-main.spec.js.map +1 -0
- package/lib/main/browser/webview/webview-context-keys.d.ts +3 -2
- package/lib/main/browser/webview/webview-context-keys.d.ts.map +1 -1
- package/lib/main/browser/webview/webview-context-keys.js +16 -2
- package/lib/main/browser/webview/webview-context-keys.js.map +1 -1
- package/lib/plugin/plugin-context.d.ts +2 -1
- package/lib/plugin/plugin-context.d.ts.map +1 -1
- package/lib/plugin/plugin-context.js +2 -3
- package/lib/plugin/plugin-context.js.map +1 -1
- package/lib/plugin/plugin-manager.d.ts +2 -0
- package/lib/plugin/plugin-manager.d.ts.map +1 -1
- package/lib/plugin/plugin-manager.js +7 -0
- package/lib/plugin/plugin-manager.js.map +1 -1
- package/lib/plugin/telemetry-ext.d.ts +23 -7
- package/lib/plugin/telemetry-ext.d.ts.map +1 -1
- package/lib/plugin/telemetry-ext.js +60 -33
- package/lib/plugin/telemetry-ext.js.map +1 -1
- package/lib/plugin/telemetry-ext.spec.js +121 -16
- package/lib/plugin/telemetry-ext.spec.js.map +1 -1
- package/package.json +32 -31
- package/src/common/plugin-api-rpc.ts +15 -1
- package/src/hosted/browser/hosted-plugin.ts +7 -2
- package/src/hosted/browser/worker/worker-main.ts +4 -1
- package/src/hosted/browser/worker/worker-plugin-module.ts +2 -0
- package/src/hosted/node/plugin-host-module.ts +2 -0
- package/src/hosted/node/plugin-host-rpc.ts +10 -4
- package/src/main/browser/editors-and-documents-main.spec.ts +140 -0
- package/src/main/browser/editors-and-documents-main.ts +19 -7
- package/src/main/browser/languages-main.spec.ts +101 -0
- package/src/main/browser/languages-main.ts +31 -9
- package/src/main/browser/main-context.ts +4 -0
- package/src/main/browser/menus/vscode-theia-menu-mappings.ts +5 -0
- package/src/main/browser/plugin-ext-frontend-module.ts +2 -1
- package/src/main/browser/telemetry-main.spec.ts +77 -0
- package/src/main/browser/telemetry-main.ts +46 -0
- package/src/main/browser/webview/webview-context-keys.ts +20 -4
- package/src/plugin/plugin-context.ts +3 -2
- package/src/plugin/plugin-manager.ts +6 -0
- package/src/plugin/telemetry-ext.spec.ts +158 -17
- package/src/plugin/telemetry-ext.ts +63 -33
|
@@ -18,34 +18,139 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
18
18
|
const chai = require("chai");
|
|
19
19
|
const telemetry_ext_1 = require("./telemetry-ext");
|
|
20
20
|
const expect = chai.expect;
|
|
21
|
-
describe('
|
|
21
|
+
describe('TelemetryExtImpl', () => {
|
|
22
22
|
const sender = {
|
|
23
23
|
sendEventData: () => { },
|
|
24
24
|
sendErrorData: () => { }
|
|
25
25
|
};
|
|
26
|
-
|
|
26
|
+
const expectations = {
|
|
27
|
+
off: { isTelemetryEnabled: false, isUsageEnabled: false, isErrorsEnabled: false },
|
|
28
|
+
crash: { isTelemetryEnabled: false, isUsageEnabled: false, isErrorsEnabled: false },
|
|
29
|
+
error: { isTelemetryEnabled: false, isUsageEnabled: false, isErrorsEnabled: true },
|
|
30
|
+
all: { isTelemetryEnabled: true, isUsageEnabled: true, isErrorsEnabled: true }
|
|
31
|
+
};
|
|
32
|
+
for (const level of ['off', 'crash', 'error', 'all']) {
|
|
33
|
+
const expected = expectations[level];
|
|
34
|
+
it(`derives the enablement states from telemetry level '${level}'`, () => {
|
|
35
|
+
const telemetry = new telemetry_ext_1.TelemetryExtImpl();
|
|
36
|
+
telemetry.$onDidChangeTelemetryLevel(level);
|
|
37
|
+
const logger = telemetry.createTelemetryLogger(sender);
|
|
38
|
+
expect(telemetry.level).to.equal(level);
|
|
39
|
+
expect(telemetry.isTelemetryEnabled).to.equal(expected.isTelemetryEnabled);
|
|
40
|
+
expect(logger.isUsageEnabled).to.equal(expected.isUsageEnabled);
|
|
41
|
+
expect(logger.isErrorsEnabled).to.equal(expected.isErrorsEnabled);
|
|
42
|
+
});
|
|
43
|
+
it(`applies telemetry level '${level}' to loggers created before the level arrived`, () => {
|
|
44
|
+
const telemetry = new telemetry_ext_1.TelemetryExtImpl();
|
|
45
|
+
const logger = telemetry.createTelemetryLogger(sender);
|
|
46
|
+
telemetry.$onDidChangeTelemetryLevel(level);
|
|
47
|
+
expect(logger.isUsageEnabled).to.equal(expected.isUsageEnabled);
|
|
48
|
+
expect(logger.isErrorsEnabled).to.equal(expected.isErrorsEnabled);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
it('only fires onDidChangeTelemetryEnabled when the boolean it reports changes', () => {
|
|
52
|
+
const telemetry = new telemetry_ext_1.TelemetryExtImpl();
|
|
53
|
+
const fired = [];
|
|
54
|
+
telemetry.onDidChangeTelemetryEnabled(enabled => fired.push(enabled));
|
|
55
|
+
telemetry.$onDidChangeTelemetryLevel('crash');
|
|
56
|
+
telemetry.$onDidChangeTelemetryLevel('error');
|
|
57
|
+
telemetry.$onDidChangeTelemetryLevel('all');
|
|
58
|
+
telemetry.$onDidChangeTelemetryLevel('off');
|
|
59
|
+
expect(fired).to.deep.equal([true, false]);
|
|
60
|
+
});
|
|
61
|
+
it('fires onDidChangeEnableStates once per transition that changes an enablement state', () => {
|
|
27
62
|
const telemetry = new telemetry_ext_1.TelemetryExtImpl();
|
|
28
63
|
const logger = telemetry.createTelemetryLogger(sender);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
expect(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
64
|
+
let changes = 0;
|
|
65
|
+
logger.onDidChangeEnableStates(() => changes++);
|
|
66
|
+
telemetry.$onDidChangeTelemetryLevel('crash'); // off -> crash: both stay false
|
|
67
|
+
expect(changes).to.equal(0);
|
|
68
|
+
telemetry.$onDidChangeTelemetryLevel('error'); // errors become enabled
|
|
69
|
+
expect(changes).to.equal(1);
|
|
70
|
+
telemetry.$onDidChangeTelemetryLevel('all'); // usage becomes enabled
|
|
71
|
+
expect(changes).to.equal(2);
|
|
72
|
+
telemetry.$onDidChangeTelemetryLevel('off');
|
|
73
|
+
expect(changes).to.equal(3);
|
|
74
|
+
});
|
|
75
|
+
it('stops following the level once the logger is disposed', () => {
|
|
76
|
+
const telemetry = new telemetry_ext_1.TelemetryExtImpl();
|
|
77
|
+
const logger = telemetry.createTelemetryLogger(sender);
|
|
78
|
+
let changes = 0;
|
|
79
|
+
logger.onDidChangeEnableStates(() => changes++);
|
|
80
|
+
logger.dispose();
|
|
81
|
+
telemetry.$onDidChangeTelemetryLevel('all');
|
|
38
82
|
expect(logger.isUsageEnabled).to.equal(false);
|
|
39
|
-
|
|
83
|
+
logger.isUsageEnabled = true;
|
|
84
|
+
expect(changes).to.equal(0);
|
|
40
85
|
});
|
|
41
|
-
it('
|
|
86
|
+
it('logs rather than propagates a sender that fails to flush on disposal', async () => {
|
|
87
|
+
const telemetry = new telemetry_ext_1.TelemetryExtImpl();
|
|
88
|
+
const logged = [];
|
|
89
|
+
const consoleError = console.error;
|
|
90
|
+
console.error = (...args) => { logged.push(args); };
|
|
91
|
+
try {
|
|
92
|
+
telemetry.createTelemetryLogger({ ...sender, flush: () => { throw new Error('boom'); } }).dispose();
|
|
93
|
+
telemetry.createTelemetryLogger({ ...sender, flush: () => Promise.reject(new Error('boom')) }).dispose();
|
|
94
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
console.error = consoleError;
|
|
98
|
+
}
|
|
99
|
+
expect(logged).to.have.lengthOf(2);
|
|
100
|
+
});
|
|
101
|
+
it('ignores a repeated telemetry level', () => {
|
|
42
102
|
const telemetry = new telemetry_ext_1.TelemetryExtImpl();
|
|
43
103
|
const logger = telemetry.createTelemetryLogger(sender);
|
|
44
104
|
let changes = 0;
|
|
45
105
|
logger.onDidChangeEnableStates(() => changes++);
|
|
46
|
-
telemetry
|
|
47
|
-
telemetry
|
|
48
|
-
expect(changes).to.equal(
|
|
106
|
+
telemetry.$onDidChangeTelemetryLevel('all');
|
|
107
|
+
telemetry.$onDidChangeTelemetryLevel('all');
|
|
108
|
+
expect(changes).to.equal(1);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
describe('TelemetryLogger', () => {
|
|
112
|
+
function createSender() {
|
|
113
|
+
const events = [];
|
|
114
|
+
const errors = [];
|
|
115
|
+
return {
|
|
116
|
+
events,
|
|
117
|
+
errors,
|
|
118
|
+
sendEventData: (eventName) => events.push(eventName),
|
|
119
|
+
sendErrorData: (error) => errors.push(error)
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
it('delivers errors but suppresses usage at telemetry level \'error\'', () => {
|
|
123
|
+
const telemetry = new telemetry_ext_1.TelemetryExtImpl();
|
|
124
|
+
telemetry.$onDidChangeTelemetryLevel('error');
|
|
125
|
+
const sender = createSender();
|
|
126
|
+
const logger = telemetry.createTelemetryLogger(sender);
|
|
127
|
+
logger.logUsage('usage-event');
|
|
128
|
+
logger.logError('error-event');
|
|
129
|
+
logger.logError(new Error('boom'));
|
|
130
|
+
expect(sender.events).to.deep.equal(['error-event']);
|
|
131
|
+
expect(sender.errors).to.have.lengthOf(1);
|
|
132
|
+
});
|
|
133
|
+
it('suppresses usage that a plugin re-enables while the telemetry level forbids it', () => {
|
|
134
|
+
const telemetry = new telemetry_ext_1.TelemetryExtImpl();
|
|
135
|
+
telemetry.$onDidChangeTelemetryLevel('off');
|
|
136
|
+
const sender = createSender();
|
|
137
|
+
const logger = telemetry.createTelemetryLogger(sender);
|
|
138
|
+
logger.isUsageEnabled = true;
|
|
139
|
+
logger.isErrorsEnabled = true;
|
|
140
|
+
logger.logUsage('usage-event');
|
|
141
|
+
logger.logError('error-event');
|
|
142
|
+
expect(sender.events).to.be.empty;
|
|
143
|
+
});
|
|
144
|
+
it('refuses to let a plugin assign the telemetry level of its logger', () => {
|
|
145
|
+
const telemetry = new telemetry_ext_1.TelemetryExtImpl();
|
|
146
|
+
telemetry.$onDidChangeTelemetryLevel('off');
|
|
147
|
+
const sender = createSender();
|
|
148
|
+
const logger = telemetry.createTelemetryLogger(sender);
|
|
149
|
+
expect(Reflect.set(logger, 'level', 'all')).to.be.false;
|
|
150
|
+
logger.logUsage('usage-event');
|
|
151
|
+
expect(logger.level).to.equal('off');
|
|
152
|
+
expect(logger.isUsageEnabled).to.be.false;
|
|
153
|
+
expect(sender.events).to.be.empty;
|
|
49
154
|
});
|
|
50
155
|
});
|
|
51
156
|
//# sourceMappingURL=telemetry-ext.spec.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetry-ext.spec.js","sourceRoot":"","sources":["../../src/plugin/telemetry-ext.spec.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,wCAAwC;AACxC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;AAEhF,6BAA6B;
|
|
1
|
+
{"version":3,"file":"telemetry-ext.spec.js","sourceRoot":"","sources":["../../src/plugin/telemetry-ext.spec.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,40 +1,41 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theia/plugin-ext",
|
|
3
|
-
"version": "1.76.0-next.
|
|
3
|
+
"version": "1.76.0-next.42+b0f9e63a6",
|
|
4
4
|
"description": "Theia - Plugin Extension",
|
|
5
5
|
"main": "lib/common/index.js",
|
|
6
6
|
"typings": "lib/common/index.d.ts",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@theia/ai-core": "1.76.0-next.
|
|
9
|
-
"@theia/ai-mcp": "1.76.0-next.
|
|
10
|
-
"@theia/bulk-edit": "1.76.0-next.
|
|
11
|
-
"@theia/callhierarchy": "1.76.0-next.
|
|
12
|
-
"@theia/console": "1.76.0-next.
|
|
13
|
-
"@theia/core": "1.76.0-next.
|
|
14
|
-
"@theia/debug": "1.76.0-next.
|
|
15
|
-
"@theia/editor": "1.76.0-next.
|
|
16
|
-
"@theia/editor-preview": "1.76.0-next.
|
|
17
|
-
"@theia/file-search": "1.76.0-next.
|
|
18
|
-
"@theia/filesystem": "1.76.0-next.
|
|
19
|
-
"@theia/markers": "1.76.0-next.
|
|
20
|
-
"@theia/messages": "1.76.0-next.
|
|
21
|
-
"@theia/monaco": "1.76.0-next.
|
|
8
|
+
"@theia/ai-core": "1.76.0-next.42+b0f9e63a6",
|
|
9
|
+
"@theia/ai-mcp": "1.76.0-next.42+b0f9e63a6",
|
|
10
|
+
"@theia/bulk-edit": "1.76.0-next.42+b0f9e63a6",
|
|
11
|
+
"@theia/callhierarchy": "1.76.0-next.42+b0f9e63a6",
|
|
12
|
+
"@theia/console": "1.76.0-next.42+b0f9e63a6",
|
|
13
|
+
"@theia/core": "1.76.0-next.42+b0f9e63a6",
|
|
14
|
+
"@theia/debug": "1.76.0-next.42+b0f9e63a6",
|
|
15
|
+
"@theia/editor": "1.76.0-next.42+b0f9e63a6",
|
|
16
|
+
"@theia/editor-preview": "1.76.0-next.42+b0f9e63a6",
|
|
17
|
+
"@theia/file-search": "1.76.0-next.42+b0f9e63a6",
|
|
18
|
+
"@theia/filesystem": "1.76.0-next.42+b0f9e63a6",
|
|
19
|
+
"@theia/markers": "1.76.0-next.42+b0f9e63a6",
|
|
20
|
+
"@theia/messages": "1.76.0-next.42+b0f9e63a6",
|
|
21
|
+
"@theia/monaco": "1.76.0-next.42+b0f9e63a6",
|
|
22
22
|
"@theia/monaco-editor-core": "1.108.201",
|
|
23
|
-
"@theia/navigator": "1.76.0-next.
|
|
24
|
-
"@theia/notebook": "1.76.0-next.
|
|
25
|
-
"@theia/output": "1.76.0-next.
|
|
26
|
-
"@theia/plugin": "1.76.0-next.
|
|
27
|
-
"@theia/plugin-utils": "1.76.0-next.
|
|
28
|
-
"@theia/preferences": "1.76.0-next.
|
|
29
|
-
"@theia/scm": "1.76.0-next.
|
|
30
|
-
"@theia/search-in-workspace": "1.76.0-next.
|
|
31
|
-
"@theia/task": "1.76.0-next.
|
|
32
|
-
"@theia/
|
|
33
|
-
"@theia/
|
|
34
|
-
"@theia/
|
|
35
|
-
"@theia/
|
|
36
|
-
"@theia/
|
|
37
|
-
"@theia/
|
|
23
|
+
"@theia/navigator": "1.76.0-next.42+b0f9e63a6",
|
|
24
|
+
"@theia/notebook": "1.76.0-next.42+b0f9e63a6",
|
|
25
|
+
"@theia/output": "1.76.0-next.42+b0f9e63a6",
|
|
26
|
+
"@theia/plugin": "1.76.0-next.42+b0f9e63a6",
|
|
27
|
+
"@theia/plugin-utils": "1.76.0-next.42+b0f9e63a6",
|
|
28
|
+
"@theia/preferences": "1.76.0-next.42+b0f9e63a6",
|
|
29
|
+
"@theia/scm": "1.76.0-next.42+b0f9e63a6",
|
|
30
|
+
"@theia/search-in-workspace": "1.76.0-next.42+b0f9e63a6",
|
|
31
|
+
"@theia/task": "1.76.0-next.42+b0f9e63a6",
|
|
32
|
+
"@theia/telemetry": "1.76.0-next.42+b0f9e63a6",
|
|
33
|
+
"@theia/terminal": "1.76.0-next.42+b0f9e63a6",
|
|
34
|
+
"@theia/test": "1.76.0-next.42+b0f9e63a6",
|
|
35
|
+
"@theia/timeline": "1.76.0-next.42+b0f9e63a6",
|
|
36
|
+
"@theia/typehierarchy": "1.76.0-next.42+b0f9e63a6",
|
|
37
|
+
"@theia/variable-resolver": "1.76.0-next.42+b0f9e63a6",
|
|
38
|
+
"@theia/workspace": "1.76.0-next.42+b0f9e63a6",
|
|
38
39
|
"@types/mime": "^2.0.3",
|
|
39
40
|
"@vscode/debugprotocol": "^1.68.0",
|
|
40
41
|
"@vscode/proxy-agent": "^0.13.2",
|
|
@@ -99,5 +100,5 @@
|
|
|
99
100
|
"nyc": {
|
|
100
101
|
"extends": "../../configs/nyc.json"
|
|
101
102
|
},
|
|
102
|
-
"gitHead": "
|
|
103
|
+
"gitHead": "b0f9e63a6d331135265869a341dce7c7f1eef158"
|
|
103
104
|
}
|
|
@@ -125,6 +125,7 @@ import * as notebookCommon from '@theia/notebook/lib/common';
|
|
|
125
125
|
import { CellExecutionUpdateType, CellRange, NotebookCellExecutionState } from '@theia/notebook/lib/common';
|
|
126
126
|
import { LanguagePackBundle } from './language-pack-service';
|
|
127
127
|
import { AccessibilityInformation } from '@theia/core/lib/common/accessibility';
|
|
128
|
+
import { TelemetryLevel } from '@theia/telemetry/lib/common/telemetry-types';
|
|
128
129
|
|
|
129
130
|
import { TreeDelta } from '@theia/test/lib/common/tree-delta';
|
|
130
131
|
import { TestItemDTO, TestOutputDTO, TestRunDTO, TestRunProfileDTO, TestRunRequestDTO, TestStateChangeDTO } from './test-types';
|
|
@@ -258,6 +259,12 @@ export interface PluginManagerInitializeParams {
|
|
|
258
259
|
webview: WebviewInitData
|
|
259
260
|
jsonValidation: PluginJsonValidationContribution[]
|
|
260
261
|
supportedActivationEvents?: string[]
|
|
262
|
+
/**
|
|
263
|
+
* The telemetry level the plugin host starts with. Defaults to `off` when absent.
|
|
264
|
+
*
|
|
265
|
+
* @experimental
|
|
266
|
+
*/
|
|
267
|
+
telemetryLevel?: TelemetryLevel
|
|
261
268
|
}
|
|
262
269
|
|
|
263
270
|
export interface PluginManagerStartParams {
|
|
@@ -2362,6 +2369,13 @@ export interface TelemetryMain {
|
|
|
2362
2369
|
}
|
|
2363
2370
|
|
|
2364
2371
|
export interface TelemetryExt {
|
|
2372
|
+
/**
|
|
2373
|
+
* Applies the telemetry level the user consented to. Only changes are sent this way;
|
|
2374
|
+
* the initial level arrives with `PluginManagerInitializeParams`.
|
|
2375
|
+
*
|
|
2376
|
+
* @experimental
|
|
2377
|
+
*/
|
|
2378
|
+
$onDidChangeTelemetryLevel(level: TelemetryLevel): void;
|
|
2365
2379
|
}
|
|
2366
2380
|
|
|
2367
2381
|
// endregion
|
|
@@ -2524,7 +2538,7 @@ export const MAIN_RPC_CONTEXT = {
|
|
|
2524
2538
|
THEMING_EXT: createProxyIdentifier<ThemingExt>('ThemingExt'),
|
|
2525
2539
|
COMMENTS_EXT: createProxyIdentifier<CommentsExt>('CommentsExt'),
|
|
2526
2540
|
TABS_EXT: createProxyIdentifier<TabsExt>('TabsExt'),
|
|
2527
|
-
TELEMETRY_EXT: createProxyIdentifier<TelemetryExt>('TelemetryExt
|
|
2541
|
+
TELEMETRY_EXT: createProxyIdentifier<TelemetryExt>('TelemetryExt'),
|
|
2528
2542
|
TESTING_EXT: createProxyIdentifier<TestingExt>('TestingExt'),
|
|
2529
2543
|
URI_EXT: createProxyIdentifier<UriExt>('UriExt'),
|
|
2530
2544
|
MCP_SERVER_DEFINITION_REGISTRY_EXT: createProxyIdentifier<McpServerDefinitionRegistryExt>('McpServerDefinitionRegistryExt'),
|
|
@@ -73,6 +73,7 @@ import {
|
|
|
73
73
|
} from '../common/hosted-plugin';
|
|
74
74
|
import { isRemote } from '@theia/core/lib/browser/browser';
|
|
75
75
|
import { WorkspaceTrustService } from '@theia/workspace/lib/browser/workspace-trust-service';
|
|
76
|
+
import { TelemetryConsentProvider } from '@theia/telemetry/lib/common/telemetry-consent-provider';
|
|
76
77
|
|
|
77
78
|
export type DebugActivationEvent = 'onDebugResolve' | 'onDebugInitialConfigurations' | 'onDebugAdapterProtocolTracker' | 'onDebugDynamicConfigurations';
|
|
78
79
|
|
|
@@ -183,6 +184,9 @@ export class HostedPluginSupport extends AbstractHostedPluginSupport<PluginManag
|
|
|
183
184
|
@inject(WorkspaceTrustService)
|
|
184
185
|
protected readonly workspaceTrustService: WorkspaceTrustService;
|
|
185
186
|
|
|
187
|
+
@inject(TelemetryConsentProvider)
|
|
188
|
+
protected readonly telemetryConsentProvider: TelemetryConsentProvider;
|
|
189
|
+
|
|
186
190
|
@inject(ILogger) @named('plugin-ext:HostedPluginSupport')
|
|
187
191
|
protected override readonly logger: ILogger;
|
|
188
192
|
|
|
@@ -245,7 +249,7 @@ export class HostedPluginSupport extends AbstractHostedPluginSupport<PluginManag
|
|
|
245
249
|
}
|
|
246
250
|
|
|
247
251
|
protected createTheiaReadyPromise(): Promise<unknown> {
|
|
248
|
-
return Promise.all([this.preferenceServiceImpl.ready, this.workspaceService.roots]);
|
|
252
|
+
return Promise.all([this.preferenceServiceImpl.ready, this.workspaceService.roots, this.telemetryConsentProvider.ready]);
|
|
249
253
|
}
|
|
250
254
|
|
|
251
255
|
protected override runOperation(operation: () => Promise<void>): Promise<void> {
|
|
@@ -364,7 +368,8 @@ export class HostedPluginSupport extends AbstractHostedPluginSupport<PluginManag
|
|
|
364
368
|
},
|
|
365
369
|
jsonValidation,
|
|
366
370
|
pluginKind: isRemote ? ExtensionKind.Workspace : ExtensionKind.UI,
|
|
367
|
-
supportedActivationEvents
|
|
371
|
+
supportedActivationEvents,
|
|
372
|
+
telemetryLevel: this.telemetryConsentProvider.level
|
|
368
373
|
});
|
|
369
374
|
if (toDisconnect.disposed) {
|
|
370
375
|
return undefined;
|
|
@@ -34,6 +34,7 @@ import { loadManifest } from './plugin-manifest-loader';
|
|
|
34
34
|
import { EnvExtImpl } from '../../../plugin/env';
|
|
35
35
|
import { DebugExtImpl } from '../../../plugin/debug/debug-ext';
|
|
36
36
|
import { LocalizationExtImpl } from '../../../plugin/localization-ext';
|
|
37
|
+
import { TelemetryExtImpl } from '../../../plugin/telemetry-ext';
|
|
37
38
|
import pluginHostModule from './worker-plugin-module';
|
|
38
39
|
import { PLUGINS_BASE_PATH } from '@theia/plugin-utils/lib/common/constants';
|
|
39
40
|
|
|
@@ -162,6 +163,7 @@ const messageRegistryExt = container.get(MessageRegistryExt);
|
|
|
162
163
|
const clipboardExt = container.get(ClipboardExt);
|
|
163
164
|
const webviewExt = container.get(WebviewsExtImpl);
|
|
164
165
|
const localizationExt = container.get(LocalizationExtImpl);
|
|
166
|
+
const telemetryExt = container.get(TelemetryExtImpl);
|
|
165
167
|
const storageProxy = container.get(KeyValueStorageProxy);
|
|
166
168
|
|
|
167
169
|
const apiFactory = createAPIFactory(
|
|
@@ -175,7 +177,8 @@ const apiFactory = createAPIFactory(
|
|
|
175
177
|
messageRegistryExt,
|
|
176
178
|
clipboardExt,
|
|
177
179
|
webviewExt,
|
|
178
|
-
localizationExt
|
|
180
|
+
localizationExt,
|
|
181
|
+
telemetryExt
|
|
179
182
|
);
|
|
180
183
|
let defaultApi: typeof theia;
|
|
181
184
|
|
|
@@ -36,6 +36,7 @@ import { WorkerEnvExtImpl } from './worker-env-ext';
|
|
|
36
36
|
import { DebugExtImpl } from '../../../plugin/debug/debug-ext';
|
|
37
37
|
import { LocalizationExtImpl } from '../../../plugin/localization-ext';
|
|
38
38
|
import { EncodingService } from '@theia/core/lib/common/encoding-service';
|
|
39
|
+
import { TelemetryExtImpl } from '../../../plugin/telemetry-ext';
|
|
39
40
|
|
|
40
41
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
41
42
|
const ctx = self as any;
|
|
@@ -79,4 +80,5 @@ export default new ContainerModule(bind => {
|
|
|
79
80
|
bind(WebviewsExtImpl).toSelf().inSingletonScope();
|
|
80
81
|
bind(TerminalServiceExtImpl).toSelf().inSingletonScope();
|
|
81
82
|
bind(MinimalTerminalServiceExt).toService(TerminalServiceExtImpl);
|
|
83
|
+
bind(TelemetryExtImpl).toSelf().inSingletonScope();
|
|
82
84
|
});
|
|
@@ -39,6 +39,7 @@ import { setupPluginHostLogger } from './plugin-host-logger';
|
|
|
39
39
|
import { LmExtImpl } from '../../plugin/lm-ext';
|
|
40
40
|
import { LanguageModelToolsExtImpl } from '../../plugin/lm-tool-ext';
|
|
41
41
|
import { EncodingService } from '@theia/core/lib/common/encoding-service';
|
|
42
|
+
import { TelemetryExtImpl } from '../../plugin/telemetry-ext';
|
|
42
43
|
|
|
43
44
|
export default new ContainerModule(bind => {
|
|
44
45
|
const channel = new IPCChannel();
|
|
@@ -76,4 +77,5 @@ export default new ContainerModule(bind => {
|
|
|
76
77
|
bind(WebviewsExtImpl).toSelf().inSingletonScope();
|
|
77
78
|
bind(MinimalTerminalServiceExt).toService(TerminalServiceExtImpl);
|
|
78
79
|
bind(TerminalServiceExtImpl).toSelf().inSingletonScope();
|
|
80
|
+
bind(TelemetryExtImpl).toSelf().inSingletonScope();
|
|
79
81
|
});
|
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
import { PluginMetadata, PluginModel, PluginPackage } from '../../common/plugin-protocol';
|
|
32
32
|
import { createAPIFactory } from '../../plugin/plugin-context';
|
|
33
33
|
import { EnvExtImpl } from '../../plugin/env';
|
|
34
|
+
import { TelemetryExtImpl } from '../../plugin/telemetry-ext';
|
|
34
35
|
import { PreferenceRegistryExtImpl } from '../../plugin/preference-registry';
|
|
35
36
|
import { ExtPluginApi, ExtPluginApiBackendInitializationFn } from '../../common/plugin-ext-api-contribution';
|
|
36
37
|
import { DebugExtImpl } from '../../plugin/debug/debug-ext';
|
|
@@ -64,7 +65,8 @@ export interface ExtInterfaces {
|
|
|
64
65
|
webviewExt: WebviewsExtImpl,
|
|
65
66
|
terminalServiceExt: TerminalServiceExtImpl,
|
|
66
67
|
secretsExt: SecretsExtImpl,
|
|
67
|
-
localizationExt: LocalizationExtImpl
|
|
68
|
+
localizationExt: LocalizationExtImpl,
|
|
69
|
+
telemetryExt: TelemetryExtImpl
|
|
68
70
|
}
|
|
69
71
|
|
|
70
72
|
/**
|
|
@@ -352,6 +354,9 @@ export class PluginHostRPC extends AbstractPluginHostRPC<PluginManagerExtImpl, P
|
|
|
352
354
|
@inject(SecretsExtImpl)
|
|
353
355
|
protected readonly secretsExt: SecretsExtImpl;
|
|
354
356
|
|
|
357
|
+
@inject(TelemetryExtImpl)
|
|
358
|
+
protected readonly telemetryExt: TelemetryExtImpl;
|
|
359
|
+
|
|
355
360
|
constructor() {
|
|
356
361
|
super('PLUGIN_HOST', '/scanners/backend-init-theia.js',
|
|
357
362
|
{
|
|
@@ -380,18 +385,19 @@ export class PluginHostRPC extends AbstractPluginHostRPC<PluginManagerExtImpl, P
|
|
|
380
385
|
webviewExt: this.webviewExt,
|
|
381
386
|
terminalServiceExt: this.terminalServiceExt,
|
|
382
387
|
secretsExt: this.secretsExt,
|
|
383
|
-
localizationExt: this.localizationExt
|
|
388
|
+
localizationExt: this.localizationExt,
|
|
389
|
+
telemetryExt: this.telemetryExt
|
|
384
390
|
};
|
|
385
391
|
}
|
|
386
392
|
|
|
387
393
|
protected createAPIFactory(extInterfaces: ExtInterfaces): PluginAPIFactory {
|
|
388
394
|
const {
|
|
389
395
|
envExt, debugExt, preferenceRegistryExt, editorsAndDocumentsExt, workspaceExt,
|
|
390
|
-
messageRegistryExt, clipboardExt, webviewExt, localizationExt
|
|
396
|
+
messageRegistryExt, clipboardExt, webviewExt, localizationExt, telemetryExt
|
|
391
397
|
} = extInterfaces;
|
|
392
398
|
return createAPIFactory(this.rpc, this.pluginManager, envExt, debugExt, preferenceRegistryExt,
|
|
393
399
|
editorsAndDocumentsExt, workspaceExt, messageRegistryExt, clipboardExt, webviewExt,
|
|
394
|
-
localizationExt);
|
|
400
|
+
localizationExt, telemetryExt);
|
|
395
401
|
}
|
|
396
402
|
|
|
397
403
|
protected initExtApi(extApi: ExtPluginApi): void {
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2026 JuliaHub, Inc. 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
|
+
// https://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 { enableJSDOM } from '@theia/core/lib/browser/test/jsdom';
|
|
18
|
+
let disableJSDOM = enableJSDOM();
|
|
19
|
+
|
|
20
|
+
import { expect } from 'chai';
|
|
21
|
+
import { Emitter, URI } from '@theia/core';
|
|
22
|
+
import { BaseWidget, Navigatable, Saveable, SaveableSource, Widget } from '@theia/core/lib/browser';
|
|
23
|
+
import { SaveableService } from '@theia/core/lib/browser/saveable-service';
|
|
24
|
+
import { EditorManager, EditorWidget } from '@theia/editor/lib/browser';
|
|
25
|
+
import { EditorsAndDocumentsMain } from './editors-and-documents-main';
|
|
26
|
+
|
|
27
|
+
disableJSDOM();
|
|
28
|
+
|
|
29
|
+
class TestSaveable implements Saveable {
|
|
30
|
+
dirty = true;
|
|
31
|
+
readonly onDirtyChanged = new Emitter<void>().event;
|
|
32
|
+
readonly onContentChanged = new Emitter<void>().event;
|
|
33
|
+
saveCount = 0;
|
|
34
|
+
|
|
35
|
+
async save(): Promise<void> {
|
|
36
|
+
this.saveCount++;
|
|
37
|
+
this.dirty = false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Navigatable to the resource, but with nothing to save. */
|
|
42
|
+
class TestNavigatableWidget extends BaseWidget implements Navigatable {
|
|
43
|
+
constructor(private readonly uri: URI) {
|
|
44
|
+
super();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
getResourceUri(): URI {
|
|
48
|
+
return this.uri;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
createMoveToUri(): URI {
|
|
52
|
+
return this.uri;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Stands in for a `CustomEditorWidget`: saveable and navigatable, but not an `EditorWidget`. */
|
|
57
|
+
class TestSaveableWidget extends TestNavigatableWidget implements SaveableSource {
|
|
58
|
+
readonly saveable = new TestSaveable();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function createEditorsAndDocumentsMain(
|
|
62
|
+
editor: EditorWidget | undefined,
|
|
63
|
+
widgets: Widget[]
|
|
64
|
+
): EditorsAndDocumentsMain {
|
|
65
|
+
// Bypass the constructor's RPC/container wiring: `save` and `saveAs` only touch the
|
|
66
|
+
// editor manager, the shell and the saveable service.
|
|
67
|
+
const main = Object.create(EditorsAndDocumentsMain.prototype) as EditorsAndDocumentsMain;
|
|
68
|
+
const fields = main as unknown as Record<string, unknown>;
|
|
69
|
+
fields.editorManager = { getByUri: async () => editor } as unknown as EditorManager;
|
|
70
|
+
fields.shell = { widgets };
|
|
71
|
+
fields.saveResourceService = new SaveableService();
|
|
72
|
+
return main;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
describe('EditorsAndDocumentsMain#save', () => {
|
|
76
|
+
|
|
77
|
+
before(() => {
|
|
78
|
+
disableJSDOM = enableJSDOM();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
after(() => {
|
|
82
|
+
disableJSDOM();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const uri = new URI('custom-editor:/some/resource?viewType=test');
|
|
86
|
+
|
|
87
|
+
it('saves a saveable widget that the editor manager does not know', async () => {
|
|
88
|
+
const widget = new TestSaveableWidget(uri);
|
|
89
|
+
const main = createEditorsAndDocumentsMain(undefined, [widget]);
|
|
90
|
+
|
|
91
|
+
const saved = await main.save(uri);
|
|
92
|
+
|
|
93
|
+
expect(widget.saveable.saveCount).to.equal(1);
|
|
94
|
+
expect(saved?.toString()).to.equal(uri.toString());
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('prefers the text editor when the editor manager has one', async () => {
|
|
98
|
+
const editor = new TestSaveableWidget(uri);
|
|
99
|
+
const custom = new TestSaveableWidget(uri);
|
|
100
|
+
const main = createEditorsAndDocumentsMain(editor as unknown as EditorWidget, [custom]);
|
|
101
|
+
|
|
102
|
+
await main.save(uri);
|
|
103
|
+
|
|
104
|
+
expect(editor.saveable.saveCount).to.equal(1);
|
|
105
|
+
expect(custom.saveable.saveCount).to.equal(0);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('leaves widgets bound to another resource alone', async () => {
|
|
109
|
+
const other = new TestSaveableWidget(new URI('custom-editor:/other/resource'));
|
|
110
|
+
const main = createEditorsAndDocumentsMain(undefined, [other]);
|
|
111
|
+
|
|
112
|
+
const saved = await main.save(uri);
|
|
113
|
+
|
|
114
|
+
expect(other.saveable.saveCount).to.equal(0);
|
|
115
|
+
expect(saved).to.be.undefined;
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('ignores a widget that is navigatable to the resource but not saveable', async () => {
|
|
119
|
+
const main = createEditorsAndDocumentsMain(undefined, [new TestNavigatableWidget(uri)]);
|
|
120
|
+
|
|
121
|
+
expect(await main.save(uri)).to.be.undefined;
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('resolves saveAs through the same fallback', async () => {
|
|
125
|
+
const widget = new TestSaveableWidget(uri);
|
|
126
|
+
const main = createEditorsAndDocumentsMain(undefined, [widget]);
|
|
127
|
+
const saveAsTargets: Widget[] = [];
|
|
128
|
+
// `SaveableService.canSaveAs` is unconditionally false on the base class, so the
|
|
129
|
+
// service is stubbed to reach the `saveAs` branch at all.
|
|
130
|
+
(main as unknown as Record<string, unknown>).saveResourceService = {
|
|
131
|
+
canSaveAs: (candidate: Widget) => candidate === widget,
|
|
132
|
+
saveAs: async (target: Widget) => { saveAsTargets.push(target); return uri; }
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
const saved = await main.saveAs(uri);
|
|
136
|
+
|
|
137
|
+
expect(saveAsTargets).to.deep.equal([widget]);
|
|
138
|
+
expect(saved?.toString()).to.equal(uri.toString());
|
|
139
|
+
});
|
|
140
|
+
});
|
|
@@ -33,6 +33,7 @@ import { MonacoEditor } from '@theia/monaco/lib/browser/monaco-editor';
|
|
|
33
33
|
import { TextEditorMain } from './text-editor-main';
|
|
34
34
|
import { DisposableCollection, Emitter, URI } from '@theia/core';
|
|
35
35
|
import { EditorManager, EditorWidget } from '@theia/editor/lib/browser';
|
|
36
|
+
import { ApplicationShell, NavigatableWidget, Saveable, Widget } from '@theia/core/lib/browser';
|
|
36
37
|
import { SaveableService } from '@theia/core/lib/browser/saveable-service';
|
|
37
38
|
import { TabsMainImpl } from './tabs/tabs-main';
|
|
38
39
|
import { NotebookCellEditorService, NotebookEditorWidgetService } from '@theia/notebook/lib/browser';
|
|
@@ -48,6 +49,7 @@ export class EditorsAndDocumentsMain implements Disposable {
|
|
|
48
49
|
|
|
49
50
|
private readonly modelService: EditorModelService;
|
|
50
51
|
private readonly editorManager: EditorManager;
|
|
52
|
+
private readonly shell: ApplicationShell;
|
|
51
53
|
private readonly saveResourceService: SaveableService;
|
|
52
54
|
private readonly encodingRegistry: EncodingRegistry;
|
|
53
55
|
|
|
@@ -69,6 +71,7 @@ export class EditorsAndDocumentsMain implements Disposable {
|
|
|
69
71
|
this.proxy = rpc.getProxy(MAIN_RPC_CONTEXT.EDITORS_AND_DOCUMENTS_EXT);
|
|
70
72
|
|
|
71
73
|
this.editorManager = container.get(EditorManager);
|
|
74
|
+
this.shell = container.get(ApplicationShell);
|
|
72
75
|
this.modelService = container.get(EditorModelService);
|
|
73
76
|
this.saveResourceService = container.get(SaveableService);
|
|
74
77
|
this.encodingRegistry = container.get(EncodingRegistry);
|
|
@@ -183,22 +186,31 @@ export class EditorsAndDocumentsMain implements Disposable {
|
|
|
183
186
|
}
|
|
184
187
|
|
|
185
188
|
async save(uri: URI): Promise<URI | undefined> {
|
|
186
|
-
const
|
|
187
|
-
if (!
|
|
189
|
+
const widget = await this.getSaveTarget(uri);
|
|
190
|
+
if (!widget) {
|
|
188
191
|
return undefined;
|
|
189
192
|
}
|
|
190
|
-
return this.saveResourceService.save(
|
|
193
|
+
return this.saveResourceService.save(widget);
|
|
191
194
|
}
|
|
192
195
|
|
|
193
196
|
async saveAs(uri: URI): Promise<URI | undefined> {
|
|
194
|
-
const
|
|
195
|
-
if (!
|
|
197
|
+
const widget = await this.getSaveTarget(uri);
|
|
198
|
+
if (!widget) {
|
|
196
199
|
return undefined;
|
|
197
200
|
}
|
|
198
|
-
if (!this.saveResourceService.canSaveAs(
|
|
201
|
+
if (!this.saveResourceService.canSaveAs(widget)) {
|
|
199
202
|
return undefined;
|
|
200
203
|
}
|
|
201
|
-
return this.saveResourceService.saveAs(
|
|
204
|
+
return this.saveResourceService.saveAs(widget);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Resolve the widget holding `uri`, preferring a text editor. Custom editors and notebooks
|
|
209
|
+
* are not opened by the `EditorManager`, so they are only reachable through the shell.
|
|
210
|
+
*/
|
|
211
|
+
protected async getSaveTarget(uri: URI): Promise<Widget | undefined> {
|
|
212
|
+
return await this.editorManager.getByUri(uri)
|
|
213
|
+
?? this.shell.widgets.find(widget => Saveable.get(widget) && NavigatableWidget.getUri(widget)?.isEqual(uri));
|
|
202
214
|
}
|
|
203
215
|
|
|
204
216
|
saveAll(includeUntitled?: boolean): Promise<boolean> {
|