Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/contrib/inlayHints/browser/inlayHintsLocations.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import * as dom from '../../../../base/browser/dom.js';
7
import { Action, IAction, Separator } from '../../../../base/common/actions.js';
8
import { CancellationToken } from '../../../../base/common/cancellation.js';
9
import { generateUuid } from '../../../../base/common/uuid.js';
10
import { IActiveCodeEditor, ICodeEditor } from '../../../browser/editorBrowser.js';
11
import { EditorOption } from '../../../common/config/editorOptions.js';
12
import { Range } from '../../../common/core/range.js';
13
import { Location } from '../../../common/languages.js';
14
import { ITextModelService } from '../../../common/services/resolverService.js';
15
import { DefinitionAction, SymbolNavigationAction, SymbolNavigationAnchor } from '../../gotoSymbol/browser/goToCommands.js';
16
import { ClickLinkMouseEvent } from '../../gotoSymbol/browser/link/clickLinkGesture.js';
17
import { RenderedInlayHintLabelPart } from './inlayHintsController.js';
18
import { PeekContext } from '../../peekView/browser/peekView.js';
19
import { isIMenuItem, MenuId, MenuItemAction, MenuRegistry } from '../../../../platform/actions/common/actions.js';
20
import { ICommandService } from '../../../../platform/commands/common/commands.js';
21
import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';
22
import { IContextMenuService } from '../../../../platform/contextview/browser/contextView.js';
23
import { IInstantiationService, ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';
24
import { INotificationService, Severity } from '../../../../platform/notification/common/notification.js';
25
26
export async function showGoToContextMenu(accessor: ServicesAccessor, editor: ICodeEditor, anchor: HTMLElement, part: RenderedInlayHintLabelPart) {
27
28
const resolverService = accessor.get(ITextModelService);
29
const contextMenuService = accessor.get(IContextMenuService);
30
const commandService = accessor.get(ICommandService);
31
const instaService = accessor.get(IInstantiationService);
32
const notificationService = accessor.get(INotificationService);
33
34
await part.item.resolve(CancellationToken.None);
35
36
if (!part.part.location) {
37
return;
38
}
39
40
const location: Location = part.part.location;
41
const menuActions: IAction[] = [];
42
43
// from all registered (not active) context menu actions select those
44
// that are a symbol navigation actions
45
const filter = new Set(MenuRegistry.getMenuItems(MenuId.EditorContext)
46
.map(item => isIMenuItem(item) ? item.command.id : generateUuid()));
47
48
for (const delegate of SymbolNavigationAction.all()) {
49
if (filter.has(delegate.desc.id)) {
50
menuActions.push(new Action(delegate.desc.id, MenuItemAction.label(delegate.desc, { renderShortTitle: true }), undefined, true, async () => {
51
const ref = await resolverService.createModelReference(location.uri);
52
try {
53
const symbolAnchor = new SymbolNavigationAnchor(ref.object.textEditorModel, Range.getStartPosition(location.range));
54
const range = part.item.anchor.range;
55
await instaService.invokeFunction(delegate.runEditorCommand.bind(delegate), editor, symbolAnchor, range);
56
} finally {
57
ref.dispose();
58
59
}
60
}));
61
}
62
}
63
64
if (part.part.command) {
65
const { command } = part.part;
66
menuActions.push(new Separator());
67
menuActions.push(new Action(command.id, command.title, undefined, true, async () => {
68
try {
69
await commandService.executeCommand(command.id, ...(command.arguments ?? []));
70
} catch (err) {
71
notificationService.notify({
72
severity: Severity.Error,
73
source: part.item.provider.displayName,
74
message: err
75
});
76
}
77
}));
78
}
79
80
// show context menu
81
const useShadowDOM = editor.getOption(EditorOption.useShadowDOM);
82
contextMenuService.showContextMenu({
83
domForShadowRoot: useShadowDOM ? editor.getDomNode() ?? undefined : undefined,
84
getAnchor: () => {
85
const box = dom.getDomNodePagePosition(anchor);
86
return { x: box.left, y: box.top + box.height + 8 };
87
},
88
getActions: () => menuActions,
89
onHide: () => {
90
editor.focus();
91
},
92
autoSelectFirstItem: true,
93
});
94
95
}
96
97
export async function goToDefinitionWithLocation(accessor: ServicesAccessor, event: ClickLinkMouseEvent, editor: IActiveCodeEditor, location: Location) {
98
99
const resolverService = accessor.get(ITextModelService);
100
const ref = await resolverService.createModelReference(location.uri);
101
102
await editor.invokeWithinContext(async (accessor) => {
103
104
const openToSide = event.hasSideBySideModifier;
105
const contextKeyService = accessor.get(IContextKeyService);
106
107
const isInPeek = PeekContext.inPeekEditor.getValue(contextKeyService);
108
const canPeek = !openToSide && editor.getOption(EditorOption.definitionLinkOpensInPeek) && !isInPeek;
109
110
const action = new DefinitionAction({ openToSide, openInPeek: canPeek, muteMessage: true }, { title: { value: '', original: '' }, id: '', precondition: undefined });
111
return action.run(accessor, new SymbolNavigationAnchor(ref.object.textEditorModel, Range.getStartPosition(location.range)), Range.lift(location.range));
112
});
113
114
ref.dispose();
115
}
116
117