@theia/markers 1.45.0 → 1.46.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/README.md +33 -33
- package/lib/browser/index.d.ts +2 -2
- package/lib/browser/index.js +29 -29
- package/lib/browser/marker-manager.d.ts +47 -47
- package/lib/browser/marker-manager.js +187 -187
- package/lib/browser/marker-tree-label-provider.d.ts +15 -15
- package/lib/browser/marker-tree-label-provider.js +84 -84
- package/lib/browser/marker-tree-label-provider.spec.d.ts +1 -1
- package/lib/browser/marker-tree-label-provider.spec.js +201 -201
- package/lib/browser/marker-tree-model.d.ts +12 -12
- package/lib/browser/marker-tree-model.js +60 -60
- package/lib/browser/marker-tree.d.ts +42 -42
- package/lib/browser/marker-tree.js +143 -143
- package/lib/browser/problem/problem-composite-tree-node.d.ts +11 -11
- package/lib/browser/problem/problem-composite-tree-node.js +76 -76
- package/lib/browser/problem/problem-composite-tree-node.spec.d.ts +1 -1
- package/lib/browser/problem/problem-composite-tree-node.spec.js +238 -238
- package/lib/browser/problem/problem-container.d.ts +8 -8
- package/lib/browser/problem/problem-container.js +46 -46
- package/lib/browser/problem/problem-contribution.d.ts +51 -51
- package/lib/browser/problem/problem-contribution.js +247 -247
- package/lib/browser/problem/problem-decorations-provider.d.ts +21 -21
- package/lib/browser/problem/problem-decorations-provider.js +95 -95
- package/lib/browser/problem/problem-decorator.d.ts +57 -57
- package/lib/browser/problem/problem-decorator.js +233 -233
- package/lib/browser/problem/problem-frontend-module.d.ts +4 -4
- package/lib/browser/problem/problem-frontend-module.js +55 -55
- package/lib/browser/problem/problem-layout-migrations.d.ts +5 -5
- package/lib/browser/problem/problem-layout-migrations.js +43 -43
- package/lib/browser/problem/problem-manager.d.ts +11 -11
- package/lib/browser/problem/problem-manager.js +53 -53
- package/lib/browser/problem/problem-manager.spec.d.ts +1 -1
- package/lib/browser/problem/problem-manager.spec.js +167 -167
- package/lib/browser/problem/problem-preferences.d.ts +13 -13
- package/lib/browser/problem/problem-preferences.js +56 -56
- package/lib/browser/problem/problem-selection.d.ts +12 -12
- package/lib/browser/problem/problem-selection.js +34 -34
- package/lib/browser/problem/problem-tabbar-decorator.d.ts +42 -42
- package/lib/browser/problem/problem-tabbar-decorator.js +160 -160
- package/lib/browser/problem/problem-tree-model.d.ts +32 -32
- package/lib/browser/problem/problem-tree-model.js +131 -131
- package/lib/browser/problem/problem-tree-model.spec.d.ts +1 -1
- package/lib/browser/problem/problem-tree-model.spec.js +172 -172
- package/lib/browser/problem/problem-utils.d.ts +44 -44
- package/lib/browser/problem/problem-utils.js +84 -84
- package/lib/browser/problem/problem-widget-tab-bar-decorator.d.ts +14 -14
- package/lib/browser/problem/problem-widget-tab-bar-decorator.js +69 -69
- package/lib/browser/problem/problem-widget.d.ts +46 -46
- package/lib/browser/problem/problem-widget.js +235 -235
- package/lib/common/marker.d.ts +16 -16
- package/lib/common/marker.js +31 -31
- package/lib/common/problem-marker.d.ts +9 -9
- package/lib/common/problem-marker.js +27 -27
- package/package.json +6 -6
- package/src/browser/index.ts +18 -18
- package/src/browser/marker-manager.ts +205 -205
- package/src/browser/marker-tree-label-provider.spec.ts +245 -245
- package/src/browser/marker-tree-label-provider.ts +75 -75
- package/src/browser/marker-tree-model.ts +47 -47
- package/src/browser/marker-tree.ts +154 -154
- package/src/browser/problem/problem-composite-tree-node.spec.ts +277 -277
- package/src/browser/problem/problem-composite-tree-node.ts +81 -81
- package/src/browser/problem/problem-container.ts +47 -47
- package/src/browser/problem/problem-contribution.ts +247 -247
- package/src/browser/problem/problem-decorations-provider.ts +72 -72
- package/src/browser/problem/problem-decorator.ts +222 -222
- package/src/browser/problem/problem-frontend-module.ts +64 -64
- package/src/browser/problem/problem-layout-migrations.ts +32 -32
- package/src/browser/problem/problem-manager.spec.ts +216 -216
- package/src/browser/problem/problem-manager.ts +51 -51
- package/src/browser/problem/problem-preferences.ts +64 -64
- package/src/browser/problem/problem-selection.ts +45 -45
- package/src/browser/problem/problem-tabbar-decorator.ts +151 -151
- package/src/browser/problem/problem-tree-model.spec.ts +189 -189
- package/src/browser/problem/problem-tree-model.ts +124 -124
- package/src/browser/problem/problem-utils.ts +90 -90
- package/src/browser/problem/problem-widget-tab-bar-decorator.ts +55 -55
- package/src/browser/problem/problem-widget.tsx +246 -246
- package/src/browser/style/index.css +92 -92
- package/src/common/marker.ts +53 -53
- package/src/common/problem-marker.ts +30 -30
|
@@ -1,247 +1,247 @@
|
|
|
1
|
-
// *****************************************************************************
|
|
2
|
-
// Copyright (C) 2017 TypeFox 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 debounce = require('@theia/core/shared/lodash.debounce');
|
|
18
|
-
import { injectable, inject } from '@theia/core/shared/inversify';
|
|
19
|
-
import { FrontendApplication, FrontendApplicationContribution, CompositeTreeNode, SelectableTreeNode, Widget, codicon } from '@theia/core/lib/browser';
|
|
20
|
-
import { StatusBar, StatusBarAlignment } from '@theia/core/lib/browser/status-bar/status-bar';
|
|
21
|
-
import { AbstractViewContribution } from '@theia/core/lib/browser/shell/view-contribution';
|
|
22
|
-
import { PROBLEM_KIND, ProblemMarker } from '../../common/problem-marker';
|
|
23
|
-
import { ProblemManager, ProblemStat } from './problem-manager';
|
|
24
|
-
import { ProblemWidget, PROBLEMS_WIDGET_ID } from './problem-widget';
|
|
25
|
-
import { MenuPath, MenuModelRegistry } from '@theia/core/lib/common/menu';
|
|
26
|
-
import { Command, CommandRegistry } from '@theia/core/lib/common/command';
|
|
27
|
-
import { TabBarToolbarContribution, TabBarToolbarRegistry } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
|
|
28
|
-
import { SelectionService } from '@theia/core/lib/common/selection-service';
|
|
29
|
-
import { ProblemSelection } from './problem-selection';
|
|
30
|
-
import { nls } from '@theia/core/lib/common/nls';
|
|
31
|
-
|
|
32
|
-
export const PROBLEMS_CONTEXT_MENU: MenuPath = [PROBLEM_KIND];
|
|
33
|
-
|
|
34
|
-
export namespace ProblemsMenu {
|
|
35
|
-
export const CLIPBOARD = [...PROBLEMS_CONTEXT_MENU, '1_clipboard'];
|
|
36
|
-
export const PROBLEMS = [...PROBLEMS_CONTEXT_MENU, '2_problems'];
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export namespace ProblemsCommands {
|
|
40
|
-
export const COLLAPSE_ALL: Command = {
|
|
41
|
-
id: 'problems.collapse.all'
|
|
42
|
-
};
|
|
43
|
-
export const COLLAPSE_ALL_TOOLBAR: Command = {
|
|
44
|
-
id: 'problems.collapse.all.toolbar',
|
|
45
|
-
iconClass: codicon('collapse-all')
|
|
46
|
-
};
|
|
47
|
-
export const COPY: Command = {
|
|
48
|
-
id: 'problems.copy'
|
|
49
|
-
};
|
|
50
|
-
export const COPY_MESSAGE: Command = {
|
|
51
|
-
id: 'problems.copy.message',
|
|
52
|
-
};
|
|
53
|
-
export const CLEAR_ALL = Command.toLocalizedCommand({
|
|
54
|
-
id: 'problems.clear.all',
|
|
55
|
-
category: 'Problems',
|
|
56
|
-
label: 'Clear All',
|
|
57
|
-
iconClass: codicon('clear-all')
|
|
58
|
-
}, 'theia/markers/clearAll', nls.getDefaultKey('Problems'));
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
@injectable()
|
|
62
|
-
export class ProblemContribution extends AbstractViewContribution<ProblemWidget> implements FrontendApplicationContribution, TabBarToolbarContribution {
|
|
63
|
-
|
|
64
|
-
@inject(ProblemManager) protected readonly problemManager: ProblemManager;
|
|
65
|
-
@inject(StatusBar) protected readonly statusBar: StatusBar;
|
|
66
|
-
@inject(SelectionService) protected readonly selectionService: SelectionService;
|
|
67
|
-
|
|
68
|
-
constructor() {
|
|
69
|
-
super({
|
|
70
|
-
widgetId: PROBLEMS_WIDGET_ID,
|
|
71
|
-
widgetName: nls.localizeByDefault('Problems'),
|
|
72
|
-
defaultWidgetOptions: {
|
|
73
|
-
area: 'bottom'
|
|
74
|
-
},
|
|
75
|
-
toggleCommandId: 'problemsView:toggle',
|
|
76
|
-
toggleKeybinding: 'ctrlcmd+shift+m'
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
onStart(app: FrontendApplication): void {
|
|
81
|
-
this.updateStatusBarElement();
|
|
82
|
-
this.problemManager.onDidChangeMarkers(this.updateStatusBarElement);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
async initializeLayout(app: FrontendApplication): Promise<void> {
|
|
86
|
-
await this.openView();
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
protected updateStatusBarElement = debounce(() => this.setStatusBarElement(this.problemManager.getProblemStat()), 10);
|
|
90
|
-
protected setStatusBarElement(problemStat: ProblemStat): void {
|
|
91
|
-
this.statusBar.setElement('problem-marker-status', {
|
|
92
|
-
text: problemStat.infos <= 0
|
|
93
|
-
? `$(codicon-error) ${problemStat.errors} $(codicon-warning) ${problemStat.warnings}`
|
|
94
|
-
: `$(codicon-error) ${problemStat.errors} $(codicon-warning) ${problemStat.warnings} $(codicon-info) ${problemStat.infos}`,
|
|
95
|
-
alignment: StatusBarAlignment.LEFT,
|
|
96
|
-
priority: 10,
|
|
97
|
-
command: this.toggleCommand ? this.toggleCommand.id : undefined,
|
|
98
|
-
tooltip: this.getStatusBarTooltip(problemStat)
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Get the tooltip to be displayed when hovering over the problem statusbar item.
|
|
104
|
-
* - Displays `No Problems` when no problems are present.
|
|
105
|
-
* - Displays a human-readable label which describes for each type of problem stat properties,
|
|
106
|
-
* their overall count and type when any one of these properties has a positive count.
|
|
107
|
-
* @param stat the problem stat describing the number of `errors`, `warnings` and `infos`.
|
|
108
|
-
*
|
|
109
|
-
* @return the tooltip to be displayed in the statusbar.
|
|
110
|
-
*/
|
|
111
|
-
protected getStatusBarTooltip(stat: ProblemStat): string {
|
|
112
|
-
if (stat.errors <= 0 && stat.warnings <= 0 && stat.infos <= 0) {
|
|
113
|
-
return nls.localizeByDefault('No Problems');
|
|
114
|
-
}
|
|
115
|
-
const tooltip: string[] = [];
|
|
116
|
-
if (stat.errors > 0) {
|
|
117
|
-
tooltip.push(nls.localizeByDefault('{0} Errors', stat.errors));
|
|
118
|
-
}
|
|
119
|
-
if (stat.warnings > 0) {
|
|
120
|
-
tooltip.push(nls.localizeByDefault('{0} Warnings', stat.warnings));
|
|
121
|
-
}
|
|
122
|
-
if (stat.infos > 0) {
|
|
123
|
-
tooltip.push(nls.localizeByDefault('{0} Infos', stat.infos));
|
|
124
|
-
}
|
|
125
|
-
return tooltip.join(', ');
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
override registerCommands(commands: CommandRegistry): void {
|
|
130
|
-
super.registerCommands(commands);
|
|
131
|
-
commands.registerCommand(ProblemsCommands.COLLAPSE_ALL, {
|
|
132
|
-
execute: () => this.collapseAllProblems()
|
|
133
|
-
});
|
|
134
|
-
commands.registerCommand(ProblemsCommands.COLLAPSE_ALL_TOOLBAR, {
|
|
135
|
-
isEnabled: widget => this.withWidget(widget, () => true),
|
|
136
|
-
isVisible: widget => this.withWidget(widget, () => true),
|
|
137
|
-
execute: widget => this.withWidget(widget, () => this.collapseAllProblems())
|
|
138
|
-
});
|
|
139
|
-
commands.registerCommand(ProblemsCommands.COPY,
|
|
140
|
-
new ProblemSelection.CommandHandler(this.selectionService, {
|
|
141
|
-
multi: false,
|
|
142
|
-
isEnabled: () => true,
|
|
143
|
-
isVisible: () => true,
|
|
144
|
-
execute: selection => this.copy(selection)
|
|
145
|
-
})
|
|
146
|
-
);
|
|
147
|
-
commands.registerCommand(ProblemsCommands.COPY_MESSAGE,
|
|
148
|
-
new ProblemSelection.CommandHandler(this.selectionService, {
|
|
149
|
-
multi: false,
|
|
150
|
-
isEnabled: () => true,
|
|
151
|
-
isVisible: () => true,
|
|
152
|
-
execute: selection => this.copyMessage(selection)
|
|
153
|
-
})
|
|
154
|
-
);
|
|
155
|
-
commands.registerCommand(ProblemsCommands.CLEAR_ALL, {
|
|
156
|
-
isEnabled: widget => this.withWidget(widget, () => true),
|
|
157
|
-
isVisible: widget => this.withWidget(widget, () => true),
|
|
158
|
-
execute: widget => this.withWidget(widget, () => this.problemManager.cleanAllMarkers())
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
override registerMenus(menus: MenuModelRegistry): void {
|
|
163
|
-
super.registerMenus(menus);
|
|
164
|
-
menus.registerMenuAction(ProblemsMenu.CLIPBOARD, {
|
|
165
|
-
commandId: ProblemsCommands.COPY.id,
|
|
166
|
-
label: nls.localizeByDefault('Copy'),
|
|
167
|
-
order: '0'
|
|
168
|
-
});
|
|
169
|
-
menus.registerMenuAction(ProblemsMenu.CLIPBOARD, {
|
|
170
|
-
commandId: ProblemsCommands.COPY_MESSAGE.id,
|
|
171
|
-
label: nls.localizeByDefault('Copy Message'),
|
|
172
|
-
order: '1'
|
|
173
|
-
});
|
|
174
|
-
menus.registerMenuAction(ProblemsMenu.PROBLEMS, {
|
|
175
|
-
commandId: ProblemsCommands.COLLAPSE_ALL.id,
|
|
176
|
-
label: nls.localizeByDefault('Collapse All'),
|
|
177
|
-
order: '2'
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
async registerToolbarItems(toolbarRegistry: TabBarToolbarRegistry): Promise<void> {
|
|
182
|
-
toolbarRegistry.registerItem({
|
|
183
|
-
id: ProblemsCommands.COLLAPSE_ALL_TOOLBAR.id,
|
|
184
|
-
command: ProblemsCommands.COLLAPSE_ALL_TOOLBAR.id,
|
|
185
|
-
tooltip: nls.localizeByDefault('Collapse All'),
|
|
186
|
-
priority: 0,
|
|
187
|
-
});
|
|
188
|
-
toolbarRegistry.registerItem({
|
|
189
|
-
id: ProblemsCommands.CLEAR_ALL.id,
|
|
190
|
-
command: ProblemsCommands.CLEAR_ALL.id,
|
|
191
|
-
tooltip: ProblemsCommands.CLEAR_ALL.label,
|
|
192
|
-
priority: 1,
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
protected async collapseAllProblems(): Promise<void> {
|
|
197
|
-
const { model } = await this.widget;
|
|
198
|
-
const root = model.root as CompositeTreeNode;
|
|
199
|
-
const firstChild = root.children[0];
|
|
200
|
-
root.children.forEach(child => CompositeTreeNode.is(child) && model.collapseAll(child));
|
|
201
|
-
if (SelectableTreeNode.is(firstChild)) {
|
|
202
|
-
model.selectNode(firstChild);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
protected addToClipboard(content: string): void {
|
|
207
|
-
const handleCopy = (e: ClipboardEvent) => {
|
|
208
|
-
document.removeEventListener('copy', handleCopy);
|
|
209
|
-
if (e.clipboardData) {
|
|
210
|
-
e.clipboardData.setData('text/plain', content);
|
|
211
|
-
e.preventDefault();
|
|
212
|
-
}
|
|
213
|
-
};
|
|
214
|
-
document.addEventListener('copy', handleCopy);
|
|
215
|
-
document.execCommand('copy');
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
protected copy(selection: ProblemSelection): void {
|
|
219
|
-
const marker = selection.marker as ProblemMarker;
|
|
220
|
-
const serializedProblem = JSON.stringify({
|
|
221
|
-
resource: marker.uri,
|
|
222
|
-
owner: marker.owner,
|
|
223
|
-
code: marker.data.code,
|
|
224
|
-
severity: marker.data.severity,
|
|
225
|
-
message: marker.data.message,
|
|
226
|
-
source: marker.data.source,
|
|
227
|
-
startLineNumber: marker.data.range.start.line,
|
|
228
|
-
startColumn: marker.data.range.start.character,
|
|
229
|
-
endLineNumber: marker.data.range.end.line,
|
|
230
|
-
endColumn: marker.data.range.end.character
|
|
231
|
-
}, undefined, '\t');
|
|
232
|
-
|
|
233
|
-
this.addToClipboard(serializedProblem);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
protected copyMessage(selection: ProblemSelection): void {
|
|
237
|
-
const marker = selection.marker as ProblemMarker;
|
|
238
|
-
this.addToClipboard(marker.data.message);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
protected withWidget<T>(widget: Widget | undefined = this.tryGetWidget(), cb: (problems: ProblemWidget) => T): T | false {
|
|
242
|
-
if (widget instanceof ProblemWidget && widget.id === PROBLEMS_WIDGET_ID) {
|
|
243
|
-
return cb(widget);
|
|
244
|
-
}
|
|
245
|
-
return false;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2017 TypeFox 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 debounce = require('@theia/core/shared/lodash.debounce');
|
|
18
|
+
import { injectable, inject } from '@theia/core/shared/inversify';
|
|
19
|
+
import { FrontendApplication, FrontendApplicationContribution, CompositeTreeNode, SelectableTreeNode, Widget, codicon } from '@theia/core/lib/browser';
|
|
20
|
+
import { StatusBar, StatusBarAlignment } from '@theia/core/lib/browser/status-bar/status-bar';
|
|
21
|
+
import { AbstractViewContribution } from '@theia/core/lib/browser/shell/view-contribution';
|
|
22
|
+
import { PROBLEM_KIND, ProblemMarker } from '../../common/problem-marker';
|
|
23
|
+
import { ProblemManager, ProblemStat } from './problem-manager';
|
|
24
|
+
import { ProblemWidget, PROBLEMS_WIDGET_ID } from './problem-widget';
|
|
25
|
+
import { MenuPath, MenuModelRegistry } from '@theia/core/lib/common/menu';
|
|
26
|
+
import { Command, CommandRegistry } from '@theia/core/lib/common/command';
|
|
27
|
+
import { TabBarToolbarContribution, TabBarToolbarRegistry } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
|
|
28
|
+
import { SelectionService } from '@theia/core/lib/common/selection-service';
|
|
29
|
+
import { ProblemSelection } from './problem-selection';
|
|
30
|
+
import { nls } from '@theia/core/lib/common/nls';
|
|
31
|
+
|
|
32
|
+
export const PROBLEMS_CONTEXT_MENU: MenuPath = [PROBLEM_KIND];
|
|
33
|
+
|
|
34
|
+
export namespace ProblemsMenu {
|
|
35
|
+
export const CLIPBOARD = [...PROBLEMS_CONTEXT_MENU, '1_clipboard'];
|
|
36
|
+
export const PROBLEMS = [...PROBLEMS_CONTEXT_MENU, '2_problems'];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export namespace ProblemsCommands {
|
|
40
|
+
export const COLLAPSE_ALL: Command = {
|
|
41
|
+
id: 'problems.collapse.all'
|
|
42
|
+
};
|
|
43
|
+
export const COLLAPSE_ALL_TOOLBAR: Command = {
|
|
44
|
+
id: 'problems.collapse.all.toolbar',
|
|
45
|
+
iconClass: codicon('collapse-all')
|
|
46
|
+
};
|
|
47
|
+
export const COPY: Command = {
|
|
48
|
+
id: 'problems.copy'
|
|
49
|
+
};
|
|
50
|
+
export const COPY_MESSAGE: Command = {
|
|
51
|
+
id: 'problems.copy.message',
|
|
52
|
+
};
|
|
53
|
+
export const CLEAR_ALL = Command.toLocalizedCommand({
|
|
54
|
+
id: 'problems.clear.all',
|
|
55
|
+
category: 'Problems',
|
|
56
|
+
label: 'Clear All',
|
|
57
|
+
iconClass: codicon('clear-all')
|
|
58
|
+
}, 'theia/markers/clearAll', nls.getDefaultKey('Problems'));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@injectable()
|
|
62
|
+
export class ProblemContribution extends AbstractViewContribution<ProblemWidget> implements FrontendApplicationContribution, TabBarToolbarContribution {
|
|
63
|
+
|
|
64
|
+
@inject(ProblemManager) protected readonly problemManager: ProblemManager;
|
|
65
|
+
@inject(StatusBar) protected readonly statusBar: StatusBar;
|
|
66
|
+
@inject(SelectionService) protected readonly selectionService: SelectionService;
|
|
67
|
+
|
|
68
|
+
constructor() {
|
|
69
|
+
super({
|
|
70
|
+
widgetId: PROBLEMS_WIDGET_ID,
|
|
71
|
+
widgetName: nls.localizeByDefault('Problems'),
|
|
72
|
+
defaultWidgetOptions: {
|
|
73
|
+
area: 'bottom'
|
|
74
|
+
},
|
|
75
|
+
toggleCommandId: 'problemsView:toggle',
|
|
76
|
+
toggleKeybinding: 'ctrlcmd+shift+m'
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
onStart(app: FrontendApplication): void {
|
|
81
|
+
this.updateStatusBarElement();
|
|
82
|
+
this.problemManager.onDidChangeMarkers(this.updateStatusBarElement);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async initializeLayout(app: FrontendApplication): Promise<void> {
|
|
86
|
+
await this.openView();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
protected updateStatusBarElement = debounce(() => this.setStatusBarElement(this.problemManager.getProblemStat()), 10);
|
|
90
|
+
protected setStatusBarElement(problemStat: ProblemStat): void {
|
|
91
|
+
this.statusBar.setElement('problem-marker-status', {
|
|
92
|
+
text: problemStat.infos <= 0
|
|
93
|
+
? `$(codicon-error) ${problemStat.errors} $(codicon-warning) ${problemStat.warnings}`
|
|
94
|
+
: `$(codicon-error) ${problemStat.errors} $(codicon-warning) ${problemStat.warnings} $(codicon-info) ${problemStat.infos}`,
|
|
95
|
+
alignment: StatusBarAlignment.LEFT,
|
|
96
|
+
priority: 10,
|
|
97
|
+
command: this.toggleCommand ? this.toggleCommand.id : undefined,
|
|
98
|
+
tooltip: this.getStatusBarTooltip(problemStat)
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Get the tooltip to be displayed when hovering over the problem statusbar item.
|
|
104
|
+
* - Displays `No Problems` when no problems are present.
|
|
105
|
+
* - Displays a human-readable label which describes for each type of problem stat properties,
|
|
106
|
+
* their overall count and type when any one of these properties has a positive count.
|
|
107
|
+
* @param stat the problem stat describing the number of `errors`, `warnings` and `infos`.
|
|
108
|
+
*
|
|
109
|
+
* @return the tooltip to be displayed in the statusbar.
|
|
110
|
+
*/
|
|
111
|
+
protected getStatusBarTooltip(stat: ProblemStat): string {
|
|
112
|
+
if (stat.errors <= 0 && stat.warnings <= 0 && stat.infos <= 0) {
|
|
113
|
+
return nls.localizeByDefault('No Problems');
|
|
114
|
+
}
|
|
115
|
+
const tooltip: string[] = [];
|
|
116
|
+
if (stat.errors > 0) {
|
|
117
|
+
tooltip.push(nls.localizeByDefault('{0} Errors', stat.errors));
|
|
118
|
+
}
|
|
119
|
+
if (stat.warnings > 0) {
|
|
120
|
+
tooltip.push(nls.localizeByDefault('{0} Warnings', stat.warnings));
|
|
121
|
+
}
|
|
122
|
+
if (stat.infos > 0) {
|
|
123
|
+
tooltip.push(nls.localizeByDefault('{0} Infos', stat.infos));
|
|
124
|
+
}
|
|
125
|
+
return tooltip.join(', ');
|
|
126
|
+
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
override registerCommands(commands: CommandRegistry): void {
|
|
130
|
+
super.registerCommands(commands);
|
|
131
|
+
commands.registerCommand(ProblemsCommands.COLLAPSE_ALL, {
|
|
132
|
+
execute: () => this.collapseAllProblems()
|
|
133
|
+
});
|
|
134
|
+
commands.registerCommand(ProblemsCommands.COLLAPSE_ALL_TOOLBAR, {
|
|
135
|
+
isEnabled: widget => this.withWidget(widget, () => true),
|
|
136
|
+
isVisible: widget => this.withWidget(widget, () => true),
|
|
137
|
+
execute: widget => this.withWidget(widget, () => this.collapseAllProblems())
|
|
138
|
+
});
|
|
139
|
+
commands.registerCommand(ProblemsCommands.COPY,
|
|
140
|
+
new ProblemSelection.CommandHandler(this.selectionService, {
|
|
141
|
+
multi: false,
|
|
142
|
+
isEnabled: () => true,
|
|
143
|
+
isVisible: () => true,
|
|
144
|
+
execute: selection => this.copy(selection)
|
|
145
|
+
})
|
|
146
|
+
);
|
|
147
|
+
commands.registerCommand(ProblemsCommands.COPY_MESSAGE,
|
|
148
|
+
new ProblemSelection.CommandHandler(this.selectionService, {
|
|
149
|
+
multi: false,
|
|
150
|
+
isEnabled: () => true,
|
|
151
|
+
isVisible: () => true,
|
|
152
|
+
execute: selection => this.copyMessage(selection)
|
|
153
|
+
})
|
|
154
|
+
);
|
|
155
|
+
commands.registerCommand(ProblemsCommands.CLEAR_ALL, {
|
|
156
|
+
isEnabled: widget => this.withWidget(widget, () => true),
|
|
157
|
+
isVisible: widget => this.withWidget(widget, () => true),
|
|
158
|
+
execute: widget => this.withWidget(widget, () => this.problemManager.cleanAllMarkers())
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
override registerMenus(menus: MenuModelRegistry): void {
|
|
163
|
+
super.registerMenus(menus);
|
|
164
|
+
menus.registerMenuAction(ProblemsMenu.CLIPBOARD, {
|
|
165
|
+
commandId: ProblemsCommands.COPY.id,
|
|
166
|
+
label: nls.localizeByDefault('Copy'),
|
|
167
|
+
order: '0'
|
|
168
|
+
});
|
|
169
|
+
menus.registerMenuAction(ProblemsMenu.CLIPBOARD, {
|
|
170
|
+
commandId: ProblemsCommands.COPY_MESSAGE.id,
|
|
171
|
+
label: nls.localizeByDefault('Copy Message'),
|
|
172
|
+
order: '1'
|
|
173
|
+
});
|
|
174
|
+
menus.registerMenuAction(ProblemsMenu.PROBLEMS, {
|
|
175
|
+
commandId: ProblemsCommands.COLLAPSE_ALL.id,
|
|
176
|
+
label: nls.localizeByDefault('Collapse All'),
|
|
177
|
+
order: '2'
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
async registerToolbarItems(toolbarRegistry: TabBarToolbarRegistry): Promise<void> {
|
|
182
|
+
toolbarRegistry.registerItem({
|
|
183
|
+
id: ProblemsCommands.COLLAPSE_ALL_TOOLBAR.id,
|
|
184
|
+
command: ProblemsCommands.COLLAPSE_ALL_TOOLBAR.id,
|
|
185
|
+
tooltip: nls.localizeByDefault('Collapse All'),
|
|
186
|
+
priority: 0,
|
|
187
|
+
});
|
|
188
|
+
toolbarRegistry.registerItem({
|
|
189
|
+
id: ProblemsCommands.CLEAR_ALL.id,
|
|
190
|
+
command: ProblemsCommands.CLEAR_ALL.id,
|
|
191
|
+
tooltip: ProblemsCommands.CLEAR_ALL.label,
|
|
192
|
+
priority: 1,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
protected async collapseAllProblems(): Promise<void> {
|
|
197
|
+
const { model } = await this.widget;
|
|
198
|
+
const root = model.root as CompositeTreeNode;
|
|
199
|
+
const firstChild = root.children[0];
|
|
200
|
+
root.children.forEach(child => CompositeTreeNode.is(child) && model.collapseAll(child));
|
|
201
|
+
if (SelectableTreeNode.is(firstChild)) {
|
|
202
|
+
model.selectNode(firstChild);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
protected addToClipboard(content: string): void {
|
|
207
|
+
const handleCopy = (e: ClipboardEvent) => {
|
|
208
|
+
document.removeEventListener('copy', handleCopy);
|
|
209
|
+
if (e.clipboardData) {
|
|
210
|
+
e.clipboardData.setData('text/plain', content);
|
|
211
|
+
e.preventDefault();
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
document.addEventListener('copy', handleCopy);
|
|
215
|
+
document.execCommand('copy');
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
protected copy(selection: ProblemSelection): void {
|
|
219
|
+
const marker = selection.marker as ProblemMarker;
|
|
220
|
+
const serializedProblem = JSON.stringify({
|
|
221
|
+
resource: marker.uri,
|
|
222
|
+
owner: marker.owner,
|
|
223
|
+
code: marker.data.code,
|
|
224
|
+
severity: marker.data.severity,
|
|
225
|
+
message: marker.data.message,
|
|
226
|
+
source: marker.data.source,
|
|
227
|
+
startLineNumber: marker.data.range.start.line,
|
|
228
|
+
startColumn: marker.data.range.start.character,
|
|
229
|
+
endLineNumber: marker.data.range.end.line,
|
|
230
|
+
endColumn: marker.data.range.end.character
|
|
231
|
+
}, undefined, '\t');
|
|
232
|
+
|
|
233
|
+
this.addToClipboard(serializedProblem);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
protected copyMessage(selection: ProblemSelection): void {
|
|
237
|
+
const marker = selection.marker as ProblemMarker;
|
|
238
|
+
this.addToClipboard(marker.data.message);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
protected withWidget<T>(widget: Widget | undefined = this.tryGetWidget(), cb: (problems: ProblemWidget) => T): T | false {
|
|
242
|
+
if (widget instanceof ProblemWidget && widget.id === PROBLEMS_WIDGET_ID) {
|
|
243
|
+
return cb(widget);
|
|
244
|
+
}
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
@@ -1,72 +1,72 @@
|
|
|
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-only WITH Classpath-exception-2.0
|
|
15
|
-
// *****************************************************************************
|
|
16
|
-
|
|
17
|
-
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
|
|
18
|
-
import URI from '@theia/core/lib/common/uri';
|
|
19
|
-
import { Decoration, DecorationsProvider, DecorationsService } from '@theia/core/lib/browser/decorations-service';
|
|
20
|
-
import { ProblemManager } from './problem-manager';
|
|
21
|
-
import { ProblemUtils } from './problem-utils';
|
|
22
|
-
import { FrontendApplicationContribution } from '@theia/core/lib/browser';
|
|
23
|
-
import { CancellationToken, Emitter, Event, nls } from '@theia/core';
|
|
24
|
-
import debounce = require('@theia/core/shared/lodash.debounce');
|
|
25
|
-
|
|
26
|
-
@injectable()
|
|
27
|
-
export class ProblemDecorationsProvider implements DecorationsProvider {
|
|
28
|
-
@inject(ProblemManager) protected readonly problemManager: ProblemManager;
|
|
29
|
-
|
|
30
|
-
protected currentUris: URI[] = [];
|
|
31
|
-
|
|
32
|
-
protected readonly onDidChangeEmitter = new Emitter<URI[]>();
|
|
33
|
-
get onDidChange(): Event<URI[]> {
|
|
34
|
-
return this.onDidChangeEmitter.event;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
@postConstruct()
|
|
38
|
-
protected init(): void {
|
|
39
|
-
this.problemManager.onDidChangeMarkers(() => this.fireDidDecorationsChanged());
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
protected fireDidDecorationsChanged = debounce(() => this.doFireDidDecorationsChanged(), 50);
|
|
43
|
-
|
|
44
|
-
protected doFireDidDecorationsChanged(): void {
|
|
45
|
-
const newUris = Array.from(this.problemManager.getUris(), stringified => new URI(stringified));
|
|
46
|
-
this.onDidChangeEmitter.fire(newUris.concat(this.currentUris));
|
|
47
|
-
this.currentUris = newUris;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
provideDecorations(uri: URI, token: CancellationToken): Decoration | Promise<Decoration | undefined> | undefined {
|
|
51
|
-
const markers = this.problemManager.findMarkers({ uri }).filter(ProblemUtils.filterMarker).sort(ProblemUtils.severityCompareMarker);
|
|
52
|
-
if (markers.length) {
|
|
53
|
-
return {
|
|
54
|
-
bubble: true,
|
|
55
|
-
letter: markers.length.toString(),
|
|
56
|
-
weight: ProblemUtils.getPriority(markers[0]),
|
|
57
|
-
colorId: ProblemUtils.getColor(markers[0]),
|
|
58
|
-
tooltip: markers.length === 1 ? nls.localizeByDefault('1 problem in this file') : nls.localizeByDefault('{0} problems in this file', markers.length),
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
@injectable()
|
|
65
|
-
export class ProblemDecorationContribution implements FrontendApplicationContribution {
|
|
66
|
-
@inject(DecorationsService) protected readonly decorationsService: DecorationsService;
|
|
67
|
-
@inject(ProblemDecorationsProvider) protected readonly problemDecorationProvider: ProblemDecorationsProvider;
|
|
68
|
-
|
|
69
|
-
initialize(): void {
|
|
70
|
-
this.decorationsService.registerDecorationsProvider(this.problemDecorationProvider);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
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-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
|
|
18
|
+
import URI from '@theia/core/lib/common/uri';
|
|
19
|
+
import { Decoration, DecorationsProvider, DecorationsService } from '@theia/core/lib/browser/decorations-service';
|
|
20
|
+
import { ProblemManager } from './problem-manager';
|
|
21
|
+
import { ProblemUtils } from './problem-utils';
|
|
22
|
+
import { FrontendApplicationContribution } from '@theia/core/lib/browser';
|
|
23
|
+
import { CancellationToken, Emitter, Event, nls } from '@theia/core';
|
|
24
|
+
import debounce = require('@theia/core/shared/lodash.debounce');
|
|
25
|
+
|
|
26
|
+
@injectable()
|
|
27
|
+
export class ProblemDecorationsProvider implements DecorationsProvider {
|
|
28
|
+
@inject(ProblemManager) protected readonly problemManager: ProblemManager;
|
|
29
|
+
|
|
30
|
+
protected currentUris: URI[] = [];
|
|
31
|
+
|
|
32
|
+
protected readonly onDidChangeEmitter = new Emitter<URI[]>();
|
|
33
|
+
get onDidChange(): Event<URI[]> {
|
|
34
|
+
return this.onDidChangeEmitter.event;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@postConstruct()
|
|
38
|
+
protected init(): void {
|
|
39
|
+
this.problemManager.onDidChangeMarkers(() => this.fireDidDecorationsChanged());
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
protected fireDidDecorationsChanged = debounce(() => this.doFireDidDecorationsChanged(), 50);
|
|
43
|
+
|
|
44
|
+
protected doFireDidDecorationsChanged(): void {
|
|
45
|
+
const newUris = Array.from(this.problemManager.getUris(), stringified => new URI(stringified));
|
|
46
|
+
this.onDidChangeEmitter.fire(newUris.concat(this.currentUris));
|
|
47
|
+
this.currentUris = newUris;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
provideDecorations(uri: URI, token: CancellationToken): Decoration | Promise<Decoration | undefined> | undefined {
|
|
51
|
+
const markers = this.problemManager.findMarkers({ uri }).filter(ProblemUtils.filterMarker).sort(ProblemUtils.severityCompareMarker);
|
|
52
|
+
if (markers.length) {
|
|
53
|
+
return {
|
|
54
|
+
bubble: true,
|
|
55
|
+
letter: markers.length.toString(),
|
|
56
|
+
weight: ProblemUtils.getPriority(markers[0]),
|
|
57
|
+
colorId: ProblemUtils.getColor(markers[0]),
|
|
58
|
+
tooltip: markers.length === 1 ? nls.localizeByDefault('1 problem in this file') : nls.localizeByDefault('{0} problems in this file', markers.length),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@injectable()
|
|
65
|
+
export class ProblemDecorationContribution implements FrontendApplicationContribution {
|
|
66
|
+
@inject(DecorationsService) protected readonly decorationsService: DecorationsService;
|
|
67
|
+
@inject(ProblemDecorationsProvider) protected readonly problemDecorationProvider: ProblemDecorationsProvider;
|
|
68
|
+
|
|
69
|
+
initialize(): void {
|
|
70
|
+
this.decorationsService.registerDecorationsProvider(this.problemDecorationProvider);
|
|
71
|
+
}
|
|
72
|
+
}
|