Path: blob/main/src/vs/editor/contrib/inlayHints/browser/inlayHintsLocations.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 * as dom from '../../../../base/browser/dom.js';6import { Action, IAction, Separator } from '../../../../base/common/actions.js';7import { CancellationToken } from '../../../../base/common/cancellation.js';8import { generateUuid } from '../../../../base/common/uuid.js';9import { IActiveCodeEditor, ICodeEditor } from '../../../browser/editorBrowser.js';10import { EditorOption } from '../../../common/config/editorOptions.js';11import { Range } from '../../../common/core/range.js';12import { Location } from '../../../common/languages.js';13import { ITextModelService } from '../../../common/services/resolverService.js';14import { DefinitionAction, SymbolNavigationAction, SymbolNavigationAnchor } from '../../gotoSymbol/browser/goToCommands.js';15import { ClickLinkMouseEvent } from '../../gotoSymbol/browser/link/clickLinkGesture.js';16import { RenderedInlayHintLabelPart } from './inlayHintsController.js';17import { PeekContext } from '../../peekView/browser/peekView.js';18import { isIMenuItem, MenuId, MenuItemAction, MenuRegistry } from '../../../../platform/actions/common/actions.js';19import { ICommandService } from '../../../../platform/commands/common/commands.js';20import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';21import { IContextMenuService } from '../../../../platform/contextview/browser/contextView.js';22import { IInstantiationService, ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';23import { INotificationService, Severity } from '../../../../platform/notification/common/notification.js';2425export async function showGoToContextMenu(accessor: ServicesAccessor, editor: ICodeEditor, anchor: HTMLElement, part: RenderedInlayHintLabelPart) {2627const resolverService = accessor.get(ITextModelService);28const contextMenuService = accessor.get(IContextMenuService);29const commandService = accessor.get(ICommandService);30const instaService = accessor.get(IInstantiationService);31const notificationService = accessor.get(INotificationService);3233await part.item.resolve(CancellationToken.None);3435if (!part.part.location) {36return;37}3839const location: Location = part.part.location;40const menuActions: IAction[] = [];4142// from all registered (not active) context menu actions select those43// that are a symbol navigation actions44const filter = new Set(MenuRegistry.getMenuItems(MenuId.EditorContext)45.map(item => isIMenuItem(item) ? item.command.id : generateUuid()));4647for (const delegate of SymbolNavigationAction.all()) {48if (filter.has(delegate.desc.id)) {49menuActions.push(new Action(delegate.desc.id, MenuItemAction.label(delegate.desc, { renderShortTitle: true }), undefined, true, async () => {50const ref = await resolverService.createModelReference(location.uri);51try {52const symbolAnchor = new SymbolNavigationAnchor(ref.object.textEditorModel, Range.getStartPosition(location.range));53const range = part.item.anchor.range;54await instaService.invokeFunction(delegate.runEditorCommand.bind(delegate), editor, symbolAnchor, range);55} finally {56ref.dispose();5758}59}));60}61}6263if (part.part.command) {64const { command } = part.part;65menuActions.push(new Separator());66menuActions.push(new Action(command.id, command.title, undefined, true, async () => {67try {68await commandService.executeCommand(command.id, ...(command.arguments ?? []));69} catch (err) {70notificationService.notify({71severity: Severity.Error,72source: part.item.provider.displayName,73message: err74});75}76}));77}7879// show context menu80const useShadowDOM = editor.getOption(EditorOption.useShadowDOM);81contextMenuService.showContextMenu({82domForShadowRoot: useShadowDOM ? editor.getDomNode() ?? undefined : undefined,83getAnchor: () => {84const box = dom.getDomNodePagePosition(anchor);85return { x: box.left, y: box.top + box.height + 8 };86},87getActions: () => menuActions,88onHide: () => {89editor.focus();90},91autoSelectFirstItem: true,92});9394}9596export async function goToDefinitionWithLocation(accessor: ServicesAccessor, event: ClickLinkMouseEvent, editor: IActiveCodeEditor, location: Location) {9798const resolverService = accessor.get(ITextModelService);99const ref = await resolverService.createModelReference(location.uri);100101await editor.invokeWithinContext(async (accessor) => {102103const openToSide = event.hasSideBySideModifier;104const contextKeyService = accessor.get(IContextKeyService);105106const isInPeek = PeekContext.inPeekEditor.getValue(contextKeyService);107const canPeek = !openToSide && editor.getOption(EditorOption.definitionLinkOpensInPeek) && !isInPeek;108109const action = new DefinitionAction({ openToSide, openInPeek: canPeek, muteMessage: true }, { title: { value: '', original: '' }, id: '', precondition: undefined });110return action.run(accessor, new SymbolNavigationAnchor(ref.object.textEditorModel, Range.getStartPosition(location.range)), Range.lift(location.range));111});112113ref.dispose();114}115116117