goToCommands.js 31 KB

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