Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
sandy081 authored Dec 27, 2022
1 parent 7445dc7 commit 68efb6f
Show file tree
Hide file tree
Showing 15 changed files with 217 additions and 65 deletions.
7 changes: 6 additions & 1 deletion src/vs/platform/action/common/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,19 @@ export function isICommandActionToggleInfo(thing: ContextKeyExpression | IComman
return thing ? (<ICommandActionToggleInfo>thing).condition !== undefined : false;
}

export interface ICommandActionSource {
readonly id: string;
readonly title: string;
}

export interface ICommandAction {
id: string;
title: string | ICommandActionTitle;
shortTitle?: string | ICommandActionTitle;
category?: keyof typeof Categories | ILocalizedString | string;
tooltip?: string | ILocalizedString;
icon?: Icon;
source?: string;
source?: ICommandActionSource;
precondition?: ContextKeyExpression;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
continueEditSessionOptions.push(new ContinueEditSessionItem(
ThemeIcon.isThemeIcon(icon) ? `$(${icon.id}) ${title}` : title,
command.id,
command.source,
command.source?.title,
when,
contribution.documentation
));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1399,18 +1399,32 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi
menu: {
id: MenuId.ExtensionContext,
group: '2_configure',
when: ContextKeyExpr.and(ContextKeyExpr.equals('extensionStatus', 'installed'), ContextKeyExpr.has('extensionHasConfiguration'))
when: ContextKeyExpr.and(ContextKeyExpr.equals('extensionStatus', 'installed'), ContextKeyExpr.has('extensionHasConfiguration')),
order: 1
},
run: async (accessor: ServicesAccessor, id: string) => accessor.get(IPreferencesService).openSettings({ jsonEditor: false, query: `@ext:${id}` })
});

this.registerExtensionAction({
id: 'workbench.extensions.action.configureKeybindings',
title: { value: localize('workbench.extensions.action.configureKeybindings', "Extension Keyboard Shortcuts"), original: 'Extension Keyboard Shortcuts' },
menu: {
id: MenuId.ExtensionContext,
group: '2_configure',
when: ContextKeyExpr.and(ContextKeyExpr.equals('extensionStatus', 'installed'), ContextKeyExpr.has('extensionHasKeybindings')),
order: 2
},
run: async (accessor: ServicesAccessor, id: string) => accessor.get(IPreferencesService).openGlobalKeybindingSettings(false, { query: `@ext:${id}` })
});

this.registerExtensionAction({
id: TOGGLE_IGNORE_EXTENSION_ACTION_ID,
title: { value: localize('workbench.extensions.action.toggleIgnoreExtension', "Sync This Extension"), original: `Sync This Extension` },
menu: {
id: MenuId.ExtensionContext,
group: '2_configure',
when: ContextKeyExpr.and(CONTEXT_SYNC_ENABLEMENT, ContextKeyExpr.has('inExtensionEditor').negate())
when: ContextKeyExpr.and(CONTEXT_SYNC_ENABLEMENT, ContextKeyExpr.has('inExtensionEditor').negate()),
order: 3
},
run: async (accessor: ServicesAccessor, id: string) => {
const extension = this.extensionsWorkbenchService.local.find(e => areSameExtensions({ id }, e.identifier));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,8 @@ async function getContextMenuActionsGroups(extension: IExtension | undefined | n
cksOverlay.push(['extension', extension.identifier.id]);
cksOverlay.push(['isBuiltinExtension', extension.isBuiltin]);
cksOverlay.push(['extensionHasConfiguration', extension.local && !!extension.local.manifest.contributes && !!extension.local.manifest.contributes.configuration]);
cksOverlay.push(['extensionHasKeybindings', extension.local && !!extension.local.manifest.contributes && !!extension.local.manifest.contributes.keybindings]);
cksOverlay.push(['extensionHasCommands', extension.local && !!extension.local.manifest.contributes && !!extension.local.manifest.contributes?.commands]);
cksOverlay.push(['isExtensionRecommended', !!extensionRecommendationsService.getAllRecommendationsWithReason()[extension.identifier.id.toLowerCase()]]);
cksOverlay.push(['isExtensionWorkspaceRecommended', extensionRecommendationsService.getAllRecommendationsWithReason()[extension.identifier.id.toLowerCase()]?.reasonId === ExtensionRecommendationReason.Workspace]);
cksOverlay.push(['isUserIgnoredRecommendation', extensionIgnoredRecommendationsService.globalIgnoredRecommendations.some(e => e === extension.identifier.id.toLowerCase())]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1024,7 +1024,14 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
return null;
}

async open(extension: IExtension, options?: IExtensionEditorOptions): Promise<void> {
async open(extension: IExtension | string, options?: IExtensionEditorOptions): Promise<void> {
if (typeof extension === 'string') {
const id = extension;
extension = this.installed.find(e => areSameExtensions(e.identifier, { id })) ?? (await this.getExtensions([{ id: extension }], CancellationToken.None))[0];
}
if (!extension) {
throw new Error(`Extension not found. ${extension}`);
}
const editor = await this.editorService.openEditor(this.instantiationService.createInstance(ExtensionsInput, extension), options, options?.sideByside ? SIDE_GROUP : ACTIVE_GROUP);
if (options?.tab && editor instanceof ExtensionEditor) {
await editor.openTab(options.tab);
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/contrib/extensions/common/extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export interface IExtensionsWorkbenchService {
setEnablement(extensions: IExtension | IExtension[], enablementState: EnablementState): Promise<void>;
setExtensionIgnoresUpdate(extension: IExtension, ignoreAutoUpate: boolean): void;
isExtensionIgnoresUpdates(extension: IExtension): boolean;
open(extension: IExtension, options?: IExtensionEditorOptions): Promise<void>;
open(extension: IExtension | string, options?: IExtensionEditorOptions): Promise<void>;
checkForUpdates(): Promise<void>;
getExtensionStatus(extension: IExtension): IExtensionsStatus | undefined;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,7 @@ export class KernelPickerMRUStrategy extends KernelPickerStrategyBase {
action: sourceAction,
picked: false,
label: sourceAction.action.label,
detail: (sourceAction.action as MenuItemAction)?.item?.source
detail: (sourceAction.action as MenuItemAction)?.item?.source?.title
};

quickPickItems.push(res);
Expand Down
75 changes: 65 additions & 10 deletions src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { localize } from 'vs/nls';
import { Delayer } from 'vs/base/common/async';
import * as DOM from 'vs/base/browser/dom';
import { isIOS, OS } from 'vs/base/common/platform';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
import { ToggleActionViewItem } from 'vs/base/browser/ui/toggle/toggle';
import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
import { KeybindingLabel } from 'vs/base/browser/ui/keybindingLabel/keybindingLabel';
Expand Down Expand Up @@ -49,6 +49,9 @@ import { KeybindingsEditorInput } from 'vs/workbench/services/preferences/browse
import { IEditorOptions } from 'vs/platform/editor/common/editor';
import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
import { defaultInputBoxStyles, defaultKeybindingLabelStyles, defaultToggleStyles } from 'vs/platform/theme/browser/defaultStyles';
import { IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { isString } from 'vs/base/common/types';

const $ = DOM.$;

Expand Down Expand Up @@ -435,14 +438,14 @@ export class KeybindingsEditor extends EditorPane implements IKeybindingsEditorP
{
label: localize('when', "When"),
tooltip: '',
weight: 0.4,
weight: 0.35,
templateId: WhenColumnRenderer.TEMPLATE_ID,
project(row: IKeybindingItemEntry): IKeybindingItemEntry { return row; }
},
{
label: localize('source', "Source"),
tooltip: '',
weight: 0.1,
weight: 0.15,
templateId: SourceColumnRenderer.TEMPLATE_ID,
project(row: IKeybindingItemEntry): IKeybindingItemEntry { return row; }
},
Expand Down Expand Up @@ -777,10 +780,11 @@ class Delegate implements ITableVirtualDelegate<IKeybindingItemEntry> {
if (element.templateId === KEYBINDING_ENTRY_TEMPLATE_ID) {
const commandIdMatched = (<IKeybindingItemEntry>element).keybindingItem.commandLabel && (<IKeybindingItemEntry>element).commandIdMatches;
const commandDefaultLabelMatched = !!(<IKeybindingItemEntry>element).commandDefaultLabelMatches;
const extensionIdMatched = !!(<IKeybindingItemEntry>element).extensionIdMatches;
if (commandIdMatched && commandDefaultLabelMatched) {
return 60;
}
if (commandIdMatched || commandDefaultLabelMatched) {
if (extensionIdMatched || commandIdMatched || commandDefaultLabelMatched) {
return 40;
}
}
Expand Down Expand Up @@ -944,7 +948,26 @@ class KeybindingColumnRenderer implements ITableRenderer<IKeybindingItemEntry, I
}

interface ISourceColumnTemplateData {
highlightedLabel: HighlightedLabel;
sourceColumn: HTMLElement;
sourceLabel: HighlightedLabel;
extensionContainer: HTMLElement;
extensionLabel: HTMLAnchorElement;
extensionId: HighlightedLabel;
disposables: DisposableStore;
}

function onClick(element: HTMLElement, callback: () => void): IDisposable {
const disposables: DisposableStore = new DisposableStore();
disposables.add(DOM.addDisposableListener(element, DOM.EventType.CLICK, DOM.finalHandler(callback)));
disposables.add(DOM.addDisposableListener(element, DOM.EventType.KEY_UP, e => {
const keyboardEvent = new StandardKeyboardEvent(e);
if (keyboardEvent.equals(KeyCode.Space) || keyboardEvent.equals(KeyCode.Enter)) {
e.preventDefault();
e.stopPropagation();
callback();
}
}));
return disposables;
}

class SourceColumnRenderer implements ITableRenderer<IKeybindingItemEntry, ISourceColumnTemplateData> {
Expand All @@ -953,17 +976,49 @@ class SourceColumnRenderer implements ITableRenderer<IKeybindingItemEntry, ISour

readonly templateId: string = SourceColumnRenderer.TEMPLATE_ID;

constructor(
@IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
) { }

renderTemplate(container: HTMLElement): ISourceColumnTemplateData {
const sourceColumn = DOM.append(container, $('.source'));
const highlightedLabel = new HighlightedLabel(sourceColumn);
return { highlightedLabel };
const sourceLabel = new HighlightedLabel(DOM.append(sourceColumn, $('.source-label')));
const extensionContainer = DOM.append(sourceColumn, $('.extension-container'));
const extensionLabel = DOM.append<HTMLAnchorElement>(extensionContainer, $('a.extension-label', { tabindex: 0 }));
const extensionId = new HighlightedLabel(DOM.append(extensionContainer, $('.extension-id-container.code')));
return { sourceColumn, sourceLabel, extensionLabel, extensionContainer, extensionId, disposables: new DisposableStore() };
}

renderElement(keybindingItemEntry: IKeybindingItemEntry, index: number, templateData: ISourceColumnTemplateData, height: number | undefined): void {
templateData.highlightedLabel.set(keybindingItemEntry.keybindingItem.source, keybindingItemEntry.sourceMatches);

if (isString(keybindingItemEntry.keybindingItem.source)) {
templateData.extensionContainer.classList.add('hide');
templateData.sourceLabel.element.classList.remove('hide');
templateData.sourceColumn.title = '';
templateData.sourceLabel.set(keybindingItemEntry.keybindingItem.source || '-', keybindingItemEntry.sourceMatches);
} else {
templateData.extensionContainer.classList.remove('hide');
templateData.sourceLabel.element.classList.add('hide');
const extension = keybindingItemEntry.keybindingItem.source;
const extensionLabel = extension.displayName ?? extension.identifier.value;
templateData.sourceColumn.title = localize('extension label', "Extension ({0})", extensionLabel);
templateData.extensionLabel.textContent = extensionLabel;
templateData.disposables.add(onClick(templateData.extensionLabel, () => {
this.extensionsWorkbenchService.open(extension.identifier.value);
}));
if (keybindingItemEntry.extensionIdMatches) {
templateData.extensionId.element.classList.remove('hide');
templateData.extensionId.set(extension.identifier.value, keybindingItemEntry.extensionIdMatches);
} else {
templateData.extensionId.element.classList.add('hide');
templateData.extensionId.set(undefined);
}
}
}

disposeTemplate(templateData: ISourceColumnTemplateData): void { }
disposeTemplate(templateData: ISourceColumnTemplateData): void {
templateData.disposables.dispose();
}
}

interface IWhenColumnTemplateData {
Expand Down Expand Up @@ -1123,8 +1178,8 @@ class AccessibilityProvider implements IListAccessibilityProvider<IKeybindingIte
getAriaLabel(keybindingItemEntry: IKeybindingItemEntry): string {
let ariaLabel = keybindingItemEntry.keybindingItem.commandLabel ? keybindingItemEntry.keybindingItem.commandLabel : keybindingItemEntry.keybindingItem.command;
ariaLabel += ', ' + (keybindingItemEntry.keybindingItem.keybinding?.getAriaLabel() || localize('noKeybinding', "No Keybinding assigned."));
ariaLabel += ', ' + keybindingItemEntry.keybindingItem.source;
ariaLabel += ', ' + keybindingItemEntry.keybindingItem.when ? keybindingItemEntry.keybindingItem.when : localize('noWhen', "No when context.");
ariaLabel += ', ' + (isString(keybindingItemEntry.keybindingItem.source) ? keybindingItemEntry.keybindingItem.source : keybindingItemEntry.keybindingItem.source.description ?? keybindingItemEntry.keybindingItem.source.identifier.value);
return ariaLabel;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,6 @@

/** Command column styling **/

.keybindings-editor > .keybindings-body > .keybindings-table-container .monaco-table-tr .monaco-table-td .command .hide {
display: none;
}

.keybindings-editor > .keybindings-body > .keybindings-table-container .monaco-table-tr .monaco-table-td .command.vertical-align-column {
flex-direction: column;
align-items: flex-start;
Expand Down Expand Up @@ -164,6 +160,21 @@
height: 24px;
}

/** Source column styling **/
.keybindings-editor>.keybindings-body>.keybindings-table-container .monaco-table-tr .monaco-table-td .source a {
color: var(--vscode-textLink-foreground);
cursor: pointer;
}

.keybindings-editor>.keybindings-body>.keybindings-table-container .monaco-table-tr .monaco-table-td .source a:hover {
text-decoration: underline;
color: var(--vscode-textLink-activeForeground);
}

.keybindings-editor>.keybindings-body>.keybindings-table-container .monaco-table-tr .monaco-table-td .source a:active {
color: var(--vscode-textLink-activeForeground);
}

/** columns styling **/

.keybindings-editor > .keybindings-body > .keybindings-table-container .monaco-table-tr .monaco-table-td .command,
Expand All @@ -177,6 +188,10 @@
text-overflow: ellipsis;
}

.keybindings-editor > .keybindings-body > .keybindings-table-container .monaco-table-tr .monaco-table-td .hide {
display: none;
}

.keybindings-editor > .keybindings-body > .keybindings-table-container .monaco-table-tr .monaco-table-td .code {
font-family: var(--monaco-monospace-font);
font-size: 90%;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -935,7 +935,7 @@ class PreferencesActionsContribution extends Disposable implements IWorkbenchCon
constructor() {
super({
id: KEYBINDINGS_EDITOR_SHOW_DEFAULT_KEYBINDINGS,
title: { value: nls.localize('showDefaultKeybindings', "Show Default Keybindings"), original: 'Show Default Keybindings' },
title: { value: nls.localize('showDefaultKeybindings', "Show System Keybindings"), original: 'Show System Keybindings' },
menu: [
{
id: MenuId.EditorTitle,
Expand All @@ -948,7 +948,7 @@ class PreferencesActionsContribution extends Disposable implements IWorkbenchCon
run(accessor: ServicesAccessor) {
const editorPane = accessor.get(IEditorService).activeEditorPane;
if (editorPane instanceof KeybindingsEditor) {
editorPane.search('@source:default');
editorPane.search('@source:system');
}
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class NewFileTemplatesManager extends Disposable {
for (const [groupName, group] of this.menu.getActions({ renderShortTitle: true })) {
for (const action of group) {
if (action instanceof MenuItemAction) {
items.push({ commandID: action.item.id, from: action.item.source ?? builtInSource, title: action.label, group: groupName });
items.push({ commandID: action.item.id, from: action.item.source?.title ?? builtInSource, title: action.label, group: groupName });
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,7 @@ commandsExtensionPoint.setHandler(extensions => {
_commandRegistrations.add(MenuRegistry.addCommand({
id: command,
title,
source: extension.description.displayName ?? extension.description.name,
source: { id: extension.description.identifier.value, title: extension.description.displayName ?? extension.description.name },
shortTitle,
tooltip: title,
category,
Expand Down
Loading

0 comments on commit 68efb6f

Please sign in to comment.