Path: blob/main/src/vs/editor/contrib/inlineCompletions/browser/inlineCompletionsAccessibleView.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 { Emitter, Event } from '../../../../base/common/event.js';6import { ICodeEditor } from '../../../browser/editorBrowser.js';7import { ICodeEditorService } from '../../../browser/services/codeEditorService.js';8import { InlineCompletionContextKeys } from './controller/inlineCompletionContextKeys.js';9import { InlineCompletionsController } from './controller/inlineCompletionsController.js';10import { AccessibleViewType, AccessibleViewProviderId, IAccessibleViewContentProvider } from '../../../../platform/accessibility/browser/accessibleView.js';11import { IAccessibleViewImplementation } from '../../../../platform/accessibility/browser/accessibleViewRegistry.js';12import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js';13import { ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';14import { Disposable } from '../../../../base/common/lifecycle.js';15import { InlineCompletionsModel } from './model/inlineCompletionsModel.js';16import { TextEdit } from '../../../common/core/edits/textEdit.js';17import { LineEdit } from '../../../common/core/edits/lineEdit.js';18import { TextModelText } from '../../../common/model/textModelText.js';1920export class InlineCompletionsAccessibleView implements IAccessibleViewImplementation {21readonly type = AccessibleViewType.View;22readonly priority = 95;23readonly name = 'inline-completions';24readonly when = ContextKeyExpr.or(InlineCompletionContextKeys.inlineSuggestionVisible, InlineCompletionContextKeys.inlineEditVisible);25getProvider(accessor: ServicesAccessor) {26const codeEditorService = accessor.get(ICodeEditorService);27const editor = codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor();28if (!editor) {29return;30}3132const model = InlineCompletionsController.get(editor)?.model.get();33if (!model?.state.get()) {34return;35}3637return new InlineCompletionsAccessibleViewContentProvider(editor, model);38}39}4041class InlineCompletionsAccessibleViewContentProvider extends Disposable implements IAccessibleViewContentProvider {42private readonly _onDidChangeContent: Emitter<void> = this._register(new Emitter<void>());43public readonly onDidChangeContent: Event<void> = this._onDidChangeContent.event;44public readonly options: { language: string | undefined; type: AccessibleViewType.View };45constructor(46private readonly _editor: ICodeEditor,47private readonly _model: InlineCompletionsModel,48) {49super();50this.options = { language: this._editor.getModel()?.getLanguageId() ?? undefined, type: AccessibleViewType.View };51}5253public readonly id = AccessibleViewProviderId.InlineCompletions;54public readonly verbositySettingKey = 'accessibility.verbosity.inlineCompletions';5556public provideContent(): string {57const state = this._model.state.get();58if (!state) {59throw new Error('Inline completion is visible but state is not available');60}61if (state.kind === 'ghostText') {6263const lineText = this._model.textModel.getLineContent(state.primaryGhostText.lineNumber);64const ghostText = state.primaryGhostText.renderForScreenReader(lineText);65if (!ghostText) {66throw new Error('Inline completion is visible but ghost text is not available');67}68return lineText + ghostText;69} else {70const text = new TextModelText(this._model.textModel);71const lineEdit = LineEdit.fromTextEdit(new TextEdit(state.edits), text);72return lineEdit.humanReadablePatch(text.getLines());73}74}75public provideNextContent(): string | undefined {76// asynchronously update the model and fire the event77this._model.next().then((() => this._onDidChangeContent.fire()));78return;79}80public providePreviousContent(): string | undefined {81// asynchronously update the model and fire the event82this._model.previous().then((() => this._onDidChangeContent.fire()));83return;84}85public onClose(): void {86this._model.stop();87this._editor.focus();88}89}909192