Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/issue/browser/issueQuickAccess.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { PickerQuickAccessProvider, IPickerQuickAccessItem, FastAndSlowPicks, Picks, TriggerAction } from '../../../../platform/quickinput/browser/pickerQuickAccess.js';
7
import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';
8
import { IMenuService, MenuId, MenuItemAction, SubmenuItemAction } from '../../../../platform/actions/common/actions.js';
9
import { matchesFuzzy } from '../../../../base/common/filters.js';
10
import { IQuickPickSeparator } from '../../../../platform/quickinput/common/quickInput.js';
11
import { localize } from '../../../../nls.js';
12
import { ICommandService } from '../../../../platform/commands/common/commands.js';
13
import { IExtensionService } from '../../../services/extensions/common/extensions.js';
14
import { IExtensionDescription } from '../../../../platform/extensions/common/extensions.js';
15
import { ThemeIcon } from '../../../../base/common/themables.js';
16
import { Codicon } from '../../../../base/common/codicons.js';
17
import { IssueSource } from '../common/issue.js';
18
import { IProductService } from '../../../../platform/product/common/productService.js';
19
20
export class IssueQuickAccess extends PickerQuickAccessProvider<IPickerQuickAccessItem> {
21
22
static PREFIX = 'issue ';
23
24
constructor(
25
@IMenuService private readonly menuService: IMenuService,
26
@IContextKeyService private readonly contextKeyService: IContextKeyService,
27
@ICommandService private readonly commandService: ICommandService,
28
@IExtensionService private readonly extensionService: IExtensionService,
29
@IProductService private readonly productService: IProductService
30
) {
31
super(IssueQuickAccess.PREFIX, { canAcceptInBackground: true });
32
}
33
34
protected override _getPicks(filter: string): Picks<IPickerQuickAccessItem> | FastAndSlowPicks<IPickerQuickAccessItem> | Promise<Picks<IPickerQuickAccessItem> | FastAndSlowPicks<IPickerQuickAccessItem>> | null {
35
const issuePicksConst = new Array<IPickerQuickAccessItem | IQuickPickSeparator>();
36
const issuePicksParts = new Array<IPickerQuickAccessItem | IQuickPickSeparator>();
37
const extensionIdSet = new Set<string>();
38
39
// Add default items
40
const productLabel = this.productService.nameLong;
41
const marketPlaceLabel = localize("reportExtensionMarketplace", "Extension Marketplace");
42
const productFilter = matchesFuzzy(filter, productLabel, true);
43
const marketPlaceFilter = matchesFuzzy(filter, marketPlaceLabel, true);
44
45
// Add product pick if product filter matches
46
if (productFilter) {
47
issuePicksConst.push({
48
label: productLabel,
49
ariaLabel: productLabel,
50
highlights: { label: productFilter },
51
accept: () => this.commandService.executeCommand('workbench.action.openIssueReporter', { issueSource: IssueSource.VSCode })
52
});
53
}
54
55
// Add marketplace pick if marketplace filter matches
56
if (marketPlaceFilter) {
57
issuePicksConst.push({
58
label: marketPlaceLabel,
59
ariaLabel: marketPlaceLabel,
60
highlights: { label: marketPlaceFilter },
61
accept: () => this.commandService.executeCommand('workbench.action.openIssueReporter', { issueSource: IssueSource.Marketplace })
62
});
63
}
64
65
issuePicksConst.push({ type: 'separator', label: localize('extensions', "Extensions") });
66
67
68
// gets menu actions from contributed
69
const actions = this.menuService.getMenuActions(MenuId.IssueReporter, this.contextKeyService, { renderShortTitle: true }).flatMap(entry => entry[1]);
70
71
// create picks from contributed menu
72
actions.forEach(action => {
73
if ('source' in action.item && action.item.source) {
74
extensionIdSet.add(action.item.source.id);
75
}
76
77
const pick = this._createPick(filter, action);
78
if (pick) {
79
issuePicksParts.push(pick);
80
}
81
});
82
83
84
// create picks from extensions
85
this.extensionService.extensions.forEach(extension => {
86
if (!extension.isBuiltin) {
87
const pick = this._createPick(filter, undefined, extension);
88
const id = extension.identifier.value;
89
if (pick && !extensionIdSet.has(id)) {
90
issuePicksParts.push(pick);
91
}
92
extensionIdSet.add(id);
93
}
94
});
95
96
issuePicksParts.sort((a, b) => {
97
const aLabel = a.label ?? '';
98
const bLabel = b.label ?? '';
99
return aLabel.localeCompare(bLabel);
100
});
101
102
return [...issuePicksConst, ...issuePicksParts];
103
}
104
105
private _createPick(filter: string, action?: MenuItemAction | SubmenuItemAction | undefined, extension?: IExtensionDescription): IPickerQuickAccessItem | undefined {
106
const buttons = [{
107
iconClass: ThemeIcon.asClassName(Codicon.info),
108
tooltip: localize('contributedIssuePage', "Open Extension Page")
109
}];
110
111
let label: string;
112
let trigger: () => TriggerAction;
113
let accept: () => void;
114
if (action && 'source' in action.item && action.item.source) {
115
label = action.item.source?.title;
116
trigger = () => {
117
if ('source' in action.item && action.item.source) {
118
this.commandService.executeCommand('extension.open', action.item.source.id);
119
}
120
return TriggerAction.CLOSE_PICKER;
121
};
122
accept = () => {
123
action.run();
124
};
125
126
} else if (extension) {
127
label = extension.displayName ?? extension.name;
128
trigger = () => {
129
this.commandService.executeCommand('extension.open', extension.identifier.value);
130
return TriggerAction.CLOSE_PICKER;
131
};
132
accept = () => {
133
this.commandService.executeCommand('workbench.action.openIssueReporter', extension.identifier.value);
134
};
135
136
} else {
137
return undefined;
138
}
139
140
const highlights = matchesFuzzy(filter, label, true);
141
if (highlights) {
142
return {
143
label,
144
highlights: { label: highlights },
145
buttons,
146
trigger,
147
accept
148
};
149
}
150
return undefined;
151
}
152
}
153
154