Path: blob/main/src/vs/workbench/contrib/inlineChat/browser/inlineChatGutterAffordance.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 { Codicon } from '../../../../base/common/codicons.js';6import { autorun, constObservable, derived, IObservable, ISettableObservable, observableValue } from '../../../../base/common/observable.js';7import { ObservableCodeEditor } from '../../../../editor/browser/observableCodeEditor.js';8import { LineRange } from '../../../../editor/common/core/ranges/lineRange.js';9import { Selection, SelectionDirection } from '../../../../editor/common/core/selection.js';10import { InlineEditsGutterIndicator, InlineEditsGutterIndicatorData, InlineSuggestionGutterMenuData, SimpleInlineSuggestModel } from '../../../../editor/contrib/inlineCompletions/browser/view/inlineEdits/components/gutterIndicatorView.js';11import { InlineEditTabAction } from '../../../../editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViewInterface.js';12import { localize } from '../../../../nls.js';13import { IAccessibilityService } from '../../../../platform/accessibility/common/accessibility.js';14import { IHoverService } from '../../../../platform/hover/browser/hover.js';15import { HoverService } from '../../../../platform/hover/browser/hoverService.js';16import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';17import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.js';18import { IThemeService } from '../../../../platform/theme/common/themeService.js';19import { IUserInteractionService } from '../../../../platform/userInteraction/browser/userInteractionService.js';20import { ACTION_START } from '../common/inlineChat.js';2122export class InlineChatGutterAffordance extends InlineEditsGutterIndicator {2324constructor(25private readonly _myEditorObs: ObservableCodeEditor,26selection: IObservable<Selection | undefined>,27private readonly _hover: ISettableObservable<{ rect: DOMRect; above: boolean; lineNumber: number } | undefined>,28@IKeybindingService private readonly _keybindingService: IKeybindingService,29@IHoverService hoverService: HoverService,30@IInstantiationService instantiationService: IInstantiationService,31@IAccessibilityService accessibilityService: IAccessibilityService,32@IThemeService themeService: IThemeService,33@IUserInteractionService userInteractionService: IUserInteractionService,34) {35const data = derived<InlineEditsGutterIndicatorData | undefined>(r => {36const value = selection.read(r);37if (!value) {38return undefined;39}4041// Use the cursor position (active end of selection) to determine the line42const cursorPosition = value.getPosition();43const lineRange = new LineRange(cursorPosition.lineNumber, cursorPosition.lineNumber + 1);4445// Create minimal gutter menu data (empty for prototype)46const gutterMenuData = new InlineSuggestionGutterMenuData(47undefined, // action48'', // displayName49[], // extensionCommands50undefined, // alternativeAction51undefined, // modelInfo52undefined, // setModelId53);5455return new InlineEditsGutterIndicatorData(56gutterMenuData,57lineRange,58new SimpleInlineSuggestModel(() => { }, () => this._doShowHover()),59undefined, // altAction60{61icon: Codicon.sparkle,62}63);64});6566const focusIsInMenu = observableValue<boolean>({}, false);6768super(69_myEditorObs, data, constObservable(InlineEditTabAction.Inactive), constObservable(0), constObservable(false), focusIsInMenu,70hoverService, instantiationService, accessibilityService, themeService, userInteractionService71);7273this._store.add(autorun(r => {74const element = _hover.read(r);75this._hoverVisible.set(!!element, undefined);76}));77}7879protected override _showHover(): void {80this._hoverService.showInstantHover({81target: this._iconRef.element,82content: this._keybindingService.appendKeybinding(localize('inlineChatGutterHover', "Inline Chat"), ACTION_START),83// appearance: { showPointer: true }84});85}8687private _doShowHover(): void {88if (this._hoverVisible.get()) {89return;90}9192// Use the icon element from the base class as anchor93const iconElement = this._iconRef.element;94if (!iconElement) {95this._hover.set(undefined, undefined);96return;97}9899const selection = this._myEditorObs.cursorSelection.get();100const direction = selection?.getDirection() ?? SelectionDirection.LTR;101const lineNumber = selection?.getPosition().lineNumber ?? 1;102this._hover.set({ rect: iconElement.getBoundingClientRect(), above: direction === SelectionDirection.RTL, lineNumber }, undefined);103}104105}106107108