123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- /*---------------------------------------------------------------------------------------------
- * 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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
- };
- import { toErrorMessage } from '../../../base/common/errorMessage.js';
- import { isPromiseCanceledError } from '../../../base/common/errors.js';
- import { matchesContiguousSubString, matchesPrefix, matchesWords, or } from '../../../base/common/filters.js';
- import { Disposable } from '../../../base/common/lifecycle.js';
- import { LRUCache } from '../../../base/common/map.js';
- import Severity from '../../../base/common/severity.js';
- import { withNullAsUndefined } from '../../../base/common/types.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 { PickerQuickAccessProvider } from './pickerQuickAccess.js';
- import { IStorageService } from '../../storage/common/storage.js';
- import { ITelemetryService } from '../../telemetry/common/telemetry.js';
- let AbstractCommandsQuickAccessProvider = class AbstractCommandsQuickAccessProvider extends PickerQuickAccessProvider {
- constructor(options, instantiationService, keybindingService, commandService, telemetryService, dialogService) {
- super(AbstractCommandsQuickAccessProvider.PREFIX, options);
- this.instantiationService = instantiationService;
- this.keybindingService = keybindingService;
- this.commandService = commandService;
- this.telemetryService = telemetryService;
- this.dialogService = dialogService;
- this.commandsHistory = this._register(this.instantiationService.createInstance(CommandsHistory));
- this.options = options;
- }
- _getPicks(filter, disposables, token) {
- return __awaiter(this, void 0, void 0, function* () {
- // Ask subclass for all command picks
- const allCommandPicks = yield this.getCommandPicks(disposables, token);
- if (token.isCancellationRequested) {
- return [];
- }
- // Filter
- const filteredCommandPicks = [];
- for (const commandPick of allCommandPicks) {
- const labelHighlights = withNullAsUndefined(AbstractCommandsQuickAccessProvider.WORD_FILTER(filter, commandPick.label));
- const aliasHighlights = commandPick.commandAlias ? withNullAsUndefined(AbstractCommandsQuickAccessProvider.WORD_FILTER(filter, commandPick.commandAlias)) : 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);
- }
- }
- // 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) => {
- 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
- }
- // both commands were never used, so we sort by name
- return commandPickA.label.localeCompare(commandPickB.label);
- });
- const commandPicks = [];
- let addSeparator = false;
- for (let i = 0; i < filteredCommandPicks.length; i++) {
- const commandPick = filteredCommandPicks[i];
- const keybinding = this.keybindingService.lookupKeybinding(commandPick.commandId);
- const ariaLabel = keybinding ?
- localize('commandPickAriaLabelWithKeybinding', "{0}, {1}", commandPick.label, keybinding.getAriaLabel()) :
- commandPick.label;
- // Separator: recently used
- if (i === 0 && this.commandsHistory.peek(commandPick.commandId)) {
- commandPicks.push({ type: 'separator', label: localize('recentlyUsed', "recently used") });
- addSeparator = true;
- }
- // Separator: other commands
- if (i !== 0 && addSeparator && !this.commandsHistory.peek(commandPick.commandId)) {
- commandPicks.push({ type: 'separator', label: localize('morecCommands', "other commands") });
- addSeparator = false; // only once
- }
- // Command
- commandPicks.push(Object.assign(Object.assign({}, commandPick), { ariaLabel, detail: this.options.showAlias && commandPick.commandAlias !== commandPick.label ? commandPick.commandAlias : undefined, keybinding, accept: () => __awaiter(this, void 0, void 0, function* () {
- // Add to history
- this.commandsHistory.push(commandPick.commandId);
- // Telementry
- this.telemetryService.publicLog2('workbenchActionExecuted', {
- id: commandPick.commandId,
- from: 'quick open'
- });
- // Run
- try {
- yield this.commandService.executeCommand(commandPick.commandId);
- }
- catch (error) {
- if (!isPromiseCanceledError(error)) {
- this.dialogService.show(Severity.Error, localize('canNotRun', "Command '{0}' resulted in an error ({1})", commandPick.label, toErrorMessage(error)));
- }
- }
- }) }));
- }
- return commandPicks;
- });
- }
- };
- AbstractCommandsQuickAccessProvider.PREFIX = '>';
- AbstractCommandsQuickAccessProvider.WORD_FILTER = or(matchesPrefix, matchesWords, matchesContiguousSubString);
- AbstractCommandsQuickAccessProvider = __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 {
- constructor(storageService, configurationService) {
- super();
- this.storageService = storageService;
- this.configurationService = configurationService;
- this.configuredCommandsHistoryLength = 0;
- this.updateConfiguration();
- this.load();
- this.registerListeners();
- }
- registerListeners() {
- this._register(this.configurationService.onDidChangeConfiguration(() => this.updateConfiguration()));
- }
- updateConfiguration() {
- this.configuredCommandsHistoryLength = CommandsHistory.getConfiguredCommandHistoryLength(this.configurationService);
- if (CommandsHistory.cache && CommandsHistory.cache.limit !== this.configuredCommandsHistoryLength) {
- CommandsHistory.cache.limit = this.configuredCommandsHistoryLength;
- CommandsHistory.saveState(this.storageService);
- }
- }
- load() {
- const raw = this.storageService.get(CommandsHistory.PREF_KEY_CACHE, 0 /* GLOBAL */);
- let serializedCache;
- if (raw) {
- try {
- serializedCache = JSON.parse(raw);
- }
- catch (error) {
- // invalid data
- }
- }
- const cache = CommandsHistory.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.counter = this.storageService.getNumber(CommandsHistory.PREF_KEY_COUNTER, 0 /* GLOBAL */, CommandsHistory.counter);
- }
- push(commandId) {
- if (!CommandsHistory.cache) {
- return;
- }
- CommandsHistory.cache.set(commandId, CommandsHistory.counter++); // set counter to command
- CommandsHistory.saveState(this.storageService);
- }
- peek(commandId) {
- var _a;
- return (_a = CommandsHistory.cache) === null || _a === void 0 ? void 0 : _a.peek(commandId);
- }
- static saveState(storageService) {
- if (!CommandsHistory.cache) {
- return;
- }
- const serializedCache = { usesLRU: true, entries: [] };
- CommandsHistory.cache.forEach((value, key) => serializedCache.entries.push({ key, value }));
- storageService.store(CommandsHistory.PREF_KEY_CACHE, JSON.stringify(serializedCache), 0 /* GLOBAL */, 0 /* USER */);
- storageService.store(CommandsHistory.PREF_KEY_COUNTER, CommandsHistory.counter, 0 /* GLOBAL */, 0 /* USER */);
- }
- static getConfiguredCommandHistoryLength(configurationService) {
- var _a, _b;
- const config = configurationService.getValue();
- const configuredCommandHistoryLength = (_b = (_a = config.workbench) === null || _a === void 0 ? void 0 : _a.commandPalette) === null || _b === void 0 ? void 0 : _b.history;
- if (typeof configuredCommandHistoryLength === 'number') {
- return configuredCommandHistoryLength;
- }
- return CommandsHistory.DEFAULT_COMMANDS_HISTORY_LENGTH;
- }
- };
- CommandsHistory.DEFAULT_COMMANDS_HISTORY_LENGTH = 50;
- CommandsHistory.PREF_KEY_CACHE = 'commandPalette.mru.cache';
- CommandsHistory.PREF_KEY_COUNTER = 'commandPalette.mru.counter';
- CommandsHistory.counter = 1;
- CommandsHistory = __decorate([
- __param(0, IStorageService),
- __param(1, IConfigurationService)
- ], CommandsHistory);
- export { CommandsHistory };
|