@theia/plugin-ext 1.71.0-next.6 → 1.71.0-next.72
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 +5 -0
- package/lib/common/plugin-api-rpc.d.ts.map +1 -1
- package/lib/common/plugin-api-rpc.js +1 -0
- package/lib/common/plugin-api-rpc.js.map +1 -1
- package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
- package/lib/hosted/browser/hosted-plugin.js +13 -6
- package/lib/hosted/browser/hosted-plugin.js.map +1 -1
- package/lib/main/browser/main-context.d.ts.map +1 -1
- package/lib/main/browser/main-context.js +2 -6
- package/lib/main/browser/main-context.js.map +1 -1
- package/lib/main/browser/main-file-system-event-service.d.ts +10 -2
- package/lib/main/browser/main-file-system-event-service.d.ts.map +1 -1
- package/lib/main/browser/main-file-system-event-service.js +19 -2
- package/lib/main/browser/main-file-system-event-service.js.map +1 -1
- package/lib/main/browser/menus/plugin-menu-command-adapter.js +1 -1
- package/lib/main/browser/menus/plugin-menu-command-adapter.js.map +1 -1
- package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts +1 -1
- package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts.map +1 -1
- package/lib/main/browser/menus/vscode-theia-menu-mappings.js +2 -2
- package/lib/main/browser/menus/vscode-theia-menu-mappings.js.map +1 -1
- package/lib/main/browser/scm-main.d.ts.map +1 -1
- package/lib/main/browser/scm-main.js +24 -1
- package/lib/main/browser/scm-main.js.map +1 -1
- package/lib/main/browser/scm-main.spec.d.ts +2 -0
- package/lib/main/browser/scm-main.spec.d.ts.map +1 -0
- package/lib/main/browser/scm-main.spec.js +87 -0
- package/lib/main/browser/scm-main.spec.js.map +1 -0
- package/lib/main/browser/test-main.d.ts +3 -2
- package/lib/main/browser/test-main.d.ts.map +1 -1
- package/lib/main/browser/test-main.js +12 -1
- package/lib/main/browser/test-main.js.map +1 -1
- package/lib/plugin/file-system-event-service-ext-impl.d.ts +11 -5
- package/lib/plugin/file-system-event-service-ext-impl.d.ts.map +1 -1
- package/lib/plugin/file-system-event-service-ext-impl.js +28 -9
- package/lib/plugin/file-system-event-service-ext-impl.js.map +1 -1
- package/lib/plugin/plugin-context.js +4 -4
- package/lib/plugin/plugin-context.js.map +1 -1
- package/lib/plugin/scm.d.ts +1 -1
- package/lib/plugin/scm.d.ts.map +1 -1
- package/lib/plugin/scm.js +23 -5
- package/lib/plugin/scm.js.map +1 -1
- package/lib/plugin/terminal-ext.d.ts +13 -3
- package/lib/plugin/terminal-ext.d.ts.map +1 -1
- package/lib/plugin/terminal-ext.js +51 -10
- package/lib/plugin/terminal-ext.js.map +1 -1
- package/lib/plugin/terminal-ext.spec.d.ts +2 -0
- package/lib/plugin/terminal-ext.spec.d.ts.map +1 -0
- package/lib/plugin/terminal-ext.spec.js +285 -0
- package/lib/plugin/terminal-ext.spec.js.map +1 -0
- package/lib/plugin/test-item.d.ts.map +1 -1
- package/lib/plugin/test-item.js +8 -3
- package/lib/plugin/test-item.js.map +1 -1
- package/lib/plugin/tests.d.ts.map +1 -1
- package/lib/plugin/tests.js +15 -3
- package/lib/plugin/tests.js.map +1 -1
- package/lib/plugin/type-converters.d.ts +2 -2
- package/lib/plugin/type-converters.d.ts.map +1 -1
- package/lib/plugin/type-converters.js +3 -9
- package/lib/plugin/type-converters.js.map +1 -1
- package/lib/plugin/types-impl.d.ts +1 -1
- package/lib/plugin/types-impl.d.ts.map +1 -1
- package/lib/plugin/types-impl.js +1 -1
- package/lib/plugin/types-impl.js.map +1 -1
- package/lib/plugin/workspace.d.ts.map +1 -1
- package/lib/plugin/workspace.js +17 -3
- package/lib/plugin/workspace.js.map +1 -1
- package/package.json +38 -38
- package/src/common/plugin-api-rpc.ts +6 -0
- package/src/hosted/browser/hosted-plugin.ts +13 -6
- package/src/main/browser/main-context.ts +3 -7
- package/src/main/browser/main-file-system-event-service.ts +26 -6
- package/src/main/browser/menus/plugin-menu-command-adapter.ts +1 -1
- package/src/main/browser/menus/vscode-theia-menu-mappings.ts +3 -3
- package/src/main/browser/scm-main.spec.ts +105 -0
- package/src/main/browser/scm-main.ts +25 -1
- package/src/main/browser/test-main.ts +13 -3
- package/src/plugin/file-system-event-service-ext-impl.ts +40 -14
- package/src/plugin/plugin-context.ts +7 -7
- package/src/plugin/scm.ts +26 -4
- package/src/plugin/terminal-ext.spec.ts +350 -0
- package/src/plugin/terminal-ext.ts +58 -12
- package/src/plugin/test-item.ts +8 -3
- package/src/plugin/tests.ts +14 -3
- package/src/plugin/type-converters.ts +7 -13
- package/src/plugin/types-impl.ts +2 -2
- package/src/plugin/workspace.ts +17 -3
package/package.json
CHANGED
|
@@ -1,55 +1,55 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theia/plugin-ext",
|
|
3
|
-
"version": "1.71.0-next.
|
|
3
|
+
"version": "1.71.0-next.72+95c8dba0e",
|
|
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-mcp": "1.71.0-next.
|
|
9
|
-
"@theia/bulk-edit": "1.71.0-next.
|
|
10
|
-
"@theia/callhierarchy": "1.71.0-next.
|
|
11
|
-
"@theia/console": "1.71.0-next.
|
|
12
|
-
"@theia/core": "1.71.0-next.
|
|
13
|
-
"@theia/debug": "1.71.0-next.
|
|
14
|
-
"@theia/editor": "1.71.0-next.
|
|
15
|
-
"@theia/editor-preview": "1.71.0-next.
|
|
16
|
-
"@theia/file-search": "1.71.0-next.
|
|
17
|
-
"@theia/filesystem": "1.71.0-next.
|
|
18
|
-
"@theia/markers": "1.71.0-next.
|
|
19
|
-
"@theia/messages": "1.71.0-next.
|
|
20
|
-
"@theia/monaco": "1.71.0-next.
|
|
8
|
+
"@theia/ai-mcp": "1.71.0-next.72+95c8dba0e",
|
|
9
|
+
"@theia/bulk-edit": "1.71.0-next.72+95c8dba0e",
|
|
10
|
+
"@theia/callhierarchy": "1.71.0-next.72+95c8dba0e",
|
|
11
|
+
"@theia/console": "1.71.0-next.72+95c8dba0e",
|
|
12
|
+
"@theia/core": "1.71.0-next.72+95c8dba0e",
|
|
13
|
+
"@theia/debug": "1.71.0-next.72+95c8dba0e",
|
|
14
|
+
"@theia/editor": "1.71.0-next.72+95c8dba0e",
|
|
15
|
+
"@theia/editor-preview": "1.71.0-next.72+95c8dba0e",
|
|
16
|
+
"@theia/file-search": "1.71.0-next.72+95c8dba0e",
|
|
17
|
+
"@theia/filesystem": "1.71.0-next.72+95c8dba0e",
|
|
18
|
+
"@theia/markers": "1.71.0-next.72+95c8dba0e",
|
|
19
|
+
"@theia/messages": "1.71.0-next.72+95c8dba0e",
|
|
20
|
+
"@theia/monaco": "1.71.0-next.72+95c8dba0e",
|
|
21
21
|
"@theia/monaco-editor-core": "1.108.201",
|
|
22
|
-
"@theia/navigator": "1.71.0-next.
|
|
23
|
-
"@theia/notebook": "1.71.0-next.
|
|
24
|
-
"@theia/output": "1.71.0-next.
|
|
25
|
-
"@theia/plugin": "1.71.0-next.
|
|
26
|
-
"@theia/preferences": "1.71.0-next.
|
|
27
|
-
"@theia/scm": "1.71.0-next.
|
|
28
|
-
"@theia/search-in-workspace": "1.71.0-next.
|
|
29
|
-
"@theia/task": "1.71.0-next.
|
|
30
|
-
"@theia/terminal": "1.71.0-next.
|
|
31
|
-
"@theia/test": "1.71.0-next.
|
|
32
|
-
"@theia/timeline": "1.71.0-next.
|
|
33
|
-
"@theia/typehierarchy": "1.71.0-next.
|
|
34
|
-
"@theia/variable-resolver": "1.71.0-next.
|
|
35
|
-
"@theia/workspace": "1.71.0-next.
|
|
36
|
-
"@types/mime": "^2.0.
|
|
37
|
-
"@vscode/debugprotocol": "^1.
|
|
22
|
+
"@theia/navigator": "1.71.0-next.72+95c8dba0e",
|
|
23
|
+
"@theia/notebook": "1.71.0-next.72+95c8dba0e",
|
|
24
|
+
"@theia/output": "1.71.0-next.72+95c8dba0e",
|
|
25
|
+
"@theia/plugin": "1.71.0-next.72+95c8dba0e",
|
|
26
|
+
"@theia/preferences": "1.71.0-next.72+95c8dba0e",
|
|
27
|
+
"@theia/scm": "1.71.0-next.72+95c8dba0e",
|
|
28
|
+
"@theia/search-in-workspace": "1.71.0-next.72+95c8dba0e",
|
|
29
|
+
"@theia/task": "1.71.0-next.72+95c8dba0e",
|
|
30
|
+
"@theia/terminal": "1.71.0-next.72+95c8dba0e",
|
|
31
|
+
"@theia/test": "1.71.0-next.72+95c8dba0e",
|
|
32
|
+
"@theia/timeline": "1.71.0-next.72+95c8dba0e",
|
|
33
|
+
"@theia/typehierarchy": "1.71.0-next.72+95c8dba0e",
|
|
34
|
+
"@theia/variable-resolver": "1.71.0-next.72+95c8dba0e",
|
|
35
|
+
"@theia/workspace": "1.71.0-next.72+95c8dba0e",
|
|
36
|
+
"@types/mime": "^2.0.3",
|
|
37
|
+
"@vscode/debugprotocol": "^1.68.0",
|
|
38
38
|
"@vscode/proxy-agent": "^0.13.2",
|
|
39
|
-
"async-mutex": "^0.4.
|
|
39
|
+
"async-mutex": "^0.4.1",
|
|
40
40
|
"decompress": "^4.2.1",
|
|
41
41
|
"escape-html": "^1.0.3",
|
|
42
|
-
"filenamify": "^4.
|
|
42
|
+
"filenamify": "^4.3.0",
|
|
43
43
|
"is-electron": "^2.2.0",
|
|
44
|
-
"jsonc-parser": "^2.
|
|
44
|
+
"jsonc-parser": "^2.3.1",
|
|
45
45
|
"lodash.clonedeep": "^4.5.0",
|
|
46
|
-
"macaddress": "^0.5.
|
|
47
|
-
"mime": "^2.
|
|
46
|
+
"macaddress": "^0.5.4",
|
|
47
|
+
"mime": "^2.6.0",
|
|
48
48
|
"node-pty": "1.2.0-beta.12",
|
|
49
|
-
"semver": "^7.
|
|
49
|
+
"semver": "^7.7.4",
|
|
50
50
|
"tslib": "^2.6.2",
|
|
51
51
|
"vhost": "^3.0.2",
|
|
52
|
-
"vscode-textmate": "^9.2
|
|
52
|
+
"vscode-textmate": "^9.3.2"
|
|
53
53
|
},
|
|
54
54
|
"publishConfig": {
|
|
55
55
|
"access": "public"
|
|
@@ -97,5 +97,5 @@
|
|
|
97
97
|
"nyc": {
|
|
98
98
|
"extends": "../../configs/nyc.json"
|
|
99
99
|
},
|
|
100
|
-
"gitHead": "
|
|
100
|
+
"gitHead": "95c8dba0ee6349c6be262ac2cf383909a3b62761"
|
|
101
101
|
}
|
|
@@ -2120,6 +2120,11 @@ export interface ExtHostFileSystemEventServiceShape {
|
|
|
2120
2120
|
$onDidRunFileOperation(operation: files.FileOperation, target: UriComponents, source: UriComponents | undefined): void;
|
|
2121
2121
|
}
|
|
2122
2122
|
|
|
2123
|
+
export interface MainFileSystemEventServiceShape {
|
|
2124
|
+
$watch(session: number, resource: UriComponents, opts: files.WatchOptions): void;
|
|
2125
|
+
$unwatch(session: number): void;
|
|
2126
|
+
}
|
|
2127
|
+
|
|
2123
2128
|
export interface ClipboardMain {
|
|
2124
2129
|
$readText(): Promise<string>;
|
|
2125
2130
|
$writeText(value: string): Promise<void>;
|
|
@@ -2384,6 +2389,7 @@ export const PLUGIN_RPC_CONTEXT = {
|
|
|
2384
2389
|
TASKS_MAIN: createProxyIdentifier<TasksMain>('TasksMain'),
|
|
2385
2390
|
DEBUG_MAIN: createProxyIdentifier<DebugMain>('DebugMain'),
|
|
2386
2391
|
FILE_SYSTEM_MAIN: createProxyIdentifier<FileSystemMain>('FileSystemMain'),
|
|
2392
|
+
FILE_SYSTEM_EVENT_SERVICE_MAIN: createProxyIdentifier<MainFileSystemEventServiceShape>('FileSystemEventServiceMain'),
|
|
2387
2393
|
SCM_MAIN: createProxyIdentifier<ScmMain>('ScmMain'),
|
|
2388
2394
|
SECRETS_MAIN: createProxyIdentifier<SecretsMain>('SecretsMain'),
|
|
2389
2395
|
DECORATIONS_MAIN: createProxyIdentifier<DecorationsMain>('DecorationsMain'),
|
|
@@ -267,10 +267,12 @@ export class HostedPluginSupport extends AbstractHostedPluginSupport<PluginManag
|
|
|
267
267
|
}
|
|
268
268
|
|
|
269
269
|
protected override async beforeLoadContributions(toDisconnect: DisposableCollection): Promise<void> {
|
|
270
|
-
//
|
|
271
|
-
//
|
|
272
|
-
//
|
|
273
|
-
|
|
270
|
+
// Make sure the shell is attached so that registries (commands, menus, views, etc.)
|
|
271
|
+
// are ready to accept contributions. We intentionally do NOT wait for initialized_layout
|
|
272
|
+
// here, because layout restoration may depend on plugin-provided file system providers
|
|
273
|
+
// (e.g. git: scheme for merge editors), and those providers are registered during
|
|
274
|
+
// startPlugins which runs after this point. Waiting for initialized_layout would deadlock.
|
|
275
|
+
await this.appState.reachedState('attached_shell');
|
|
274
276
|
this.workspaceTrusted = await this.workspaceTrustService.getWorkspaceTrust();
|
|
275
277
|
}
|
|
276
278
|
|
|
@@ -464,12 +466,17 @@ export class HostedPluginSupport extends AbstractHostedPluginSupport<PluginManag
|
|
|
464
466
|
}
|
|
465
467
|
|
|
466
468
|
protected ensureFileSystemActivation(event: FileSystemProviderActivationEvent): void {
|
|
467
|
-
event.waitUntil(
|
|
469
|
+
event.waitUntil((async () => {
|
|
470
|
+
// Wait until plugins are synced so that activation events are recorded
|
|
471
|
+
// and will be replayed when managers start. This does not depend on
|
|
472
|
+
// layout initialization, so it cannot deadlock.
|
|
473
|
+
await this.willStart;
|
|
474
|
+
await this.activateByFileSystem(event);
|
|
468
475
|
if (!this.fileService.hasProvider(event.scheme)) {
|
|
469
476
|
return waitForEvent(Event.filter(this.fileService.onDidChangeFileSystemProviderRegistrations,
|
|
470
477
|
({ added, scheme }) => added && scheme === event.scheme), 3000);
|
|
471
478
|
}
|
|
472
|
-
}));
|
|
479
|
+
})());
|
|
473
480
|
}
|
|
474
481
|
|
|
475
482
|
protected ensureCommandHandlerRegistration(event: WillExecuteCommandEvent): void {
|
|
@@ -171,15 +171,11 @@ export function setUpPluginApi(rpc: RPCProtocol, container: interfaces.Container
|
|
|
171
171
|
rpc.set(PLUGIN_RPC_CONTEXT.DEBUG_MAIN, debugMain);
|
|
172
172
|
|
|
173
173
|
const fs = new FileSystemMainImpl(rpc, container);
|
|
174
|
-
const fsEventService = new MainFileSystemEventService(rpc, container);
|
|
175
|
-
const disposeFS = fs.dispose.bind(fs);
|
|
176
|
-
fs.dispose = () => {
|
|
177
|
-
fsEventService.dispose();
|
|
178
|
-
disposeFS();
|
|
179
|
-
};
|
|
180
|
-
|
|
181
174
|
rpc.set(PLUGIN_RPC_CONTEXT.FILE_SYSTEM_MAIN, fs);
|
|
182
175
|
|
|
176
|
+
const fsEventService = new MainFileSystemEventService(rpc, container);
|
|
177
|
+
rpc.set(PLUGIN_RPC_CONTEXT.FILE_SYSTEM_EVENT_SERVICE_MAIN, fsEventService);
|
|
178
|
+
|
|
183
179
|
const scmMain = new ScmMainImpl(rpc, container);
|
|
184
180
|
rpc.set(PLUGIN_RPC_CONTEXT.SCM_MAIN, scmMain);
|
|
185
181
|
|
|
@@ -21,21 +21,24 @@
|
|
|
21
21
|
|
|
22
22
|
import { interfaces } from '@theia/core/shared/inversify';
|
|
23
23
|
import { RPCProtocol } from '../../common/rpc-protocol';
|
|
24
|
-
import { MAIN_RPC_CONTEXT, FileSystemEvents } from '../../common/plugin-api-rpc';
|
|
25
|
-
import {
|
|
24
|
+
import { MAIN_RPC_CONTEXT, FileSystemEvents, MainFileSystemEventServiceShape } from '../../common/plugin-api-rpc';
|
|
25
|
+
import { UriComponents } from '../../common/uri-components';
|
|
26
|
+
import { URI } from '@theia/core';
|
|
27
|
+
import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable';
|
|
26
28
|
import { FileService } from '@theia/filesystem/lib/browser/file-service';
|
|
27
|
-
import { FileChangeType } from '@theia/filesystem/lib/common/files';
|
|
29
|
+
import { FileChangeType, WatchOptions } from '@theia/filesystem/lib/common/files';
|
|
28
30
|
|
|
29
|
-
export class MainFileSystemEventService {
|
|
31
|
+
export class MainFileSystemEventService implements MainFileSystemEventServiceShape {
|
|
30
32
|
|
|
31
33
|
private readonly toDispose = new DisposableCollection();
|
|
34
|
+
private readonly watches = new Map<number, Disposable>();
|
|
32
35
|
|
|
33
36
|
constructor(
|
|
34
37
|
rpc: RPCProtocol,
|
|
35
|
-
container: interfaces.Container
|
|
38
|
+
container: interfaces.Container,
|
|
39
|
+
private readonly fileService = container.get(FileService)
|
|
36
40
|
) {
|
|
37
41
|
const proxy = rpc.getProxy(MAIN_RPC_CONTEXT.ExtHostFileSystemEventService);
|
|
38
|
-
const fileService = container.get(FileService);
|
|
39
42
|
|
|
40
43
|
this.toDispose.push(fileService.onDidFilesChange(event => {
|
|
41
44
|
// file system events - (changes the editor and others make)
|
|
@@ -73,4 +76,21 @@ export class MainFileSystemEventService {
|
|
|
73
76
|
dispose(): void {
|
|
74
77
|
this.toDispose.dispose();
|
|
75
78
|
}
|
|
79
|
+
|
|
80
|
+
$watch(session: number, resource: UriComponents, options: WatchOptions): void {
|
|
81
|
+
if (this.watches.has(session)) {
|
|
82
|
+
throw new Error(`There is already a watch request for the key ${session}`);
|
|
83
|
+
}
|
|
84
|
+
const watch = this.fileService.watch(URI.fromComponents(resource), options);
|
|
85
|
+
this.toDispose.push(watch);
|
|
86
|
+
this.watches.set(session, watch);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
$unwatch(session: number): void {
|
|
90
|
+
const watch = this.watches.get(session);
|
|
91
|
+
if (watch) {
|
|
92
|
+
watch.dispose();
|
|
93
|
+
this.watches.delete(session);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
76
96
|
}
|
|
@@ -69,9 +69,9 @@ export class PluginMenuCommandAdapter {
|
|
|
69
69
|
['scm/resourceFolder/context', toScmArgs],
|
|
70
70
|
['scm/resourceGroup/context', toScmArgs],
|
|
71
71
|
['scm/resourceState/context', toScmArgs],
|
|
72
|
+
['scm/repository', toScmArgs],
|
|
72
73
|
['scm/title', () => [this.toScmArg(this.scmService.selectedRepository)]],
|
|
73
74
|
['scm/sourceControl', toScmArgs],
|
|
74
|
-
['scm/sourceControl/context', toScmArgs],
|
|
75
75
|
['scm/sourceControl/title', () => [this.toScmArg(this.scmService.selectedRepository)]],
|
|
76
76
|
['testing/message/context', toTestMessageArgs],
|
|
77
77
|
['testing/profiles/context', noArgs],
|
|
@@ -27,7 +27,7 @@ import { NAVIGATOR_CONTEXT_MENU } from '@theia/navigator/lib/browser/navigator-c
|
|
|
27
27
|
import { ScmTreeWidget } from '@theia/scm/lib/browser/scm-tree-widget';
|
|
28
28
|
import { PLUGIN_SCM_CHANGE_TITLE_MENU } from '@theia/scm/lib/browser/dirty-diff/dirty-diff-widget';
|
|
29
29
|
import {
|
|
30
|
-
|
|
30
|
+
SCM_REPOSITORY_MENU, SCM_SOURCE_CONTROL_MENU, SCM_SOURCE_CONTROL_TITLE_MENU, SCM_TITLE_MENU
|
|
31
31
|
} from '@theia/scm/lib/browser/scm-repositories-widget';
|
|
32
32
|
import { TIMELINE_ITEM_CONTEXT_MENU } from '@theia/timeline/lib/browser/timeline-tree-widget';
|
|
33
33
|
import { COMMENT_CONTEXT, COMMENT_THREAD_CONTEXT, COMMENT_TITLE } from '../comments/comment-thread-widget';
|
|
@@ -62,8 +62,8 @@ export const implementedVSCodeContributionPoints = [
|
|
|
62
62
|
'scm/resourceFolder/context',
|
|
63
63
|
'scm/resourceGroup/context',
|
|
64
64
|
'scm/resourceState/context',
|
|
65
|
+
'scm/repository',
|
|
65
66
|
'scm/sourceControl',
|
|
66
|
-
'scm/sourceControl/context',
|
|
67
67
|
'scm/sourceControl/title',
|
|
68
68
|
'scm/title',
|
|
69
69
|
'timeline/item/context',
|
|
@@ -100,8 +100,8 @@ export const codeToTheiaMappings = new Map<string, MenuPath[]>([
|
|
|
100
100
|
['scm/resourceFolder/context', [ScmTreeWidget.RESOURCE_FOLDER_CONTEXT_MENU]],
|
|
101
101
|
['scm/resourceGroup/context', [ScmTreeWidget.RESOURCE_GROUP_CONTEXT_MENU]],
|
|
102
102
|
['scm/resourceState/context', [ScmTreeWidget.RESOURCE_CONTEXT_MENU]],
|
|
103
|
+
['scm/repository', [SCM_REPOSITORY_MENU]],
|
|
103
104
|
['scm/sourceControl', [SCM_SOURCE_CONTROL_MENU]],
|
|
104
|
-
['scm/sourceControl/context', [SCM_SOURCE_CONTROL_CONTEXT_MENU]],
|
|
105
105
|
['scm/sourceControl/title', [SCM_SOURCE_CONTROL_TITLE_MENU]],
|
|
106
106
|
['scm/title', [SCM_TITLE_MENU]],
|
|
107
107
|
['testing/item/context', [TEST_VIEW_CONTEXT_MENU]],
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2026 EclipseSource GmbH 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 { expect } from 'chai';
|
|
18
|
+
import { ScmService } from '@theia/scm/lib/browser/scm-service';
|
|
19
|
+
import { ScmMainImpl } from './scm-main';
|
|
20
|
+
|
|
21
|
+
interface ScmMainInternals {
|
|
22
|
+
repositories: Map<number, unknown>;
|
|
23
|
+
repositoryDisposables: Map<number, { dispose(): void }>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function createScmMainImpl(scmService: ScmService): ScmMainImpl {
|
|
27
|
+
// Bypass the constructor's RPC/container wiring. ScmMainImpl's $register and
|
|
28
|
+
// $unregister only touch the proxy for input box validation and selection
|
|
29
|
+
// forwarding — not exercised in this test — so we can stub those safely.
|
|
30
|
+
const proxy = new Proxy({}, {
|
|
31
|
+
get: () => (): unknown => undefined
|
|
32
|
+
});
|
|
33
|
+
const impl = Object.create(ScmMainImpl.prototype) as ScmMainImpl;
|
|
34
|
+
const anyImpl = impl as unknown as Record<string, unknown>;
|
|
35
|
+
anyImpl.proxy = proxy;
|
|
36
|
+
anyImpl.scmService = scmService;
|
|
37
|
+
anyImpl.repositories = new Map();
|
|
38
|
+
anyImpl.repositoryDisposables = new Map();
|
|
39
|
+
anyImpl.disposables = { push: (): void => { } };
|
|
40
|
+
anyImpl.colors = { toCssVariableName: (x: string) => x };
|
|
41
|
+
anyImpl.sharedStyle = { toIconClass: () => ({ object: { iconClass: '' }, dispose: () => { } }) };
|
|
42
|
+
return impl;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
describe('ScmMainImpl - cascade dispose of children on $unregisterSourceControl', () => {
|
|
46
|
+
let scmService: ScmService;
|
|
47
|
+
let impl: ScmMainImpl;
|
|
48
|
+
|
|
49
|
+
beforeEach(() => {
|
|
50
|
+
scmService = new ScmService();
|
|
51
|
+
// Stub the optional context key dependency used by ScmService.
|
|
52
|
+
(scmService as unknown as Record<string, unknown>).contextKeys = {};
|
|
53
|
+
impl = createScmMainImpl(scmService);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should unregister worktree children when their parent is unregistered', async () => {
|
|
57
|
+
// Parent
|
|
58
|
+
await impl.$registerSourceControl(1, 'git', 'Main', { scheme: 'file', path: '/repo', authority: '', query: '', fragment: '' });
|
|
59
|
+
// Two worktree children pointing at the parent
|
|
60
|
+
await impl.$registerSourceControl(2, 'git', 'WT-A', { scheme: 'file', path: '/wt-a', authority: '', query: '', fragment: '' }, 1);
|
|
61
|
+
await impl.$registerSourceControl(3, 'git', 'WT-B', { scheme: 'file', path: '/wt-b', authority: '', query: '', fragment: '' }, 1);
|
|
62
|
+
|
|
63
|
+
expect(scmService.repositories).to.have.length(3);
|
|
64
|
+
|
|
65
|
+
const removed: unknown[] = [];
|
|
66
|
+
scmService.onDidRemoveRepository(r => removed.push(r));
|
|
67
|
+
|
|
68
|
+
await impl.$unregisterSourceControl(1);
|
|
69
|
+
|
|
70
|
+
// Parent and both children must be removed from the service.
|
|
71
|
+
expect(scmService.repositories).to.have.length(0);
|
|
72
|
+
expect(removed).to.have.length(3);
|
|
73
|
+
|
|
74
|
+
// Internal bookkeeping must be clean.
|
|
75
|
+
const internals = impl as unknown as ScmMainInternals;
|
|
76
|
+
expect(internals.repositories.size).to.equal(0);
|
|
77
|
+
expect(internals.repositoryDisposables.size).to.equal(0);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should leave unrelated repositories untouched when a parent is unregistered', async () => {
|
|
81
|
+
await impl.$registerSourceControl(1, 'git', 'Main', { scheme: 'file', path: '/repo', authority: '', query: '', fragment: '' });
|
|
82
|
+
await impl.$registerSourceControl(2, 'git', 'WT-A', { scheme: 'file', path: '/wt-a', authority: '', query: '', fragment: '' }, 1);
|
|
83
|
+
// An independent repository (no parent)
|
|
84
|
+
await impl.$registerSourceControl(3, 'git', 'Other', { scheme: 'file', path: '/other', authority: '', query: '', fragment: '' });
|
|
85
|
+
|
|
86
|
+
await impl.$unregisterSourceControl(1);
|
|
87
|
+
|
|
88
|
+
const remaining = scmService.repositories;
|
|
89
|
+
expect(remaining).to.have.length(1);
|
|
90
|
+
expect(remaining[0].provider.rootUri).to.include('/other');
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('should not crash when the child was already unregistered before the parent', async () => {
|
|
94
|
+
await impl.$registerSourceControl(1, 'git', 'Main', { scheme: 'file', path: '/repo', authority: '', query: '', fragment: '' });
|
|
95
|
+
await impl.$registerSourceControl(2, 'git', 'WT-A', { scheme: 'file', path: '/wt-a', authority: '', query: '', fragment: '' }, 1);
|
|
96
|
+
|
|
97
|
+
// Plugin-side unregister for the child arrives first (race scenario).
|
|
98
|
+
await impl.$unregisterSourceControl(2);
|
|
99
|
+
expect(scmService.repositories).to.have.length(1);
|
|
100
|
+
|
|
101
|
+
// Now the parent is unregistered — cascade should find no child and succeed.
|
|
102
|
+
await impl.$unregisterSourceControl(1);
|
|
103
|
+
expect(scmService.repositories).to.have.length(0);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
@@ -388,7 +388,31 @@ export class ScmMainImpl implements ScmMain {
|
|
|
388
388
|
return;
|
|
389
389
|
}
|
|
390
390
|
|
|
391
|
-
|
|
391
|
+
// Defensively cascade-dispose any children (e.g. worktrees) whose parent
|
|
392
|
+
// is being unregistered. The plugin API exposes onDidDisposeParent, but if
|
|
393
|
+
// a plugin fails to propagate it (or races with an external change like a
|
|
394
|
+
// worktree being removed on disk), children would otherwise be orphaned
|
|
395
|
+
// in the Repositories view. Children are torn down inline (not recursively)
|
|
396
|
+
// to keep the iteration over `this.repositories` safe and to tolerate a
|
|
397
|
+
// plugin-side RPC for the child arriving first.
|
|
398
|
+
const childHandles: number[] = [];
|
|
399
|
+
for (const [childHandle, childRepo] of this.repositories) {
|
|
400
|
+
if (childHandle !== handle && (childRepo.provider as PluginScmProvider).parentHandle === handle) {
|
|
401
|
+
childHandles.push(childHandle);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
for (const childHandle of childHandles) {
|
|
405
|
+
const childRepository = this.repositories.get(childHandle);
|
|
406
|
+
if (!childRepository) {
|
|
407
|
+
continue;
|
|
408
|
+
}
|
|
409
|
+
this.repositoryDisposables.get(childHandle)?.dispose();
|
|
410
|
+
this.repositoryDisposables.delete(childHandle);
|
|
411
|
+
childRepository.dispose();
|
|
412
|
+
this.repositories.delete(childHandle);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
this.repositoryDisposables.get(handle)?.dispose();
|
|
392
416
|
this.repositoryDisposables.delete(handle);
|
|
393
417
|
|
|
394
418
|
repository.dispose();
|
|
@@ -410,7 +410,8 @@ class TestControllerImpl implements TestController {
|
|
|
410
410
|
private _runs = new SimpleObservableCollection<TestRunImpl>();
|
|
411
411
|
readonly deltaBuilder = new AccumulatingTreeDeltaEmitter<string, TestItemImpl>(300);
|
|
412
412
|
canRefresh: boolean;
|
|
413
|
-
|
|
413
|
+
canResolveChildren: boolean = false;
|
|
414
|
+
private hasTriggeredInitialResolve: boolean = false;
|
|
414
415
|
readonly items = new TestItemCollection(this, item => item.path, () => this.deltaBuilder);
|
|
415
416
|
|
|
416
417
|
constructor(private readonly proxy: TestingExt, readonly id: string, public label: string) {
|
|
@@ -510,6 +511,10 @@ class TestControllerImpl implements TestController {
|
|
|
510
511
|
}
|
|
511
512
|
if ('canResolve' in change) {
|
|
512
513
|
this.canResolveChildren = change.canResolve!;
|
|
514
|
+
if (change.canResolve && !this.hasTriggeredInitialResolve) {
|
|
515
|
+
this.hasTriggeredInitialResolve = true;
|
|
516
|
+
this.resolveChildren();
|
|
517
|
+
}
|
|
513
518
|
}
|
|
514
519
|
if ('label' in change) {
|
|
515
520
|
this.label = change.label!;
|
|
@@ -543,9 +548,14 @@ class TestControllerImpl implements TestController {
|
|
|
543
548
|
}
|
|
544
549
|
onItemsChanged: Event<TreeDelta<string, TestItemImpl>[]> = this.deltaBuilder.onDidFlush;
|
|
545
550
|
|
|
546
|
-
resolveChildren(item
|
|
551
|
+
resolveChildren(item?: TestItem): void {
|
|
547
552
|
if (this.canResolveChildren) {
|
|
548
|
-
|
|
553
|
+
if (item) {
|
|
554
|
+
this.proxy.$onResolveChildren(this.id, itemToPath(item));
|
|
555
|
+
} else {
|
|
556
|
+
// Root-level resolve: trigger discovery of top-level test items
|
|
557
|
+
this.proxy.$onResolveChildren(this.id, []);
|
|
558
|
+
}
|
|
549
559
|
}
|
|
550
560
|
}
|
|
551
561
|
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
19
19
|
*--------------------------------------------------------------------------------------------*/
|
|
20
20
|
/**
|
|
21
|
-
* **IMPORTANT** this code is running in the plugin host process and should be
|
|
21
|
+
* **IMPORTANT** this code is running in the plugin host process and should be close as possible to VS Code counterpart:
|
|
22
22
|
* https://github.com/microsoft/vscode/blob/04c36be045a94fee58e5f8992d3e3fd980294a84/src/vs/workbench/api/common/extHostFileSystemEventService.ts
|
|
23
23
|
* One should be able to diff them to see differences.
|
|
24
24
|
*/
|
|
@@ -28,11 +28,12 @@
|
|
|
28
28
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
29
29
|
/* eslint-disable @typescript-eslint/tslint/config */
|
|
30
30
|
|
|
31
|
-
import { Emitter, WaitUntilEvent, AsyncEmitter, WaitUntilData } from '@theia/core/lib/common/event';
|
|
32
|
-
import {
|
|
31
|
+
import { Emitter, Event as EventNamespace, WaitUntilEvent, AsyncEmitter, WaitUntilData } from '@theia/core/lib/common/event';
|
|
32
|
+
import { GLOB_SPLIT, GLOBSTAR, parse } from '@theia/core/lib/common/glob';
|
|
33
33
|
import { UriComponents } from '../common/uri-components';
|
|
34
|
-
import { Disposable, URI, WorkspaceEdit } from './types-impl';
|
|
34
|
+
import { Disposable, RelativePattern, URI, WorkspaceEdit } from './types-impl';
|
|
35
35
|
import { EditorsAndDocumentsExtImpl as ExtHostDocumentsAndEditors } from './editors-and-documents';
|
|
36
|
+
import { WorkspaceExtImpl as ExtHostWorkspace } from './workspace';
|
|
36
37
|
import type * as vscode from '@theia/plugin';
|
|
37
38
|
import * as typeConverter from './type-converters';
|
|
38
39
|
import { FileOperation } from '@theia/filesystem/lib/common/files';
|
|
@@ -68,8 +69,9 @@ export class FileSystemWatcher implements vscode.FileSystemWatcher {
|
|
|
68
69
|
return Boolean(this._config & 0b100);
|
|
69
70
|
}
|
|
70
71
|
|
|
71
|
-
constructor(dispatcher: Event<FileSystemEvents>, globPattern: string |
|
|
72
|
-
ignoreCreateEvents?: boolean, ignoreChangeEvents?: boolean, ignoreDeleteEvents?: boolean, excludes?: string[]
|
|
72
|
+
constructor(dispatcher: Event<FileSystemEvents>, globPattern: string | RelativePattern,
|
|
73
|
+
ignoreCreateEvents?: boolean, ignoreChangeEvents?: boolean, ignoreDeleteEvents?: boolean, excludes?: string[],
|
|
74
|
+
filter: (uri: URI) => boolean = () => true, disposable: { dispose(): unknown } = Disposable.from()) {
|
|
73
75
|
|
|
74
76
|
this._config = 0;
|
|
75
77
|
if (ignoreCreateEvents) {
|
|
@@ -89,7 +91,7 @@ export class FileSystemWatcher implements vscode.FileSystemWatcher {
|
|
|
89
91
|
if (!ignoreCreateEvents) {
|
|
90
92
|
for (const created of events.created) {
|
|
91
93
|
const uri = URI.revive(created);
|
|
92
|
-
if (parsedPattern(uri.fsPath) && !excludePatterns.some(p => p(uri.fsPath))) {
|
|
94
|
+
if (parsedPattern(uri.fsPath) && !excludePatterns.some(p => p(uri.fsPath)) && filter(uri)) {
|
|
93
95
|
this._onDidCreate.fire(uri);
|
|
94
96
|
}
|
|
95
97
|
}
|
|
@@ -97,7 +99,7 @@ export class FileSystemWatcher implements vscode.FileSystemWatcher {
|
|
|
97
99
|
if (!ignoreChangeEvents) {
|
|
98
100
|
for (const changed of events.changed) {
|
|
99
101
|
const uri = URI.revive(changed);
|
|
100
|
-
if (parsedPattern(uri.fsPath) && !excludePatterns.some(p => p(uri.fsPath))) {
|
|
102
|
+
if (parsedPattern(uri.fsPath) && !excludePatterns.some(p => p(uri.fsPath)) && filter(uri)) {
|
|
101
103
|
this._onDidChange.fire(uri);
|
|
102
104
|
}
|
|
103
105
|
}
|
|
@@ -105,14 +107,14 @@ export class FileSystemWatcher implements vscode.FileSystemWatcher {
|
|
|
105
107
|
if (!ignoreDeleteEvents) {
|
|
106
108
|
for (const deleted of events.deleted) {
|
|
107
109
|
const uri = URI.revive(deleted);
|
|
108
|
-
if (parsedPattern(uri.fsPath) && !excludePatterns.some(p => p(uri.fsPath))) {
|
|
110
|
+
if (parsedPattern(uri.fsPath) && !excludePatterns.some(p => p(uri.fsPath)) && filter(uri)) {
|
|
109
111
|
this._onDidDelete.fire(uri);
|
|
110
112
|
}
|
|
111
113
|
}
|
|
112
114
|
}
|
|
113
115
|
});
|
|
114
116
|
|
|
115
|
-
this._disposable = Disposable.from(this._onDidCreate, this._onDidChange, this._onDidDelete, subscription);
|
|
117
|
+
this._disposable = Disposable.from(disposable, this._onDidCreate, this._onDidChange, this._onDidDelete, subscription);
|
|
116
118
|
}
|
|
117
119
|
|
|
118
120
|
dispose(): void {
|
|
@@ -155,16 +157,40 @@ export class ExtHostFileSystemEventService implements ExtHostFileSystemEventServ
|
|
|
155
157
|
constructor(
|
|
156
158
|
rpc: RPCProtocol,
|
|
157
159
|
private readonly _extHostDocumentsAndEditors: ExtHostDocumentsAndEditors,
|
|
158
|
-
private readonly
|
|
160
|
+
private readonly _extHostWorkspace: ExtHostWorkspace,
|
|
161
|
+
private readonly _mainThreadTextEditors: MainThreadTextEditorsShape = rpc.getProxy(PLUGIN_RPC_CONTEXT.TEXT_EDITORS_MAIN),
|
|
162
|
+
private readonly _mainThreadFileSystemEventService = rpc.getProxy(PLUGIN_RPC_CONTEXT.FILE_SYSTEM_EVENT_SERVICE_MAIN)
|
|
159
163
|
) {
|
|
160
|
-
//
|
|
164
|
+
// Language services often watch every component of source trees (including dependencies),
|
|
165
|
+
// which can result in hundreds of watchers in large projects.
|
|
166
|
+
// Disable the leak warning (maxListeners 0 = unbounded) to avoid false positives.
|
|
167
|
+
EventNamespace.setMaxListeners(this._onFileSystemEvent.event, 0);
|
|
161
168
|
}
|
|
162
169
|
|
|
163
170
|
// --- file events
|
|
164
171
|
|
|
165
|
-
createFileSystemWatcher(globPattern: string |
|
|
172
|
+
createFileSystemWatcher(globPattern: string | RelativePattern, ignoreCreateEvents?: boolean,
|
|
166
173
|
ignoreChangeEvents?: boolean, ignoreDeleteEvents?: boolean): vscode.FileSystemWatcher {
|
|
167
|
-
|
|
174
|
+
const filter = typeof globPattern === 'string' ? // ignore events outside the workspace when only a string pattern is provided
|
|
175
|
+
(uri: URI) => !!this._extHostWorkspace.getWorkspaceFolder(uri) : undefined;
|
|
176
|
+
return new FileSystemWatcher(this._onFileSystemEvent.event, globPattern, ignoreCreateEvents, ignoreChangeEvents, ignoreDeleteEvents,
|
|
177
|
+
undefined, filter, this.ensureWatching(globPattern, ignoreCreateEvents, ignoreChangeEvents, ignoreDeleteEvents));
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
private ensureWatching(globPattern: string | RelativePattern,
|
|
181
|
+
ignoreCreateEvents?: boolean, ignoreChangeEvents?: boolean, ignoreDeleteEvents?: boolean): Disposable | undefined {
|
|
182
|
+
if (typeof globPattern === 'string' || this._extHostWorkspace.getWorkspaceFolder(globPattern.baseUri)) {
|
|
183
|
+
return; // workspace is already watched by default, no need to watch again
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (ignoreChangeEvents && ignoreCreateEvents && ignoreDeleteEvents) {
|
|
187
|
+
return; // no need to watch if we ignore all events
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const session = Math.random();
|
|
191
|
+
const recursive = globPattern.pattern.includes(GLOBSTAR) || globPattern.pattern.includes(GLOB_SPLIT); // only watch recursively if pattern indicates the need for it
|
|
192
|
+
this._mainThreadFileSystemEventService.$watch(session, globPattern.baseUri, { recursive, excludes: [] });
|
|
193
|
+
return Disposable.from({ dispose: () => this._mainThreadFileSystemEventService.$unwatch(session) });
|
|
168
194
|
}
|
|
169
195
|
|
|
170
196
|
$onFileEvent(events: FileSystemEvents) {
|
|
@@ -257,7 +257,7 @@ import { DocumentsExtImpl } from './documents';
|
|
|
257
257
|
import { TextEditorCursorStyle } from '../common/editor-options';
|
|
258
258
|
import { PreferenceRegistryExtImpl } from './preference-registry';
|
|
259
259
|
import { OutputChannelRegistryExtImpl } from './output-channel-registry';
|
|
260
|
-
import { TerminalServiceExtImpl
|
|
260
|
+
import { TerminalServiceExtImpl } from './terminal-ext';
|
|
261
261
|
import { LanguagesExtImpl } from './languages';
|
|
262
262
|
import { fromDocumentSelector, pluginToPluginInfo, fromGlobPattern } from './type-converters';
|
|
263
263
|
import { DialogsExtImpl } from './dialogs';
|
|
@@ -348,7 +348,7 @@ export function createAPIFactory(
|
|
|
348
348
|
const connectionExt = rpc.set(MAIN_RPC_CONTEXT.CONNECTION_EXT, new ConnectionImpl(rpc.getProxy(PLUGIN_RPC_CONTEXT.CONNECTION_MAIN)));
|
|
349
349
|
const fileSystemExt = rpc.set(MAIN_RPC_CONTEXT.FILE_SYSTEM_EXT, new FileSystemExtImpl(rpc));
|
|
350
350
|
const languagesExt = rpc.set(MAIN_RPC_CONTEXT.LANGUAGES_EXT, new LanguagesExtImpl(rpc, documents, commandRegistry, fileSystemExt));
|
|
351
|
-
const extHostFileSystemEvent = rpc.set(MAIN_RPC_CONTEXT.ExtHostFileSystemEventService, new ExtHostFileSystemEventService(rpc, editorsAndDocumentsExt));
|
|
351
|
+
const extHostFileSystemEvent = rpc.set(MAIN_RPC_CONTEXT.ExtHostFileSystemEventService, new ExtHostFileSystemEventService(rpc, editorsAndDocumentsExt, workspaceExt));
|
|
352
352
|
const scmExt = rpc.set(MAIN_RPC_CONTEXT.SCM_EXT, new ScmExtImpl(rpc, commandRegistry));
|
|
353
353
|
const decorationsExt = rpc.set(MAIN_RPC_CONTEXT.DECORATIONS_EXT, new DecorationsExtImpl(rpc));
|
|
354
354
|
const labelServiceExt = rpc.set(MAIN_RPC_CONTEXT.LABEL_SERVICE_EXT, new LabelServiceExtImpl(rpc));
|
|
@@ -462,7 +462,7 @@ export function createAPIFactory(
|
|
|
462
462
|
const showErrorMessage = messageRegistryExt.showMessage.bind(messageRegistryExt, MainMessageType.Error);
|
|
463
463
|
const window: typeof theia.window = {
|
|
464
464
|
|
|
465
|
-
get activeTerminal():
|
|
465
|
+
get activeTerminal(): theia.Terminal | undefined {
|
|
466
466
|
return terminalExt.activeTerminal;
|
|
467
467
|
},
|
|
468
468
|
get activeTextEditor(): TextEditorExt | undefined {
|
|
@@ -471,7 +471,7 @@ export function createAPIFactory(
|
|
|
471
471
|
get visibleTextEditors(): theia.TextEditor[] {
|
|
472
472
|
return editors.getVisibleTextEditors();
|
|
473
473
|
},
|
|
474
|
-
get terminals():
|
|
474
|
+
get terminals(): theia.Terminal[] {
|
|
475
475
|
return terminalExt.terminals;
|
|
476
476
|
},
|
|
477
477
|
onDidChangeActiveTerminal,
|
|
@@ -633,7 +633,7 @@ export function createAPIFactory(
|
|
|
633
633
|
createTerminal(nameOrOptions: theia.TerminalOptions | theia.ExtensionTerminalOptions | theia.ExtensionTerminalOptions | (string | undefined),
|
|
634
634
|
shellPath?: string,
|
|
635
635
|
shellArgs?: string[] | string): theia.Terminal {
|
|
636
|
-
return
|
|
636
|
+
return terminalExt.createTerminal(plugin, nameOrOptions, shellPath, shellArgs, createAPIObject);
|
|
637
637
|
},
|
|
638
638
|
onDidChangeTerminalState,
|
|
639
639
|
onDidCloseTerminal,
|
|
@@ -1286,8 +1286,8 @@ export function createAPIFactory(
|
|
|
1286
1286
|
throw new Error('Input box not found!');
|
|
1287
1287
|
}
|
|
1288
1288
|
},
|
|
1289
|
-
createSourceControl(id: string, label: string, rootUri?: URI, iconPath?: theia.IconPath, parent?: theia.SourceControl): theia.SourceControl {
|
|
1290
|
-
return
|
|
1289
|
+
createSourceControl(id: string, label: string, rootUri?: URI, iconPath?: theia.IconPath, isHidden?: boolean, parent?: theia.SourceControl): theia.SourceControl {
|
|
1290
|
+
return scmExt.createSourceControl(plugin, id, label, rootUri, iconPath, isHidden, parent);
|
|
1291
1291
|
}
|
|
1292
1292
|
};
|
|
1293
1293
|
|