Path: blob/main/src/vs/workbench/contrib/accessibility/browser/accessibleViewActions.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Codicon } from '../../../../base/common/codicons.js';6import { KeyCode, KeyMod } from '../../../../base/common/keyCodes.js';7import { Command, MultiCommand, ServicesAccessor } from '../../../../editor/browser/editorExtensions.js';8import { localize } from '../../../../nls.js';9import { Action2, MenuId, registerAction2 } from '../../../../platform/actions/common/actions.js';10import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js';11import { KeybindingWeight } from '../../../../platform/keybinding/common/keybindingsRegistry.js';12import { AccessibilityCommandId } from '../common/accessibilityCommands.js';13import { accessibilityHelpIsShown, accessibleViewContainsCodeBlocks, accessibleViewCurrentProviderId, accessibleViewGoToSymbolSupported, accessibleViewHasAssignedKeybindings, accessibleViewHasUnassignedKeybindings, accessibleViewIsShown, accessibleViewSupportsNavigation, accessibleViewVerbosityEnabled } from './accessibilityConfiguration.js';14import { AccessibleViewProviderId, IAccessibleViewService } from '../../../../platform/accessibility/browser/accessibleView.js';15import { ICodeEditorService } from '../../../../editor/browser/services/codeEditorService.js';16import { InlineCompletionsController } from '../../../../editor/contrib/inlineCompletions/browser/controller/inlineCompletionsController.js';1718const accessibleViewMenu = {19id: MenuId.AccessibleView,20group: 'navigation',21when: accessibleViewIsShown22};23const commandPalette = {24id: MenuId.CommandPalette,25group: '',26order: 127};28class AccessibleViewNextAction extends Action2 {29constructor() {30super({31id: AccessibilityCommandId.ShowNext,32precondition: ContextKeyExpr.and(accessibleViewIsShown, accessibleViewSupportsNavigation),33keybinding: {34primary: KeyMod.Alt | KeyCode.BracketRight,35weight: KeybindingWeight.WorkbenchContrib36},37menu: [38commandPalette,39{40...accessibleViewMenu,41when: ContextKeyExpr.and(accessibleViewIsShown, accessibleViewSupportsNavigation),42}],43icon: Codicon.arrowDown,44title: localize('editor.action.accessibleViewNext', "Show Next in Accessible View")45});46}47run(accessor: ServicesAccessor): void {48accessor.get(IAccessibleViewService).next();49}50}51registerAction2(AccessibleViewNextAction);525354class AccessibleViewNextCodeBlockAction extends Action2 {55constructor() {56super({57id: AccessibilityCommandId.NextCodeBlock,58precondition: ContextKeyExpr.and(accessibleViewContainsCodeBlocks, ContextKeyExpr.or(ContextKeyExpr.equals(accessibleViewCurrentProviderId.key, AccessibleViewProviderId.PanelChat), ContextKeyExpr.equals(accessibleViewCurrentProviderId.key, AccessibleViewProviderId.InlineChat), ContextKeyExpr.equals(accessibleViewCurrentProviderId.key, AccessibleViewProviderId.QuickChat))),59keybinding: {60primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.PageDown,61mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.PageDown, },62weight: KeybindingWeight.WorkbenchContrib,63},64icon: Codicon.arrowRight,65menu:66{67...accessibleViewMenu,68when: ContextKeyExpr.and(accessibleViewIsShown, accessibleViewContainsCodeBlocks),69},70title: localize('editor.action.accessibleViewNextCodeBlock', "Accessible View: Next Code Block")71});72}73run(accessor: ServicesAccessor): void {74accessor.get(IAccessibleViewService).navigateToCodeBlock('next');75}76}77registerAction2(AccessibleViewNextCodeBlockAction);787980class AccessibleViewPreviousCodeBlockAction extends Action2 {81constructor() {82super({83id: AccessibilityCommandId.PreviousCodeBlock,84precondition: ContextKeyExpr.and(accessibleViewContainsCodeBlocks, ContextKeyExpr.or(ContextKeyExpr.equals(accessibleViewCurrentProviderId.key, AccessibleViewProviderId.PanelChat), ContextKeyExpr.equals(accessibleViewCurrentProviderId.key, AccessibleViewProviderId.InlineChat), ContextKeyExpr.equals(accessibleViewCurrentProviderId.key, AccessibleViewProviderId.QuickChat))),85keybinding: {86primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.PageUp,87mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.PageUp, },88weight: KeybindingWeight.WorkbenchContrib,89},90icon: Codicon.arrowLeft,91menu: {92...accessibleViewMenu,93when: ContextKeyExpr.and(accessibleViewIsShown, accessibleViewContainsCodeBlocks),94},95title: localize('editor.action.accessibleViewPreviousCodeBlock', "Accessible View: Previous Code Block")96});97}98run(accessor: ServicesAccessor): void {99accessor.get(IAccessibleViewService).navigateToCodeBlock('previous');100}101}102registerAction2(AccessibleViewPreviousCodeBlockAction);103104class AccessibleViewPreviousAction extends Action2 {105constructor() {106super({107id: AccessibilityCommandId.ShowPrevious,108precondition: ContextKeyExpr.and(accessibleViewIsShown, accessibleViewSupportsNavigation),109keybinding: {110primary: KeyMod.Alt | KeyCode.BracketLeft,111weight: KeybindingWeight.WorkbenchContrib112},113icon: Codicon.arrowUp,114menu: [115commandPalette,116{117...accessibleViewMenu,118when: ContextKeyExpr.and(accessibleViewIsShown, accessibleViewSupportsNavigation),119}120],121title: localize('editor.action.accessibleViewPrevious', "Show Previous in Accessible View")122});123}124run(accessor: ServicesAccessor): void {125accessor.get(IAccessibleViewService).previous();126}127}128registerAction2(AccessibleViewPreviousAction);129130131class AccessibleViewGoToSymbolAction extends Action2 {132constructor() {133super({134id: AccessibilityCommandId.GoToSymbol,135precondition: ContextKeyExpr.and(ContextKeyExpr.or(accessibleViewIsShown, accessibilityHelpIsShown), accessibleViewGoToSymbolSupported),136keybinding: {137primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyO,138secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Period],139weight: KeybindingWeight.WorkbenchContrib + 10140},141icon: Codicon.symbolMisc,142menu: [143commandPalette,144{145...accessibleViewMenu,146when: ContextKeyExpr.and(ContextKeyExpr.or(accessibleViewIsShown, accessibilityHelpIsShown), accessibleViewGoToSymbolSupported),147}148],149title: localize('editor.action.accessibleViewGoToSymbol', "Go To Symbol in Accessible View")150});151}152run(accessor: ServicesAccessor): void {153accessor.get(IAccessibleViewService).goToSymbol();154}155}156registerAction2(AccessibleViewGoToSymbolAction);157158function registerCommand<T extends Command>(command: T): T {159command.register();160return command;161}162163export const AccessibilityHelpAction = registerCommand(new MultiCommand({164id: AccessibilityCommandId.OpenAccessibilityHelp,165precondition: undefined,166kbOpts: {167primary: KeyMod.Alt | KeyCode.F1,168weight: KeybindingWeight.WorkbenchContrib,169linux: {170primary: KeyMod.Alt | KeyMod.Shift | KeyCode.F1,171secondary: [KeyMod.Alt | KeyCode.F1]172},173kbExpr: accessibilityHelpIsShown.toNegated()174},175menuOpts: [{176menuId: MenuId.CommandPalette,177group: '',178title: localize('editor.action.accessibilityHelp', "Open Accessibility Help"),179order: 1180}],181}));182183184export const AccessibleViewAction = registerCommand(new MultiCommand({185id: AccessibilityCommandId.OpenAccessibleView,186precondition: undefined,187kbOpts: {188primary: KeyMod.Alt | KeyCode.F2,189weight: KeybindingWeight.WorkbenchContrib,190linux: {191primary: KeyMod.Alt | KeyMod.Shift | KeyCode.F2,192secondary: [KeyMod.Alt | KeyCode.F2]193}194},195menuOpts: [{196menuId: MenuId.CommandPalette,197group: '',198title: localize('editor.action.accessibleView', "Open Accessible View"),199order: 1200}],201}));202203class AccessibleViewDisableHintAction extends Action2 {204constructor() {205super({206id: AccessibilityCommandId.DisableVerbosityHint,207precondition: ContextKeyExpr.and(ContextKeyExpr.or(accessibleViewIsShown, accessibilityHelpIsShown), accessibleViewVerbosityEnabled),208keybinding: {209primary: KeyMod.Alt | KeyCode.F6,210weight: KeybindingWeight.WorkbenchContrib211},212icon: Codicon.bellSlash,213menu: [214commandPalette,215{216id: MenuId.AccessibleView,217group: 'navigation',218when: ContextKeyExpr.and(ContextKeyExpr.or(accessibleViewIsShown, accessibilityHelpIsShown), accessibleViewVerbosityEnabled),219}220],221title: localize('editor.action.accessibleViewDisableHint', "Disable Accessible View Hint")222});223}224run(accessor: ServicesAccessor): void {225accessor.get(IAccessibleViewService).disableHint();226}227}228registerAction2(AccessibleViewDisableHintAction);229230class AccessibilityHelpConfigureKeybindingsAction extends Action2 {231constructor() {232super({233id: AccessibilityCommandId.AccessibilityHelpConfigureKeybindings,234precondition: ContextKeyExpr.and(accessibilityHelpIsShown, accessibleViewHasUnassignedKeybindings),235icon: Codicon.recordKeys,236keybinding: {237primary: KeyMod.Alt | KeyCode.KeyK,238weight: KeybindingWeight.WorkbenchContrib239},240menu: [241{242id: MenuId.AccessibleView,243group: 'navigation',244order: 3,245when: accessibleViewHasUnassignedKeybindings,246}247],248title: localize('editor.action.accessibilityHelpConfigureUnassignedKeybindings', "Accessibility Help Configure Unassigned Keybindings")249});250}251async run(accessor: ServicesAccessor): Promise<void> {252await accessor.get(IAccessibleViewService).configureKeybindings(true);253}254}255registerAction2(AccessibilityHelpConfigureKeybindingsAction);256257class AccessibilityHelpConfigureAssignedKeybindingsAction extends Action2 {258constructor() {259super({260id: AccessibilityCommandId.AccessibilityHelpConfigureAssignedKeybindings,261precondition: ContextKeyExpr.and(accessibilityHelpIsShown, accessibleViewHasAssignedKeybindings),262icon: Codicon.recordKeys,263keybinding: {264primary: KeyMod.Alt | KeyCode.KeyA,265weight: KeybindingWeight.WorkbenchContrib266},267menu: [268{269id: MenuId.AccessibleView,270group: 'navigation',271order: 4,272when: accessibleViewHasAssignedKeybindings,273}274],275title: localize('editor.action.accessibilityHelpConfigureAssignedKeybindings', "Accessibility Help Configure Assigned Keybindings")276});277}278async run(accessor: ServicesAccessor): Promise<void> {279await accessor.get(IAccessibleViewService).configureKeybindings(false);280}281}282registerAction2(AccessibilityHelpConfigureAssignedKeybindingsAction);283284285class AccessibilityHelpOpenHelpLinkAction extends Action2 {286constructor() {287super({288id: AccessibilityCommandId.AccessibilityHelpOpenHelpLink,289precondition: ContextKeyExpr.and(accessibilityHelpIsShown),290keybinding: {291primary: KeyMod.Alt | KeyCode.KeyH,292weight: KeybindingWeight.WorkbenchContrib293},294title: localize('editor.action.accessibilityHelpOpenHelpLink', "Accessibility Help Open Help Link")295});296}297run(accessor: ServicesAccessor): void {298accessor.get(IAccessibleViewService).openHelpLink();299}300}301registerAction2(AccessibilityHelpOpenHelpLinkAction);302303class AccessibleViewAcceptInlineCompletionAction extends Action2 {304constructor() {305super({306id: AccessibilityCommandId.AccessibleViewAcceptInlineCompletion,307precondition: ContextKeyExpr.and(accessibleViewIsShown, ContextKeyExpr.equals(accessibleViewCurrentProviderId.key, AccessibleViewProviderId.InlineCompletions)),308keybinding: {309primary: KeyMod.CtrlCmd | KeyCode.Slash,310mac: { primary: KeyMod.WinCtrl | KeyCode.Slash },311weight: KeybindingWeight.WorkbenchContrib312},313icon: Codicon.check,314menu: [315commandPalette,316{317id: MenuId.AccessibleView,318group: 'navigation',319order: 0,320when: ContextKeyExpr.and(accessibleViewIsShown, ContextKeyExpr.equals(accessibleViewCurrentProviderId.key, AccessibleViewProviderId.InlineCompletions))321}],322title: localize('editor.action.accessibleViewAcceptInlineCompletionAction', "Accept Inline Completion")323});324}325async run(accessor: ServicesAccessor): Promise<void> {326const codeEditorService = accessor.get(ICodeEditorService);327const editor = codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor();328if (!editor) {329return;330}331const model = InlineCompletionsController.get(editor)?.model.get();332const state = model?.state.get();333if (!model || !state) {334return;335}336await model.accept(editor);337model.stop();338editor.focus();339}340}341registerAction2(AccessibleViewAcceptInlineCompletionAction);342343344345