883132780da79078e4989c3349cc3e06916714a32bfae06bbbb27bcd9995a653d28f0b474fac904174945e47e203b15d33e88b4c75a23984bf6a6e453b5e9a 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  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. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  6. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  7. return new (P || (P = Promise))(function (resolve, reject) {
  8. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  9. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  10. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  11. step((generator = generator.apply(thisArg, _arguments || [])).next());
  12. });
  13. };
  14. var _a, _b, _c, _d, _e, _f, _g, _h;
  15. import { isStandalone } from '../../../../base/browser/browser.js';
  16. import { alert } from '../../../../base/browser/ui/aria/aria.js';
  17. import { createCancelablePromise, raceCancellation } from '../../../../base/common/async.js';
  18. import { KeyChord } from '../../../../base/common/keyCodes.js';
  19. import { isWeb } from '../../../../base/common/platform.js';
  20. import { assertType } from '../../../../base/common/types.js';
  21. import { URI } from '../../../../base/common/uri.js';
  22. import { EditorStateCancellationTokenSource } from '../../editorState/browser/editorState.js';
  23. import { isCodeEditor } from '../../../browser/editorBrowser.js';
  24. import { EditorAction, registerInstantiatedEditorAction } from '../../../browser/editorExtensions.js';
  25. import { ICodeEditorService } from '../../../browser/services/codeEditorService.js';
  26. import { EmbeddedCodeEditorWidget } from '../../../browser/widget/embeddedCodeEditorWidget.js';
  27. import * as corePosition from '../../../common/core/position.js';
  28. import { Range } from '../../../common/core/range.js';
  29. import { EditorContextKeys } from '../../../common/editorContextKeys.js';
  30. import { isLocationLink } from '../../../common/languages.js';
  31. import { ReferencesController } from './peek/referencesController.js';
  32. import { ReferencesModel } from './referencesModel.js';
  33. import { ISymbolNavigationService } from './symbolNavigation.js';
  34. import { MessageController } from '../../message/browser/messageController.js';
  35. import { PeekContext } from '../../peekView/browser/peekView.js';
  36. import * as nls from '../../../../nls.js';
  37. import { MenuId, MenuRegistry } from '../../../../platform/actions/common/actions.js';
  38. import { CommandsRegistry, ICommandService } from '../../../../platform/commands/common/commands.js';
  39. import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js';
  40. import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
  41. import { INotificationService } from '../../../../platform/notification/common/notification.js';
  42. import { IEditorProgressService } from '../../../../platform/progress/common/progress.js';
  43. import { getDeclarationsAtPosition, getDefinitionsAtPosition, getImplementationsAtPosition, getReferencesAtPosition, getTypeDefinitionsAtPosition } from './goToSymbol.js';
  44. import { ILanguageFeaturesService } from '../../../common/services/languageFeatures.js';
  45. MenuRegistry.appendMenuItem(MenuId.EditorContext, {
  46. submenu: MenuId.EditorContextPeek,
  47. title: nls.localize('peek.submenu', "Peek"),
  48. group: 'navigation',
  49. order: 100
  50. });
  51. const _goToActionIds = new Set();
  52. function registerGoToAction(ctor) {
  53. const result = new ctor();
  54. registerInstantiatedEditorAction(result);
  55. _goToActionIds.add(result.id);
  56. return result;
  57. }
  58. export class SymbolNavigationAnchor {
  59. constructor(model, position) {
  60. this.model = model;
  61. this.position = position;
  62. }
  63. static is(thing) {
  64. if (!thing || typeof thing !== 'object') {
  65. return false;
  66. }
  67. if (thing instanceof SymbolNavigationAnchor) {
  68. return true;
  69. }
  70. if (corePosition.Position.isIPosition(thing.position) && thing.model) {
  71. return true;
  72. }
  73. return false;
  74. }
  75. }
  76. export class SymbolNavigationAction extends EditorAction {
  77. constructor(configuration, opts) {
  78. super(opts);
  79. this.configuration = configuration;
  80. }
  81. run(accessor, editor, arg) {
  82. if (!editor.hasModel()) {
  83. return Promise.resolve(undefined);
  84. }
  85. const notificationService = accessor.get(INotificationService);
  86. const editorService = accessor.get(ICodeEditorService);
  87. const progressService = accessor.get(IEditorProgressService);
  88. const symbolNavService = accessor.get(ISymbolNavigationService);
  89. const languageFeaturesService = accessor.get(ILanguageFeaturesService);
  90. const model = editor.getModel();
  91. const position = editor.getPosition();
  92. const anchor = SymbolNavigationAnchor.is(arg) ? arg : new SymbolNavigationAnchor(model, position);
  93. const cts = new EditorStateCancellationTokenSource(editor, 1 /* CodeEditorStateFlag.Value */ | 4 /* CodeEditorStateFlag.Position */);
  94. const promise = raceCancellation(this._getLocationModel(languageFeaturesService, anchor.model, anchor.position, cts.token), cts.token).then((references) => __awaiter(this, void 0, void 0, function* () {
  95. var _a;
  96. if (!references || cts.token.isCancellationRequested) {
  97. return;
  98. }
  99. alert(references.ariaMessage);
  100. let altAction;
  101. if (references.referenceAt(model.uri, position)) {
  102. const altActionId = this._getAlternativeCommand(editor);
  103. if (!SymbolNavigationAction._activeAlternativeCommands.has(altActionId) && _goToActionIds.has(altActionId)) {
  104. altAction = editor.getAction(altActionId);
  105. }
  106. }
  107. const referenceCount = references.references.length;
  108. if (referenceCount === 0) {
  109. // no result -> show message
  110. if (!this.configuration.muteMessage) {
  111. const info = model.getWordAtPosition(position);
  112. (_a = MessageController.get(editor)) === null || _a === void 0 ? void 0 : _a.showMessage(this._getNoResultFoundMessage(info), position);
  113. }
  114. }
  115. else if (referenceCount === 1 && altAction) {
  116. // already at the only result, run alternative
  117. SymbolNavigationAction._activeAlternativeCommands.add(this.id);
  118. altAction.run().finally(() => {
  119. SymbolNavigationAction._activeAlternativeCommands.delete(this.id);
  120. });
  121. }
  122. else {
  123. // normal results handling
  124. return this._onResult(editorService, symbolNavService, editor, references);
  125. }
  126. }), (err) => {
  127. // report an error
  128. notificationService.error(err);
  129. }).finally(() => {
  130. cts.dispose();
  131. });
  132. progressService.showWhile(promise, 250);
  133. return promise;
  134. }
  135. _onResult(editorService, symbolNavService, editor, model) {
  136. return __awaiter(this, void 0, void 0, function* () {
  137. const gotoLocation = this._getGoToPreference(editor);
  138. if (!(editor instanceof EmbeddedCodeEditorWidget) && (this.configuration.openInPeek || (gotoLocation === 'peek' && model.references.length > 1))) {
  139. this._openInPeek(editor, model);
  140. }
  141. else {
  142. const next = model.firstReference();
  143. const peek = model.references.length > 1 && gotoLocation === 'gotoAndPeek';
  144. const targetEditor = yield this._openReference(editor, editorService, next, this.configuration.openToSide, !peek);
  145. if (peek && targetEditor) {
  146. this._openInPeek(targetEditor, model);
  147. }
  148. else {
  149. model.dispose();
  150. }
  151. // keep remaining locations around when using
  152. // 'goto'-mode
  153. if (gotoLocation === 'goto') {
  154. symbolNavService.put(next);
  155. }
  156. }
  157. });
  158. }
  159. _openReference(editor, editorService, reference, sideBySide, highlight) {
  160. return __awaiter(this, void 0, void 0, function* () {
  161. // range is the target-selection-range when we have one
  162. // and the fallback is the 'full' range
  163. let range = undefined;
  164. if (isLocationLink(reference)) {
  165. range = reference.targetSelectionRange;
  166. }
  167. if (!range) {
  168. range = reference.range;
  169. }
  170. if (!range) {
  171. return undefined;
  172. }
  173. const targetEditor = yield editorService.openCodeEditor({
  174. resource: reference.uri,
  175. options: {
  176. selection: Range.collapseToStart(range),
  177. selectionRevealType: 3 /* TextEditorSelectionRevealType.NearTopIfOutsideViewport */,
  178. selectionSource: "code.jump" /* TextEditorSelectionSource.JUMP */
  179. }
  180. }, editor, sideBySide);
  181. if (!targetEditor) {
  182. return undefined;
  183. }
  184. if (highlight) {
  185. const modelNow = targetEditor.getModel();
  186. const decorations = targetEditor.createDecorationsCollection([{ range, options: { description: 'symbol-navigate-action-highlight', className: 'symbolHighlight' } }]);
  187. setTimeout(() => {
  188. if (targetEditor.getModel() === modelNow) {
  189. decorations.clear();
  190. }
  191. }, 350);
  192. }
  193. return targetEditor;
  194. });
  195. }
  196. _openInPeek(target, model) {
  197. const controller = ReferencesController.get(target);
  198. if (controller && target.hasModel()) {
  199. controller.toggleWidget(target.getSelection(), createCancelablePromise(_ => Promise.resolve(model)), this.configuration.openInPeek);
  200. }
  201. else {
  202. model.dispose();
  203. }
  204. }
  205. }
  206. SymbolNavigationAction._activeAlternativeCommands = new Set();
  207. //#region --- DEFINITION
  208. export class DefinitionAction extends SymbolNavigationAction {
  209. _getLocationModel(languageFeaturesService, model, position, token) {
  210. return __awaiter(this, void 0, void 0, function* () {
  211. return new ReferencesModel(yield getDefinitionsAtPosition(languageFeaturesService.definitionProvider, model, position, token), nls.localize('def.title', 'Definitions'));
  212. });
  213. }
  214. _getNoResultFoundMessage(info) {
  215. return info && info.word
  216. ? nls.localize('noResultWord', "No definition found for '{0}'", info.word)
  217. : nls.localize('generic.noResults', "No definition found");
  218. }
  219. _getAlternativeCommand(editor) {
  220. return editor.getOption(53 /* EditorOption.gotoLocation */).alternativeDefinitionCommand;
  221. }
  222. _getGoToPreference(editor) {
  223. return editor.getOption(53 /* EditorOption.gotoLocation */).multipleDefinitions;
  224. }
  225. }
  226. const goToDefinitionKb = isWeb && !isStandalone()
  227. ? 2048 /* KeyMod.CtrlCmd */ | 70 /* KeyCode.F12 */
  228. : 70 /* KeyCode.F12 */;
  229. registerGoToAction((_a = class GoToDefinitionAction extends DefinitionAction {
  230. constructor() {
  231. super({
  232. openToSide: false,
  233. openInPeek: false,
  234. muteMessage: false
  235. }, {
  236. id: GoToDefinitionAction.id,
  237. label: nls.localize('actions.goToDecl.label', "Go to Definition"),
  238. alias: 'Go to Definition',
  239. precondition: ContextKeyExpr.and(EditorContextKeys.hasDefinitionProvider, EditorContextKeys.isInWalkThroughSnippet.toNegated()),
  240. kbOpts: {
  241. kbExpr: EditorContextKeys.editorTextFocus,
  242. primary: goToDefinitionKb,
  243. weight: 100 /* KeybindingWeight.EditorContrib */
  244. },
  245. contextMenuOpts: {
  246. group: 'navigation',
  247. order: 1.1
  248. }
  249. });
  250. CommandsRegistry.registerCommandAlias('editor.action.goToDeclaration', GoToDefinitionAction.id);
  251. }
  252. },
  253. _a.id = 'editor.action.revealDefinition',
  254. _a));
  255. registerGoToAction((_b = class OpenDefinitionToSideAction extends DefinitionAction {
  256. constructor() {
  257. super({
  258. openToSide: true,
  259. openInPeek: false,
  260. muteMessage: false
  261. }, {
  262. id: OpenDefinitionToSideAction.id,
  263. label: nls.localize('actions.goToDeclToSide.label', "Open Definition to the Side"),
  264. alias: 'Open Definition to the Side',
  265. precondition: ContextKeyExpr.and(EditorContextKeys.hasDefinitionProvider, EditorContextKeys.isInWalkThroughSnippet.toNegated()),
  266. kbOpts: {
  267. kbExpr: EditorContextKeys.editorTextFocus,
  268. primary: KeyChord(2048 /* KeyMod.CtrlCmd */ | 41 /* KeyCode.KeyK */, goToDefinitionKb),
  269. weight: 100 /* KeybindingWeight.EditorContrib */
  270. }
  271. });
  272. CommandsRegistry.registerCommandAlias('editor.action.openDeclarationToTheSide', OpenDefinitionToSideAction.id);
  273. }
  274. },
  275. _b.id = 'editor.action.revealDefinitionAside',
  276. _b));
  277. registerGoToAction((_c = class PeekDefinitionAction extends DefinitionAction {
  278. constructor() {
  279. super({
  280. openToSide: false,
  281. openInPeek: true,
  282. muteMessage: false
  283. }, {
  284. id: PeekDefinitionAction.id,
  285. label: nls.localize('actions.previewDecl.label', "Peek Definition"),
  286. alias: 'Peek Definition',
  287. precondition: ContextKeyExpr.and(EditorContextKeys.hasDefinitionProvider, PeekContext.notInPeekEditor, EditorContextKeys.isInWalkThroughSnippet.toNegated()),
  288. kbOpts: {
  289. kbExpr: EditorContextKeys.editorTextFocus,
  290. primary: 512 /* KeyMod.Alt */ | 70 /* KeyCode.F12 */,
  291. linux: { primary: 2048 /* KeyMod.CtrlCmd */ | 1024 /* KeyMod.Shift */ | 68 /* KeyCode.F10 */ },
  292. weight: 100 /* KeybindingWeight.EditorContrib */
  293. },
  294. contextMenuOpts: {
  295. menuId: MenuId.EditorContextPeek,
  296. group: 'peek',
  297. order: 2
  298. }
  299. });
  300. CommandsRegistry.registerCommandAlias('editor.action.previewDeclaration', PeekDefinitionAction.id);
  301. }
  302. },
  303. _c.id = 'editor.action.peekDefinition',
  304. _c));
  305. //#endregion
  306. //#region --- DECLARATION
  307. class DeclarationAction extends SymbolNavigationAction {
  308. _getLocationModel(languageFeaturesService, model, position, token) {
  309. return __awaiter(this, void 0, void 0, function* () {
  310. return new ReferencesModel(yield getDeclarationsAtPosition(languageFeaturesService.declarationProvider, model, position, token), nls.localize('decl.title', 'Declarations'));
  311. });
  312. }
  313. _getNoResultFoundMessage(info) {
  314. return info && info.word
  315. ? nls.localize('decl.noResultWord', "No declaration found for '{0}'", info.word)
  316. : nls.localize('decl.generic.noResults', "No declaration found");
  317. }
  318. _getAlternativeCommand(editor) {
  319. return editor.getOption(53 /* EditorOption.gotoLocation */).alternativeDeclarationCommand;
  320. }
  321. _getGoToPreference(editor) {
  322. return editor.getOption(53 /* EditorOption.gotoLocation */).multipleDeclarations;
  323. }
  324. }
  325. registerGoToAction((_d = class GoToDeclarationAction extends DeclarationAction {
  326. constructor() {
  327. super({
  328. openToSide: false,
  329. openInPeek: false,
  330. muteMessage: false
  331. }, {
  332. id: GoToDeclarationAction.id,
  333. label: nls.localize('actions.goToDeclaration.label', "Go to Declaration"),
  334. alias: 'Go to Declaration',
  335. precondition: ContextKeyExpr.and(EditorContextKeys.hasDeclarationProvider, EditorContextKeys.isInWalkThroughSnippet.toNegated()),
  336. contextMenuOpts: {
  337. group: 'navigation',
  338. order: 1.3
  339. },
  340. });
  341. }
  342. _getNoResultFoundMessage(info) {
  343. return info && info.word
  344. ? nls.localize('decl.noResultWord', "No declaration found for '{0}'", info.word)
  345. : nls.localize('decl.generic.noResults', "No declaration found");
  346. }
  347. },
  348. _d.id = 'editor.action.revealDeclaration',
  349. _d));
  350. registerGoToAction(class PeekDeclarationAction extends DeclarationAction {
  351. constructor() {
  352. super({
  353. openToSide: false,
  354. openInPeek: true,
  355. muteMessage: false
  356. }, {
  357. id: 'editor.action.peekDeclaration',
  358. label: nls.localize('actions.peekDecl.label', "Peek Declaration"),
  359. alias: 'Peek Declaration',
  360. precondition: ContextKeyExpr.and(EditorContextKeys.hasDeclarationProvider, PeekContext.notInPeekEditor, EditorContextKeys.isInWalkThroughSnippet.toNegated()),
  361. contextMenuOpts: {
  362. menuId: MenuId.EditorContextPeek,
  363. group: 'peek',
  364. order: 3
  365. }
  366. });
  367. }
  368. });
  369. //#endregion
  370. //#region --- TYPE DEFINITION
  371. class TypeDefinitionAction extends SymbolNavigationAction {
  372. _getLocationModel(languageFeaturesService, model, position, token) {
  373. return __awaiter(this, void 0, void 0, function* () {
  374. return new ReferencesModel(yield getTypeDefinitionsAtPosition(languageFeaturesService.typeDefinitionProvider, model, position, token), nls.localize('typedef.title', 'Type Definitions'));
  375. });
  376. }
  377. _getNoResultFoundMessage(info) {
  378. return info && info.word
  379. ? nls.localize('goToTypeDefinition.noResultWord', "No type definition found for '{0}'", info.word)
  380. : nls.localize('goToTypeDefinition.generic.noResults', "No type definition found");
  381. }
  382. _getAlternativeCommand(editor) {
  383. return editor.getOption(53 /* EditorOption.gotoLocation */).alternativeTypeDefinitionCommand;
  384. }
  385. _getGoToPreference(editor) {
  386. return editor.getOption(53 /* EditorOption.gotoLocation */).multipleTypeDefinitions;
  387. }
  388. }
  389. registerGoToAction((_e = class GoToTypeDefinitionAction extends TypeDefinitionAction {
  390. constructor() {
  391. super({
  392. openToSide: false,
  393. openInPeek: false,
  394. muteMessage: false
  395. }, {
  396. id: GoToTypeDefinitionAction.ID,
  397. label: nls.localize('actions.goToTypeDefinition.label', "Go to Type Definition"),
  398. alias: 'Go to Type Definition',
  399. precondition: ContextKeyExpr.and(EditorContextKeys.hasTypeDefinitionProvider, EditorContextKeys.isInWalkThroughSnippet.toNegated()),
  400. kbOpts: {
  401. kbExpr: EditorContextKeys.editorTextFocus,
  402. primary: 0,
  403. weight: 100 /* KeybindingWeight.EditorContrib */
  404. },
  405. contextMenuOpts: {
  406. group: 'navigation',
  407. order: 1.4
  408. }
  409. });
  410. }
  411. },
  412. _e.ID = 'editor.action.goToTypeDefinition',
  413. _e));
  414. registerGoToAction((_f = class PeekTypeDefinitionAction extends TypeDefinitionAction {
  415. constructor() {
  416. super({
  417. openToSide: false,
  418. openInPeek: true,
  419. muteMessage: false
  420. }, {
  421. id: PeekTypeDefinitionAction.ID,
  422. label: nls.localize('actions.peekTypeDefinition.label', "Peek Type Definition"),
  423. alias: 'Peek Type Definition',
  424. precondition: ContextKeyExpr.and(EditorContextKeys.hasTypeDefinitionProvider, PeekContext.notInPeekEditor, EditorContextKeys.isInWalkThroughSnippet.toNegated()),
  425. contextMenuOpts: {
  426. menuId: MenuId.EditorContextPeek,
  427. group: 'peek',
  428. order: 4
  429. }
  430. });
  431. }
  432. },
  433. _f.ID = 'editor.action.peekTypeDefinition',
  434. _f));
  435. //#endregion
  436. //#region --- IMPLEMENTATION
  437. class ImplementationAction extends SymbolNavigationAction {
  438. _getLocationModel(languageFeaturesService, model, position, token) {
  439. return __awaiter(this, void 0, void 0, function* () {
  440. return new ReferencesModel(yield getImplementationsAtPosition(languageFeaturesService.implementationProvider, model, position, token), nls.localize('impl.title', 'Implementations'));
  441. });
  442. }
  443. _getNoResultFoundMessage(info) {
  444. return info && info.word
  445. ? nls.localize('goToImplementation.noResultWord', "No implementation found for '{0}'", info.word)
  446. : nls.localize('goToImplementation.generic.noResults', "No implementation found");
  447. }
  448. _getAlternativeCommand(editor) {
  449. return editor.getOption(53 /* EditorOption.gotoLocation */).alternativeImplementationCommand;
  450. }
  451. _getGoToPreference(editor) {
  452. return editor.getOption(53 /* EditorOption.gotoLocation */).multipleImplementations;
  453. }
  454. }
  455. registerGoToAction((_g = class GoToImplementationAction extends ImplementationAction {
  456. constructor() {
  457. super({
  458. openToSide: false,
  459. openInPeek: false,
  460. muteMessage: false
  461. }, {
  462. id: GoToImplementationAction.ID,
  463. label: nls.localize('actions.goToImplementation.label', "Go to Implementations"),
  464. alias: 'Go to Implementations',
  465. precondition: ContextKeyExpr.and(EditorContextKeys.hasImplementationProvider, EditorContextKeys.isInWalkThroughSnippet.toNegated()),
  466. kbOpts: {
  467. kbExpr: EditorContextKeys.editorTextFocus,
  468. primary: 2048 /* KeyMod.CtrlCmd */ | 70 /* KeyCode.F12 */,
  469. weight: 100 /* KeybindingWeight.EditorContrib */
  470. },
  471. contextMenuOpts: {
  472. group: 'navigation',
  473. order: 1.45
  474. }
  475. });
  476. }
  477. },
  478. _g.ID = 'editor.action.goToImplementation',
  479. _g));
  480. registerGoToAction((_h = class PeekImplementationAction extends ImplementationAction {
  481. constructor() {
  482. super({
  483. openToSide: false,
  484. openInPeek: true,
  485. muteMessage: false
  486. }, {
  487. id: PeekImplementationAction.ID,
  488. label: nls.localize('actions.peekImplementation.label', "Peek Implementations"),
  489. alias: 'Peek Implementations',
  490. precondition: ContextKeyExpr.and(EditorContextKeys.hasImplementationProvider, PeekContext.notInPeekEditor, EditorContextKeys.isInWalkThroughSnippet.toNegated()),
  491. kbOpts: {
  492. kbExpr: EditorContextKeys.editorTextFocus,
  493. primary: 2048 /* KeyMod.CtrlCmd */ | 1024 /* KeyMod.Shift */ | 70 /* KeyCode.F12 */,
  494. weight: 100 /* KeybindingWeight.EditorContrib */
  495. },
  496. contextMenuOpts: {
  497. menuId: MenuId.EditorContextPeek,
  498. group: 'peek',
  499. order: 5
  500. }
  501. });
  502. }
  503. },
  504. _h.ID = 'editor.action.peekImplementation',
  505. _h));
  506. //#endregion
  507. //#region --- REFERENCES
  508. class ReferencesAction extends SymbolNavigationAction {
  509. _getNoResultFoundMessage(info) {
  510. return info
  511. ? nls.localize('references.no', "No references found for '{0}'", info.word)
  512. : nls.localize('references.noGeneric', "No references found");
  513. }
  514. _getAlternativeCommand(editor) {
  515. return editor.getOption(53 /* EditorOption.gotoLocation */).alternativeReferenceCommand;
  516. }
  517. _getGoToPreference(editor) {
  518. return editor.getOption(53 /* EditorOption.gotoLocation */).multipleReferences;
  519. }
  520. }
  521. registerGoToAction(class GoToReferencesAction extends ReferencesAction {
  522. constructor() {
  523. super({
  524. openToSide: false,
  525. openInPeek: false,
  526. muteMessage: false
  527. }, {
  528. id: 'editor.action.goToReferences',
  529. label: nls.localize('goToReferences.label', "Go to References"),
  530. alias: 'Go to References',
  531. precondition: ContextKeyExpr.and(EditorContextKeys.hasReferenceProvider, PeekContext.notInPeekEditor, EditorContextKeys.isInWalkThroughSnippet.toNegated()),
  532. kbOpts: {
  533. kbExpr: EditorContextKeys.editorTextFocus,
  534. primary: 1024 /* KeyMod.Shift */ | 70 /* KeyCode.F12 */,
  535. weight: 100 /* KeybindingWeight.EditorContrib */
  536. },
  537. contextMenuOpts: {
  538. group: 'navigation',
  539. order: 1.45
  540. }
  541. });
  542. }
  543. _getLocationModel(languageFeaturesService, model, position, token) {
  544. return __awaiter(this, void 0, void 0, function* () {
  545. return new ReferencesModel(yield getReferencesAtPosition(languageFeaturesService.referenceProvider, model, position, true, token), nls.localize('ref.title', 'References'));
  546. });
  547. }
  548. });
  549. registerGoToAction(class PeekReferencesAction extends ReferencesAction {
  550. constructor() {
  551. super({
  552. openToSide: false,
  553. openInPeek: true,
  554. muteMessage: false
  555. }, {
  556. id: 'editor.action.referenceSearch.trigger',
  557. label: nls.localize('references.action.label', "Peek References"),
  558. alias: 'Peek References',
  559. precondition: ContextKeyExpr.and(EditorContextKeys.hasReferenceProvider, PeekContext.notInPeekEditor, EditorContextKeys.isInWalkThroughSnippet.toNegated()),
  560. contextMenuOpts: {
  561. menuId: MenuId.EditorContextPeek,
  562. group: 'peek',
  563. order: 6
  564. }
  565. });
  566. }
  567. _getLocationModel(languageFeaturesService, model, position, token) {
  568. return __awaiter(this, void 0, void 0, function* () {
  569. return new ReferencesModel(yield getReferencesAtPosition(languageFeaturesService.referenceProvider, model, position, false, token), nls.localize('ref.title', 'References'));
  570. });
  571. }
  572. });
  573. //#endregion
  574. //#region --- GENERIC goto symbols command
  575. class GenericGoToLocationAction extends SymbolNavigationAction {
  576. constructor(config, _references, _gotoMultipleBehaviour) {
  577. super(config, {
  578. id: 'editor.action.goToLocation',
  579. label: nls.localize('label.generic', "Go to Any Symbol"),
  580. alias: 'Go to Any Symbol',
  581. precondition: ContextKeyExpr.and(PeekContext.notInPeekEditor, EditorContextKeys.isInWalkThroughSnippet.toNegated()),
  582. });
  583. this._references = _references;
  584. this._gotoMultipleBehaviour = _gotoMultipleBehaviour;
  585. }
  586. _getLocationModel(languageFeaturesService, _model, _position, _token) {
  587. return __awaiter(this, void 0, void 0, function* () {
  588. return new ReferencesModel(this._references, nls.localize('generic.title', 'Locations'));
  589. });
  590. }
  591. _getNoResultFoundMessage(info) {
  592. return info && nls.localize('generic.noResult', "No results for '{0}'", info.word) || '';
  593. }
  594. _getGoToPreference(editor) {
  595. var _a;
  596. return (_a = this._gotoMultipleBehaviour) !== null && _a !== void 0 ? _a : editor.getOption(53 /* EditorOption.gotoLocation */).multipleReferences;
  597. }
  598. _getAlternativeCommand() { return ''; }
  599. }
  600. CommandsRegistry.registerCommand({
  601. id: 'editor.action.goToLocations',
  602. description: {
  603. description: 'Go to locations from a position in a file',
  604. args: [
  605. { name: 'uri', description: 'The text document in which to start', constraint: URI },
  606. { name: 'position', description: 'The position at which to start', constraint: corePosition.Position.isIPosition },
  607. { name: 'locations', description: 'An array of locations.', constraint: Array },
  608. { name: 'multiple', description: 'Define what to do when having multiple results, either `peek`, `gotoAndPeek`, or `goto' },
  609. { name: 'noResultsMessage', description: 'Human readable message that shows when locations is empty.' },
  610. ]
  611. },
  612. handler: (accessor, resource, position, references, multiple, noResultsMessage, openInPeek) => __awaiter(void 0, void 0, void 0, function* () {
  613. assertType(URI.isUri(resource));
  614. assertType(corePosition.Position.isIPosition(position));
  615. assertType(Array.isArray(references));
  616. assertType(typeof multiple === 'undefined' || typeof multiple === 'string');
  617. assertType(typeof openInPeek === 'undefined' || typeof openInPeek === 'boolean');
  618. const editorService = accessor.get(ICodeEditorService);
  619. const editor = yield editorService.openCodeEditor({ resource }, editorService.getFocusedCodeEditor());
  620. if (isCodeEditor(editor)) {
  621. editor.setPosition(position);
  622. editor.revealPositionInCenterIfOutsideViewport(position, 0 /* ScrollType.Smooth */);
  623. return editor.invokeWithinContext(accessor => {
  624. const command = new class extends GenericGoToLocationAction {
  625. _getNoResultFoundMessage(info) {
  626. return noResultsMessage || super._getNoResultFoundMessage(info);
  627. }
  628. }({
  629. muteMessage: !Boolean(noResultsMessage),
  630. openInPeek: Boolean(openInPeek),
  631. openToSide: false
  632. }, references, multiple);
  633. accessor.get(IInstantiationService).invokeFunction(command.run.bind(command), editor);
  634. });
  635. }
  636. })
  637. });
  638. CommandsRegistry.registerCommand({
  639. id: 'editor.action.peekLocations',
  640. description: {
  641. description: 'Peek locations from a position in a file',
  642. args: [
  643. { name: 'uri', description: 'The text document in which to start', constraint: URI },
  644. { name: 'position', description: 'The position at which to start', constraint: corePosition.Position.isIPosition },
  645. { name: 'locations', description: 'An array of locations.', constraint: Array },
  646. { name: 'multiple', description: 'Define what to do when having multiple results, either `peek`, `gotoAndPeek`, or `goto' },
  647. ]
  648. },
  649. handler: (accessor, resource, position, references, multiple) => __awaiter(void 0, void 0, void 0, function* () {
  650. accessor.get(ICommandService).executeCommand('editor.action.goToLocations', resource, position, references, multiple, undefined, true);
  651. })
  652. });
  653. //#endregion
  654. //#region --- REFERENCE search special commands
  655. CommandsRegistry.registerCommand({
  656. id: 'editor.action.findReferences',
  657. handler: (accessor, resource, position) => {
  658. assertType(URI.isUri(resource));
  659. assertType(corePosition.Position.isIPosition(position));
  660. const languageFeaturesService = accessor.get(ILanguageFeaturesService);
  661. const codeEditorService = accessor.get(ICodeEditorService);
  662. return codeEditorService.openCodeEditor({ resource }, codeEditorService.getFocusedCodeEditor()).then(control => {
  663. if (!isCodeEditor(control) || !control.hasModel()) {
  664. return undefined;
  665. }
  666. const controller = ReferencesController.get(control);
  667. if (!controller) {
  668. return undefined;
  669. }
  670. const references = createCancelablePromise(token => getReferencesAtPosition(languageFeaturesService.referenceProvider, control.getModel(), corePosition.Position.lift(position), false, token).then(references => new ReferencesModel(references, nls.localize('ref.title', 'References'))));
  671. const range = new Range(position.lineNumber, position.column, position.lineNumber, position.column);
  672. return Promise.resolve(controller.toggleWidget(range, references, false));
  673. });
  674. }
  675. });
  676. // use NEW command
  677. CommandsRegistry.registerCommandAlias('editor.action.showReferences', 'editor.action.peekLocations');
  678. //#endregion
  679. // -- unconditionally register goto-action
  680. MenuRegistry.appendMenuItems([
  681. {
  682. id: MenuId.MenubarGoMenu,
  683. item: {
  684. command: {
  685. id: 'editor.action.revealDefinition',
  686. title: nls.localize({ key: 'miGotoDefinition', comment: ['&& denotes a mnemonic'] }, "Go to &&Definition")
  687. },
  688. group: '4_symbol_nav',
  689. order: 2,
  690. },
  691. },
  692. {
  693. id: MenuId.MenubarGoMenu,
  694. item: {
  695. command: {
  696. id: 'editor.action.revealDeclaration',
  697. title: nls.localize({ key: 'miGotoDeclaration', comment: ['&& denotes a mnemonic'] }, "Go to &&Declaration")
  698. },
  699. group: '4_symbol_nav',
  700. order: 3,
  701. },
  702. },
  703. {
  704. id: MenuId.MenubarGoMenu,
  705. item: {
  706. command: {
  707. id: 'editor.action.goToTypeDefinition',
  708. title: nls.localize({ key: 'miGotoTypeDefinition', comment: ['&& denotes a mnemonic'] }, "Go to &&Type Definition")
  709. },
  710. group: '4_symbol_nav',
  711. order: 3,
  712. },
  713. },
  714. {
  715. id: MenuId.MenubarGoMenu,
  716. item: {
  717. command: {
  718. id: 'editor.action.goToImplementation',
  719. title: nls.localize({ key: 'miGotoImplementation', comment: ['&& denotes a mnemonic'] }, "Go to &&Implementations")
  720. },
  721. group: '4_symbol_nav',
  722. order: 4,
  723. },
  724. },
  725. {
  726. id: MenuId.MenubarGoMenu,
  727. item: {
  728. command: {
  729. id: 'editor.action.goToReferences',
  730. title: nls.localize({ key: 'miGotoReference', comment: ['&& denotes a mnemonic'] }, "Go to &&References")
  731. },
  732. group: '4_symbol_nav',
  733. order: 5,
  734. },
  735. },
  736. ]);