Skip to content

Commit

Permalink
add configure keybindings quickpick for extension contributed accessi…
Browse files Browse the repository at this point in the history
…bility help dialogs (#212997)
  • Loading branch information
meganrogge authored May 18, 2024
1 parent 5d6671d commit 9f83563
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 16 deletions.
7 changes: 7 additions & 0 deletions src/vs/platform/accessibility/browser/accessibleView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding';
import { IPickerQuickAccessItem } from 'vs/platform/quickinput/browser/pickerQuickAccess';
import { Event } from 'vs/base/common/event';
import { IAction } from 'vs/base/common/actions';
import { IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';

export const IAccessibleViewService = createDecorator<IAccessibleViewService>('accessibleViewService');

Expand Down Expand Up @@ -60,6 +61,11 @@ export interface IAccessibleViewOptions {
* If this provider might want to request to be shown again, provide an ID.
*/
id?: AccessibleViewProviderId;

/**
* Keybinding items to configure
*/
configureKeybindingItems?: IQuickPickItem[];
}


Expand Down Expand Up @@ -113,6 +119,7 @@ export interface IAccessibleViewService {
*/
getOpenAriaHint(verbositySettingKey: string): string | null;
getCodeBlockContext(): ICodeBlockActionContext | undefined;
configureKeybindings(): void;
}


Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/api/browser/viewsExtensionPoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ const viewDescriptor: IJSONSchema = {
},
accessibilityHelpContent: {
type: 'string',
markdownDescription: localize('vscode.extension.contributes.view.accessibilityHelpContent', "When the accessibility help dialog is invoked in this view, this content will be presented to the user as a markdown string. Keybindings will be resolved when provided in the format of <keybinding:commandId>. If there is no keybinding, that will be indicated with a link to configure one.")
markdownDescription: localize('vscode.extension.contributes.view.accessibilityHelpContent', "When the accessibility help dialog is invoked in this view, this content will be presented to the user as a markdown string. Keybindings will be resolved when provided in the format of <keybinding:commandId>. If there is no keybinding, that will be indicated and this command will be included in a quickpick for easy configuration.")
}
}
};
Expand Down
29 changes: 27 additions & 2 deletions src/vs/workbench/contrib/accessibility/browser/accessibleView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { ResultKind } from 'vs/platform/keybinding/common/keybindingResolver';
import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
import { IQuickInputService, IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { AccessibilityVerbositySettingId, AccessibilityWorkbenchSettingId, accessibilityHelpIsShown, accessibleViewContainsCodeBlocks, accessibleViewCurrentProviderId, accessibleViewGoToSymbolSupported, accessibleViewInCodeBlock, accessibleViewIsShown, accessibleViewOnLastLine, accessibleViewSupportsNavigation, accessibleViewVerbosityEnabled } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands';
Expand Down Expand Up @@ -96,7 +96,8 @@ export class AccessibleView extends Disposable {
@IMenuService private readonly _menuService: IMenuService,
@ICommandService private readonly _commandService: ICommandService,
@IChatCodeBlockContextProviderService private readonly _codeBlockContextProviderService: IChatCodeBlockContextProviderService,
@IStorageService private readonly _storageService: IStorageService
@IStorageService private readonly _storageService: IStorageService,
@IQuickInputService private readonly _quickInputService: IQuickInputService
) {
super();

Expand Down Expand Up @@ -361,6 +362,27 @@ export class AccessibleView extends Disposable {
return symbols.length ? symbols : undefined;
}

configureKeybindings(): void {
const items = this._currentProvider?.options?.configureKeybindingItems;
if (!items) {
return;
}
const quickPick: IQuickPick<IQuickPickItem> = this._quickInputService.createQuickPick();
this._register(quickPick);
quickPick.items = items;
quickPick.title = localize('keybindings', 'Configure keybindings');
quickPick.placeholder = localize('selectKeybinding', 'Select a command ID to configure a keybinding for it');
quickPick.show();
quickPick.onDidAccept(async () => {
const item = quickPick.selectedItems[0];
if (item) {
await this._commandService.executeCommand('workbench.action.openGlobalKeybindings', item.id);
}
quickPick.dispose();
});
quickPick.onDidHide(() => quickPick.dispose());
}

private _convertTokensToSymbols(tokens: marked.TokensList, symbols: IAccessibleViewSymbol[]): void {
let firstListItem: string | undefined;
for (const token of tokens) {
Expand Down Expand Up @@ -750,6 +772,9 @@ export class AccessibleViewService extends Disposable implements IAccessibleView
}
this._accessibleView.show(provider, undefined, undefined, position);
}
configureKeybindings(): void {
this._accessibleView?.configureKeybindings();
}
showLastProvider(id: AccessibleViewProviderId): void {
this._accessibleView?.showLastProvider(id);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,24 @@ class AccessibleViewDisableHintAction extends Action2 {
}
registerAction2(AccessibleViewDisableHintAction);

class AccessibilityHelpConfigureKeybindingsAction extends Action2 {
constructor() {
super({
id: AccessibilityCommandId.AccessibilityHelpConfigureKeybindings,
precondition: ContextKeyExpr.and(accessibilityHelpIsShown),
keybinding: {
primary: KeyMod.Alt | KeyCode.KeyK,
weight: KeybindingWeight.WorkbenchContrib
},
title: localize('editor.action.accessibilityHelpConfigureKeybindings', "Accessibility Help Configure Keybindings")
});
}
async run(accessor: ServicesAccessor): Promise<void> {
await accessor.get(IAccessibleViewService).configureKeybindings();
}
}
registerAction2(AccessibilityHelpConfigureKeybindingsAction);

class AccessibleViewAcceptInlineCompletionAction extends Action2 {
constructor() {
super({
Expand Down Expand Up @@ -267,3 +285,4 @@ class AccessibleViewAcceptInlineCompletionAction extends Action2 {
}
}
registerAction2(AccessibleViewAcceptInlineCompletionAction);

Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@

import { MarkdownString } from 'vs/base/common/htmlContent';
import { DisposableMap, IDisposable, DisposableStore, Disposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { AccessibleViewType, ExtensionContentProvider } from 'vs/platform/accessibility/browser/accessibleView';
import { AccessibleViewRegistry } from 'vs/platform/accessibility/browser/accessibleViewRegistry';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IPickerQuickAccessItem } from 'vs/platform/quickinput/browser/pickerQuickAccess';
import { Registry } from 'vs/platform/registry/common/platform';
import { FocusedViewContext } from 'vs/workbench/common/contextkeys';
import { IViewsRegistry, Extensions, IViewDescriptor } from 'vs/workbench/common/views';
import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands';
import { IViewsService } from 'vs/workbench/services/views/common/viewsService';

export class ExtensionAccessibilityHelpDialogContribution extends Disposable {
Expand Down Expand Up @@ -54,9 +55,9 @@ function registerAccessibilityHelpAction(keybindingService: IKeybindingService,
const viewsService = accessor.get(IViewsService);
return new ExtensionContentProvider(
viewDescriptor.id,
{ type: AccessibleViewType.Help },
() => helpContent.value,
() => viewsService.openView(viewDescriptor.id, true)
{ type: AccessibleViewType.Help, configureKeybindingItems: helpContent.configureKeybindingItems },
() => helpContent.value.value,
() => viewsService.openView(viewDescriptor.id, true),
);
}
}));
Expand All @@ -68,27 +69,34 @@ function registerAccessibilityHelpAction(keybindingService: IKeybindingService,
return disposableStore;
}

function resolveExtensionHelpContent(keybindingService: IKeybindingService, content?: MarkdownString): MarkdownString | undefined {
function resolveExtensionHelpContent(keybindingService: IKeybindingService, content?: MarkdownString): { value: MarkdownString; configureKeybindingItems: IPickerQuickAccessItem[] | undefined } | undefined {
if (!content) {
return;
}
const configureKeybindingItems: IPickerQuickAccessItem[] = [];
let resolvedContent = typeof content === 'string' ? content : content.value;
const matches = resolvedContent.matchAll(/\<keybinding:(?<commandId>.*)\>/gm);
for (const match of [...matches]) {
const commandId = match?.groups?.commandId;
let kbLabel;
if (match?.length && commandId) {
const keybinding = keybindingService.lookupKeybinding(commandId)?.getAriaLabel();
let kbLabel = keybinding;
if (!kbLabel) {
const args = URI.parse(`command:workbench.action.openGlobalKeybindings?${encodeURIComponent(JSON.stringify(commandId))}`);
kbLabel = ` [Configure a keybinding](${args})`;
if (!keybinding) {
const configureKb = keybindingService.lookupKeybinding(AccessibilityCommandId.AccessibilityHelpConfigureKeybindings)?.getAriaLabel();
const keybindingToConfigureQuickPick = configureKb ? '(' + configureKb + ')' : 'by assigning a keybinding to the command accessibility.openQuickPick.';
kbLabel = `, configure a keybinding ` + keybindingToConfigureQuickPick;
configureKeybindingItems.push({
label: commandId,
id: commandId
});
} else {
kbLabel = ' (' + keybinding + ')';
}
resolvedContent = resolvedContent.replace(match[0], kbLabel);
}
}
const result = new MarkdownString(resolvedContent);
result.isTrusted = true;
return result;
const value = new MarkdownString(resolvedContent);
value.isTrusted = true;
return { value, configureKeybindingItems: configureKeybindingItems.length ? configureKeybindingItems : undefined };
}

Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ export const enum AccessibilityCommandId {
ShowPrevious = 'editor.action.accessibleViewPrevious',
AccessibleViewAcceptInlineCompletion = 'editor.action.accessibleViewAcceptInlineCompletion',
NextCodeBlock = 'editor.action.accessibleViewNextCodeBlock',
PreviousCodeBlock = 'editor.action.accessibleViewPreviousCodeBlock'
PreviousCodeBlock = 'editor.action.accessibleViewPreviousCodeBlock',
AccessibilityHelpConfigureKeybindings = 'editor.action.accessibilityHelpConfigureKeybindings',
}

0 comments on commit 9f83563

Please sign in to comment.