@theia/plugin-ext 1.28.0-next.7 → 1.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/common/plugin-api-rpc-model.d.ts +1 -0
- package/lib/common/plugin-api-rpc-model.d.ts.map +1 -1
- package/lib/common/plugin-api-rpc-model.js.map +1 -1
- package/lib/common/plugin-api-rpc.d.ts +3 -0
- package/lib/common/plugin-api-rpc.d.ts.map +1 -1
- package/lib/common/plugin-api-rpc.js.map +1 -1
- package/lib/common/plugin-protocol.d.ts +4 -0
- package/lib/common/plugin-protocol.d.ts.map +1 -1
- package/lib/common/plugin-protocol.js.map +1 -1
- package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
- package/lib/hosted/browser/hosted-plugin.js +4 -2
- package/lib/hosted/browser/hosted-plugin.js.map +1 -1
- package/lib/hosted/browser/worker/worker-env-ext.d.ts +1 -0
- package/lib/hosted/browser/worker/worker-env-ext.d.ts.map +1 -1
- package/lib/hosted/browser/worker/worker-env-ext.js +3 -0
- package/lib/hosted/browser/worker/worker-env-ext.js.map +1 -1
- package/lib/hosted/node/scanners/scanner-theia.d.ts +5 -1
- package/lib/hosted/node/scanners/scanner-theia.d.ts.map +1 -1
- package/lib/hosted/node/scanners/scanner-theia.js +22 -15
- package/lib/hosted/node/scanners/scanner-theia.js.map +1 -1
- package/lib/main/browser/comments/comment-thread-widget.js +5 -5
- package/lib/main/browser/comments/comment-thread-widget.js.map +1 -1
- package/lib/main/browser/debug/debug-main.d.ts +1 -0
- package/lib/main/browser/debug/debug-main.d.ts.map +1 -1
- package/lib/main/browser/debug/debug-main.js +10 -0
- package/lib/main/browser/debug/debug-main.js.map +1 -1
- package/lib/main/browser/languages-main.d.ts.map +1 -1
- package/lib/main/browser/languages-main.js.map +1 -1
- package/lib/main/browser/menus/menus-contribution-handler.d.ts +24 -88
- package/lib/main/browser/menus/menus-contribution-handler.d.ts.map +1 -1
- package/lib/main/browser/menus/menus-contribution-handler.js +108 -518
- package/lib/main/browser/menus/menus-contribution-handler.js.map +1 -1
- package/lib/main/browser/menus/plugin-menu-command-adapter.d.ts +44 -0
- package/lib/main/browser/menus/plugin-menu-command-adapter.d.ts.map +1 -0
- package/lib/main/browser/menus/plugin-menu-command-adapter.js +274 -0
- package/lib/main/browser/menus/plugin-menu-command-adapter.js.map +1 -0
- package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts +18 -0
- package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts.map +1 -0
- package/lib/main/browser/menus/vscode-theia-menu-mappings.js +88 -0
- package/lib/main/browser/menus/vscode-theia-menu-mappings.js.map +1 -0
- package/lib/main/browser/plugin-contribution-handler.d.ts.map +1 -1
- package/lib/main/browser/plugin-contribution-handler.js +9 -4
- package/lib/main/browser/plugin-contribution-handler.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 +4 -3
- package/lib/main/browser/plugin-ext-frontend-module.js.map +1 -1
- package/lib/main/browser/plugin-frontend-contribution.d.ts +0 -2
- package/lib/main/browser/plugin-frontend-contribution.d.ts.map +1 -1
- package/lib/main/browser/plugin-frontend-contribution.js +0 -8
- package/lib/main/browser/plugin-frontend-contribution.js.map +1 -1
- package/lib/main/browser/plugin-shared-style.d.ts.map +1 -1
- package/lib/main/browser/plugin-shared-style.js +0 -1
- package/lib/main/browser/plugin-shared-style.js.map +1 -1
- package/lib/main/browser/scm-main.d.ts +1 -0
- package/lib/main/browser/scm-main.d.ts.map +1 -1
- package/lib/main/browser/scm-main.js +7 -0
- package/lib/main/browser/scm-main.js.map +1 -1
- package/lib/main/browser/view/tree-view-widget.js +2 -2
- package/lib/main/browser/view/tree-view-widget.js.map +1 -1
- package/lib/main/node/handlers/plugin-theia-file-handler.d.ts +0 -4
- package/lib/main/node/handlers/plugin-theia-file-handler.d.ts.map +1 -1
- package/lib/main/node/handlers/plugin-theia-file-handler.js +0 -26
- package/lib/main/node/handlers/plugin-theia-file-handler.js.map +1 -1
- package/lib/main/node/plugin-ext-backend-module.d.ts.map +1 -1
- package/lib/main/node/plugin-ext-backend-module.js +0 -2
- package/lib/main/node/plugin-ext-backend-module.js.map +1 -1
- package/lib/main/node/resolvers/local-plugin-deployer-resolver.d.ts.map +1 -1
- package/lib/main/node/resolvers/local-plugin-deployer-resolver.js.map +1 -1
- package/lib/plugin/debug/debug-ext.d.ts +3 -1
- package/lib/plugin/debug/debug-ext.d.ts.map +1 -1
- package/lib/plugin/debug/debug-ext.js +26 -4
- package/lib/plugin/debug/debug-ext.js.map +1 -1
- package/lib/plugin/debug/plugin-debug-adapter-session.d.ts +1 -0
- package/lib/plugin/debug/plugin-debug-adapter-session.d.ts.map +1 -1
- package/lib/plugin/debug/plugin-debug-adapter-session.js +3 -0
- package/lib/plugin/debug/plugin-debug-adapter-session.js.map +1 -1
- package/lib/plugin/env.d.ts +11 -0
- package/lib/plugin/env.d.ts.map +1 -1
- package/lib/plugin/env.js +20 -0
- package/lib/plugin/env.js.map +1 -1
- package/lib/plugin/languages/signature.d.ts.map +1 -1
- package/lib/plugin/languages/signature.js +5 -1
- package/lib/plugin/languages/signature.js.map +1 -1
- package/lib/plugin/node/debug/debug.spec.d.ts +2 -0
- package/lib/plugin/node/debug/debug.spec.d.ts.map +1 -0
- package/lib/plugin/node/debug/debug.spec.js +68 -0
- package/lib/plugin/node/debug/debug.spec.js.map +1 -0
- package/lib/plugin/node/env-node-ext.d.ts +3 -0
- package/lib/plugin/node/env-node-ext.d.ts.map +1 -1
- package/lib/plugin/node/env-node-ext.js +11 -0
- package/lib/plugin/node/env-node-ext.js.map +1 -1
- package/lib/plugin/plugin-context.d.ts.map +1 -1
- package/lib/plugin/plugin-context.js +10 -0
- package/lib/plugin/plugin-context.js.map +1 -1
- package/lib/plugin/plugin-manager.d.ts.map +1 -1
- package/lib/plugin/plugin-manager.js +1 -0
- package/lib/plugin/plugin-manager.js.map +1 -1
- package/lib/plugin/quick-open.d.ts.map +1 -1
- package/lib/plugin/quick-open.js +1 -0
- package/lib/plugin/quick-open.js.map +1 -1
- package/lib/plugin/scm.d.ts +3 -0
- package/lib/plugin/scm.d.ts.map +1 -1
- package/lib/plugin/scm.js +8 -0
- package/lib/plugin/scm.js.map +1 -1
- package/lib/plugin/type-converters.d.ts.map +1 -1
- package/lib/plugin/type-converters.js +4 -2
- package/lib/plugin/type-converters.js.map +1 -1
- package/lib/plugin/types-impl.d.ts +4 -3
- package/lib/plugin/types-impl.d.ts.map +1 -1
- package/lib/plugin/types-impl.js +9 -8
- package/lib/plugin/types-impl.js.map +1 -1
- package/package.json +27 -27
- package/src/common/plugin-api-rpc-model.ts +1 -0
- package/src/common/plugin-api-rpc.ts +3 -0
- package/src/common/plugin-protocol.ts +4 -0
- package/src/hosted/browser/hosted-plugin.ts +4 -2
- package/src/hosted/browser/worker/worker-env-ext.ts +4 -0
- package/src/hosted/node/scanners/scanner-theia.ts +21 -15
- package/src/main/browser/comments/comment-thread-widget.tsx +5 -5
- package/src/main/browser/debug/debug-main.ts +9 -0
- package/src/main/browser/languages-main.ts +5 -0
- package/src/main/browser/menus/menus-contribution-handler.ts +104 -578
- package/src/main/browser/menus/plugin-menu-command-adapter.ts +259 -0
- package/src/main/browser/menus/vscode-theia-menu-mappings.ts +85 -0
- package/src/main/browser/plugin-contribution-handler.ts +3 -1
- package/src/main/browser/plugin-ext-frontend-module.ts +4 -3
- package/src/main/browser/plugin-frontend-contribution.ts +0 -9
- package/src/main/browser/plugin-shared-style.ts +0 -1
- package/src/main/browser/scm-main.ts +10 -0
- package/src/main/browser/view/tree-view-widget.tsx +2 -2
- package/src/main/node/handlers/plugin-theia-file-handler.ts +0 -26
- package/src/main/node/plugin-ext-backend-module.ts +0 -2
- package/src/main/node/resolvers/local-plugin-deployer-resolver.ts +4 -8
- package/src/plugin/debug/debug-ext.ts +30 -5
- package/src/plugin/debug/plugin-debug-adapter-session.ts +4 -0
- package/src/plugin/env.ts +30 -0
- package/src/plugin/languages/signature.ts +3 -1
- package/src/plugin/node/debug/debug.spec.ts +94 -0
- package/src/plugin/node/env-node-ext.ts +13 -1
- package/src/plugin/plugin-context.ts +10 -0
- package/src/plugin/plugin-manager.ts +1 -0
- package/src/plugin/quick-open.ts +1 -0
- package/src/plugin/scm.ts +11 -0
- package/src/plugin/type-converters.ts +4 -2
- package/src/plugin/types-impl.ts +7 -5
- package/lib/main/browser/plugin-ext-deploy-command.d.ts +0 -10
- package/lib/main/browser/plugin-ext-deploy-command.d.ts.map +0 -1
- package/lib/main/browser/plugin-ext-deploy-command.js +0 -64
- package/lib/main/browser/plugin-ext-deploy-command.js.map +0 -1
- package/lib/main/node/resolvers/local-file-plugin-deployer-resolver.d.ts +0 -8
- package/lib/main/node/resolvers/local-file-plugin-deployer-resolver.d.ts.map +0 -1
- package/lib/main/node/resolvers/local-file-plugin-deployer-resolver.js +0 -43
- package/lib/main/node/resolvers/local-file-plugin-deployer-resolver.js.map +0 -1
- package/src/main/browser/plugin-ext-deploy-command.ts +0 -50
- package/src/main/node/resolvers/local-file-plugin-deployer-resolver.ts +0 -34
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2022 Ericsson 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 WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { CommandRegistry, Disposable, MenuCommandAdapter, MenuPath, SelectionService, UriSelection } from '@theia/core';
|
|
18
|
+
import { ResourceContextKey } from '@theia/core/lib/browser/resource-context-key';
|
|
19
|
+
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
|
|
20
|
+
import { URI as CodeUri } from '@theia/core/shared/vscode-uri';
|
|
21
|
+
import { TreeWidgetSelection } from '@theia/core/lib/browser/tree/tree-widget-selection';
|
|
22
|
+
import { ScmRepository } from '@theia/scm/lib/browser/scm-repository';
|
|
23
|
+
import { ScmService } from '@theia/scm/lib/browser/scm-service';
|
|
24
|
+
import { TimelineItem } from '@theia/timeline/lib/common/timeline-model';
|
|
25
|
+
import { ScmCommandArg, TimelineCommandArg, TreeViewSelection } from '../../../common';
|
|
26
|
+
import { PluginScmProvider, PluginScmResource, PluginScmResourceGroup } from '../scm-main';
|
|
27
|
+
import { TreeViewWidget } from '../view/tree-view-widget';
|
|
28
|
+
import { CodeEditorWidgetUtil, codeToTheiaMappings, ContributionPoint } from './vscode-theia-menu-mappings';
|
|
29
|
+
import { TAB_BAR_TOOLBAR_CONTEXT_MENU } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
|
|
30
|
+
|
|
31
|
+
export type ArgumentAdapter = (...args: unknown[]) => unknown[];
|
|
32
|
+
|
|
33
|
+
export class ReferenceCountingSet<T> {
|
|
34
|
+
protected readonly references: Map<T, number>;
|
|
35
|
+
constructor(initialMembers?: Iterable<T>) {
|
|
36
|
+
this.references = new Map();
|
|
37
|
+
if (initialMembers) {
|
|
38
|
+
for (const member of initialMembers) {
|
|
39
|
+
this.add(member);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
add(newMember: T): ReferenceCountingSet<T> {
|
|
45
|
+
const value = this.references.get(newMember) ?? 0;
|
|
46
|
+
this.references.set(newMember, value + 1);
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** @returns true if the deletion results in the removal of the element from the set */
|
|
51
|
+
delete(member: T): boolean {
|
|
52
|
+
const value = this.references.get(member);
|
|
53
|
+
if (value === undefined) { } else if (value <= 1) {
|
|
54
|
+
this.references.delete(member);
|
|
55
|
+
return true;
|
|
56
|
+
} else {
|
|
57
|
+
this.references.set(member, value - 1);
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
has(maybeMember: T): boolean {
|
|
63
|
+
return this.references.has(maybeMember);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@injectable()
|
|
68
|
+
export class PluginMenuCommandAdapter implements MenuCommandAdapter {
|
|
69
|
+
@inject(CommandRegistry) protected readonly commandRegistry: CommandRegistry;
|
|
70
|
+
@inject(CodeEditorWidgetUtil) protected readonly codeEditorUtil: CodeEditorWidgetUtil;
|
|
71
|
+
@inject(ScmService) protected readonly scmService: ScmService;
|
|
72
|
+
@inject(SelectionService) protected readonly selectionService: SelectionService;
|
|
73
|
+
@inject(ResourceContextKey) protected readonly resourceContextKey: ResourceContextKey;
|
|
74
|
+
|
|
75
|
+
protected readonly commands = new ReferenceCountingSet<string>();
|
|
76
|
+
protected readonly argumentAdapters = new Map<string, ArgumentAdapter>();
|
|
77
|
+
protected readonly separator = ':)(:';
|
|
78
|
+
|
|
79
|
+
@postConstruct()
|
|
80
|
+
protected init(): void {
|
|
81
|
+
const toCommentArgs: ArgumentAdapter = (...args) => this.toCommentArgs(...args);
|
|
82
|
+
const firstArgOnly: ArgumentAdapter = (...args) => [args[0]];
|
|
83
|
+
const noArgs: ArgumentAdapter = () => [];
|
|
84
|
+
const toScmArgs: ArgumentAdapter = (...args) => this.toScmArgs(...args);
|
|
85
|
+
const selectedResource = () => this.getSelectedResources();
|
|
86
|
+
const widgetURI: ArgumentAdapter = widget => this.codeEditorUtil.is(widget) ? [this.codeEditorUtil.getResourceUri(widget)] : [];
|
|
87
|
+
(<Array<[ContributionPoint, ArgumentAdapter | undefined]>>[
|
|
88
|
+
['comments/comment/context', toCommentArgs],
|
|
89
|
+
['comments/comment/title', toCommentArgs],
|
|
90
|
+
['comments/commentThread/context', toCommentArgs],
|
|
91
|
+
['debug/callstack/context', firstArgOnly],
|
|
92
|
+
['debug/toolBar', noArgs],
|
|
93
|
+
['editor/context', selectedResource],
|
|
94
|
+
['editor/title', widgetURI],
|
|
95
|
+
['editor/title/context', selectedResource],
|
|
96
|
+
['explorer/context', selectedResource],
|
|
97
|
+
['scm/resourceFolder/context', toScmArgs],
|
|
98
|
+
['scm/resourceGroup/context', toScmArgs],
|
|
99
|
+
['scm/resourceState/context', toScmArgs],
|
|
100
|
+
['scm/title', () => this.toScmArg(this.scmService.selectedRepository)],
|
|
101
|
+
['timeline/item/context', (...args) => this.toTimelineArgs(...args)],
|
|
102
|
+
['view/item/context', (...args) => this.toTreeArgs(...args)],
|
|
103
|
+
['view/title', noArgs],
|
|
104
|
+
]).forEach(([contributionPoint, adapter]) => {
|
|
105
|
+
if (adapter) {
|
|
106
|
+
const paths = codeToTheiaMappings.get(contributionPoint);
|
|
107
|
+
if (paths) {
|
|
108
|
+
paths.forEach(([path]) => this.addArgumentAdapter(path, adapter));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
this.addArgumentAdapter(TAB_BAR_TOOLBAR_CONTEXT_MENU, widgetURI);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
canHandle(menuPath: MenuPath, command: string, ...commandArgs: unknown[]): number {
|
|
116
|
+
if (this.commands.has(command) && this.getArgumentAdapterForMenu(menuPath)) {
|
|
117
|
+
return 500;
|
|
118
|
+
}
|
|
119
|
+
return -1;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
executeCommand(menuPath: MenuPath, command: string, ...commandArgs: unknown[]): Promise<unknown> {
|
|
123
|
+
const argumentAdapter = this.getAdapterOrThrow(menuPath);
|
|
124
|
+
return this.commandRegistry.executeCommand(command, ...argumentAdapter(...commandArgs));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
isVisible(menuPath: MenuPath, command: string, ...commandArgs: unknown[]): boolean {
|
|
128
|
+
const argumentAdapter = this.getAdapterOrThrow(menuPath);
|
|
129
|
+
return this.commandRegistry.isVisible(command, ...argumentAdapter(...commandArgs));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
isEnabled(menuPath: MenuPath, command: string, ...commandArgs: unknown[]): boolean {
|
|
133
|
+
const argumentAdapter = this.getAdapterOrThrow(menuPath);
|
|
134
|
+
return this.commandRegistry.isEnabled(command, ...argumentAdapter(...commandArgs));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
isToggled(menuPath: MenuPath, command: string, ...commandArgs: unknown[]): boolean {
|
|
138
|
+
const argumentAdapter = this.getAdapterOrThrow(menuPath);
|
|
139
|
+
return this.commandRegistry.isToggled(command, ...argumentAdapter(...commandArgs));
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
protected getAdapterOrThrow(menuPath: MenuPath): ArgumentAdapter {
|
|
143
|
+
const argumentAdapter = this.getArgumentAdapterForMenu(menuPath);
|
|
144
|
+
if (!argumentAdapter) {
|
|
145
|
+
throw new Error('PluginMenuCommandAdapter attempted to execute command for unregistered menu: ' + JSON.stringify(menuPath));
|
|
146
|
+
}
|
|
147
|
+
return argumentAdapter;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
addCommand(commandId: string): Disposable {
|
|
151
|
+
this.commands.add(commandId);
|
|
152
|
+
return Disposable.create(() => this.commands.delete(commandId));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
protected getArgumentAdapterForMenu(menuPath: MenuPath): ArgumentAdapter | undefined {
|
|
156
|
+
return this.argumentAdapters.get(menuPath.join(this.separator));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
protected addArgumentAdapter(menuPath: MenuPath, adapter: ArgumentAdapter): void {
|
|
160
|
+
this.argumentAdapters.set(menuPath.join(this.separator), adapter);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
164
|
+
|
|
165
|
+
protected toCommentArgs(...args: any[]): any[] {
|
|
166
|
+
const arg = args[0];
|
|
167
|
+
if ('text' in arg) {
|
|
168
|
+
if ('commentUniqueId' in arg) {
|
|
169
|
+
return [{
|
|
170
|
+
commentControlHandle: arg.thread.controllerHandle,
|
|
171
|
+
commentThreadHandle: arg.thread.commentThreadHandle,
|
|
172
|
+
text: arg.text,
|
|
173
|
+
commentUniqueId: arg.commentUniqueId
|
|
174
|
+
}];
|
|
175
|
+
}
|
|
176
|
+
return [{
|
|
177
|
+
commentControlHandle: arg.thread.controllerHandle,
|
|
178
|
+
commentThreadHandle: arg.thread.commentThreadHandle,
|
|
179
|
+
text: arg.text
|
|
180
|
+
}];
|
|
181
|
+
}
|
|
182
|
+
return [{
|
|
183
|
+
commentControlHandle: arg.thread.controllerHandle,
|
|
184
|
+
commentThreadHandle: arg.thread.commentThreadHandle,
|
|
185
|
+
commentUniqueId: arg.commentUniqueId
|
|
186
|
+
}];
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
protected toScmArgs(...args: any[]): any[] {
|
|
190
|
+
const scmArgs: any[] = [];
|
|
191
|
+
for (const arg of args) {
|
|
192
|
+
const scmArg = this.toScmArg(arg);
|
|
193
|
+
if (scmArg) {
|
|
194
|
+
scmArgs.push(scmArg);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return scmArgs;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
protected toScmArg(arg: any): ScmCommandArg | undefined {
|
|
201
|
+
if (arg instanceof ScmRepository && arg.provider instanceof PluginScmProvider) {
|
|
202
|
+
return {
|
|
203
|
+
sourceControlHandle: arg.provider.handle
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
if (arg instanceof PluginScmResourceGroup) {
|
|
207
|
+
return {
|
|
208
|
+
sourceControlHandle: arg.provider.handle,
|
|
209
|
+
resourceGroupHandle: arg.handle
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
if (arg instanceof PluginScmResource) {
|
|
213
|
+
return {
|
|
214
|
+
sourceControlHandle: arg.group.provider.handle,
|
|
215
|
+
resourceGroupHandle: arg.group.handle,
|
|
216
|
+
resourceStateHandle: arg.handle
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
protected toTimelineArgs(...args: any[]): any[] {
|
|
222
|
+
const timelineArgs: any[] = [];
|
|
223
|
+
const arg = args[0];
|
|
224
|
+
timelineArgs.push(this.toTimelineArg(arg));
|
|
225
|
+
timelineArgs.push(CodeUri.parse(arg.uri));
|
|
226
|
+
timelineArgs.push(arg.source ?? '');
|
|
227
|
+
return timelineArgs;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
protected toTimelineArg(arg: TimelineItem): TimelineCommandArg {
|
|
231
|
+
return {
|
|
232
|
+
timelineHandle: arg.handle,
|
|
233
|
+
source: arg.source,
|
|
234
|
+
uri: arg.uri
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
protected toTreeArgs(...args: any[]): any[] {
|
|
239
|
+
const treeArgs: any[] = [];
|
|
240
|
+
for (const arg of args) {
|
|
241
|
+
if (TreeViewSelection.is(arg)) {
|
|
242
|
+
treeArgs.push(arg);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return treeArgs;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
protected getSelectedResources(): [CodeUri | TreeViewSelection | undefined, CodeUri[] | undefined] {
|
|
249
|
+
const selection = this.selectionService.selection;
|
|
250
|
+
const firstMember = TreeWidgetSelection.is(selection) && selection.source instanceof TreeViewWidget && selection[0]
|
|
251
|
+
? selection.source.toTreeViewSelection(selection[0])
|
|
252
|
+
: (UriSelection.getUri(selection) ?? this.resourceContextKey.get())?.['codeUri'];
|
|
253
|
+
const secondMember = TreeWidgetSelection.is(selection)
|
|
254
|
+
? UriSelection.getUris(selection).map(uri => uri['codeUri'])
|
|
255
|
+
: undefined;
|
|
256
|
+
return [firstMember, secondMember];
|
|
257
|
+
}
|
|
258
|
+
/* eslint-enable @typescript-eslint/no-explicit-any */
|
|
259
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2022 Ericsson 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 WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { MenuPath } from '@theia/core';
|
|
18
|
+
import { SHELL_TABBAR_CONTEXT_MENU } from '@theia/core/lib/browser';
|
|
19
|
+
import { Navigatable } from '@theia/core/lib/browser/navigatable';
|
|
20
|
+
import { injectable } from '@theia/core/shared/inversify';
|
|
21
|
+
import { URI as CodeUri } from '@theia/core/shared/vscode-uri';
|
|
22
|
+
import { DebugStackFramesWidget } from '@theia/debug/lib/browser/view/debug-stack-frames-widget';
|
|
23
|
+
import { DebugThreadsWidget } from '@theia/debug/lib/browser/view/debug-threads-widget';
|
|
24
|
+
import { EditorWidget, EDITOR_CONTEXT_MENU } from '@theia/editor/lib/browser';
|
|
25
|
+
import { NAVIGATOR_CONTEXT_MENU } from '@theia/navigator/lib/browser/navigator-contribution';
|
|
26
|
+
import { ScmTreeWidget } from '@theia/scm/lib/browser/scm-tree-widget';
|
|
27
|
+
import { TIMELINE_ITEM_CONTEXT_MENU } from '@theia/timeline/lib/browser/timeline-tree-widget';
|
|
28
|
+
import { COMMENT_CONTEXT, COMMENT_THREAD_CONTEXT, COMMENT_TITLE } from '../comments/comment-thread-widget';
|
|
29
|
+
import { VIEW_ITEM_CONTEXT_MENU } from '../view/tree-view-widget';
|
|
30
|
+
import { WebviewWidget } from '../webview/webview';
|
|
31
|
+
|
|
32
|
+
export const PLUGIN_EDITOR_TITLE_MENU = ['plugin_editor/title'];
|
|
33
|
+
export const PLUGIN_SCM_TITLE_MENU = ['plugin_scm/title'];
|
|
34
|
+
export const PLUGIN_VIEW_TITLE_MENU = ['plugin_view/title'];
|
|
35
|
+
|
|
36
|
+
export const implementedVSCodeContributionPoints = [
|
|
37
|
+
'comments/comment/context',
|
|
38
|
+
'comments/comment/title',
|
|
39
|
+
'comments/commentThread/context',
|
|
40
|
+
'debug/callstack/context',
|
|
41
|
+
'editor/context',
|
|
42
|
+
'editor/title',
|
|
43
|
+
'editor/title/context',
|
|
44
|
+
'explorer/context',
|
|
45
|
+
'scm/resourceFolder/context',
|
|
46
|
+
'scm/resourceGroup/context',
|
|
47
|
+
'scm/resourceState/context',
|
|
48
|
+
'scm/title',
|
|
49
|
+
'timeline/item/context',
|
|
50
|
+
'view/item/context',
|
|
51
|
+
'view/title'
|
|
52
|
+
] as const;
|
|
53
|
+
|
|
54
|
+
export type ContributionPoint = (typeof implementedVSCodeContributionPoints)[number];
|
|
55
|
+
|
|
56
|
+
/** The values are combinations of MenuPath and `when` clause, if any */
|
|
57
|
+
export const codeToTheiaMappings = new Map<ContributionPoint, Array<[MenuPath] | [MenuPath, string]>>([
|
|
58
|
+
['comments/comment/context', [[COMMENT_CONTEXT]]],
|
|
59
|
+
['comments/comment/title', [[COMMENT_TITLE]]],
|
|
60
|
+
['comments/commentThread/context', [[COMMENT_THREAD_CONTEXT]]],
|
|
61
|
+
['debug/callstack/context', [[DebugStackFramesWidget.CONTEXT_MENU], [DebugThreadsWidget.CONTEXT_MENU]]],
|
|
62
|
+
['editor/context', [[EDITOR_CONTEXT_MENU]]],
|
|
63
|
+
['editor/title', [[PLUGIN_EDITOR_TITLE_MENU]]],
|
|
64
|
+
['editor/title/context', [[SHELL_TABBAR_CONTEXT_MENU, 'resourceSet']]],
|
|
65
|
+
['explorer/context', [[NAVIGATOR_CONTEXT_MENU]]],
|
|
66
|
+
['scm/resourceFolder/context', [[ScmTreeWidget.RESOURCE_FOLDER_CONTEXT_MENU]]],
|
|
67
|
+
['scm/resourceGroup/context', [[ScmTreeWidget.RESOURCE_GROUP_CONTEXT_MENU]]],
|
|
68
|
+
['scm/resourceState/context', [[ScmTreeWidget.RESOURCE_CONTEXT_MENU]]],
|
|
69
|
+
['scm/title', [[PLUGIN_SCM_TITLE_MENU]]],
|
|
70
|
+
['timeline/item/context', [[TIMELINE_ITEM_CONTEXT_MENU]]],
|
|
71
|
+
['view/item/context', [[VIEW_ITEM_CONTEXT_MENU]]],
|
|
72
|
+
['view/title', [[PLUGIN_VIEW_TITLE_MENU]]],
|
|
73
|
+
]);
|
|
74
|
+
|
|
75
|
+
type CodeEditorWidget = EditorWidget | WebviewWidget;
|
|
76
|
+
@injectable()
|
|
77
|
+
export class CodeEditorWidgetUtil {
|
|
78
|
+
is(arg: unknown): arg is CodeEditorWidget {
|
|
79
|
+
return arg instanceof EditorWidget || arg instanceof WebviewWidget;
|
|
80
|
+
}
|
|
81
|
+
getResourceUri(editor: CodeEditorWidget): CodeUri | undefined {
|
|
82
|
+
const resourceUri = Navigatable.is(editor) && editor.getResourceUri();
|
|
83
|
+
return resourceUri ? resourceUri['codeUri'] : undefined;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -222,7 +222,9 @@ export class PluginContributionHandler {
|
|
|
222
222
|
pushContribution(`grammar.language.${language}.scope`, () => this.grammarsRegistry.mapLanguageIdToTextmateGrammar(language, grammar.scope));
|
|
223
223
|
pushContribution(`grammar.language.${language}.configuration`, () => this.grammarsRegistry.registerGrammarConfiguration(language, {
|
|
224
224
|
embeddedLanguages: this.convertEmbeddedLanguages(grammar.embeddedLanguages, logWarning),
|
|
225
|
-
tokenTypes: this.convertTokenTypes(grammar.tokenTypes)
|
|
225
|
+
tokenTypes: this.convertTokenTypes(grammar.tokenTypes),
|
|
226
|
+
balancedBracketSelectors: grammar.balancedBracketScopes ?? ['*'],
|
|
227
|
+
unbalancedBracketSelectors: grammar.balancedBracketScopes,
|
|
226
228
|
}));
|
|
227
229
|
}
|
|
228
230
|
// activate grammars only once everything else is loaded.
|
|
@@ -33,9 +33,8 @@ import { HostedPluginServer, hostedServicePath, PluginServer, pluginServerJsonRp
|
|
|
33
33
|
import { ModalNotification } from './dialogs/modal-notification';
|
|
34
34
|
import { PluginWidget } from './plugin-ext-widget';
|
|
35
35
|
import { PluginFrontendViewContribution } from './plugin-frontend-view-contribution';
|
|
36
|
-
import { PluginExtDeployCommandService } from './plugin-ext-deploy-command';
|
|
37
36
|
import { EditorModelService } from './text-editor-model-service';
|
|
38
|
-
import {
|
|
37
|
+
import { MenusContributionPointHandler } from './menus/menus-contribution-handler';
|
|
39
38
|
import { PluginContributionHandler } from './plugin-contribution-handler';
|
|
40
39
|
import { PluginViewRegistry, PLUGIN_VIEW_CONTAINER_FACTORY_ID, PLUGIN_VIEW_FACTORY_ID, PLUGIN_VIEW_DATA_FACTORY_ID } from './view/plugin-view-registry';
|
|
41
40
|
import { TextContentResourceResolver } from './workspace-main';
|
|
@@ -78,6 +77,8 @@ import { WebviewFrontendSecurityWarnings } from './webview/webview-frontend-secu
|
|
|
78
77
|
import { PluginAuthenticationServiceImpl } from './plugin-authentication-service';
|
|
79
78
|
import { AuthenticationService } from '@theia/core/lib/browser/authentication-service';
|
|
80
79
|
import { bindTreeViewDecoratorUtilities, TreeViewDecoratorService } from './view/tree-view-decorator-service';
|
|
80
|
+
import { CodeEditorWidgetUtil } from './menus/vscode-theia-menu-mappings';
|
|
81
|
+
import { PluginMenuCommandAdapter } from './menus/plugin-menu-command-adapter';
|
|
81
82
|
|
|
82
83
|
export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|
83
84
|
|
|
@@ -131,7 +132,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|
|
131
132
|
createWidget: () => ctx.container.get(PluginWidget)
|
|
132
133
|
}));
|
|
133
134
|
|
|
134
|
-
bind(PluginExtDeployCommandService).toSelf().inSingletonScope();
|
|
135
135
|
bind(PluginServer).toDynamicValue(ctx => {
|
|
136
136
|
const provider = ctx.container.get(WebSocketConnectionProvider);
|
|
137
137
|
return provider.createProxy<PluginServer>(pluginServerJsonRpcPath);
|
|
@@ -213,6 +213,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|
|
213
213
|
bind(LabelProviderContribution).toService(PluginIconThemeService);
|
|
214
214
|
|
|
215
215
|
bind(MenusContributionPointHandler).toSelf().inSingletonScope();
|
|
216
|
+
bind(PluginMenuCommandAdapter).toSelf().inSingletonScope();
|
|
216
217
|
bind(CodeEditorWidgetUtil).toSelf().inSingletonScope();
|
|
217
218
|
bind(KeybindingsContributionPointHandler).toSelf().inSingletonScope();
|
|
218
219
|
bind(PluginContributionHandler).toSelf().inSingletonScope();
|
|
@@ -16,25 +16,16 @@
|
|
|
16
16
|
|
|
17
17
|
import { injectable, inject } from '@theia/core/shared/inversify';
|
|
18
18
|
import { CommandRegistry, CommandContribution } from '@theia/core/lib/common';
|
|
19
|
-
import { PluginExtDeployCommandService } from './plugin-ext-deploy-command';
|
|
20
19
|
import { OpenUriCommandHandler } from './commands';
|
|
21
20
|
import URI from '@theia/core/lib/common/uri';
|
|
22
21
|
|
|
23
22
|
@injectable()
|
|
24
23
|
export class PluginApiFrontendContribution implements CommandContribution {
|
|
25
24
|
|
|
26
|
-
@inject(PluginExtDeployCommandService)
|
|
27
|
-
protected readonly pluginExtDeployCommandService: PluginExtDeployCommandService;
|
|
28
|
-
|
|
29
25
|
@inject(OpenUriCommandHandler)
|
|
30
26
|
protected readonly openUriCommandHandler: OpenUriCommandHandler;
|
|
31
27
|
|
|
32
28
|
registerCommands(commands: CommandRegistry): void {
|
|
33
|
-
|
|
34
|
-
commands.registerCommand(PluginExtDeployCommandService.COMMAND, {
|
|
35
|
-
execute: () => this.pluginExtDeployCommandService.deploy()
|
|
36
|
-
});
|
|
37
|
-
|
|
38
29
|
commands.registerCommand(OpenUriCommandHandler.COMMAND_METADATA, {
|
|
39
30
|
execute: (arg: URI) => this.openUriCommandHandler.execute(arg),
|
|
40
31
|
isVisible: () => false
|
|
@@ -111,7 +111,6 @@ export class PluginSharedStyle {
|
|
|
111
111
|
const iconClass = 'plugin-icon-' + this.iconSequence++;
|
|
112
112
|
const toDispose = new DisposableCollection();
|
|
113
113
|
toDispose.push(this.insertRule('.' + iconClass, theme => `
|
|
114
|
-
display: inline-block;
|
|
115
114
|
background-position: 2px;
|
|
116
115
|
width: ${size}px;
|
|
117
116
|
height: ${size}px;
|
|
@@ -430,4 +430,14 @@ export class ScmMainImpl implements ScmMain {
|
|
|
430
430
|
|
|
431
431
|
repository.input.placeholder = placeholder;
|
|
432
432
|
}
|
|
433
|
+
|
|
434
|
+
$setInputBoxVisible(sourceControlHandle: number, visible: boolean): void {
|
|
435
|
+
const repository = this.repositories.get(sourceControlHandle);
|
|
436
|
+
|
|
437
|
+
if (!repository) {
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
repository.input.visible = visible;
|
|
442
|
+
}
|
|
433
443
|
}
|
|
@@ -399,14 +399,14 @@ export class TreeViewWidget extends TreeViewWelcomeWidget {
|
|
|
399
399
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
400
400
|
protected renderInlineCommand(node: ActionMenuNode, index: number, tabbable: boolean, arg: any): React.ReactNode {
|
|
401
401
|
const { icon } = node;
|
|
402
|
-
if (!icon || !this.commands.isVisible(node.
|
|
402
|
+
if (!icon || !this.commands.isVisible(node.command, arg) || !node.when || !this.contextKeys.match(node.when)) {
|
|
403
403
|
return false;
|
|
404
404
|
}
|
|
405
405
|
const className = [TREE_NODE_SEGMENT_CLASS, TREE_NODE_TAIL_CLASS, icon, ACTION_ITEM, 'theia-tree-view-inline-action'].join(' ');
|
|
406
406
|
const tabIndex = tabbable ? 0 : undefined;
|
|
407
407
|
return <div key={index} className={className} title={node.label} tabIndex={tabIndex} onClick={e => {
|
|
408
408
|
e.stopPropagation();
|
|
409
|
-
this.commands.executeCommand(node.
|
|
409
|
+
this.commands.executeCommand(node.command, arg);
|
|
410
410
|
}} />;
|
|
411
411
|
}
|
|
412
412
|
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
import * as path from 'path';
|
|
18
17
|
import { PluginDeployerFileHandler, PluginDeployerEntry, PluginDeployerFileHandlerContext, PluginType } from '../../../common/plugin-protocol';
|
|
19
18
|
import { injectable, inject } from '@theia/core/shared/inversify';
|
|
20
19
|
import { getTempDir } from '../temp-dir-util';
|
|
@@ -22,7 +21,6 @@ import * as fs from '@theia/core/shared/fs-extra';
|
|
|
22
21
|
import * as filenamify from 'filenamify';
|
|
23
22
|
import { FileUri } from '@theia/core/lib/node/file-uri';
|
|
24
23
|
import { PluginTheiaEnvironment } from '../../common/plugin-theia-environment';
|
|
25
|
-
import URI from '@theia/core/lib/common/uri';
|
|
26
24
|
|
|
27
25
|
@injectable()
|
|
28
26
|
export class PluginTheiaFileHandler implements PluginDeployerFileHandler {
|
|
@@ -37,7 +35,6 @@ export class PluginTheiaFileHandler implements PluginDeployerFileHandler {
|
|
|
37
35
|
}
|
|
38
36
|
|
|
39
37
|
async handle(context: PluginDeployerFileHandlerContext): Promise<void> {
|
|
40
|
-
await this.ensureDiscoverability(context);
|
|
41
38
|
const id = context.pluginEntry().id();
|
|
42
39
|
const pluginDir = await this.getPluginDir(context);
|
|
43
40
|
console.log(`[${id}]: trying to decompress into "${pluginDir}"...`);
|
|
@@ -51,29 +48,6 @@ export class PluginTheiaFileHandler implements PluginDeployerFileHandler {
|
|
|
51
48
|
context.pluginEntry().updatePath(pluginDir);
|
|
52
49
|
}
|
|
53
50
|
|
|
54
|
-
/**
|
|
55
|
-
* Ensures that a user-installed plugin file is transferred to the user extension folder.
|
|
56
|
-
*/
|
|
57
|
-
protected async ensureDiscoverability(context: PluginDeployerFileHandlerContext): Promise<void> {
|
|
58
|
-
if (context.pluginEntry().type === PluginType.User) {
|
|
59
|
-
const userExtensionsDir = await this.environment.getPluginsDirUri();
|
|
60
|
-
const currentPath = context.pluginEntry().path();
|
|
61
|
-
if (!userExtensionsDir.isEqualOrParent(new URI(currentPath)) && !userExtensionsDir.isEqualOrParent(new URI(context.pluginEntry().originalPath()))) {
|
|
62
|
-
try {
|
|
63
|
-
const newPath = FileUri.fsPath(userExtensionsDir.resolve(path.basename(currentPath)));
|
|
64
|
-
await fs.mkdirp(FileUri.fsPath(userExtensionsDir));
|
|
65
|
-
await new Promise<void>((resolve, reject) => {
|
|
66
|
-
fs.copyFile(currentPath, newPath, error => error ? reject(error) : resolve());
|
|
67
|
-
});
|
|
68
|
-
context.pluginEntry().updatePath(newPath);
|
|
69
|
-
context.pluginEntry().storeValue('sourceLocations', [newPath]);
|
|
70
|
-
} catch (e) {
|
|
71
|
-
console.error(`[${context.pluginEntry().id}]: Failed to copy to user directory. Future sessions may not have access to this plugin.`);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
51
|
protected async getPluginDir(context: PluginDeployerFileHandlerContext): Promise<string> {
|
|
78
52
|
return FileUri.fsPath(this.systemPluginsDirUri.resolve(filenamify(context.pluginEntry().id(), { replacement: '_' })));
|
|
79
53
|
}
|
|
@@ -25,7 +25,6 @@ import {
|
|
|
25
25
|
PluginDeployerDirectoryHandler, PluginServer, pluginServerJsonRpcPath, PluginDeployerParticipant
|
|
26
26
|
} from '../../common/plugin-protocol';
|
|
27
27
|
import { PluginDeployerImpl } from './plugin-deployer-impl';
|
|
28
|
-
import { LocalFilePluginDeployerResolver } from './resolvers/local-file-plugin-deployer-resolver';
|
|
29
28
|
import { LocalDirectoryPluginDeployerResolver } from './resolvers/local-directory-plugin-deployer-resolver';
|
|
30
29
|
import { PluginTheiaFileHandler } from './handlers/plugin-theia-file-handler';
|
|
31
30
|
import { PluginTheiaDirectoryHandler } from './handlers/plugin-theia-directory-handler';
|
|
@@ -54,7 +53,6 @@ export function bindMainBackend(bind: interfaces.Bind): void {
|
|
|
54
53
|
bind(PluginUninstallationManager).toSelf().inSingletonScope();
|
|
55
54
|
|
|
56
55
|
bind(PluginDeployerResolver).to(LocalDirectoryPluginDeployerResolver).inSingletonScope();
|
|
57
|
-
bind(PluginDeployerResolver).to(LocalFilePluginDeployerResolver).inSingletonScope();
|
|
58
56
|
bind(PluginDeployerResolver).to(GithubPluginDeployerResolver).inSingletonScope();
|
|
59
57
|
bind(PluginDeployerResolver).to(HttpPluginDeployerResolver).inSingletonScope();
|
|
60
58
|
|
|
@@ -23,16 +23,14 @@ import URI from '@theia/core/lib/common/uri';
|
|
|
23
23
|
|
|
24
24
|
@injectable()
|
|
25
25
|
export abstract class LocalPluginDeployerResolver implements PluginDeployerResolver {
|
|
26
|
-
|
|
27
|
-
const localPath = await this.resolveLocalPluginPath(
|
|
28
|
-
pluginResolverContext,
|
|
29
|
-
this.supportedScheme);
|
|
26
|
+
async resolve(pluginResolverContext: PluginDeployerResolverContext): Promise<void> {
|
|
27
|
+
const localPath = await this.resolveLocalPluginPath(pluginResolverContext, this.supportedScheme);
|
|
30
28
|
if (localPath) {
|
|
31
29
|
await this.resolveFromLocalPath(pluginResolverContext, localPath);
|
|
32
30
|
}
|
|
33
31
|
}
|
|
34
32
|
|
|
35
|
-
|
|
33
|
+
accept(pluginId: string): boolean {
|
|
36
34
|
return pluginId.startsWith(this.supportedScheme);
|
|
37
35
|
}
|
|
38
36
|
|
|
@@ -40,9 +38,7 @@ export abstract class LocalPluginDeployerResolver implements PluginDeployerResol
|
|
|
40
38
|
|
|
41
39
|
protected abstract resolveFromLocalPath(pluginResolverContext: PluginDeployerResolverContext, localPath: string): Promise<void>;
|
|
42
40
|
|
|
43
|
-
private async resolveLocalPluginPath(
|
|
44
|
-
pluginResolverContext: PluginDeployerResolverContext,
|
|
45
|
-
expectedScheme: string): Promise<string | null> {
|
|
41
|
+
private async resolveLocalPluginPath(pluginResolverContext: PluginDeployerResolverContext, expectedScheme: string): Promise<string | null> {
|
|
46
42
|
const localUri = new URI(pluginResolverContext.getOriginId());
|
|
47
43
|
if (localUri.scheme !== expectedScheme) {
|
|
48
44
|
return null;
|
|
@@ -23,13 +23,15 @@ import { PluginPackageDebuggersContribution } from '../../common/plugin-protocol
|
|
|
23
23
|
import { RPCProtocol } from '../../common/rpc-protocol';
|
|
24
24
|
import { CommandRegistryImpl } from '../command-registry';
|
|
25
25
|
import { ConnectionImpl } from '../../common/connection';
|
|
26
|
-
import {
|
|
26
|
+
import { DEBUG_SCHEME, SCHEME_PATTERN } from '@theia/debug/lib/common/debug-uri-utils';
|
|
27
|
+
import { Disposable, Breakpoint as BreakpointExt, SourceBreakpoint, FunctionBreakpoint, Location, Range, URI as URIImpl } from '../types-impl';
|
|
27
28
|
import { PluginDebugAdapterSession } from './plugin-debug-adapter-session';
|
|
28
29
|
import { PluginDebugAdapterTracker } from './plugin-debug-adapter-tracker';
|
|
29
30
|
import uuid = require('uuid');
|
|
30
31
|
import { DebugAdapter } from '@theia/debug/lib/common/debug-model';
|
|
31
32
|
import { PluginDebugAdapterCreator } from './plugin-debug-adapter-creator';
|
|
32
33
|
import { NodeDebugAdapterCreator } from '../node/debug/plugin-node-debug-adapter-creator';
|
|
34
|
+
import { DebugProtocol } from 'vscode-debugprotocol';
|
|
33
35
|
|
|
34
36
|
interface ConfigurationProviderRecord {
|
|
35
37
|
handle: number;
|
|
@@ -176,6 +178,27 @@ export class DebugExtImpl implements DebugExt {
|
|
|
176
178
|
return this.proxy.$stopDebugging(session?.id);
|
|
177
179
|
}
|
|
178
180
|
|
|
181
|
+
asDebugSourceUri(source: theia.DebugProtocolSource, session?: theia.DebugSession): theia.Uri {
|
|
182
|
+
return this.getDebugSourceUri(source, session?.id);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
private getDebugSourceUri(raw: DebugProtocol.Source, sessionId?: string): theia.Uri {
|
|
186
|
+
if (raw.sourceReference && raw.sourceReference > 0) {
|
|
187
|
+
let query = 'ref=' + String(raw.sourceReference);
|
|
188
|
+
if (sessionId) {
|
|
189
|
+
query += `&session=${sessionId}`;
|
|
190
|
+
}
|
|
191
|
+
return URIImpl.from({ scheme: DEBUG_SCHEME, path: raw.path ?? '', query });
|
|
192
|
+
}
|
|
193
|
+
if (!raw.path) {
|
|
194
|
+
throw new Error('Unrecognized source type: ' + JSON.stringify(raw));
|
|
195
|
+
}
|
|
196
|
+
if (raw.path.match(SCHEME_PATTERN)) {
|
|
197
|
+
return URIImpl.parse(raw.path);
|
|
198
|
+
}
|
|
199
|
+
return URIImpl.file(raw.path);
|
|
200
|
+
}
|
|
201
|
+
|
|
179
202
|
registerDebugAdapterDescriptorFactory(debugType: string, factory: theia.DebugAdapterDescriptorFactory): Disposable {
|
|
180
203
|
if (this.descriptorFactories.has(debugType)) {
|
|
181
204
|
throw new Error(`Descriptor factory for ${debugType} has been already registered`);
|
|
@@ -279,13 +302,13 @@ export class DebugExtImpl implements DebugExt {
|
|
|
279
302
|
this.onDidChangeBreakpointsEmitter.fire({ added: a, removed: r, changed: c });
|
|
280
303
|
}
|
|
281
304
|
|
|
282
|
-
protected toBreakpointExt({ functionName, location, enabled, condition, hitCondition, logMessage }: Breakpoint): BreakpointExt | undefined {
|
|
305
|
+
protected toBreakpointExt({ functionName, location, enabled, condition, hitCondition, logMessage, id }: Breakpoint): BreakpointExt | undefined {
|
|
283
306
|
if (location) {
|
|
284
307
|
const range = new Range(location.range.startLineNumber, location.range.startColumn, location.range.endLineNumber, location.range.endColumn);
|
|
285
|
-
return new SourceBreakpoint(new Location(URI.revive(location.uri), range), enabled, condition, hitCondition, logMessage);
|
|
308
|
+
return new SourceBreakpoint(new Location(URI.revive(location.uri), range), enabled, condition, hitCondition, logMessage, id);
|
|
286
309
|
}
|
|
287
310
|
if (functionName) {
|
|
288
|
-
return new FunctionBreakpoint(functionName!, enabled, condition, hitCondition, logMessage);
|
|
311
|
+
return new FunctionBreakpoint(functionName!, enabled, condition, hitCondition, logMessage, id);
|
|
289
312
|
}
|
|
290
313
|
return undefined;
|
|
291
314
|
}
|
|
@@ -305,7 +328,9 @@ export class DebugExtImpl implements DebugExt {
|
|
|
305
328
|
return response.body;
|
|
306
329
|
}
|
|
307
330
|
return Promise.reject(new Error(response.message ?? 'custom request failed'));
|
|
308
|
-
}
|
|
331
|
+
},
|
|
332
|
+
getDebugProtocolBreakpoint: async (breakpoint: Breakpoint) =>
|
|
333
|
+
this.proxy.$getDebugProtocolBreakpoint(sessionId, breakpoint.id)
|
|
309
334
|
};
|
|
310
335
|
|
|
311
336
|
const tracker = await this.createDebugAdapterTracker(theiaSession);
|
|
@@ -61,6 +61,10 @@ export class PluginDebugAdapterSession extends DebugAdapterSessionImpl {
|
|
|
61
61
|
return this.theiaSession.customRequest(command, args);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
async getDebugProtocolBreakpoint(breakpoint: theia.Breakpoint): Promise<theia.DebugProtocolBreakpoint | undefined> {
|
|
65
|
+
return this.theiaSession.getDebugProtocolBreakpoint(breakpoint);
|
|
66
|
+
}
|
|
67
|
+
|
|
64
68
|
protected override onDebugAdapterError(error: Error): void {
|
|
65
69
|
if (this.tracker.onError) {
|
|
66
70
|
this.tracker.onError(error);
|