This commit is contained in:
2025-11-02 19:17:20 +08:00
parent ebf784146e
commit e71b69db5f
2575 changed files with 1242294 additions and 95 deletions

View File

@@ -0,0 +1,354 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var AbstractCommandsQuickAccessProvider_1, CommandsHistory_1;
import { toErrorMessage } from '../../../base/common/errorMessage.js';
import { isCancellationError } from '../../../base/common/errors.js';
import { matchesContiguousSubString, matchesPrefix, matchesWords, or } from '../../../base/common/filters.js';
import { createSingleCallFunction } from '../../../base/common/functional.js';
import { Disposable } from '../../../base/common/lifecycle.js';
import { LRUCache } from '../../../base/common/map.js';
import { TfIdfCalculator, normalizeTfIdfScores } from '../../../base/common/tfIdf.js';
import { localize } from '../../../nls.js';
import { ICommandService } from '../../commands/common/commands.js';
import { IConfigurationService } from '../../configuration/common/configuration.js';
import { IDialogService } from '../../dialogs/common/dialogs.js';
import { IInstantiationService } from '../../instantiation/common/instantiation.js';
import { IKeybindingService } from '../../keybinding/common/keybinding.js';
import { ILogService } from '../../log/common/log.js';
import { PickerQuickAccessProvider } from './pickerQuickAccess.js';
import { IStorageService, WillSaveStateReason } from '../../storage/common/storage.js';
import { ITelemetryService } from '../../telemetry/common/telemetry.js';
let AbstractCommandsQuickAccessProvider = class AbstractCommandsQuickAccessProvider extends PickerQuickAccessProvider {
static { AbstractCommandsQuickAccessProvider_1 = this; }
static { this.PREFIX = '>'; }
static { this.TFIDF_THRESHOLD = 0.5; }
static { this.TFIDF_MAX_RESULTS = 5; }
static { this.WORD_FILTER = or(matchesPrefix, matchesWords, matchesContiguousSubString); }
constructor(options, instantiationService, keybindingService, commandService, telemetryService, dialogService) {
super(AbstractCommandsQuickAccessProvider_1.PREFIX, options);
this.keybindingService = keybindingService;
this.commandService = commandService;
this.telemetryService = telemetryService;
this.dialogService = dialogService;
this.commandsHistory = this._register(instantiationService.createInstance(CommandsHistory));
this.options = options;
}
async _getPicks(filter, _disposables, token, runOptions) {
// Ask subclass for all command picks
const allCommandPicks = await this.getCommandPicks(token);
if (token.isCancellationRequested) {
return [];
}
const runTfidf = createSingleCallFunction(() => {
const tfidf = new TfIdfCalculator();
tfidf.updateDocuments(allCommandPicks.map(commandPick => ({
key: commandPick.commandId,
textChunks: [this.getTfIdfChunk(commandPick)]
})));
const result = tfidf.calculateScores(filter, token);
return normalizeTfIdfScores(result)
.filter(score => score.score > AbstractCommandsQuickAccessProvider_1.TFIDF_THRESHOLD)
.slice(0, AbstractCommandsQuickAccessProvider_1.TFIDF_MAX_RESULTS);
});
// Filter
const filteredCommandPicks = [];
for (const commandPick of allCommandPicks) {
const labelHighlights = AbstractCommandsQuickAccessProvider_1.WORD_FILTER(filter, commandPick.label) ?? undefined;
const aliasHighlights = commandPick.commandAlias ? AbstractCommandsQuickAccessProvider_1.WORD_FILTER(filter, commandPick.commandAlias) ?? undefined : undefined;
// Add if matching in label or alias
if (labelHighlights || aliasHighlights) {
commandPick.highlights = {
label: labelHighlights,
detail: this.options.showAlias ? aliasHighlights : undefined
};
filteredCommandPicks.push(commandPick);
}
// Also add if we have a 100% command ID match
else if (filter === commandPick.commandId) {
filteredCommandPicks.push(commandPick);
}
// Handle tf-idf scoring for the rest if there's a filter
else if (filter.length >= 3) {
const tfidf = runTfidf();
if (token.isCancellationRequested) {
return [];
}
// Add if we have a tf-idf score
const tfidfScore = tfidf.find(score => score.key === commandPick.commandId);
if (tfidfScore) {
commandPick.tfIdfScore = tfidfScore.score;
filteredCommandPicks.push(commandPick);
}
}
}
// Add description to commands that have duplicate labels
const mapLabelToCommand = new Map();
for (const commandPick of filteredCommandPicks) {
const existingCommandForLabel = mapLabelToCommand.get(commandPick.label);
if (existingCommandForLabel) {
commandPick.description = commandPick.commandId;
existingCommandForLabel.description = existingCommandForLabel.commandId;
}
else {
mapLabelToCommand.set(commandPick.label, commandPick);
}
}
// Sort by MRU order and fallback to name otherwise
filteredCommandPicks.sort((commandPickA, commandPickB) => {
// If a result came from tf-idf, we want to put that towards the bottom
if (commandPickA.tfIdfScore && commandPickB.tfIdfScore) {
if (commandPickA.tfIdfScore === commandPickB.tfIdfScore) {
return commandPickA.label.localeCompare(commandPickB.label); // prefer lexicographically smaller command
}
return commandPickB.tfIdfScore - commandPickA.tfIdfScore; // prefer higher tf-idf score
}
else if (commandPickA.tfIdfScore) {
return 1; // first command has a score but other doesn't so other wins
}
else if (commandPickB.tfIdfScore) {
return -1; // other command has a score but first doesn't so first wins
}
const commandACounter = this.commandsHistory.peek(commandPickA.commandId);
const commandBCounter = this.commandsHistory.peek(commandPickB.commandId);
if (commandACounter && commandBCounter) {
return commandACounter > commandBCounter ? -1 : 1; // use more recently used command before older
}
if (commandACounter) {
return -1; // first command was used, so it wins over the non used one
}
if (commandBCounter) {
return 1; // other command was used so it wins over the command
}
if (this.options.suggestedCommandIds) {
const commandASuggestion = this.options.suggestedCommandIds.has(commandPickA.commandId);
const commandBSuggestion = this.options.suggestedCommandIds.has(commandPickB.commandId);
if (commandASuggestion && commandBSuggestion) {
return 0; // honor the order of the array
}
if (commandASuggestion) {
return -1; // first command was suggested, so it wins over the non suggested one
}
if (commandBSuggestion) {
return 1; // other command was suggested so it wins over the command
}
}
// both commands were never used, so we sort by name
return commandPickA.label.localeCompare(commandPickB.label);
});
const commandPicks = [];
let addOtherSeparator = false;
let addSuggestedSeparator = true;
let addCommonlyUsedSeparator = !!this.options.suggestedCommandIds;
for (let i = 0; i < filteredCommandPicks.length; i++) {
const commandPick = filteredCommandPicks[i];
// Separator: recently used
if (i === 0 && this.commandsHistory.peek(commandPick.commandId)) {
commandPicks.push({ type: 'separator', label: localize(1723, "recently used") });
addOtherSeparator = true;
}
if (addSuggestedSeparator && commandPick.tfIdfScore !== undefined) {
commandPicks.push({ type: 'separator', label: localize(1724, "similar commands") });
addSuggestedSeparator = false;
}
// Separator: commonly used
if (addCommonlyUsedSeparator && commandPick.tfIdfScore === undefined && !this.commandsHistory.peek(commandPick.commandId) && this.options.suggestedCommandIds?.has(commandPick.commandId)) {
commandPicks.push({ type: 'separator', label: localize(1725, "commonly used") });
addOtherSeparator = true;
addCommonlyUsedSeparator = false;
}
// Separator: other commands
if (addOtherSeparator && commandPick.tfIdfScore === undefined && !this.commandsHistory.peek(commandPick.commandId) && !this.options.suggestedCommandIds?.has(commandPick.commandId)) {
commandPicks.push({ type: 'separator', label: localize(1726, "other commands") });
addOtherSeparator = false;
}
// Command
commandPicks.push(this.toCommandPick(commandPick, runOptions));
}
if (!this.hasAdditionalCommandPicks(filter, token)) {
return commandPicks;
}
return {
picks: commandPicks,
additionalPicks: (async () => {
const additionalCommandPicks = await this.getAdditionalCommandPicks(allCommandPicks, filteredCommandPicks, filter, token);
if (token.isCancellationRequested) {
return [];
}
const commandPicks = additionalCommandPicks.map(commandPick => this.toCommandPick(commandPick, runOptions));
// Basically, if we haven't already added a separator, we add one before the additional picks so long
// as one hasn't been added to the start of the array.
if (addSuggestedSeparator && commandPicks[0]?.type !== 'separator') {
commandPicks.unshift({ type: 'separator', label: localize(1727, "similar commands") });
}
return commandPicks;
})()
};
}
toCommandPick(commandPick, runOptions) {
if (commandPick.type === 'separator') {
return commandPick;
}
const keybinding = this.keybindingService.lookupKeybinding(commandPick.commandId);
const ariaLabel = keybinding ?
localize(1728, "{0}, {1}", commandPick.label, keybinding.getAriaLabel()) :
commandPick.label;
return {
...commandPick,
ariaLabel,
detail: this.options.showAlias && commandPick.commandAlias !== commandPick.label ? commandPick.commandAlias : undefined,
keybinding,
accept: async () => {
// Add to history
this.commandsHistory.push(commandPick.commandId);
// Telementry
this.telemetryService.publicLog2('workbenchActionExecuted', {
id: commandPick.commandId,
from: runOptions?.from ?? 'quick open'
});
// Run
try {
commandPick.args?.length
? await this.commandService.executeCommand(commandPick.commandId, ...commandPick.args)
: await this.commandService.executeCommand(commandPick.commandId);
}
catch (error) {
if (!isCancellationError(error)) {
this.dialogService.error(localize(1729, "Command '{0}' resulted in an error", commandPick.label), toErrorMessage(error));
}
}
}
};
}
// TF-IDF string to be indexed
getTfIdfChunk({ label, commandAlias, commandDescription }) {
let chunk = label;
if (commandAlias && commandAlias !== label) {
chunk += ` - ${commandAlias}`;
}
if (commandDescription && commandDescription.value !== label) {
// If the original is the same as the value, don't add it
chunk += ` - ${commandDescription.value === commandDescription.original ? commandDescription.value : `${commandDescription.value} (${commandDescription.original})`}`;
}
return chunk;
}
};
AbstractCommandsQuickAccessProvider = AbstractCommandsQuickAccessProvider_1 = __decorate([
__param(1, IInstantiationService),
__param(2, IKeybindingService),
__param(3, ICommandService),
__param(4, ITelemetryService),
__param(5, IDialogService)
], AbstractCommandsQuickAccessProvider);
export { AbstractCommandsQuickAccessProvider };
let CommandsHistory = class CommandsHistory extends Disposable {
static { CommandsHistory_1 = this; }
static { this.DEFAULT_COMMANDS_HISTORY_LENGTH = 50; }
static { this.PREF_KEY_CACHE = 'commandPalette.mru.cache'; }
static { this.PREF_KEY_COUNTER = 'commandPalette.mru.counter'; }
static { this.counter = 1; }
static { this.hasChanges = false; }
constructor(storageService, configurationService, logService) {
super();
this.storageService = storageService;
this.configurationService = configurationService;
this.logService = logService;
this.configuredCommandsHistoryLength = 0;
this.updateConfiguration();
this.load();
this.registerListeners();
}
registerListeners() {
this._register(this.configurationService.onDidChangeConfiguration(e => this.updateConfiguration(e)));
this._register(this.storageService.onWillSaveState(e => {
if (e.reason === WillSaveStateReason.SHUTDOWN) {
// Commands history is very dynamic and so we limit impact
// on storage to only save on shutdown. This helps reduce
// the overhead of syncing this data across machines.
this.saveState();
}
}));
}
updateConfiguration(e) {
if (e && !e.affectsConfiguration('workbench.commandPalette.history')) {
return;
}
this.configuredCommandsHistoryLength = CommandsHistory_1.getConfiguredCommandHistoryLength(this.configurationService);
if (CommandsHistory_1.cache && CommandsHistory_1.cache.limit !== this.configuredCommandsHistoryLength) {
CommandsHistory_1.cache.limit = this.configuredCommandsHistoryLength;
CommandsHistory_1.hasChanges = true;
}
}
load() {
const raw = this.storageService.get(CommandsHistory_1.PREF_KEY_CACHE, 0 /* StorageScope.PROFILE */);
let serializedCache;
if (raw) {
try {
serializedCache = JSON.parse(raw);
}
catch (error) {
this.logService.error(`[CommandsHistory] invalid data: ${error}`);
}
}
const cache = CommandsHistory_1.cache = new LRUCache(this.configuredCommandsHistoryLength, 1);
if (serializedCache) {
let entries;
if (serializedCache.usesLRU) {
entries = serializedCache.entries;
}
else {
entries = serializedCache.entries.sort((a, b) => a.value - b.value);
}
entries.forEach(entry => cache.set(entry.key, entry.value));
}
CommandsHistory_1.counter = this.storageService.getNumber(CommandsHistory_1.PREF_KEY_COUNTER, 0 /* StorageScope.PROFILE */, CommandsHistory_1.counter);
}
push(commandId) {
if (!CommandsHistory_1.cache) {
return;
}
CommandsHistory_1.cache.set(commandId, CommandsHistory_1.counter++); // set counter to command
CommandsHistory_1.hasChanges = true;
}
peek(commandId) {
return CommandsHistory_1.cache?.peek(commandId);
}
saveState() {
if (!CommandsHistory_1.cache) {
return;
}
if (!CommandsHistory_1.hasChanges) {
return;
}
const serializedCache = { usesLRU: true, entries: [] };
CommandsHistory_1.cache.forEach((value, key) => serializedCache.entries.push({ key, value }));
this.storageService.store(CommandsHistory_1.PREF_KEY_CACHE, JSON.stringify(serializedCache), 0 /* StorageScope.PROFILE */, 0 /* StorageTarget.USER */);
this.storageService.store(CommandsHistory_1.PREF_KEY_COUNTER, CommandsHistory_1.counter, 0 /* StorageScope.PROFILE */, 0 /* StorageTarget.USER */);
CommandsHistory_1.hasChanges = false;
}
static getConfiguredCommandHistoryLength(configurationService) {
const config = configurationService.getValue();
const configuredCommandHistoryLength = config.workbench?.commandPalette?.history;
if (typeof configuredCommandHistoryLength === 'number') {
return configuredCommandHistoryLength;
}
return CommandsHistory_1.DEFAULT_COMMANDS_HISTORY_LENGTH;
}
};
CommandsHistory = CommandsHistory_1 = __decorate([
__param(0, IStorageService),
__param(1, IConfigurationService),
__param(2, ILogService)
], CommandsHistory);
export { CommandsHistory };
//# sourceMappingURL=commandsQuickAccess.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,76 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var HelpQuickAccessProvider_1;
import { localize } from '../../../nls.js';
import { Registry } from '../../registry/common/platform.js';
import { DisposableStore } from '../../../base/common/lifecycle.js';
import { IKeybindingService } from '../../keybinding/common/keybinding.js';
import { Extensions } from '../common/quickAccess.js';
import { IQuickInputService } from '../common/quickInput.js';
let HelpQuickAccessProvider = class HelpQuickAccessProvider {
static { HelpQuickAccessProvider_1 = this; }
static { this.PREFIX = '?'; }
constructor(quickInputService, keybindingService) {
this.quickInputService = quickInputService;
this.keybindingService = keybindingService;
this.registry = Registry.as(Extensions.Quickaccess);
}
provide(picker) {
const disposables = new DisposableStore();
// Open a picker with the selected value if picked
disposables.add(picker.onDidAccept(() => {
const [item] = picker.selectedItems;
if (item) {
this.quickInputService.quickAccess.show(item.prefix, { preserveValue: true });
}
}));
// Also open a picker when we detect the user typed the exact
// name of a provider (e.g. `?term` for terminals)
disposables.add(picker.onDidChangeValue(value => {
const providerDescriptor = this.registry.getQuickAccessProvider(value.substr(HelpQuickAccessProvider_1.PREFIX.length));
if (providerDescriptor && providerDescriptor.prefix && providerDescriptor.prefix !== HelpQuickAccessProvider_1.PREFIX) {
this.quickInputService.quickAccess.show(providerDescriptor.prefix, { preserveValue: true });
}
}));
// Fill in all providers
picker.items = this.getQuickAccessProviders().filter(p => p.prefix !== HelpQuickAccessProvider_1.PREFIX);
return disposables;
}
getQuickAccessProviders() {
const providers = this.registry
.getQuickAccessProviders()
.sort((providerA, providerB) => providerA.prefix.localeCompare(providerB.prefix))
.flatMap(provider => this.createPicks(provider));
return providers;
}
createPicks(provider) {
return provider.helpEntries.map(helpEntry => {
const prefix = helpEntry.prefix || provider.prefix;
const label = prefix || '\u2026' /* ... */;
return {
prefix,
label,
keybinding: helpEntry.commandId ? this.keybindingService.lookupKeybinding(helpEntry.commandId) : undefined,
ariaLabel: localize(1730, "{0}, {1}", label, helpEntry.description),
description: helpEntry.description
};
});
}
};
HelpQuickAccessProvider = HelpQuickAccessProvider_1 = __decorate([
__param(0, IQuickInputService),
__param(1, IKeybindingService)
], HelpQuickAccessProvider);
export { HelpQuickAccessProvider };
//# sourceMappingURL=helpQuickAccess.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,486 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.quick-input-widget {
position: absolute;
width: 600px;
z-index: 2550;
left: 50%;
-webkit-app-region: no-drag;
border-radius: 6px;
}
.quick-input-titlebar {
cursor: grab;
display: flex;
align-items: center;
border-top-right-radius: 5px;
border-top-left-radius: 5px;
}
.quick-input-left-action-bar {
display: flex;
margin-left: 4px;
flex: 1;
}
/* give some space between input and action bar */
.quick-input-inline-action-bar > .actions-container > .action-item:first-child {
margin-left: 5px;
}
/* center horizontally */
.quick-input-inline-action-bar > .actions-container > .action-item {
margin-top: 2px;
}
.quick-input-title {
cursor: grab;
padding: 3px 0px;
text-align: center;
text-overflow: ellipsis;
overflow: hidden;
}
.quick-input-right-action-bar {
display: flex;
margin-right: 4px;
flex: 1;
}
.quick-input-right-action-bar > .actions-container {
justify-content: flex-end;
}
.quick-input-right-action-bar > .actions-container > .action-item {
margin-left: 4px;
}
.quick-input-titlebar .monaco-action-bar .action-label.codicon {
background-position: center;
background-repeat: no-repeat;
padding: 2px;
}
.quick-input-description {
margin: 6px 6px 6px 11px;
}
.quick-input-header .quick-input-description {
margin: 4px 2px;
flex: 1;
}
.quick-input-header {
cursor: grab;
display: flex;
padding: 6px 6px 2px 6px;
}
.quick-input-widget.hidden-input .quick-input-header {
/* reduce margins and paddings when input box hidden */
padding: 0;
margin-bottom: 0;
}
.quick-input-and-message {
display: flex;
flex-direction: column;
flex-grow: 1;
min-width: 0;
position: relative;
}
.quick-input-check-all {
align-self: center;
margin: 0;
}
.quick-input-widget .quick-input-header .monaco-checkbox {
margin-top: 6px;
}
.quick-input-filter {
flex-grow: 1;
display: flex;
position: relative;
}
.quick-input-box {
flex-grow: 1;
}
.quick-input-widget.show-checkboxes .quick-input-box,
.quick-input-widget.show-checkboxes .quick-input-message {
margin-left: 5px;
}
.quick-input-visible-count {
position: absolute;
left: -10000px;
}
.quick-input-count {
align-self: center;
position: absolute;
right: 4px;
display: flex;
align-items: center;
}
.quick-input-count .monaco-count-badge {
vertical-align: middle;
padding: 2px 4px;
border-radius: 2px;
min-height: auto;
line-height: normal;
}
.quick-input-action {
margin-left: 6px;
}
.quick-input-action .monaco-text-button {
font-size: 11px;
padding: 0 6px;
display: flex;
height: 25px;
align-items: center;
}
.quick-input-message {
margin-top: -1px;
padding: 5px;
overflow-wrap: break-word;
}
.quick-input-message > .codicon {
margin: 0 0.2em;
vertical-align: text-bottom;
}
/* Links in descriptions & validations */
.quick-input-message a {
color: inherit;
}
.quick-input-progress.monaco-progress-container {
position: relative;
}
.quick-input-list {
line-height: 22px;
}
.quick-input-widget.hidden-input .quick-input-list {
margin-top: 4px;
/* reduce margins when input box hidden */
padding-bottom: 4px;
}
.quick-input-list .monaco-list {
overflow: hidden;
max-height: calc(20 * 22px);
padding-bottom: 5px;
}
.quick-input-list .monaco-scrollable-element {
padding: 0px 6px;
}
.quick-input-list .quick-input-list-entry {
box-sizing: border-box;
overflow: hidden;
display: flex;
padding: 0 6px;
}
.quick-input-list .quick-input-list-entry.quick-input-list-separator-border {
border-top-width: 1px;
border-top-style: solid;
}
.quick-input-list .monaco-list-row {
border-radius: 3px;
}
.quick-input-list .monaco-list-row[data-index="0"] .quick-input-list-entry.quick-input-list-separator-border {
border-top-style: none;
}
.quick-input-list .quick-input-list-label {
overflow: hidden;
display: flex;
height: 100%;
flex: 1;
}
.quick-input-widget .monaco-checkbox {
margin-right: 0;
}
.quick-input-widget .quick-input-list .monaco-checkbox,
.quick-input-widget .quick-input-tree .monaco-checkbox {
margin-top: 4px;
}
.quick-input-list .quick-input-list-icon {
background-size: 16px;
background-position: left center;
background-repeat: no-repeat;
padding-right: 6px;
width: 16px;
height: 22px;
display: flex;
align-items: center;
justify-content: center;
}
.quick-input-list .quick-input-list-rows {
overflow: hidden;
text-overflow: ellipsis;
display: flex;
flex-direction: column;
height: 100%;
flex: 1;
margin-left: 5px;
}
.quick-input-list .quick-input-list-rows > .quick-input-list-row {
display: flex;
align-items: center;
}
.quick-input-list .quick-input-list-rows > .quick-input-list-row .monaco-icon-label,
.quick-input-list .quick-input-list-rows > .quick-input-list-row .monaco-icon-label .monaco-icon-label-container > .monaco-icon-name-container {
flex: 1;
/* make sure the icon label grows within the row */
}
.quick-input-list .quick-input-list-rows > .quick-input-list-row .codicon[class*='codicon-'] {
vertical-align: text-bottom;
}
.quick-input-list .quick-input-list-rows .monaco-highlighted-label > span {
opacity: 1;
}
.quick-input-list .quick-input-list-entry .quick-input-list-entry-keybinding {
margin-right: 8px;
/* separate from the separator label or scrollbar if any */
}
.quick-input-list .quick-input-list-label-meta {
opacity: 0.7;
line-height: normal;
text-overflow: ellipsis;
overflow: hidden;
}
/* preserve list-like styling instead of tree-like styling */
.quick-input-list .monaco-list .monaco-list-row .monaco-highlighted-label .highlight {
font-weight: bold;
background-color: unset;
color: var(--vscode-list-highlightForeground) !important;
}
/* preserve list-like styling instead of tree-like styling */
.quick-input-list .monaco-list .monaco-list-row.focused .monaco-highlighted-label .highlight {
color: var(--vscode-list-focusHighlightForeground) !important;
}
.quick-input-list .quick-input-list-entry .quick-input-list-separator {
margin-right: 4px;
/* separate from keybindings or actions */
}
.quick-input-list .quick-input-list-entry-action-bar {
display: flex;
flex: 0;
overflow: visible;
}
.quick-input-list .quick-input-list-entry-action-bar .action-label {
/*
* By default, actions in the quick input action bar are hidden
* until hovered over them or selected.
*/
display: none;
}
.quick-input-list .quick-input-list-entry-action-bar .action-label.codicon {
margin-right: 4px;
padding: 2px;
}
.quick-input-list .quick-input-list-entry-action-bar {
margin-top: 1px;
}
.quick-input-list .quick-input-list-entry-action-bar {
margin-right: 4px;
/* separate from scrollbar */
}
.quick-input-list .quick-input-list-entry .quick-input-list-entry-action-bar .action-label.always-visible,
.quick-input-list .quick-input-list-entry:hover .quick-input-list-entry-action-bar .action-label,
.quick-input-list .quick-input-list-entry.focus-inside .quick-input-list-entry-action-bar .action-label,
.quick-input-list .monaco-list-row.focused .quick-input-list-entry-action-bar .action-label,
.quick-input-list .monaco-list-row.passive-focused .quick-input-list-entry-action-bar .action-label {
display: flex;
}
.quick-input-list > .monaco-list:focus .monaco-list-row.focused {
outline: 1px solid var(--vscode-list-focusOutline) !important;
outline-offset: -1px;
}
.quick-input-list > .monaco-list:focus .monaco-list-row.focused .quick-input-list-entry.quick-input-list-separator-border {
border-color: transparent;
}
/* focused items in quick pick */
.quick-input-list .monaco-list-row.focused .monaco-keybinding-key,
.quick-input-list .monaco-list-row.focused .quick-input-list-entry .quick-input-list-separator {
color: inherit
}
.quick-input-list .monaco-list-row.focused .monaco-keybinding-key {
background: none;
}
.quick-input-list .quick-input-list-separator-as-item {
padding: 4px 6px;
font-size: 12px;
}
/* Quick input separators as full-row item */
.quick-input-list .quick-input-list-separator-as-item .label-name {
font-weight: 600;
}
.quick-input-list .quick-input-list-separator-as-item .label-description {
/* Override default description opacity so we don't have a contrast ratio issue. */
opacity: 1 !important;
}
/* Hide border when the item becomes the sticky one */
.quick-input-list .monaco-tree-sticky-row .quick-input-list-entry.quick-input-list-separator-as-item.quick-input-list-separator-border {
border-top-style: none;
}
/* Give sticky row the same padding as the scrollable list */
.quick-input-list .monaco-tree-sticky-row {
padding: 0 5px;
}
/* Hide the twistie containers so that there isn't blank indent */
.quick-input-list .monaco-tl-twistie {
display: none !important;
}
/* Tree */
.quick-input-tree .monaco-list {
overflow: hidden;
max-height: calc(20 * 22px);
padding-bottom: 5px;
}
.quick-input-tree .quick-input-tree-entry {
box-sizing: border-box;
overflow: hidden;
display: flex;
padding: 0 6px;
}
.quick-input-tree .quick-input-tree-label {
overflow: hidden;
display: flex;
height: 100%;
flex: 1;
}
.quick-input-tree .quick-input-tree-icon {
background-size: 16px;
background-position: left center;
background-repeat: no-repeat;
padding-right: 6px;
width: 16px;
height: 22px;
display: flex;
align-items: center;
justify-content: center;
}
.quick-input-tree .quick-input-tree-rows {
overflow: hidden;
text-overflow: ellipsis;
display: flex;
flex-direction: column;
height: 100%;
flex: 1;
margin-left: 5px;
}
.quick-input-tree .quick-input-tree-rows > .quick-input-tree-row {
display: flex;
align-items: center;
}
.quick-input-tree .quick-input-tree-rows > .quick-input-tree-row .monaco-icon-label,
.quick-input-tree .quick-input-tree-rows > .quick-input-tree-row .monaco-icon-label .monaco-icon-label-container > .monaco-icon-name-container {
flex: 1;
/* make sure the icon label grows within the row */
}
.quick-input-tree .quick-input-tree-rows > .quick-input-tree-row .codicon[class*='codicon-'] {
vertical-align: text-bottom;
}
.quick-input-tree .quick-input-tree-rows .monaco-highlighted-label > span {
opacity: 1;
}
.quick-input-tree .quick-input-tree-entry-action-bar {
display: flex;
flex: 0;
overflow: visible;
}
.quick-input-tree .quick-input-tree-entry-action-bar .action-label {
/*
* By default, actions in the quick input action bar are hidden
* until hovered over them or selected.
*/
display: none;
}
.quick-input-tree .quick-input-tree-entry-action-bar .action-label.codicon {
margin-right: 4px;
padding: 2px;
}
.quick-input-tree .quick-input-tree-entry-action-bar {
margin-top: 1px;
}
.quick-input-tree .quick-input-tree-entry-action-bar {
margin-right: 4px;
/* separate from scrollbar */
}
.quick-input-tree .quick-input-tree-entry .quick-input-tree-entry-action-bar .action-label.always-visible,
.quick-input-tree .quick-input-tree-entry:hover .quick-input-tree-entry-action-bar .action-label,
.quick-input-tree .quick-input-tree-entry.focus-inside .quick-input-tree-entry-action-bar .action-label,
.quick-input-tree .monaco-list-row.focused .quick-input-tree-entry-action-bar .action-label,
.quick-input-tree .monaco-list-row.passive-focused .quick-input-tree-entry-action-bar .action-label {
display: flex;
}
.quick-input-tree > .monaco-list:focus .monaco-list-row.focused {
outline: 1px solid var(--vscode-list-focusOutline) !important;
outline-offset: -1px;
}

View File

@@ -0,0 +1,271 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { timeout } from '../../../base/common/async.js';
import { CancellationTokenSource } from '../../../base/common/cancellation.js';
import { Disposable, DisposableStore, MutableDisposable } from '../../../base/common/lifecycle.js';
import { isFunction } from '../../../base/common/types.js';
export var TriggerAction;
(function (TriggerAction) {
/**
* Do nothing after the button was clicked.
*/
TriggerAction[TriggerAction["NO_ACTION"] = 0] = "NO_ACTION";
/**
* Close the picker.
*/
TriggerAction[TriggerAction["CLOSE_PICKER"] = 1] = "CLOSE_PICKER";
/**
* Update the results of the picker.
*/
TriggerAction[TriggerAction["REFRESH_PICKER"] = 2] = "REFRESH_PICKER";
/**
* Remove the item from the picker.
*/
TriggerAction[TriggerAction["REMOVE_ITEM"] = 3] = "REMOVE_ITEM";
})(TriggerAction || (TriggerAction = {}));
function isPicksWithActive(obj) {
const candidate = obj;
return Array.isArray(candidate.items);
}
function isFastAndSlowPicks(obj) {
const candidate = obj;
return !!candidate.picks && candidate.additionalPicks instanceof Promise;
}
export class PickerQuickAccessProvider extends Disposable {
constructor(prefix, options) {
super();
this.prefix = prefix;
this.options = options;
}
provide(picker, token, runOptions) {
const disposables = new DisposableStore();
// Apply options if any
picker.canAcceptInBackground = !!this.options?.canAcceptInBackground;
// Disable filtering & sorting, we control the results
picker.matchOnLabel = picker.matchOnDescription = picker.matchOnDetail = picker.sortByLabel = false;
// Set initial picks and update on type
let picksCts = undefined;
const picksDisposable = disposables.add(new MutableDisposable());
const updatePickerItems = async () => {
// Cancel any previous ask for picks and busy
picksCts?.dispose(true);
picker.busy = false;
// Setting the .value will call dispose() on the previous value, so we need to do this AFTER cancelling with dispose(true).
const picksDisposables = picksDisposable.value = new DisposableStore();
// Create new cancellation source for this run
picksCts = picksDisposables.add(new CancellationTokenSource(token));
// Collect picks and support both long running and short or combined
const picksToken = picksCts.token;
let picksFilter = picker.value.substring(this.prefix.length);
if (!this.options?.shouldSkipTrimPickFilter) {
picksFilter = picksFilter.trim();
}
const providedPicks = this._getPicks(picksFilter, picksDisposables, picksToken, runOptions);
const applyPicks = (picks, skipEmpty) => {
let items;
let activeItem = undefined;
if (isPicksWithActive(picks)) {
items = picks.items;
activeItem = picks.active;
}
else {
items = picks;
}
if (items.length === 0) {
if (skipEmpty) {
return false;
}
// We show the no results pick if we have no input to prevent completely empty pickers #172613
if ((picksFilter.length > 0 || picker.hideInput) && this.options?.noResultsPick) {
if (isFunction(this.options.noResultsPick)) {
items = [this.options.noResultsPick(picksFilter)];
}
else {
items = [this.options.noResultsPick];
}
}
}
picker.items = items;
if (activeItem) {
picker.activeItems = [activeItem];
}
return true;
};
const applyFastAndSlowPicks = async (fastAndSlowPicks) => {
let fastPicksApplied = false;
let slowPicksApplied = false;
await Promise.all([
// Fast Picks: if `mergeDelay` is configured, in order to reduce
// amount of flicker, we race against the slow picks over some delay
// and then set the fast picks.
// If the slow picks are faster, we reduce the flicker by only
// setting the items once.
(async () => {
if (typeof fastAndSlowPicks.mergeDelay === 'number') {
await timeout(fastAndSlowPicks.mergeDelay);
if (picksToken.isCancellationRequested) {
return;
}
}
if (!slowPicksApplied) {
fastPicksApplied = applyPicks(fastAndSlowPicks.picks, true /* skip over empty to reduce flicker */);
}
})(),
// Slow Picks: we await the slow picks and then set them at
// once together with the fast picks, but only if we actually
// have additional results.
(async () => {
picker.busy = true;
try {
const awaitedAdditionalPicks = await fastAndSlowPicks.additionalPicks;
if (picksToken.isCancellationRequested) {
return;
}
let picks;
let activePick = undefined;
if (isPicksWithActive(fastAndSlowPicks.picks)) {
picks = fastAndSlowPicks.picks.items;
activePick = fastAndSlowPicks.picks.active;
}
else {
picks = fastAndSlowPicks.picks;
}
let additionalPicks;
let additionalActivePick = undefined;
if (isPicksWithActive(awaitedAdditionalPicks)) {
additionalPicks = awaitedAdditionalPicks.items;
additionalActivePick = awaitedAdditionalPicks.active;
}
else {
additionalPicks = awaitedAdditionalPicks;
}
if (additionalPicks.length > 0 || !fastPicksApplied) {
// If we do not have any activePick or additionalActivePick
// we try to preserve the currently active pick from the
// fast results. This fixes an issue where the user might
// have made a pick active before the additional results
// kick in.
// See https://github.com/microsoft/vscode/issues/102480
let fallbackActivePick = undefined;
if (!activePick && !additionalActivePick) {
const fallbackActivePickCandidate = picker.activeItems[0];
if (fallbackActivePickCandidate && picks.indexOf(fallbackActivePickCandidate) !== -1) {
fallbackActivePick = fallbackActivePickCandidate;
}
}
applyPicks({
items: [...picks, ...additionalPicks],
active: activePick || additionalActivePick || fallbackActivePick
});
}
}
finally {
if (!picksToken.isCancellationRequested) {
picker.busy = false;
}
slowPicksApplied = true;
}
})()
]);
};
// No Picks
if (providedPicks === null) {
// Ignore
}
// Fast and Slow Picks
else if (isFastAndSlowPicks(providedPicks)) {
await applyFastAndSlowPicks(providedPicks);
}
// Fast Picks
else if (!(providedPicks instanceof Promise)) {
applyPicks(providedPicks);
}
// Slow Picks
else {
picker.busy = true;
try {
const awaitedPicks = await providedPicks;
if (picksToken.isCancellationRequested) {
return;
}
if (isFastAndSlowPicks(awaitedPicks)) {
await applyFastAndSlowPicks(awaitedPicks);
}
else {
applyPicks(awaitedPicks);
}
}
finally {
if (!picksToken.isCancellationRequested) {
picker.busy = false;
}
}
}
};
disposables.add(picker.onDidChangeValue(() => updatePickerItems()));
updatePickerItems();
// Accept the pick on accept and hide picker
disposables.add(picker.onDidAccept(event => {
if (runOptions?.handleAccept) {
if (!event.inBackground) {
picker.hide(); // hide picker unless we accept in background
}
runOptions.handleAccept?.(picker.activeItems[0], event.inBackground);
return;
}
const [item] = picker.selectedItems;
if (typeof item?.accept === 'function') {
if (!event.inBackground) {
picker.hide(); // hide picker unless we accept in background
}
item.accept(picker.keyMods, event);
}
}));
const buttonTrigger = async (button, item) => {
if (typeof item.trigger !== 'function') {
return;
}
const buttonIndex = item.buttons?.indexOf(button) ?? -1;
if (buttonIndex >= 0) {
const result = item.trigger(buttonIndex, picker.keyMods);
const action = (typeof result === 'number') ? result : await result;
if (token.isCancellationRequested) {
return;
}
switch (action) {
case TriggerAction.NO_ACTION:
break;
case TriggerAction.CLOSE_PICKER:
picker.hide();
break;
case TriggerAction.REFRESH_PICKER:
updatePickerItems();
break;
case TriggerAction.REMOVE_ITEM: {
const index = picker.items.indexOf(item);
if (index !== -1) {
const items = picker.items.slice();
const removed = items.splice(index, 1);
const activeItems = picker.activeItems.filter(activeItem => activeItem !== removed[0]);
const keepScrollPositionBefore = picker.keepScrollPosition;
picker.keepScrollPosition = true;
picker.items = items;
if (activeItems) {
picker.activeItems = activeItems;
}
picker.keepScrollPosition = keepScrollPositionBefore;
}
break;
}
}
}
};
// Trigger the pick with button index if button triggered
disposables.add(picker.onDidTriggerItemButton(({ button, item }) => buttonTrigger(button, item)));
disposables.add(picker.onDidTriggerSeparatorButton(({ button, separator }) => buttonTrigger(button, separator)));
return disposables;
}
}
//# sourceMappingURL=pickerQuickAccess.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,208 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
import { DeferredPromise } from '../../../base/common/async.js';
import { CancellationTokenSource } from '../../../base/common/cancellation.js';
import { Event } from '../../../base/common/event.js';
import { Disposable, DisposableStore, isDisposable, toDisposable } from '../../../base/common/lifecycle.js';
import { IInstantiationService } from '../../instantiation/common/instantiation.js';
import { DefaultQuickAccessFilterValue, Extensions } from '../common/quickAccess.js';
import { IQuickInputService, ItemActivation } from '../common/quickInput.js';
import { Registry } from '../../registry/common/platform.js';
let QuickAccessController = class QuickAccessController extends Disposable {
constructor(quickInputService, instantiationService) {
super();
this.quickInputService = quickInputService;
this.instantiationService = instantiationService;
this.registry = Registry.as(Extensions.Quickaccess);
this.mapProviderToDescriptor = new Map();
this.lastAcceptedPickerValues = new Map();
this.visibleQuickAccess = undefined;
this._register(toDisposable(() => {
for (const provider of this.mapProviderToDescriptor.values()) {
if (isDisposable(provider)) {
provider.dispose();
}
}
this.visibleQuickAccess?.picker.dispose();
}));
}
show(value = '', options) {
this.doShowOrPick(value, false, options);
}
doShowOrPick(value, pick, options) {
// Find provider for the value to show
const [provider, descriptor] = this.getOrInstantiateProvider(value, options?.enabledProviderPrefixes);
// Return early if quick access is already showing on that same prefix
const visibleQuickAccess = this.visibleQuickAccess;
const visibleDescriptor = visibleQuickAccess?.descriptor;
if (visibleQuickAccess && descriptor && visibleDescriptor === descriptor) {
// Apply value only if it is more specific than the prefix
// from the provider and we are not instructed to preserve
if (value !== descriptor.prefix && !options?.preserveValue) {
visibleQuickAccess.picker.value = value;
}
// Always adjust selection
this.adjustValueSelection(visibleQuickAccess.picker, descriptor, options);
return;
}
// Rewrite the filter value based on certain rules unless disabled
if (descriptor && !options?.preserveValue) {
let newValue = undefined;
// If we have a visible provider with a value, take it's filter value but
// rewrite to new provider prefix in case they differ
if (visibleQuickAccess && visibleDescriptor && visibleDescriptor !== descriptor) {
const newValueCandidateWithoutPrefix = visibleQuickAccess.value.substr(visibleDescriptor.prefix.length);
if (newValueCandidateWithoutPrefix) {
newValue = `${descriptor.prefix}${newValueCandidateWithoutPrefix}`;
}
}
// Otherwise, take a default value as instructed
if (!newValue) {
const defaultFilterValue = provider?.defaultFilterValue;
if (defaultFilterValue === DefaultQuickAccessFilterValue.LAST) {
newValue = this.lastAcceptedPickerValues.get(descriptor);
}
else if (typeof defaultFilterValue === 'string') {
newValue = `${descriptor.prefix}${defaultFilterValue}`;
}
}
if (typeof newValue === 'string') {
value = newValue;
}
}
// Store the existing selection if there was one.
const visibleSelection = visibleQuickAccess?.picker?.valueSelection;
const visibleValue = visibleQuickAccess?.picker?.value;
// Create a picker for the provider to use with the initial value
// and adjust the filtering to exclude the prefix from filtering
const disposables = new DisposableStore();
const picker = disposables.add(this.quickInputService.createQuickPick({ useSeparators: true }));
picker.value = value;
this.adjustValueSelection(picker, descriptor, options);
picker.placeholder = options?.placeholder ?? descriptor?.placeholder;
picker.quickNavigate = options?.quickNavigateConfiguration;
picker.hideInput = !!picker.quickNavigate && !visibleQuickAccess; // only hide input if there was no picker opened already
if (typeof options?.itemActivation === 'number' || options?.quickNavigateConfiguration) {
picker.itemActivation = options?.itemActivation ?? ItemActivation.SECOND /* quick nav is always second */;
}
picker.contextKey = descriptor?.contextKey;
picker.filterValue = (value) => value.substring(descriptor ? descriptor.prefix.length : 0);
// Pick mode: setup a promise that can be resolved
// with the selected items and prevent execution
let pickPromise = undefined;
if (pick) {
pickPromise = new DeferredPromise();
disposables.add(Event.once(picker.onWillAccept)(e => {
e.veto();
picker.hide();
}));
}
// Register listeners
disposables.add(this.registerPickerListeners(picker, provider, descriptor, value, options));
// Ask provider to fill the picker as needed if we have one
// and pass over a cancellation token that will indicate when
// the picker is hiding without a pick being made.
const cts = disposables.add(new CancellationTokenSource());
if (provider) {
disposables.add(provider.provide(picker, cts.token, options?.providerOptions));
}
// Finally, trigger disposal and cancellation when the picker
// hides depending on items selected or not.
Event.once(picker.onDidHide)(() => {
if (picker.selectedItems.length === 0) {
cts.cancel();
}
// Start to dispose once picker hides
disposables.dispose();
// Resolve pick promise with selected items
pickPromise?.complete(picker.selectedItems.slice(0));
});
// Finally, show the picker. This is important because a provider
// may not call this and then our disposables would leak that rely
// on the onDidHide event.
picker.show();
// If the previous picker had a selection and the value is unchanged, we should set that in the new picker.
if (visibleSelection && visibleValue === value) {
picker.valueSelection = visibleSelection;
}
// Pick mode: return with promise
if (pick) {
return pickPromise?.p;
}
}
adjustValueSelection(picker, descriptor, options) {
let valueSelection;
// Preserve: just always put the cursor at the end
if (options?.preserveValue) {
valueSelection = [picker.value.length, picker.value.length];
}
// Otherwise: select the value up until the prefix
else {
valueSelection = [descriptor?.prefix.length ?? 0, picker.value.length];
}
picker.valueSelection = valueSelection;
}
registerPickerListeners(picker, provider, descriptor, value, options) {
const disposables = new DisposableStore();
// Remember as last visible picker and clean up once picker get's disposed
const visibleQuickAccess = this.visibleQuickAccess = { picker, descriptor, value };
disposables.add(toDisposable(() => {
if (visibleQuickAccess === this.visibleQuickAccess) {
this.visibleQuickAccess = undefined;
}
}));
// Whenever the value changes, check if the provider has
// changed and if so - re-create the picker from the beginning
disposables.add(picker.onDidChangeValue(value => {
const [providerForValue] = this.getOrInstantiateProvider(value, options?.enabledProviderPrefixes);
if (providerForValue !== provider) {
this.show(value, {
enabledProviderPrefixes: options?.enabledProviderPrefixes,
// do not rewrite value from user typing!
preserveValue: true,
// persist the value of the providerOptions from the original showing
providerOptions: options?.providerOptions
});
}
else {
visibleQuickAccess.value = value; // remember the value in our visible one
}
}));
// Remember picker input for future use when accepting
if (descriptor) {
disposables.add(picker.onDidAccept(() => {
this.lastAcceptedPickerValues.set(descriptor, picker.value);
}));
}
return disposables;
}
getOrInstantiateProvider(value, enabledProviderPrefixes) {
const providerDescriptor = this.registry.getQuickAccessProvider(value);
if (!providerDescriptor || enabledProviderPrefixes && !enabledProviderPrefixes?.includes(providerDescriptor.prefix)) {
return [undefined, undefined];
}
let provider = this.mapProviderToDescriptor.get(providerDescriptor);
if (!provider) {
provider = this.instantiationService.createInstance(providerDescriptor.ctor);
this.mapProviderToDescriptor.set(providerDescriptor, provider);
}
return [provider, providerDescriptor];
}
};
QuickAccessController = __decorate([
__param(0, IQuickInputService),
__param(1, IInstantiationService)
], QuickAccessController);
export { QuickAccessController };
//# sourceMappingURL=quickAccess.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,189 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { isMacintosh } from '../../../base/common/platform.js';
import { localize } from '../../../nls.js';
import { ContextKeyExpr } from '../../contextkey/common/contextkey.js';
import { InputFocusedContext } from '../../contextkey/common/contextkeys.js';
import { KeybindingsRegistry } from '../../keybinding/common/keybindingsRegistry.js';
import { endOfQuickInputBoxContext, inQuickInputContext, quickInputTypeContextKeyValue } from './quickInput.js';
import { IQuickInputService, QuickPickFocus } from '../common/quickInput.js';
function registerQuickInputCommandAndKeybindingRule(rule, options = {}) {
KeybindingsRegistry.registerCommandAndKeybindingRule({
weight: 200 /* KeybindingWeight.WorkbenchContrib */,
when: inQuickInputContext,
metadata: { description: localize(1741, "Used while in the context of any kind of quick input. If you change one keybinding for this command, you should change all of the other keybindings (modifier variants) of this command as well.") },
...rule,
secondary: getSecondary(rule.primary, rule.secondary ?? [], options)
});
}
function registerQuickPickCommandAndKeybindingRule(rule, options = {}) {
KeybindingsRegistry.registerCommandAndKeybindingRule({
weight: 200 /* KeybindingWeight.WorkbenchContrib */,
when: ContextKeyExpr.and(ContextKeyExpr.or(
// Only things that use Tree widgets
ContextKeyExpr.equals(quickInputTypeContextKeyValue, "quickPick" /* QuickInputType.QuickPick */), ContextKeyExpr.equals(quickInputTypeContextKeyValue, "quickTree" /* QuickInputType.QuickTree */)), inQuickInputContext),
metadata: { description: localize(1742, "Used while in the context of the quick pick. If you change one keybinding for this command, you should change all of the other keybindings (modifier variants) of this command as well.") },
...rule,
secondary: getSecondary(rule.primary, rule.secondary ?? [], options)
});
}
const ctrlKeyMod = isMacintosh ? 256 /* KeyMod.WinCtrl */ : 2048 /* KeyMod.CtrlCmd */;
// This function will generate all the combinations of keybindings for the given primary keybinding
function getSecondary(primary, secondary, options = {}) {
if (options.withAltMod) {
secondary.push(512 /* KeyMod.Alt */ + primary);
}
if (options.withCtrlMod) {
secondary.push(ctrlKeyMod + primary);
if (options.withAltMod) {
secondary.push(512 /* KeyMod.Alt */ + ctrlKeyMod + primary);
}
}
if (options.withCmdMod && isMacintosh) {
secondary.push(2048 /* KeyMod.CtrlCmd */ + primary);
if (options.withCtrlMod) {
secondary.push(2048 /* KeyMod.CtrlCmd */ + 256 /* KeyMod.WinCtrl */ + primary);
}
if (options.withAltMod) {
secondary.push(2048 /* KeyMod.CtrlCmd */ + 512 /* KeyMod.Alt */ + primary);
if (options.withCtrlMod) {
secondary.push(2048 /* KeyMod.CtrlCmd */ + 512 /* KeyMod.Alt */ + 256 /* KeyMod.WinCtrl */ + primary);
}
}
}
return secondary;
}
//#region Navigation
function focusHandler(focus, focusOnQuickNatigate) {
return accessor => {
// Assuming this is a quick pick due to above when clause
const currentQuickPick = accessor.get(IQuickInputService).currentQuickInput;
if (!currentQuickPick) {
return;
}
if (focusOnQuickNatigate && currentQuickPick.quickNavigate) {
return currentQuickPick.focus(focusOnQuickNatigate);
}
return currentQuickPick.focus(focus);
};
}
registerQuickPickCommandAndKeybindingRule({ id: 'quickInput.pageNext', primary: 12 /* KeyCode.PageDown */, handler: focusHandler(QuickPickFocus.NextPage) }, { withAltMod: true, withCtrlMod: true, withCmdMod: true });
registerQuickPickCommandAndKeybindingRule({ id: 'quickInput.pagePrevious', primary: 11 /* KeyCode.PageUp */, handler: focusHandler(QuickPickFocus.PreviousPage) }, { withAltMod: true, withCtrlMod: true, withCmdMod: true });
registerQuickPickCommandAndKeybindingRule({ id: 'quickInput.first', primary: ctrlKeyMod + 14 /* KeyCode.Home */, handler: focusHandler(QuickPickFocus.First) }, { withAltMod: true, withCmdMod: true });
registerQuickPickCommandAndKeybindingRule({ id: 'quickInput.last', primary: ctrlKeyMod + 13 /* KeyCode.End */, handler: focusHandler(QuickPickFocus.Last) }, { withAltMod: true, withCmdMod: true });
registerQuickPickCommandAndKeybindingRule({ id: 'quickInput.next', primary: 18 /* KeyCode.DownArrow */, handler: focusHandler(QuickPickFocus.Next) }, { withCtrlMod: true });
registerQuickPickCommandAndKeybindingRule({ id: 'quickInput.previous', primary: 16 /* KeyCode.UpArrow */, handler: focusHandler(QuickPickFocus.Previous) }, { withCtrlMod: true });
// The next & previous separator commands are interesting because if we are in quick access mode, we are already holding a modifier key down.
// In this case, we want that modifier key+up/down to navigate to the next/previous item, not the next/previous separator.
// To handle this, we have a separate command for navigating to the next/previous separator when we are not in quick access mode.
// If, however, we are in quick access mode, and you hold down an additional modifier key, we will navigate to the next/previous separator.
const nextSeparatorFallbackDesc = localize(1743, "If we're in quick access mode, this will navigate to the next item. If we are not in quick access mode, this will navigate to the next separator.");
const prevSeparatorFallbackDesc = localize(1744, "If we're in quick access mode, this will navigate to the previous item. If we are not in quick access mode, this will navigate to the previous separator.");
if (isMacintosh) {
registerQuickPickCommandAndKeybindingRule({
id: 'quickInput.nextSeparatorWithQuickAccessFallback',
primary: 2048 /* KeyMod.CtrlCmd */ + 18 /* KeyCode.DownArrow */,
handler: focusHandler(QuickPickFocus.NextSeparator, QuickPickFocus.Next),
metadata: { description: nextSeparatorFallbackDesc }
});
registerQuickPickCommandAndKeybindingRule({
id: 'quickInput.nextSeparator',
primary: 2048 /* KeyMod.CtrlCmd */ + 512 /* KeyMod.Alt */ + 18 /* KeyCode.DownArrow */,
// Since macOS has the cmd key as the primary modifier, we need to add this additional
// keybinding to capture cmd+ctrl+upArrow
secondary: [2048 /* KeyMod.CtrlCmd */ + 256 /* KeyMod.WinCtrl */ + 18 /* KeyCode.DownArrow */],
handler: focusHandler(QuickPickFocus.NextSeparator)
}, { withCtrlMod: true });
registerQuickPickCommandAndKeybindingRule({
id: 'quickInput.previousSeparatorWithQuickAccessFallback',
primary: 2048 /* KeyMod.CtrlCmd */ + 16 /* KeyCode.UpArrow */,
handler: focusHandler(QuickPickFocus.PreviousSeparator, QuickPickFocus.Previous),
metadata: { description: prevSeparatorFallbackDesc }
});
registerQuickPickCommandAndKeybindingRule({
id: 'quickInput.previousSeparator',
primary: 2048 /* KeyMod.CtrlCmd */ + 512 /* KeyMod.Alt */ + 16 /* KeyCode.UpArrow */,
// Since macOS has the cmd key as the primary modifier, we need to add this additional
// keybinding to capture cmd+ctrl+upArrow
secondary: [2048 /* KeyMod.CtrlCmd */ + 256 /* KeyMod.WinCtrl */ + 16 /* KeyCode.UpArrow */],
handler: focusHandler(QuickPickFocus.PreviousSeparator)
}, { withCtrlMod: true });
}
else {
registerQuickPickCommandAndKeybindingRule({
id: 'quickInput.nextSeparatorWithQuickAccessFallback',
primary: 512 /* KeyMod.Alt */ + 18 /* KeyCode.DownArrow */,
handler: focusHandler(QuickPickFocus.NextSeparator, QuickPickFocus.Next),
metadata: { description: nextSeparatorFallbackDesc }
});
registerQuickPickCommandAndKeybindingRule({
id: 'quickInput.nextSeparator',
primary: 2048 /* KeyMod.CtrlCmd */ + 512 /* KeyMod.Alt */ + 18 /* KeyCode.DownArrow */,
handler: focusHandler(QuickPickFocus.NextSeparator)
});
registerQuickPickCommandAndKeybindingRule({
id: 'quickInput.previousSeparatorWithQuickAccessFallback',
primary: 512 /* KeyMod.Alt */ + 16 /* KeyCode.UpArrow */,
handler: focusHandler(QuickPickFocus.PreviousSeparator, QuickPickFocus.Previous),
metadata: { description: prevSeparatorFallbackDesc }
});
registerQuickPickCommandAndKeybindingRule({
id: 'quickInput.previousSeparator',
primary: 2048 /* KeyMod.CtrlCmd */ + 512 /* KeyMod.Alt */ + 16 /* KeyCode.UpArrow */,
handler: focusHandler(QuickPickFocus.PreviousSeparator)
});
}
//#endregion
//#region Accept
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: 'quickInput.accept',
primary: 3 /* KeyCode.Enter */,
weight: 200 /* KeybindingWeight.WorkbenchContrib */,
when: ContextKeyExpr.and(
// All other kinds of Quick things handle Accept, except Widget. In other words, Accepting is a detail on the things
// that extend IQuickInput
ContextKeyExpr.notEquals(quickInputTypeContextKeyValue, "quickWidget" /* QuickInputType.QuickWidget */), inQuickInputContext),
metadata: { description: localize(1745, "Used while in the context of some quick input. If you change one keybinding for this command, you should change all of the other keybindings (modifier variants) of this command as well.") },
handler: (accessor) => {
const currentQuickPick = accessor.get(IQuickInputService).currentQuickInput;
currentQuickPick?.accept();
},
secondary: getSecondary(3 /* KeyCode.Enter */, [], { withAltMod: true, withCtrlMod: true, withCmdMod: true })
});
registerQuickPickCommandAndKeybindingRule({
id: 'quickInput.acceptInBackground',
// If we are in the quick pick but the input box is not focused or our cursor is at the end of the input box
when: ContextKeyExpr.and(inQuickInputContext, ContextKeyExpr.equals(quickInputTypeContextKeyValue, "quickPick" /* QuickInputType.QuickPick */), ContextKeyExpr.or(InputFocusedContext.negate(), endOfQuickInputBoxContext)),
primary: 17 /* KeyCode.RightArrow */,
// Need a little extra weight to ensure this keybinding is preferred over the default cmd+alt+right arrow keybinding
// https://github.com/microsoft/vscode/blob/1451e4fbbbf074a4355cc537c35b547b80ce1c52/src/vs/workbench/browser/parts/editor/editorActions.ts#L1178-L1195
weight: 200 /* KeybindingWeight.WorkbenchContrib */ + 50,
handler: (accessor) => {
const currentQuickPick = accessor.get(IQuickInputService).currentQuickInput;
currentQuickPick?.accept(true);
},
}, { withAltMod: true, withCtrlMod: true, withCmdMod: true });
//#endregion
//#region Hide
registerQuickInputCommandAndKeybindingRule({
id: 'quickInput.hide',
primary: 9 /* KeyCode.Escape */,
handler: (accessor) => {
const currentQuickPick = accessor.get(IQuickInputService).currentQuickInput;
currentQuickPick?.hide();
}
}, { withAltMod: true, withCtrlMod: true, withCmdMod: true });
//#endregion
//#region Toggle Hover
registerQuickPickCommandAndKeybindingRule({
id: 'quickInput.toggleHover',
primary: ctrlKeyMod | 10 /* KeyCode.Space */,
handler: accessor => {
const quickInputService = accessor.get(IQuickInputService);
quickInputService.toggleHover();
}
});
//#endregion
//# sourceMappingURL=quickInputActions.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,102 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as dom from '../../../base/browser/dom.js';
import { FindInput } from '../../../base/browser/ui/findinput/findInput.js';
import { Disposable } from '../../../base/common/lifecycle.js';
import Severity from '../../../base/common/severity.js';
import './media/quickInput.css';
const $ = dom.$;
export class QuickInputBox extends Disposable {
constructor(parent, inputBoxStyles, toggleStyles) {
super();
this.parent = parent;
this.onDidChange = (handler) => {
return this.findInput.onDidChange(handler);
};
this.container = dom.append(this.parent, $('.quick-input-box'));
this.findInput = this._register(new FindInput(this.container, undefined, { label: '', inputBoxStyles, toggleStyles }));
const input = this.findInput.inputBox.inputElement;
input.role = 'textbox';
input.ariaHasPopup = 'menu';
input.ariaAutoComplete = 'list';
}
get onKeyDown() {
return this.findInput.onKeyDown;
}
get value() {
return this.findInput.getValue();
}
set value(value) {
this.findInput.setValue(value);
}
select(range = null) {
this.findInput.inputBox.select(range);
}
getSelection() {
return this.findInput.inputBox.getSelection();
}
isSelectionAtEnd() {
return this.findInput.inputBox.isSelectionAtEnd();
}
get placeholder() {
return this.findInput.inputBox.inputElement.getAttribute('placeholder') || '';
}
set placeholder(placeholder) {
this.findInput.inputBox.setPlaceHolder(placeholder);
}
get password() {
return this.findInput.inputBox.inputElement.type === 'password';
}
set password(password) {
this.findInput.inputBox.inputElement.type = password ? 'password' : 'text';
}
set enabled(enabled) {
// We can't disable the input box because it is still used for
// navigating the list. Instead, we disable the list and the OK
// so that nothing can be selected.
// TODO: should this be what we do for all find inputs? Or maybe some _other_ API
// on findInput to change it to readonly?
this.findInput.inputBox.inputElement.toggleAttribute('readonly', !enabled);
// TODO: styles of the quick pick need to be moved to the CSS instead of being in line
// so things like this can be done in CSS
// this.findInput.inputBox.inputElement.classList.toggle('disabled', !enabled);
}
set toggles(toggles) {
this.findInput.setAdditionalToggles(toggles);
}
get ariaLabel() {
return this.findInput.inputBox.inputElement.getAttribute('aria-label') || '';
}
set ariaLabel(ariaLabel) {
this.findInput.inputBox.inputElement.setAttribute('aria-label', ariaLabel);
}
hasFocus() {
return this.findInput.inputBox.hasFocus();
}
setAttribute(name, value) {
this.findInput.inputBox.inputElement.setAttribute(name, value);
}
removeAttribute(name) {
this.findInput.inputBox.inputElement.removeAttribute(name);
}
showDecoration(decoration) {
if (decoration === Severity.Ignore) {
this.findInput.clearMessage();
}
else {
this.findInput.showMessage({ type: decoration === Severity.Info ? 1 /* MessageType.INFO */ : decoration === Severity.Warning ? 2 /* MessageType.WARNING */ : 3 /* MessageType.ERROR */, content: '' });
}
}
stylesForType(decoration) {
return this.findInput.inputBox.stylesForType(decoration === Severity.Info ? 1 /* MessageType.INFO */ : decoration === Severity.Warning ? 2 /* MessageType.WARNING */ : 3 /* MessageType.ERROR */);
}
setFocus() {
this.findInput.focus();
}
layout() {
this.findInput.inputBox.layout();
}
}
//# sourceMappingURL=quickInputBox.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,888 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var QuickInputController_1;
import * as dom from '../../../base/browser/dom.js';
import * as domStylesheetsJs from '../../../base/browser/domStylesheets.js';
import { ActionBar } from '../../../base/browser/ui/actionbar/actionbar.js';
import { Button } from '../../../base/browser/ui/button/button.js';
import { CountBadge } from '../../../base/browser/ui/countBadge/countBadge.js';
import { ProgressBar } from '../../../base/browser/ui/progressbar/progressbar.js';
import { CancellationToken } from '../../../base/common/cancellation.js';
import { Emitter, Event } from '../../../base/common/event.js';
import { Disposable, dispose } from '../../../base/common/lifecycle.js';
import Severity from '../../../base/common/severity.js';
import { isString } from '../../../base/common/types.js';
import { localize } from '../../../nls.js';
import { QuickInputHideReason } from '../common/quickInput.js';
import { QuickInputBox } from './quickInputBox.js';
import { QuickPick, backButton, InputBox, InQuickInputContextKey, QuickInputTypeContextKey, EndOfQuickInputBoxContextKey, QuickInputAlignmentContextKey } from './quickInput.js';
import { ILayoutService } from '../../layout/browser/layoutService.js';
import { mainWindow } from '../../../base/browser/window.js';
import { IInstantiationService } from '../../instantiation/common/instantiation.js';
import { QuickInputList } from './quickInputList.js';
import { IContextKeyService } from '../../contextkey/common/contextkey.js';
import './quickInputActions.js';
import { autorun, observableValue } from '../../../base/common/observable.js';
import { StandardMouseEvent } from '../../../base/browser/mouseEvent.js';
import { IStorageService } from '../../storage/common/storage.js';
import { IConfigurationService } from '../../configuration/common/configuration.js';
import { platform } from '../../../base/common/platform.js';
import { getWindowControlsStyle } from '../../window/common/window.js';
import { getZoomFactor } from '../../../base/browser/browser.js';
import { TriStateCheckbox } from '../../../base/browser/ui/toggle/toggle.js';
import { defaultCheckboxStyles } from '../../theme/browser/defaultStyles.js';
import { QuickInputTreeController } from './tree/quickInputTreeController.js';
const $ = dom.$;
const VIEWSTATE_STORAGE_KEY = 'workbench.quickInput.viewState';
let QuickInputController = class QuickInputController extends Disposable {
static { QuickInputController_1 = this; }
static { this.MAX_WIDTH = 600; } // Max total width of quick input widget
get currentQuickInput() { return this.controller ?? undefined; }
get container() { return this._container; }
constructor(options, layoutService, instantiationService, contextKeyService, storageService) {
super();
this.options = options;
this.layoutService = layoutService;
this.instantiationService = instantiationService;
this.storageService = storageService;
this.enabled = true;
this.onDidAcceptEmitter = this._register(new Emitter());
this.onDidCustomEmitter = this._register(new Emitter());
this.onDidTriggerButtonEmitter = this._register(new Emitter());
this.keyMods = { ctrlCmd: false, alt: false };
this.controller = null;
this.onShowEmitter = this._register(new Emitter());
this.onShow = this.onShowEmitter.event;
this.onHideEmitter = this._register(new Emitter());
this.onHide = this.onHideEmitter.event;
this.inQuickInputContext = InQuickInputContextKey.bindTo(contextKeyService);
this.quickInputTypeContext = QuickInputTypeContextKey.bindTo(contextKeyService);
this.endOfQuickInputBoxContext = EndOfQuickInputBoxContextKey.bindTo(contextKeyService);
this.idPrefix = options.idPrefix;
this._container = options.container;
this.styles = options.styles;
this._register(Event.runAndSubscribe(dom.onDidRegisterWindow, ({ window, disposables }) => this.registerKeyModsListeners(window, disposables), { window: mainWindow, disposables: this._store }));
this._register(dom.onWillUnregisterWindow(window => {
if (this.ui && dom.getWindow(this.ui.container) === window) {
// The window this quick input is contained in is about to
// close, so we have to make sure to reparent it back to an
// existing parent to not loose functionality.
// (https://github.com/microsoft/vscode/issues/195870)
this.reparentUI(this.layoutService.mainContainer);
this.layout(this.layoutService.mainContainerDimension, this.layoutService.mainContainerOffset.quickPickTop);
}
}));
this.viewState = this.loadViewState();
}
registerKeyModsListeners(window, disposables) {
const listener = (e) => {
this.keyMods.ctrlCmd = e.ctrlKey || e.metaKey;
this.keyMods.alt = e.altKey;
};
for (const event of [dom.EventType.KEY_DOWN, dom.EventType.KEY_UP, dom.EventType.MOUSE_DOWN]) {
disposables.add(dom.addDisposableListener(window, event, listener, true));
}
}
getUI(showInActiveContainer) {
if (this.ui) {
// In order to support aux windows, re-parent the controller
// if the original event is from a different document
if (showInActiveContainer) {
if (dom.getWindow(this._container) !== dom.getWindow(this.layoutService.activeContainer)) {
this.reparentUI(this.layoutService.activeContainer);
this.layout(this.layoutService.activeContainerDimension, this.layoutService.activeContainerOffset.quickPickTop);
}
}
return this.ui;
}
const container = dom.append(this._container, $('.quick-input-widget.show-file-icons'));
container.tabIndex = -1;
container.style.display = 'none';
const styleSheet = domStylesheetsJs.createStyleSheet(container);
const titleBar = dom.append(container, $('.quick-input-titlebar'));
const leftActionBar = this._register(new ActionBar(titleBar, { hoverDelegate: this.options.hoverDelegate }));
leftActionBar.domNode.classList.add('quick-input-left-action-bar');
const title = dom.append(titleBar, $('.quick-input-title'));
const rightActionBar = this._register(new ActionBar(titleBar, { hoverDelegate: this.options.hoverDelegate }));
rightActionBar.domNode.classList.add('quick-input-right-action-bar');
const headerContainer = dom.append(container, $('.quick-input-header'));
const checkAll = this._register(new TriStateCheckbox(localize(1746, "Toggle all checkboxes"), false, { ...defaultCheckboxStyles, size: 15 }));
dom.append(headerContainer, checkAll.domNode);
this._register(checkAll.onChange(() => {
const checked = checkAll.checked;
list.setAllVisibleChecked(checked === true);
}));
this._register(dom.addDisposableListener(checkAll.domNode, dom.EventType.CLICK, e => {
if (e.x || e.y) { // Avoid 'click' triggered by 'space'...
inputBox.setFocus();
}
}));
const description2 = dom.append(headerContainer, $('.quick-input-description'));
const inputContainer = dom.append(headerContainer, $('.quick-input-and-message'));
const filterContainer = dom.append(inputContainer, $('.quick-input-filter'));
const inputBox = this._register(new QuickInputBox(filterContainer, this.styles.inputBox, this.styles.toggle));
inputBox.setAttribute('aria-describedby', `${this.idPrefix}message`);
const visibleCountContainer = dom.append(filterContainer, $('.quick-input-visible-count'));
visibleCountContainer.setAttribute('aria-live', 'polite');
visibleCountContainer.setAttribute('aria-atomic', 'true');
const visibleCount = this._register(new CountBadge(visibleCountContainer, { countFormat: localize(1747, "{0} Results") }, this.styles.countBadge));
const countContainer = dom.append(filterContainer, $('.quick-input-count'));
countContainer.setAttribute('aria-live', 'polite');
const count = this._register(new CountBadge(countContainer, { countFormat: localize(1748, "{0} Selected") }, this.styles.countBadge));
const inlineActionBar = this._register(new ActionBar(headerContainer, { hoverDelegate: this.options.hoverDelegate }));
inlineActionBar.domNode.classList.add('quick-input-inline-action-bar');
const okContainer = dom.append(headerContainer, $('.quick-input-action'));
const ok = this._register(new Button(okContainer, this.styles.button));
ok.label = localize(1749, "OK");
this._register(ok.onDidClick(e => {
this.onDidAcceptEmitter.fire();
}));
const customButtonContainer = dom.append(headerContainer, $('.quick-input-action'));
const customButton = this._register(new Button(customButtonContainer, { ...this.styles.button, supportIcons: true }));
customButton.label = localize(1750, "Custom");
this._register(customButton.onDidClick(e => {
this.onDidCustomEmitter.fire();
}));
const message = dom.append(inputContainer, $(`#${this.idPrefix}message.quick-input-message`));
const progressBar = this._register(new ProgressBar(container, this.styles.progressBar));
progressBar.getContainer().classList.add('quick-input-progress');
const widget = dom.append(container, $('.quick-input-html-widget'));
widget.tabIndex = -1;
const description1 = dom.append(container, $('.quick-input-description'));
// List
const listId = this.idPrefix + 'list';
const list = this._register(this.instantiationService.createInstance(QuickInputList, container, this.options.hoverDelegate, this.options.linkOpenerDelegate, listId));
inputBox.setAttribute('aria-controls', listId);
this._register(list.onDidChangeFocus(() => {
if (inputBox.hasFocus()) {
inputBox.setAttribute('aria-activedescendant', list.getActiveDescendant() ?? '');
}
}));
this._register(list.onChangedAllVisibleChecked(checked => {
// TODO: Support tri-state checkbox when we remove the .indent property that is faking tree structure.
checkAll.checked = checked;
}));
this._register(list.onChangedVisibleCount(c => {
visibleCount.setCount(c);
}));
this._register(list.onChangedCheckedCount(c => {
count.setCount(c);
}));
this._register(list.onLeave(() => {
// Defer to avoid the input field reacting to the triggering key.
// TODO@TylerLeonhardt https://github.com/microsoft/vscode/issues/203675
setTimeout(() => {
if (!this.controller) {
return;
}
inputBox.setFocus();
if (this.controller instanceof QuickPick && this.controller.canSelectMany) {
list.clearFocus();
}
}, 0);
}));
// Tree
const tree = this._register(this.instantiationService.createInstance(QuickInputTreeController, container, this.options.hoverDelegate));
this._register(tree.tree.onDidChangeFocus(() => {
if (inputBox.hasFocus()) {
inputBox.setAttribute('aria-activedescendant', tree.getActiveDescendant() ?? '');
}
}));
this._register(tree.onLeave(() => {
// Defer to avoid the input field reacting to the triggering key.
// TODO@TylerLeonhardt https://github.com/microsoft/vscode/issues/203675
setTimeout(() => {
if (!this.controller) {
return;
}
inputBox.setFocus();
tree.tree.setFocus([]);
}, 0);
}));
// Wire up tree's accept event to the UI's accept emitter for non-pickable items
this._register(tree.onDidAccept(() => {
this.onDidAcceptEmitter.fire();
}));
this._register(tree.tree.onDidChangeContentHeight(() => this.updateLayout()));
const focusTracker = dom.trackFocus(container);
this._register(focusTracker);
this._register(dom.addDisposableListener(container, dom.EventType.FOCUS, e => {
const ui = this.getUI();
if (dom.isAncestor(e.relatedTarget, ui.inputContainer)) {
const value = ui.inputBox.isSelectionAtEnd();
if (this.endOfQuickInputBoxContext.get() !== value) {
this.endOfQuickInputBoxContext.set(value);
}
}
// Ignore focus events within container
if (dom.isAncestor(e.relatedTarget, ui.container)) {
return;
}
this.inQuickInputContext.set(true);
this.previousFocusElement = dom.isHTMLElement(e.relatedTarget) ? e.relatedTarget : undefined;
}, true));
this._register(focusTracker.onDidBlur(() => {
if (!this.getUI().ignoreFocusOut && !this.options.ignoreFocusOut()) {
this.hide(QuickInputHideReason.Blur);
}
this.inQuickInputContext.set(false);
this.endOfQuickInputBoxContext.set(false);
this.previousFocusElement = undefined;
}));
this._register(inputBox.onKeyDown(_ => {
const value = this.getUI().inputBox.isSelectionAtEnd();
if (this.endOfQuickInputBoxContext.get() !== value) {
this.endOfQuickInputBoxContext.set(value);
}
// Allow screenreaders to read what's in the input
// Note: this works for arrow keys and selection changes,
// but not for deletions since that often triggers a
// change in the list.
inputBox.removeAttribute('aria-activedescendant');
}));
this._register(dom.addDisposableListener(container, dom.EventType.FOCUS, (e) => {
inputBox.setFocus();
}));
// Drag and Drop support
this.dndController = this._register(this.instantiationService.createInstance(QuickInputDragAndDropController, this._container, container, [
{
node: titleBar,
includeChildren: true
},
{
node: headerContainer,
includeChildren: false
}
], this.viewState));
// DnD update layout
this._register(autorun(reader => {
const dndViewState = this.dndController?.dndViewState.read(reader);
if (!dndViewState) {
return;
}
if (dndViewState.top !== undefined && dndViewState.left !== undefined) {
this.viewState = {
...this.viewState,
top: dndViewState.top,
left: dndViewState.left
};
}
else {
// Reset position/size
this.viewState = undefined;
}
this.updateLayout();
// Save position
if (dndViewState.done) {
this.saveViewState(this.viewState);
}
}));
this.ui = {
container,
styleSheet,
leftActionBar,
titleBar,
title,
description1,
description2,
widget,
rightActionBar,
inlineActionBar,
checkAll,
inputContainer,
filterContainer,
inputBox,
visibleCountContainer,
visibleCount,
countContainer,
count,
okContainer,
ok,
message,
customButtonContainer,
customButton,
list,
tree,
progressBar,
onDidAccept: this.onDidAcceptEmitter.event,
onDidCustom: this.onDidCustomEmitter.event,
onDidTriggerButton: this.onDidTriggerButtonEmitter.event,
ignoreFocusOut: false,
keyMods: this.keyMods,
show: controller => this.show(controller),
hide: () => this.hide(),
setVisibilities: visibilities => this.setVisibilities(visibilities),
setEnabled: enabled => this.setEnabled(enabled),
setContextKey: contextKey => this.options.setContextKey(contextKey),
linkOpenerDelegate: content => this.options.linkOpenerDelegate(content)
};
this.updateStyles();
return this.ui;
}
reparentUI(container) {
if (this.ui) {
this._container = container;
dom.append(this._container, this.ui.container);
this.dndController?.reparentUI(this._container);
}
}
pick(picks, options = {}, token = CancellationToken.None) {
return new Promise((doResolve, reject) => {
let resolve = (result) => {
resolve = doResolve;
options.onKeyMods?.(input.keyMods);
doResolve(result);
};
if (token.isCancellationRequested) {
resolve(undefined);
return;
}
const input = this.createQuickPick({ useSeparators: true });
let activeItem;
const disposables = [
input,
input.onDidAccept(() => {
if (input.canSelectMany) {
resolve(input.selectedItems.slice());
input.hide();
}
else {
const result = input.activeItems[0];
if (result) {
resolve(result);
input.hide();
}
}
}),
input.onDidChangeActive(items => {
const focused = items[0];
if (focused && options.onDidFocus) {
options.onDidFocus(focused);
}
}),
input.onDidChangeSelection(items => {
if (!input.canSelectMany) {
const result = items[0];
if (result) {
resolve(result);
input.hide();
}
}
}),
input.onDidTriggerItemButton(event => options.onDidTriggerItemButton && options.onDidTriggerItemButton({
...event,
removeItem: () => {
const index = input.items.indexOf(event.item);
if (index !== -1) {
const items = input.items.slice();
const removed = items.splice(index, 1);
const activeItems = input.activeItems.filter(activeItem => activeItem !== removed[0]);
const keepScrollPositionBefore = input.keepScrollPosition;
input.keepScrollPosition = true;
input.items = items;
if (activeItems) {
input.activeItems = activeItems;
}
input.keepScrollPosition = keepScrollPositionBefore;
}
}
})),
input.onDidTriggerSeparatorButton(event => options.onDidTriggerSeparatorButton?.(event)),
input.onDidChangeValue(value => {
if (activeItem && !value && (input.activeItems.length !== 1 || input.activeItems[0] !== activeItem)) {
input.activeItems = [activeItem];
}
}),
token.onCancellationRequested(() => {
input.hide();
}),
input.onDidHide(() => {
dispose(disposables);
resolve(undefined);
}),
];
input.title = options.title;
if (options.value) {
input.value = options.value;
}
input.canSelectMany = !!options.canPickMany;
input.placeholder = options.placeHolder;
input.ignoreFocusOut = !!options.ignoreFocusLost;
input.matchOnDescription = !!options.matchOnDescription;
input.matchOnDetail = !!options.matchOnDetail;
if (options.sortByLabel !== undefined) {
input.sortByLabel = options.sortByLabel;
}
input.matchOnLabel = (options.matchOnLabel === undefined) || options.matchOnLabel; // default to true
input.quickNavigate = options.quickNavigate;
input.hideInput = !!options.hideInput;
input.contextKey = options.contextKey;
input.busy = true;
Promise.all([picks, options.activeItem])
.then(([items, _activeItem]) => {
activeItem = _activeItem;
input.busy = false;
input.items = items;
if (input.canSelectMany) {
input.selectedItems = items.filter(item => item.type !== 'separator' && item.picked);
}
if (activeItem) {
input.activeItems = [activeItem];
}
});
input.show();
Promise.resolve(picks).then(undefined, err => {
reject(err);
input.hide();
});
});
}
setValidationOnInput(input, validationResult) {
if (validationResult && isString(validationResult)) {
input.severity = Severity.Error;
input.validationMessage = validationResult;
}
else if (validationResult && !isString(validationResult)) {
input.severity = validationResult.severity;
input.validationMessage = validationResult.content;
}
else {
input.severity = Severity.Ignore;
input.validationMessage = undefined;
}
}
input(options = {}, token = CancellationToken.None) {
return new Promise((resolve) => {
if (token.isCancellationRequested) {
resolve(undefined);
return;
}
const input = this.createInputBox();
const validateInput = options.validateInput || (() => Promise.resolve(undefined));
const onDidValueChange = Event.debounce(input.onDidChangeValue, (last, cur) => cur, 100);
let validationValue = options.value || '';
let validation = Promise.resolve(validateInput(validationValue));
const disposables = [
input,
onDidValueChange(value => {
if (value !== validationValue) {
validation = Promise.resolve(validateInput(value));
validationValue = value;
}
validation.then(result => {
if (value === validationValue) {
this.setValidationOnInput(input, result);
}
});
}),
input.onDidAccept(() => {
const value = input.value;
if (value !== validationValue) {
validation = Promise.resolve(validateInput(value));
validationValue = value;
}
validation.then(result => {
if (!result || (!isString(result) && result.severity !== Severity.Error)) {
resolve(value);
input.hide();
}
else if (value === validationValue) {
this.setValidationOnInput(input, result);
}
});
}),
token.onCancellationRequested(() => {
input.hide();
}),
input.onDidHide(() => {
dispose(disposables);
resolve(undefined);
}),
];
input.title = options.title;
input.value = options.value || '';
input.valueSelection = options.valueSelection;
input.prompt = options.prompt;
input.placeholder = options.placeHolder;
input.password = !!options.password;
input.ignoreFocusOut = !!options.ignoreFocusLost;
input.show();
});
}
createQuickPick(options = { useSeparators: false }) {
const ui = this.getUI(true);
return new QuickPick(ui);
}
createInputBox() {
const ui = this.getUI(true);
return new InputBox(ui);
}
show(controller) {
const ui = this.getUI(true);
this.onShowEmitter.fire();
const oldController = this.controller;
this.controller = controller;
oldController?.didHide();
this.setEnabled(true);
ui.leftActionBar.clear();
ui.title.textContent = '';
ui.description1.textContent = '';
ui.description2.textContent = '';
dom.reset(ui.widget);
ui.rightActionBar.clear();
ui.inlineActionBar.clear();
ui.checkAll.checked = false;
// ui.inputBox.value = ''; Avoid triggering an event.
ui.inputBox.placeholder = '';
ui.inputBox.password = false;
ui.inputBox.showDecoration(Severity.Ignore);
ui.visibleCount.setCount(0);
ui.count.setCount(0);
dom.reset(ui.message);
ui.progressBar.stop();
ui.list.setElements([]);
ui.list.matchOnDescription = false;
ui.list.matchOnDetail = false;
ui.list.matchOnLabel = true;
ui.list.sortByLabel = true;
ui.ignoreFocusOut = false;
ui.inputBox.toggles = undefined;
const backKeybindingLabel = this.options.backKeybindingLabel();
backButton.tooltip = backKeybindingLabel ? localize(1751, "Back ({0})", backKeybindingLabel) : localize(1752, "Back");
ui.container.style.display = '';
this.updateLayout();
this.dndController?.layoutContainer();
ui.inputBox.setFocus();
this.quickInputTypeContext.set(controller.type);
}
isVisible() {
return !!this.ui && this.ui.container.style.display !== 'none';
}
setVisibilities(visibilities) {
const ui = this.getUI();
ui.title.style.display = visibilities.title ? '' : 'none';
ui.description1.style.display = visibilities.description && (visibilities.inputBox || visibilities.checkAll) ? '' : 'none';
ui.description2.style.display = visibilities.description && !(visibilities.inputBox || visibilities.checkAll) ? '' : 'none';
ui.checkAll.domNode.style.display = visibilities.checkAll ? '' : 'none';
ui.inputContainer.style.display = visibilities.inputBox ? '' : 'none';
ui.filterContainer.style.display = visibilities.inputBox ? '' : 'none';
ui.visibleCountContainer.style.display = visibilities.visibleCount ? '' : 'none';
ui.countContainer.style.display = visibilities.count ? '' : 'none';
ui.okContainer.style.display = visibilities.ok ? '' : 'none';
ui.customButtonContainer.style.display = visibilities.customButton ? '' : 'none';
ui.message.style.display = visibilities.message ? '' : 'none';
ui.progressBar.getContainer().style.display = visibilities.progressBar ? '' : 'none';
ui.list.displayed = !!visibilities.list;
ui.tree.displayed = !!visibilities.tree;
ui.container.classList.toggle('show-checkboxes', !!visibilities.checkBox);
ui.container.classList.toggle('hidden-input', !visibilities.inputBox && !visibilities.description);
this.updateLayout(); // TODO
}
setEnabled(enabled) {
if (enabled !== this.enabled) {
this.enabled = enabled;
const ui = this.getUI();
for (const item of ui.leftActionBar.viewItems) {
item.action.enabled = enabled;
}
for (const item of ui.rightActionBar.viewItems) {
item.action.enabled = enabled;
}
if (enabled) {
ui.checkAll.enable();
}
else {
ui.checkAll.disable();
}
ui.inputBox.enabled = enabled;
ui.ok.enabled = enabled;
ui.list.enabled = enabled;
}
}
hide(reason) {
const controller = this.controller;
if (!controller) {
return;
}
controller.willHide(reason);
const container = this.ui?.container;
const focusChanged = container && !dom.isAncestorOfActiveElement(container);
this.controller = null;
this.onHideEmitter.fire();
if (container) {
container.style.display = 'none';
}
if (!focusChanged) {
let currentElement = this.previousFocusElement;
while (currentElement && !currentElement.offsetParent) {
currentElement = currentElement.parentElement ?? undefined;
}
if (currentElement?.offsetParent) {
currentElement.focus();
this.previousFocusElement = undefined;
}
else {
this.options.returnFocus();
}
}
controller.didHide(reason);
}
toggleHover() {
if (this.isVisible() && this.controller instanceof QuickPick) {
this.getUI().list.toggleHover();
}
}
layout(dimension, titleBarOffset) {
this.dimension = dimension;
this.titleBarOffset = titleBarOffset;
this.updateLayout();
}
updateLayout() {
if (this.ui && this.isVisible()) {
const style = this.ui.container.style;
const width = Math.min(this.dimension.width * 0.62 /* golden cut */, QuickInputController_1.MAX_WIDTH);
style.width = width + 'px';
// Position
style.top = `${this.viewState?.top ? Math.round(this.dimension.height * this.viewState.top) : this.titleBarOffset}px`;
style.left = `${Math.round((this.dimension.width * (this.viewState?.left ?? 0.5 /* center */)) - (width / 2))}px`;
this.ui.inputBox.layout();
this.ui.list.layout(this.dimension && this.dimension.height * 0.4);
this.ui.tree.layout(this.dimension && this.dimension.height * 0.4);
}
}
applyStyles(styles) {
this.styles = styles;
this.updateStyles();
}
updateStyles() {
if (this.ui) {
const { quickInputTitleBackground, quickInputBackground, quickInputForeground, widgetBorder, widgetShadow, } = this.styles.widget;
this.ui.titleBar.style.backgroundColor = quickInputTitleBackground ?? '';
this.ui.container.style.backgroundColor = quickInputBackground ?? '';
this.ui.container.style.color = quickInputForeground ?? '';
this.ui.container.style.border = widgetBorder ? `1px solid ${widgetBorder}` : '';
this.ui.container.style.boxShadow = widgetShadow ? `0 0 8px 2px ${widgetShadow}` : '';
this.ui.list.style(this.styles.list);
this.ui.tree.tree.style(this.styles.list);
const content = [];
if (this.styles.pickerGroup.pickerGroupBorder) {
content.push(`.quick-input-list .quick-input-list-entry { border-top-color: ${this.styles.pickerGroup.pickerGroupBorder}; }`);
}
if (this.styles.pickerGroup.pickerGroupForeground) {
content.push(`.quick-input-list .quick-input-list-separator { color: ${this.styles.pickerGroup.pickerGroupForeground}; }`);
}
if (this.styles.pickerGroup.pickerGroupForeground) {
content.push(`.quick-input-list .quick-input-list-separator-as-item { color: var(--vscode-descriptionForeground); }`);
}
if (this.styles.keybindingLabel.keybindingLabelBackground ||
this.styles.keybindingLabel.keybindingLabelBorder ||
this.styles.keybindingLabel.keybindingLabelBottomBorder ||
this.styles.keybindingLabel.keybindingLabelShadow ||
this.styles.keybindingLabel.keybindingLabelForeground) {
content.push('.quick-input-list .monaco-keybinding > .monaco-keybinding-key {');
if (this.styles.keybindingLabel.keybindingLabelBackground) {
content.push(`background-color: ${this.styles.keybindingLabel.keybindingLabelBackground};`);
}
if (this.styles.keybindingLabel.keybindingLabelBorder) {
// Order matters here. `border-color` must come before `border-bottom-color`.
content.push(`border-color: ${this.styles.keybindingLabel.keybindingLabelBorder};`);
}
if (this.styles.keybindingLabel.keybindingLabelBottomBorder) {
content.push(`border-bottom-color: ${this.styles.keybindingLabel.keybindingLabelBottomBorder};`);
}
if (this.styles.keybindingLabel.keybindingLabelShadow) {
content.push(`box-shadow: inset 0 -1px 0 ${this.styles.keybindingLabel.keybindingLabelShadow};`);
}
if (this.styles.keybindingLabel.keybindingLabelForeground) {
content.push(`color: ${this.styles.keybindingLabel.keybindingLabelForeground};`);
}
content.push('}');
}
const newStyles = content.join('\n');
if (newStyles !== this.ui.styleSheet.textContent) {
this.ui.styleSheet.textContent = newStyles;
}
}
}
loadViewState() {
try {
const data = JSON.parse(this.storageService.get(VIEWSTATE_STORAGE_KEY, -1 /* StorageScope.APPLICATION */, '{}'));
if (data.top !== undefined || data.left !== undefined) {
return data;
}
}
catch { }
return undefined;
}
saveViewState(viewState) {
const isMainWindow = this.layoutService.activeContainer === this.layoutService.mainContainer;
if (!isMainWindow) {
return;
}
if (viewState !== undefined) {
this.storageService.store(VIEWSTATE_STORAGE_KEY, JSON.stringify(viewState), -1 /* StorageScope.APPLICATION */, 1 /* StorageTarget.MACHINE */);
}
else {
this.storageService.remove(VIEWSTATE_STORAGE_KEY, -1 /* StorageScope.APPLICATION */);
}
}
};
QuickInputController = QuickInputController_1 = __decorate([
__param(1, ILayoutService),
__param(2, IInstantiationService),
__param(3, IContextKeyService),
__param(4, IStorageService)
], QuickInputController);
export { QuickInputController };
let QuickInputDragAndDropController = class QuickInputDragAndDropController extends Disposable {
constructor(_container, _quickInputContainer, _quickInputDragAreas, initialViewState, _layoutService, contextKeyService, configurationService) {
super();
this._container = _container;
this._quickInputContainer = _quickInputContainer;
this._quickInputDragAreas = _quickInputDragAreas;
this._layoutService = _layoutService;
this.configurationService = configurationService;
this.dndViewState = observableValue(this, undefined);
this._snapThreshold = 20;
this._snapLineHorizontalRatio = 0.25;
this._quickInputAlignmentContext = QuickInputAlignmentContextKey.bindTo(contextKeyService);
const customWindowControls = getWindowControlsStyle(this.configurationService) === "custom" /* WindowControlsStyle.CUSTOM */;
// Do not allow the widget to overflow or underflow window controls.
// Use CSS calculations to avoid having to force layout with `.clientWidth`
this._controlsOnLeft = customWindowControls && platform === 1 /* Platform.Mac */;
this._controlsOnRight = customWindowControls && (platform === 3 /* Platform.Windows */ || platform === 2 /* Platform.Linux */);
this._registerLayoutListener();
this.registerMouseListeners();
this.dndViewState.set({ ...initialViewState, done: true }, undefined);
}
reparentUI(container) {
this._container = container;
}
layoutContainer(dimension = this._layoutService.activeContainerDimension) {
const state = this.dndViewState.get();
const dragAreaRect = this._quickInputContainer.getBoundingClientRect();
if (state?.top && state?.left) {
const a = Math.round(state.left * 1e2) / 1e2;
const b = dimension.width;
const c = dragAreaRect.width;
const d = a * b - c / 2;
this._layout(state.top * dimension.height, d);
}
}
_registerLayoutListener() {
this._register(Event.filter(this._layoutService.onDidLayoutContainer, e => e.container === this._container)((e) => this.layoutContainer(e.dimension)));
}
registerMouseListeners() {
const dragArea = this._quickInputContainer;
// Double click
this._register(dom.addDisposableGenericMouseUpListener(dragArea, (event) => {
const originEvent = new StandardMouseEvent(dom.getWindow(dragArea), event);
if (originEvent.detail !== 2) {
return;
}
// Ignore event if the target is not the drag area
if (!this._quickInputDragAreas.some(({ node, includeChildren }) => includeChildren ? dom.isAncestor(originEvent.target, node) : originEvent.target === node)) {
return;
}
this.dndViewState.set({ top: undefined, left: undefined, done: true }, undefined);
}));
// Mouse down
this._register(dom.addDisposableGenericMouseDownListener(dragArea, (e) => {
const activeWindow = dom.getWindow(this._layoutService.activeContainer);
const originEvent = new StandardMouseEvent(activeWindow, e);
// Ignore event if the target is not the drag area
if (!this._quickInputDragAreas.some(({ node, includeChildren }) => includeChildren ? dom.isAncestor(originEvent.target, node) : originEvent.target === node)) {
return;
}
// Mouse position offset relative to dragArea
const dragAreaRect = this._quickInputContainer.getBoundingClientRect();
const dragOffsetX = originEvent.browserEvent.clientX - dragAreaRect.left;
const dragOffsetY = originEvent.browserEvent.clientY - dragAreaRect.top;
let isMovingQuickInput = false;
const mouseMoveListener = dom.addDisposableGenericMouseMoveListener(activeWindow, (e) => {
const mouseMoveEvent = new StandardMouseEvent(activeWindow, e);
mouseMoveEvent.preventDefault();
if (!isMovingQuickInput) {
isMovingQuickInput = true;
}
this._layout(e.clientY - dragOffsetY, e.clientX - dragOffsetX);
});
const mouseUpListener = dom.addDisposableGenericMouseUpListener(activeWindow, (e) => {
if (isMovingQuickInput) {
// Save position
const state = this.dndViewState.get();
this.dndViewState.set({ top: state?.top, left: state?.left, done: true }, undefined);
}
// Dispose listeners
mouseMoveListener.dispose();
mouseUpListener.dispose();
});
}));
}
_layout(topCoordinate, leftCoordinate) {
const snapCoordinateYTop = this._getTopSnapValue();
const snapCoordinateY = this._getCenterYSnapValue();
const snapCoordinateX = this._getCenterXSnapValue();
// Make sure the quick input is not moved outside the container
topCoordinate = Math.max(0, Math.min(topCoordinate, this._container.clientHeight - this._quickInputContainer.clientHeight));
if (topCoordinate < this._layoutService.activeContainerOffset.top) {
if (this._controlsOnLeft) {
leftCoordinate = Math.max(leftCoordinate, 80 / getZoomFactor(dom.getActiveWindow()));
}
else if (this._controlsOnRight) {
leftCoordinate = Math.min(leftCoordinate, this._container.clientWidth - this._quickInputContainer.clientWidth - (140 / getZoomFactor(dom.getActiveWindow())));
}
}
const snappingToTop = Math.abs(topCoordinate - snapCoordinateYTop) < this._snapThreshold;
topCoordinate = snappingToTop ? snapCoordinateYTop : topCoordinate;
const snappingToCenter = Math.abs(topCoordinate - snapCoordinateY) < this._snapThreshold;
topCoordinate = snappingToCenter ? snapCoordinateY : topCoordinate;
const top = topCoordinate / this._container.clientHeight;
// Make sure the quick input is not moved outside the container
leftCoordinate = Math.max(0, Math.min(leftCoordinate, this._container.clientWidth - this._quickInputContainer.clientWidth));
const snappingToCenterX = Math.abs(leftCoordinate - snapCoordinateX) < this._snapThreshold;
leftCoordinate = snappingToCenterX ? snapCoordinateX : leftCoordinate;
const b = this._container.clientWidth;
const c = this._quickInputContainer.clientWidth;
const d = leftCoordinate;
const left = (d + c / 2) / b;
this.dndViewState.set({ top, left, done: false }, undefined);
if (snappingToCenterX) {
if (snappingToTop) {
this._quickInputAlignmentContext.set('top');
return;
}
else if (snappingToCenter) {
this._quickInputAlignmentContext.set('center');
return;
}
}
this._quickInputAlignmentContext.set(undefined);
}
_getTopSnapValue() {
return this._layoutService.activeContainerOffset.quickPickTop;
}
_getCenterYSnapValue() {
return Math.round(this._container.clientHeight * this._snapLineHorizontalRatio);
}
_getCenterXSnapValue() {
return Math.round(this._container.clientWidth / 2) - Math.round(this._quickInputContainer.clientWidth / 2);
}
};
QuickInputDragAndDropController = __decorate([
__param(4, ILayoutService),
__param(5, IContextKeyService),
__param(6, IConfigurationService)
], QuickInputDragAndDropController);
//# sourceMappingURL=quickInputController.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,186 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
import { CancellationToken } from '../../../base/common/cancellation.js';
import { Emitter } from '../../../base/common/event.js';
import { IContextKeyService, RawContextKey } from '../../contextkey/common/contextkey.js';
import { IInstantiationService } from '../../instantiation/common/instantiation.js';
import { ILayoutService } from '../../layout/browser/layoutService.js';
import { IOpenerService } from '../../opener/common/opener.js';
import { QuickAccessController } from './quickAccess.js';
import { defaultButtonStyles, defaultCountBadgeStyles, defaultInputBoxStyles, defaultKeybindingLabelStyles, defaultProgressBarStyles, defaultToggleStyles, getListStyles } from '../../theme/browser/defaultStyles.js';
import { activeContrastBorder, asCssVariable, pickerGroupBorder, pickerGroupForeground, quickInputBackground, quickInputForeground, quickInputListFocusBackground, quickInputListFocusForeground, quickInputListFocusIconForeground, quickInputTitleBackground, widgetBorder, widgetShadow } from '../../theme/common/colorRegistry.js';
import { IThemeService, Themable } from '../../theme/common/themeService.js';
import { QuickInputHoverDelegate } from './quickInput.js';
import { QuickInputController } from './quickInputController.js';
import { IConfigurationService } from '../../configuration/common/configuration.js';
import { getWindow } from '../../../base/browser/dom.js';
let QuickInputService = class QuickInputService extends Themable {
get controller() {
if (!this._controller) {
this._controller = this._register(this.createController());
}
return this._controller;
}
get hasController() { return !!this._controller; }
get currentQuickInput() { return this.controller.currentQuickInput; }
get quickAccess() {
if (!this._quickAccess) {
this._quickAccess = this._register(this.instantiationService.createInstance(QuickAccessController));
}
return this._quickAccess;
}
constructor(instantiationService, contextKeyService, themeService, layoutService, configurationService) {
super(themeService);
this.instantiationService = instantiationService;
this.contextKeyService = contextKeyService;
this.layoutService = layoutService;
this.configurationService = configurationService;
this._onShow = this._register(new Emitter());
this._onHide = this._register(new Emitter());
this.contexts = new Map();
}
createController(host = this.layoutService, options) {
const defaultOptions = {
idPrefix: 'quickInput_',
container: host.activeContainer,
ignoreFocusOut: () => false,
backKeybindingLabel: () => undefined,
setContextKey: (id) => this.setContextKey(id),
linkOpenerDelegate: (content) => {
// HACK: https://github.com/microsoft/vscode/issues/173691
this.instantiationService.invokeFunction(accessor => {
const openerService = accessor.get(IOpenerService);
openerService.open(content, { allowCommands: true, fromUserGesture: true });
});
},
returnFocus: () => host.focus(),
styles: this.computeStyles(),
hoverDelegate: this._register(this.instantiationService.createInstance(QuickInputHoverDelegate))
};
const controller = this._register(this.instantiationService.createInstance(QuickInputController, {
...defaultOptions,
...options
}));
controller.layout(host.activeContainerDimension, host.activeContainerOffset.quickPickTop);
// Layout changes
this._register(host.onDidLayoutActiveContainer(dimension => {
if (getWindow(host.activeContainer) === getWindow(controller.container)) {
controller.layout(dimension, host.activeContainerOffset.quickPickTop);
}
}));
this._register(host.onDidChangeActiveContainer(() => {
if (controller.isVisible()) {
return;
}
controller.layout(host.activeContainerDimension, host.activeContainerOffset.quickPickTop);
}));
// Context keys
this._register(controller.onShow(() => {
this.resetContextKeys();
this._onShow.fire();
}));
this._register(controller.onHide(() => {
this.resetContextKeys();
this._onHide.fire();
}));
return controller;
}
setContextKey(id) {
let key;
if (id) {
key = this.contexts.get(id);
if (!key) {
key = new RawContextKey(id, false)
.bindTo(this.contextKeyService);
this.contexts.set(id, key);
}
}
if (key && key.get()) {
return; // already active context
}
this.resetContextKeys();
key?.set(true);
}
resetContextKeys() {
this.contexts.forEach(context => {
if (context.get()) {
context.reset();
}
});
}
pick(picks, options, token = CancellationToken.None) {
return this.controller.pick(picks, options, token);
}
input(options = {}, token = CancellationToken.None) {
return this.controller.input(options, token);
}
createQuickPick(options = { useSeparators: false }) {
return this.controller.createQuickPick(options);
}
createInputBox() {
return this.controller.createInputBox();
}
toggleHover() {
if (this.hasController) {
this.controller.toggleHover();
}
}
updateStyles() {
if (this.hasController) {
this.controller.applyStyles(this.computeStyles());
}
}
computeStyles() {
return {
widget: {
quickInputBackground: asCssVariable(quickInputBackground),
quickInputForeground: asCssVariable(quickInputForeground),
quickInputTitleBackground: asCssVariable(quickInputTitleBackground),
widgetBorder: asCssVariable(widgetBorder),
widgetShadow: asCssVariable(widgetShadow),
},
inputBox: defaultInputBoxStyles,
toggle: defaultToggleStyles,
countBadge: defaultCountBadgeStyles,
button: defaultButtonStyles,
progressBar: defaultProgressBarStyles,
keybindingLabel: defaultKeybindingLabelStyles,
list: getListStyles({
listBackground: quickInputBackground,
listFocusBackground: quickInputListFocusBackground,
listFocusForeground: quickInputListFocusForeground,
// Look like focused when inactive.
listInactiveFocusForeground: quickInputListFocusForeground,
listInactiveSelectionIconForeground: quickInputListFocusIconForeground,
listInactiveFocusBackground: quickInputListFocusBackground,
listFocusOutline: activeContrastBorder,
listInactiveFocusOutline: activeContrastBorder,
treeStickyScrollBackground: quickInputBackground,
}),
pickerGroup: {
pickerGroupBorder: asCssVariable(pickerGroupBorder),
pickerGroupForeground: asCssVariable(pickerGroupForeground),
}
};
}
};
QuickInputService = __decorate([
__param(0, IInstantiationService),
__param(1, IContextKeyService),
__param(2, IThemeService),
__param(3, ILayoutService),
__param(4, IConfigurationService)
], QuickInputService);
export { QuickInputService };
//# sourceMappingURL=quickInputService.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,87 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as dom from '../../../base/browser/dom.js';
import * as domStylesheetsJs from '../../../base/browser/domStylesheets.js';
import * as cssJs from '../../../base/browser/cssValue.js';
import { DomEmitter } from '../../../base/browser/event.js';
import { Event } from '../../../base/common/event.js';
import { StandardKeyboardEvent } from '../../../base/browser/keyboardEvent.js';
import { Gesture, EventType as GestureEventType } from '../../../base/browser/touch.js';
import { renderLabelWithIcons } from '../../../base/browser/ui/iconLabel/iconLabels.js';
import { IdGenerator } from '../../../base/common/idGenerator.js';
import { parseLinkedText } from '../../../base/common/linkedText.js';
import './media/quickInput.css';
import { localize } from '../../../nls.js';
const iconPathToClass = {};
const iconClassGenerator = new IdGenerator('quick-input-button-icon-');
function getIconClass(iconPath) {
if (!iconPath) {
return undefined;
}
let iconClass;
const key = iconPath.dark.toString();
if (iconPathToClass[key]) {
iconClass = iconPathToClass[key];
}
else {
iconClass = iconClassGenerator.nextId();
domStylesheetsJs.createCSSRule(`.${iconClass}, .hc-light .${iconClass}`, `background-image: ${cssJs.asCSSUrl(iconPath.light || iconPath.dark)}`);
domStylesheetsJs.createCSSRule(`.vs-dark .${iconClass}, .hc-black .${iconClass}`, `background-image: ${cssJs.asCSSUrl(iconPath.dark)}`);
iconPathToClass[key] = iconClass;
}
return iconClass;
}
export function quickInputButtonToAction(button, id, run) {
let cssClasses = button.iconClass || getIconClass(button.iconPath);
if (button.alwaysVisible) {
cssClasses = cssClasses ? `${cssClasses} always-visible` : 'always-visible';
}
return {
id,
label: '',
tooltip: button.tooltip || '',
class: cssClasses,
enabled: true,
run
};
}
export function renderQuickInputDescription(description, container, actionHandler) {
dom.reset(container);
const parsed = parseLinkedText(description);
let tabIndex = 0;
for (const node of parsed.nodes) {
if (typeof node === 'string') {
container.append(...renderLabelWithIcons(node));
}
else {
let title = node.title;
if (!title && node.href.startsWith('command:')) {
title = localize(1754, "Click to execute command '{0}'", node.href.substring('command:'.length));
}
else if (!title) {
title = node.href;
}
const anchor = dom.$('a', { href: node.href, title, tabIndex: tabIndex++ }, node.label);
anchor.style.textDecoration = 'underline';
const handleOpen = (e) => {
if (dom.isEventLike(e)) {
dom.EventHelper.stop(e, true);
}
actionHandler.callback(node.href);
};
const onClick = actionHandler.disposables.add(new DomEmitter(anchor, dom.EventType.CLICK)).event;
const onKeydown = actionHandler.disposables.add(new DomEmitter(anchor, dom.EventType.KEY_DOWN)).event;
const onSpaceOrEnter = Event.chain(onKeydown, $ => $.filter(e => {
const event = new StandardKeyboardEvent(e);
return event.equals(10 /* KeyCode.Space */) || event.equals(3 /* KeyCode.Enter */);
}));
actionHandler.disposables.add(Gesture.addTarget(anchor));
const onTap = actionHandler.disposables.add(new DomEmitter(anchor, GestureEventType.Tap)).event;
Event.any(onClick, onTap, onSpaceOrEnter)(handleOpen, null, actionHandler.disposables);
container.appendChild(anchor);
}
}
}
//# sourceMappingURL=quickInputUtils.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,17 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { QuickInputTreeRenderer } from './quickInputTreeRenderer.js';
/**
* Delegate for QuickInputTree that provides height and template information.
*/
export class QuickInputTreeDelegate {
getHeight(_element) {
return 22;
}
getTemplateId(_element) {
return QuickInputTreeRenderer.ID;
}
}
//# sourceMappingURL=quickInputDelegate.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/platform/quickinput/browser/tree/quickInputDelegate.ts","vs/platform/quickinput/browser/tree/quickInputDelegate.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAIhG,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAErE;;GAEG;AACH,MAAM,OAAO,sBAAsB;IAClC,SAAS,CAAC,QAAW;QACpB,OAAO,EAAE,CAAC;IACX,CAAC;IAED,aAAa,CAAC,QAAW;QACxB,OAAO,sBAAsB,CAAC,EAAE,CAAC;IAClC,CAAC;CACD","file":"quickInputDelegate.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IListVirtualDelegate } from '../../../../base/browser/ui/list/list.js';\nimport { IQuickTreeItem } from '../../common/quickInput.js';\nimport { QuickInputTreeRenderer } from './quickInputTreeRenderer.js';\n\n/**\n * Delegate for QuickInputTree that provides height and template information.\n */\nexport class QuickInputTreeDelegate<T extends IQuickTreeItem> implements IListVirtualDelegate<T> {\n\tgetHeight(_element: T): number {\n\t\treturn 22;\n\t}\n\n\tgetTemplateId(_element: T): string {\n\t\treturn QuickInputTreeRenderer.ID;\n\t}\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IListVirtualDelegate } from '../../../../base/browser/ui/list/list.js';\nimport { IQuickTreeItem } from '../../common/quickInput.js';\nimport { QuickInputTreeRenderer } from './quickInputTreeRenderer.js';\n\n/**\n * Delegate for QuickInputTree that provides height and template information.\n */\nexport class QuickInputTreeDelegate<T extends IQuickTreeItem> implements IListVirtualDelegate<T> {\n\tgetHeight(_element: T): number {\n\t\treturn 22;\n\t}\n\n\tgetTemplateId(_element: T): string {\n\t\treturn QuickInputTreeRenderer.ID;\n\t}\n}\n"]}

View File

@@ -0,0 +1,36 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export function getParentNodeState(parentChildren) {
let containsChecks = false;
let containsUnchecks = false;
let containsPartial = false;
for (const element of parentChildren) {
switch (element.element?.checked) {
case 'partial':
containsPartial = true;
break;
case true:
containsChecks = true;
break;
default:
containsUnchecks = true;
break;
}
if (containsChecks && containsUnchecks && containsPartial) {
break;
}
}
const newState = containsUnchecks
? containsPartial
? 'partial'
: containsChecks
? 'partial'
: false
: containsPartial
? 'partial'
: containsChecks;
return newState;
}
//# sourceMappingURL=quickInputTree.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/platform/quickinput/browser/tree/quickInputTree.ts","vs/platform/quickinput/browser/tree/quickInputTree.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAWhG,MAAM,UAAU,kBAAkB,CAAC,cAA+G;IACjJ,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,IAAI,gBAAgB,GAAG,KAAK,CAAC;IAC7B,IAAI,eAAe,GAAG,KAAK,CAAC;IAE5B,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE,CAAC;QACtC,QAAQ,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;YAClC,KAAK,SAAS;gBACb,eAAe,GAAG,IAAI,CAAC;gBACvB,MAAM;YACP,KAAK,IAAI;gBACR,cAAc,GAAG,IAAI,CAAC;gBACtB,MAAM;YACP;gBACC,gBAAgB,GAAG,IAAI,CAAC;gBACxB,MAAM;QACR,CAAC;QACD,IAAI,cAAc,IAAI,gBAAgB,IAAI,eAAe,EAAE,CAAC;YAC3D,MAAM;QACP,CAAC;IACF,CAAC;IACD,MAAM,QAAQ,GAAG,gBAAgB;QAChC,CAAC,CAAC,eAAe;YAChB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,cAAc;gBACf,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,KAAK;QACT,CAAC,CAAC,eAAe;YAChB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,cAAc,CAAC;IACnB,OAAO,QAAQ,CAAC;AACjB,CAAC","file":"quickInputTree.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IMatch } from '../../../../base/common/filters.js';\nimport { IQuickTreeItem } from '../../common/quickInput.js';\nimport { IObjectTreeElement, ITreeNode } from '../../../../base/browser/ui/tree/tree.js';\n\nexport interface IQuickTreeFilterData {\n\treadonly labelHighlights?: IMatch[];\n\treadonly descriptionHighlights?: IMatch[];\n}\n\nexport function getParentNodeState(parentChildren: ITreeNode<IQuickTreeItem | null, IQuickTreeFilterData>[] | IObjectTreeElement<IQuickTreeItem>[]): boolean | 'partial' {\n\tlet containsChecks = false;\n\tlet containsUnchecks = false;\n\tlet containsPartial = false;\n\n\tfor (const element of parentChildren) {\n\t\tswitch (element.element?.checked) {\n\t\t\tcase 'partial':\n\t\t\t\tcontainsPartial = true;\n\t\t\t\tbreak;\n\t\t\tcase true:\n\t\t\t\tcontainsChecks = true;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tcontainsUnchecks = true;\n\t\t\t\tbreak;\n\t\t}\n\t\tif (containsChecks && containsUnchecks && containsPartial) {\n\t\t\tbreak;\n\t\t}\n\t}\n\tconst newState = containsUnchecks\n\t\t? containsPartial\n\t\t\t? 'partial'\n\t\t\t: containsChecks\n\t\t\t\t? 'partial'\n\t\t\t\t: false\n\t\t: containsPartial\n\t\t\t? 'partial'\n\t\t\t: containsChecks;\n\treturn newState;\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IMatch } from '../../../../base/common/filters.js';\nimport { IQuickTreeItem } from '../../common/quickInput.js';\nimport { IObjectTreeElement, ITreeNode } from '../../../../base/browser/ui/tree/tree.js';\n\nexport interface IQuickTreeFilterData {\n\treadonly labelHighlights?: IMatch[];\n\treadonly descriptionHighlights?: IMatch[];\n}\n\nexport function getParentNodeState(parentChildren: ITreeNode<IQuickTreeItem | null, IQuickTreeFilterData>[] | IObjectTreeElement<IQuickTreeItem>[]): boolean | 'partial' {\n\tlet containsChecks = false;\n\tlet containsUnchecks = false;\n\tlet containsPartial = false;\n\n\tfor (const element of parentChildren) {\n\t\tswitch (element.element?.checked) {\n\t\t\tcase 'partial':\n\t\t\t\tcontainsPartial = true;\n\t\t\t\tbreak;\n\t\t\tcase true:\n\t\t\t\tcontainsChecks = true;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tcontainsUnchecks = true;\n\t\t\t\tbreak;\n\t\t}\n\t\tif (containsChecks && containsUnchecks && containsPartial) {\n\t\t\tbreak;\n\t\t}\n\t}\n\tconst newState = containsUnchecks\n\t\t? containsPartial\n\t\t\t? 'partial'\n\t\t\t: containsChecks\n\t\t\t\t? 'partial'\n\t\t\t\t: false\n\t\t: containsPartial\n\t\t\t? 'partial'\n\t\t\t: containsChecks;\n\treturn newState;\n}\n"]}

View File

@@ -0,0 +1,37 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Event } from '../../../../base/common/event.js';
import { getCodiconAriaLabel } from '../../../../base/common/iconLabels.js';
import { localize } from '../../../../nls.js';
/**
* Accessibility provider for QuickTree.
*/
export class QuickTreeAccessibilityProvider {
constructor(onCheckedEvent) {
this.onCheckedEvent = onCheckedEvent;
}
getWidgetAriaLabel() {
return localize(1755, "Quick Tree");
}
getAriaLabel(element) {
return element.ariaLabel || [element.label, element.description]
.map(s => getCodiconAriaLabel(s))
.filter(s => !!s)
.join(', ');
}
getWidgetRole() {
return 'tree';
}
getRole(_element) {
return 'checkbox';
}
isChecked(element) {
return {
get value() { return element.checked === true; },
onDidChange: e => Event.filter(this.onCheckedEvent, e => e.item === element)(_ => e()),
};
}
}
//# sourceMappingURL=quickInputTreeAccessibilityProvider.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["vs/platform/quickinput/browser/tree/quickInputTreeAccessibilityProvider.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAIhG,OAAO,EAAE,KAAK,EAAyB,MAAM,kCAAkC,CAAC;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C;;GAEG;AACH,MAAM,OAAO,8BAA8B;IAC1C,YAA6B,cAAiD;QAAjD,mBAAc,GAAd,cAAc,CAAmC;IAAI,CAAC;IAEnF,kBAAkB;QACjB,OAAO,QAAQ,CAAC,IAAW,EAAE,YAAY,CAAC,CAAC;IAC5C,CAAC;IAED,YAAY,CAAC,OAAU;QACtB,OAAO,OAAO,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC;aAC9D,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;aAChC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;aAChB,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,CAAC;IAED,aAAa;QACZ,OAAO,MAAM,CAAC;IACf,CAAC;IAED,OAAO,CAAC,QAAW;QAClB,OAAO,UAAU,CAAC;IACnB,CAAC;IAED,SAAS,CAAC,OAAU;QACnB,OAAO;YACN,IAAI,KAAK,KAAK,OAAO,OAAO,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC;YAChD,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;SACtF,CAAC;IACH,CAAC;CACD","file":"quickInputTreeAccessibilityProvider.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { AriaRole } from '../../../../base/browser/ui/aria/aria.js';\nimport { IListAccessibilityProvider } from '../../../../base/browser/ui/list/listWidget.js';\nimport { Event, IValueWithChangeEvent } from '../../../../base/common/event.js';\nimport { getCodiconAriaLabel } from '../../../../base/common/iconLabels.js';\nimport { localize } from '../../../../nls.js';\nimport { IQuickTreeCheckboxEvent, IQuickTreeItem } from '../../common/quickInput.js';\n/**\n * Accessibility provider for QuickTree.\n */\nexport class QuickTreeAccessibilityProvider<T extends IQuickTreeItem> implements IListAccessibilityProvider<T> {\n\tconstructor(private readonly onCheckedEvent: Event<IQuickTreeCheckboxEvent<T>>) { }\n\n\tgetWidgetAriaLabel(): string {\n\t\treturn localize('quickTree', \"Quick Tree\");\n\t}\n\n\tgetAriaLabel(element: T): string {\n\t\treturn element.ariaLabel || [element.label, element.description]\n\t\t\t.map(s => getCodiconAriaLabel(s))\n\t\t\t.filter(s => !!s)\n\t\t\t.join(', ');\n\t}\n\n\tgetWidgetRole(): AriaRole {\n\t\treturn 'tree';\n\t}\n\n\tgetRole(_element: T): AriaRole {\n\t\treturn 'checkbox';\n\t}\n\n\tisChecked(element: T): IValueWithChangeEvent<boolean> | undefined {\n\t\treturn {\n\t\t\tget value() { return element.checked === true; },\n\t\t\tonDidChange: e => Event.filter(this.onCheckedEvent, e => e.item === element)(_ => e()),\n\t\t};\n\t}\n}\n"]}

View File

@@ -0,0 +1,187 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
import * as dom from '../../../../base/browser/dom.js';
import { RenderIndentGuides } from '../../../../base/browser/ui/tree/abstractTree.js';
import { Emitter } from '../../../../base/common/event.js';
import { Disposable } from '../../../../base/common/lifecycle.js';
import { IInstantiationService } from '../../../instantiation/common/instantiation.js';
import { WorkbenchObjectTree } from '../../../list/browser/listService.js';
import { QuickInputTreeDelegate } from './quickInputDelegate.js';
import { getParentNodeState } from './quickInputTree.js';
import { QuickTreeAccessibilityProvider } from './quickInputTreeAccessibilityProvider.js';
import { QuickInputTreeFilter } from './quickInputTreeFilter.js';
import { QuickInputTreeRenderer } from './quickInputTreeRenderer.js';
const $ = dom.$;
let QuickInputTreeController = class QuickInputTreeController extends Disposable {
constructor(container, hoverDelegate, instantiationService) {
super();
this.instantiationService = instantiationService;
this._onDidTriggerButton = this._register(new Emitter());
this._onDidChangeCheckboxState = this._register(new Emitter());
this.onDidChangeCheckboxState = this._onDidChangeCheckboxState.event;
this._onDidCheckedLeafItemsChange = this._register(new Emitter);
this._onLeave = new Emitter();
/**
* Event that is fired when the tree would no longer have focus.
*/
this.onLeave = this._onLeave.event;
this._onDidAccept = this._register(new Emitter());
/**
* Event that is fired when a non-pickable item is clicked, indicating acceptance.
*/
this.onDidAccept = this._onDidAccept.event;
this._container = dom.append(container, $('.quick-input-tree'));
this._renderer = this._register(this.instantiationService.createInstance(QuickInputTreeRenderer, hoverDelegate, this._onDidTriggerButton, this.onDidChangeCheckboxState));
this._filter = this.instantiationService.createInstance(QuickInputTreeFilter);
this._tree = this._register(this.instantiationService.createInstance((WorkbenchObjectTree), 'QuickInputTree', this._container, new QuickInputTreeDelegate(), [this._renderer], {
accessibilityProvider: new QuickTreeAccessibilityProvider(this.onDidChangeCheckboxState),
horizontalScrolling: false,
multipleSelectionSupport: false,
findWidgetEnabled: false,
alwaysConsumeMouseWheel: true,
hideTwistiesOfChildlessElements: true,
renderIndentGuides: RenderIndentGuides.None,
expandOnDoubleClick: true,
expandOnlyOnTwistieClick: true,
disableExpandOnSpacebar: true,
sorter: {
compare: (a, b) => {
if (a.label < b.label) {
return -1;
}
else if (a.label > b.label) {
return 1;
}
// use description to break ties
if (a.description && b.description) {
if (a.description < b.description) {
return -1;
}
else if (a.description > b.description) {
return 1;
}
}
else if (a.description) {
return -1;
}
else if (b.description) {
return 1;
}
return 0;
}
},
filter: this._filter
}));
this.registerOnOpenListener();
}
get tree() {
return this._tree;
}
get displayed() {
return this._container.style.display !== 'none';
}
set displayed(value) {
this._container.style.display = value ? '' : 'none';
}
getActiveDescendant() {
return this._tree.getHTMLElement().getAttribute('aria-activedescendant');
}
layout(maxHeight) {
this._tree.getHTMLElement().style.maxHeight = maxHeight ? `${
// Make sure height aligns with list item heights
Math.floor(maxHeight / 44) * 44
// Add some extra height so that it's clear there's more to scroll
+ 6}px` : '';
this._tree.layout();
}
registerOnOpenListener() {
this._register(this._tree.onDidOpen(e => {
const item = e.element;
if (!item) {
return;
}
if (item.disabled) {
return;
}
// Check if the item is pickable (defaults to true if not specified)
if (item.pickable === false) {
// For non-pickable items, set it as the active item and fire the accept event
this._tree.setFocus([item]);
this._onDidAccept.fire();
return;
}
const newState = item.checked !== true;
if ((item.checked ?? false) === newState) {
return; // No change
}
// Handle checked item
item.checked = newState;
this._tree.rerender(item);
// Handle children of the checked item
const updateSet = new Set();
const toUpdate = [...this._tree.getNode(item).children];
while (toUpdate.length) {
const pop = toUpdate.shift();
if (pop?.element && !updateSet.has(pop.element)) {
updateSet.add(pop.element);
if ((pop.element.checked ?? false) !== item.checked) {
pop.element.checked = item.checked;
this._tree.rerender(pop.element);
}
toUpdate.push(...pop.children);
}
}
// Handle parents of the checked item
let parent = this._tree.getParentElement(item);
while (parent) {
const parentChildren = [...this._tree.getNode(parent).children];
const newState = getParentNodeState(parentChildren);
if ((parent.checked ?? false) !== newState) {
parent.checked = newState;
this._tree.rerender(parent);
}
parent = this._tree.getParentElement(parent);
}
this._onDidChangeCheckboxState.fire({
item,
checked: item.checked ?? false
});
this._onDidCheckedLeafItemsChange.fire(this.getCheckedLeafItems());
}));
}
getCheckedLeafItems() {
const lookedAt = new Set();
const toLookAt = [...this._tree.getNode().children];
const checkedItems = new Array();
while (toLookAt.length) {
const lookAt = toLookAt.shift();
if (!lookAt?.element || lookedAt.has(lookAt.element)) {
continue;
}
if (lookAt.element.checked) {
lookedAt.add(lookAt.element);
toLookAt.push(...lookAt.children);
if (!lookAt.element.children) {
checkedItems.push(lookAt.element);
}
}
}
return checkedItems;
}
};
QuickInputTreeController = __decorate([
__param(2, IInstantiationService)
], QuickInputTreeController);
export { QuickInputTreeController };
//# sourceMappingURL=quickInputTreeController.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,40 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { matchesFuzzyIconAware, parseLabelWithIcons } from '../../../../base/common/iconLabels.js';
export class QuickInputTreeFilter {
constructor() {
this.filterValue = '';
this.matchOnLabel = true;
this.matchOnDescription = false;
}
filter(element, parentVisibility) {
if (!this.filterValue || !(this.matchOnLabel || this.matchOnDescription)) {
return element.children
? { visibility: 2 /* TreeVisibility.Recurse */, data: {} }
: { visibility: 1 /* TreeVisibility.Visible */, data: {} };
}
const labelHighlights = this.matchOnLabel ? matchesFuzzyIconAware(this.filterValue, parseLabelWithIcons(element.label)) ?? undefined : undefined;
const descriptionHighlights = this.matchOnDescription ? matchesFuzzyIconAware(this.filterValue, parseLabelWithIcons(element.description || '')) ?? undefined : undefined;
const visibility = parentVisibility === 1 /* TreeVisibility.Visible */
// Parent is visible because it had matches, so we show all children
? 1 /* TreeVisibility.Visible */
// This would only happen on Parent is recurse so...
: (labelHighlights || descriptionHighlights)
// If we have any highlights, we are visible
? 1 /* TreeVisibility.Visible */
// Otherwise, we defer to the children or if no children, we are hidden
: element.children
? 2 /* TreeVisibility.Recurse */
: 0 /* TreeVisibility.Hidden */;
return {
visibility,
data: {
labelHighlights,
descriptionHighlights
}
};
}
}
//# sourceMappingURL=quickInputTreeFilter.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,140 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var QuickInputTreeRenderer_1;
import * as cssJs from '../../../../base/browser/cssValue.js';
import * as dom from '../../../../base/browser/dom.js';
import { ActionBar } from '../../../../base/browser/ui/actionbar/actionbar.js';
import { IconLabel } from '../../../../base/browser/ui/iconLabel/iconLabel.js';
import { TriStateCheckbox } from '../../../../base/browser/ui/toggle/toggle.js';
import { Event } from '../../../../base/common/event.js';
import { Disposable, DisposableStore } from '../../../../base/common/lifecycle.js';
import { URI } from '../../../../base/common/uri.js';
import { defaultCheckboxStyles } from '../../../theme/browser/defaultStyles.js';
import { isDark } from '../../../theme/common/theme.js';
import { escape } from '../../../../base/common/strings.js';
import { IThemeService } from '../../../theme/common/themeService.js';
import { quickInputButtonToAction } from '../quickInputUtils.js';
const $ = dom.$;
let QuickInputTreeRenderer = class QuickInputTreeRenderer extends Disposable {
static { QuickInputTreeRenderer_1 = this; }
static { this.ID = 'quickInputTreeElement'; }
constructor(_hoverDelegate, _buttonTriggeredEmitter, onCheckedEvent, _themeService) {
super();
this._hoverDelegate = _hoverDelegate;
this._buttonTriggeredEmitter = _buttonTriggeredEmitter;
this.onCheckedEvent = onCheckedEvent;
this._themeService = _themeService;
this.templateId = QuickInputTreeRenderer_1.ID;
}
renderTemplate(container) {
const store = new DisposableStore();
// Main entry container
const entry = dom.append(container, $('.quick-input-tree-entry'));
const checkbox = store.add(new TriStateCheckbox('', false, { ...defaultCheckboxStyles, size: 15 }));
entry.appendChild(checkbox.domNode);
const checkboxLabel = dom.append(entry, $('label.quick-input-tree-label'));
const rows = dom.append(checkboxLabel, $('.quick-input-tree-rows'));
const row1 = dom.append(rows, $('.quick-input-tree-row'));
const icon = dom.prepend(row1, $('.quick-input-tree-icon'));
const label = store.add(new IconLabel(row1, {
supportHighlights: true,
supportDescriptionHighlights: true,
supportIcons: true,
hoverDelegate: this._hoverDelegate
}));
const actionBar = store.add(new ActionBar(entry, this._hoverDelegate ? { hoverDelegate: this._hoverDelegate } : undefined));
actionBar.domNode.classList.add('quick-input-tree-entry-action-bar');
return {
toDisposeTemplate: store,
entry,
checkbox,
icon,
label,
actionBar,
toDisposeElement: new DisposableStore(),
};
}
renderElement(node, index, templateData, _details) {
const store = templateData.toDisposeElement;
const quickTreeItem = node.element;
// Checkbox
if (quickTreeItem.pickable === false) {
// Hide checkbox for non-pickable items
templateData.checkbox.domNode.style.display = 'none';
}
else {
templateData.checkbox.domNode.style.display = '';
templateData.checkbox.checked = quickTreeItem.checked ?? false;
store.add(Event.filter(this.onCheckedEvent, e => e.item === quickTreeItem)(e => templateData.checkbox.checked = e.checked));
if (quickTreeItem.disabled) {
templateData.checkbox.disable();
}
}
// Icon
if (quickTreeItem.iconPath) {
const icon = isDark(this._themeService.getColorTheme().type) ? quickTreeItem.iconPath.dark : (quickTreeItem.iconPath.light ?? quickTreeItem.iconPath.dark);
const iconUrl = URI.revive(icon);
templateData.icon.className = 'quick-input-tree-icon';
templateData.icon.style.backgroundImage = cssJs.asCSSUrl(iconUrl);
}
else {
templateData.icon.style.backgroundImage = '';
templateData.icon.className = quickTreeItem.iconClass ? `quick-input-tree-icon ${quickTreeItem.iconClass}` : '';
}
const { labelHighlights: matches, descriptionHighlights: descriptionMatches } = node.filterData || {};
// Label and Description
let descriptionTitle;
// NOTE: If we bring back quick tool tips, we need to check that here like we do in the QuickInputListRenderer
if (quickTreeItem.description) {
descriptionTitle = {
markdown: {
value: escape(quickTreeItem.description),
supportThemeIcons: true
},
markdownNotSupportedFallback: quickTreeItem.description
};
}
templateData.label.setLabel(quickTreeItem.label, quickTreeItem.description, {
matches,
descriptionMatches,
extraClasses: quickTreeItem.iconClasses,
italic: quickTreeItem.italic,
strikethrough: quickTreeItem.strikethrough,
labelEscapeNewLines: true,
descriptionTitle
});
// Action Bar
const buttons = quickTreeItem.buttons;
if (buttons && buttons.length) {
templateData.actionBar.push(buttons.map((button, index) => quickInputButtonToAction(button, `tree-${index}`, () => this._buttonTriggeredEmitter.fire({ item: quickTreeItem, button }))), { icon: true, label: false });
templateData.entry.classList.add('has-actions');
}
else {
templateData.entry.classList.remove('has-actions');
}
}
disposeElement(_element, _index, templateData, _details) {
templateData.toDisposeElement.clear();
templateData.actionBar.clear();
}
disposeTemplate(templateData) {
templateData.toDisposeElement.dispose();
templateData.toDisposeTemplate.dispose();
}
};
QuickInputTreeRenderer = QuickInputTreeRenderer_1 = __decorate([
__param(3, IThemeService)
], QuickInputTreeRenderer);
export { QuickInputTreeRenderer };
//# sourceMappingURL=quickInputTreeRenderer.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,54 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { coalesce } from '../../../base/common/arrays.js';
import { toDisposable } from '../../../base/common/lifecycle.js';
import { Registry } from '../../registry/common/platform.js';
export var DefaultQuickAccessFilterValue;
(function (DefaultQuickAccessFilterValue) {
/**
* Keep the value as it is given to quick access.
*/
DefaultQuickAccessFilterValue[DefaultQuickAccessFilterValue["PRESERVE"] = 0] = "PRESERVE";
/**
* Use the value that was used last time something was accepted from the picker.
*/
DefaultQuickAccessFilterValue[DefaultQuickAccessFilterValue["LAST"] = 1] = "LAST";
})(DefaultQuickAccessFilterValue || (DefaultQuickAccessFilterValue = {}));
export const Extensions = {
Quickaccess: 'workbench.contributions.quickaccess'
};
export class QuickAccessRegistry {
constructor() {
this.providers = [];
this.defaultProvider = undefined;
}
registerQuickAccessProvider(provider) {
// Extract the default provider when no prefix is present
if (provider.prefix.length === 0) {
this.defaultProvider = provider;
}
else {
this.providers.push(provider);
}
// sort the providers by decreasing prefix length, such that longer
// prefixes take priority: 'ext' vs 'ext install' - the latter should win
this.providers.sort((providerA, providerB) => providerB.prefix.length - providerA.prefix.length);
return toDisposable(() => {
this.providers.splice(this.providers.indexOf(provider), 1);
if (this.defaultProvider === provider) {
this.defaultProvider = undefined;
}
});
}
getQuickAccessProviders() {
return coalesce([this.defaultProvider, ...this.providers]);
}
getQuickAccessProvider(prefix) {
const result = prefix ? (this.providers.find(provider => prefix.startsWith(provider.prefix)) || undefined) : undefined;
return result || this.defaultProvider;
}
}
Registry.add(Extensions.Quickaccess, new QuickAccessRegistry());
//# sourceMappingURL=quickAccess.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,107 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { createDecorator } from '../../instantiation/common/instantiation.js';
export const NO_KEY_MODS = { ctrlCmd: false, alt: false };
export var QuickInputHideReason;
(function (QuickInputHideReason) {
/**
* Focus moved away from the quick input.
*/
QuickInputHideReason[QuickInputHideReason["Blur"] = 1] = "Blur";
/**
* An explicit user gesture, e.g. pressing Escape key.
*/
QuickInputHideReason[QuickInputHideReason["Gesture"] = 2] = "Gesture";
/**
* Anything else.
*/
QuickInputHideReason[QuickInputHideReason["Other"] = 3] = "Other";
})(QuickInputHideReason || (QuickInputHideReason = {}));
/**
* Represents the activation behavior for items in a quick input. This means which item will be
* "active" (aka focused).
*/
export var ItemActivation;
(function (ItemActivation) {
/**
* No item will be active.
*/
ItemActivation[ItemActivation["NONE"] = 0] = "NONE";
/**
* First item will be active.
*/
ItemActivation[ItemActivation["FIRST"] = 1] = "FIRST";
/**
* Second item will be active.
*/
ItemActivation[ItemActivation["SECOND"] = 2] = "SECOND";
/**
* Last item will be active.
*/
ItemActivation[ItemActivation["LAST"] = 3] = "LAST";
})(ItemActivation || (ItemActivation = {}));
/**
* Represents the focus options for a quick pick.
*/
export var QuickPickFocus;
(function (QuickPickFocus) {
/**
* Focus the first item in the list.
*/
QuickPickFocus[QuickPickFocus["First"] = 1] = "First";
/**
* Focus the second item in the list.
*/
QuickPickFocus[QuickPickFocus["Second"] = 2] = "Second";
/**
* Focus the last item in the list.
*/
QuickPickFocus[QuickPickFocus["Last"] = 3] = "Last";
/**
* Focus the next item in the list.
*/
QuickPickFocus[QuickPickFocus["Next"] = 4] = "Next";
/**
* Focus the previous item in the list.
*/
QuickPickFocus[QuickPickFocus["Previous"] = 5] = "Previous";
/**
* Focus the next page in the list.
*/
QuickPickFocus[QuickPickFocus["NextPage"] = 6] = "NextPage";
/**
* Focus the previous page in the list.
*/
QuickPickFocus[QuickPickFocus["PreviousPage"] = 7] = "PreviousPage";
/**
* Focus the first item under the next separator.
*/
QuickPickFocus[QuickPickFocus["NextSeparator"] = 8] = "NextSeparator";
/**
* Focus the first item under the current separator.
*/
QuickPickFocus[QuickPickFocus["PreviousSeparator"] = 9] = "PreviousSeparator";
})(QuickPickFocus || (QuickPickFocus = {}));
export var QuickInputButtonLocation;
(function (QuickInputButtonLocation) {
/**
* In the title bar.
*/
QuickInputButtonLocation[QuickInputButtonLocation["Title"] = 1] = "Title";
/**
* To the right of the input box.
*/
QuickInputButtonLocation[QuickInputButtonLocation["Inline"] = 2] = "Inline";
})(QuickInputButtonLocation || (QuickInputButtonLocation = {}));
export class QuickPickItemScorerAccessor {
constructor(options) {
this.options = options;
}
}
export const quickPickItemScorerAccessor = new QuickPickItemScorerAccessor();
//#endregion
export const IQuickInputService = createDecorator('quickInputService');
//#endregion
//# sourceMappingURL=quickInput.js.map

File diff suppressed because one or more lines are too long