Path: blob/main/src/vs/workbench/contrib/output/browser/outputAccessibilityHelp.ts
5241 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 { Disposable } from '../../../../base/common/lifecycle.js';6import { AccessibleViewType, AccessibleContentProvider, IAccessibleViewContentProvider, AccessibleViewProviderId } from '../../../../platform/accessibility/browser/accessibleView.js';7import { IAccessibleViewImplementation } from '../../../../platform/accessibility/browser/accessibleViewRegistry.js';8import { ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';9import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.js';10import * as nls from '../../../../nls.js';11import { AccessibilityVerbositySettingId } from '../../accessibility/browser/accessibilityConfiguration.js';12import { OUTPUT_FILTER_FOCUS_CONTEXT } from '../../../services/output/common/output.js';1314export class OutputAccessibilityHelp implements IAccessibleViewImplementation {15readonly type = AccessibleViewType.Help;16readonly priority = 105;17readonly name = 'outputFilter';18readonly when = OUTPUT_FILTER_FOCUS_CONTEXT;1920getProvider(accessor: ServicesAccessor): AccessibleContentProvider {21return new OutputAccessibilityHelpProvider(accessor.get(IKeybindingService));22}23}2425class OutputAccessibilityHelpProvider extends Disposable implements IAccessibleViewContentProvider {26readonly id = AccessibleViewProviderId.OutputFindHelp;27readonly verbositySettingKey = AccessibilityVerbositySettingId.Find;28readonly options = { type: AccessibleViewType.Help };2930constructor(31private readonly _keybindingService: IKeybindingService,32) {33super();34}3536provideContent(): string {37const lines: string[] = [];3839// Header40lines.push(nls.localize('output.header', 'Accessibility Help: Output Panel Filter'));41lines.push(nls.localize('output.context', 'You are in the Output panel filter input. This is NOT a navigating search. Instead, it instantly hides lines that do not match your filter, showing only the lines you want to see.'));42lines.push('');4344// Current Filter Status45lines.push(nls.localize('output.statusHeader', 'Current Filter Status:'));46lines.push(nls.localize('output.statusDesc', 'You are filtering the output.'));47lines.push('');4849// Inside the Filter Input50lines.push(nls.localize('output.inputHeader', 'Inside the Filter Input (What It Does):'));51lines.push(nls.localize('output.inputDesc', 'While you are in the filter input, your focus stays in the field. You can type, edit, or adjust your filter without leaving the input. As you type, the Output panel instantly updates to show only lines matching your filter.'));52lines.push('');5354// What Happens When You Filter55lines.push(nls.localize('output.filterHeader', 'What Happens When You Filter:'));56lines.push(nls.localize('output.filterDesc1', 'Each time you change the filter text, the panel instantly regenerates to show only matching lines. Your screen reader announces how many lines are now visible. This is live feedback: as you type or delete characters, the displayed lines update immediately.'));57lines.push(nls.localize('output.filterDesc2', 'New output from your running program is appended to the panel and automatically filtered, so matching new output appears instantly.'));58lines.push('');5960// Focus Behavior61lines.push(nls.localize('output.focusHeader', 'Focus Behavior (Important):'));62lines.push(nls.localize('output.focusDesc1', 'Your focus stays in the filter input while the panel updates in the background. This is intentional, so you can keep typing without losing your place.'));63lines.push(nls.localize('output.focusDesc2', 'If you want to review the filtered output, press Down Arrow to move focus from the filter into the output content below.'));64lines.push(nls.localize('output.focusDesc3', 'If you want to clear the filter and see all output, press Escape or delete all filter text.'));65lines.push('');6667// Filter Syntax68lines.push(nls.localize('output.syntaxHeader', 'Filter Syntax and Patterns:'));69lines.push(nls.localize('output.syntaxText', '- Type text: Shows only lines containing that text (case-insensitive by default).'));70lines.push(nls.localize('output.syntaxExclude', '- !text (exclude): Hides lines containing \'text\', showing all other lines.'));71lines.push(nls.localize('output.syntaxEscape', '- \\\\! (escape): Use backslash to search for a literal "!" character.'));72lines.push(nls.localize('output.syntaxMultiple', '- text1, text2 (multiple patterns): Separate patterns with commas to show lines matching ANY pattern.'));73lines.push(nls.localize('output.syntaxExample', 'Example: typing "error, warning" shows lines containing either "error" or "warning".'));74lines.push('');7576// Keyboard Navigation Summary77lines.push(nls.localize('output.keyboardHeader', 'Keyboard Navigation Summary:'));78lines.push(nls.localize('output.keyDown', '- Down Arrow: Move focus from filter into the output content.'));79lines.push(nls.localize('output.keyTab', '- Tab: Move to log level filter buttons if available.'));80lines.push(nls.localize('output.keyEscape', '- Escape: Clear the filter and return to showing all output.'));81lines.push('');8283// Settings84lines.push(nls.localize('output.settingsHeader', 'Settings You Can Adjust ({0} opens Settings):', this._describeCommand('workbench.action.openSettings') || 'Ctrl+,'));85lines.push(nls.localize('output.settingsIntro', 'These settings affect how the Output panel works.'));86lines.push(nls.localize('output.settingVerbosity', '- `accessibility.verbosity.find`: Controls whether the filter input announces the Accessibility Help hint.'));87lines.push(nls.localize('output.settingSmartScroll', '- `output.smartScroll.enabled`: Automatically scroll to the latest output when messages arrive.'));88lines.push('');8990// Closing91lines.push(nls.localize('output.closingHeader', 'Closing:'));92lines.push(nls.localize('output.closingDesc', 'Press Escape to clear the filter and see all output, or close the Output panel. Your filter text is preserved if you reopen the panel.'));9394return lines.join('\n');95}9697private _describeCommand(commandId: string): string | undefined {98const kb = this._keybindingService.lookupKeybinding(commandId);99return kb?.getAriaLabel() ?? undefined;100}101102onClose(): void {103// No-op104}105}106107108