a3858f385b987979ed47916b7b4db3dbbf516c6d7f7563612e616b0d51a5cd94f0c28bfcd4ac0d7c76737a2139b885fadeda5e057f57ed262541c6286be832 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  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 __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  6. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  7. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  8. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  9. return c > 3 && r && Object.defineProperty(target, key, r), r;
  10. };
  11. var __param = (this && this.__param) || function (paramIndex, decorator) {
  12. return function (target, key) { decorator(target, key, paramIndex); }
  13. };
  14. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  15. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  16. return new (P || (P = Promise))(function (resolve, reject) {
  17. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  18. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  19. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  20. step((generator = generator.apply(thisArg, _arguments || [])).next());
  21. });
  22. };
  23. import { Codicon } from '../../../../base/common/codicons.js';
  24. import { DisposableStore } from '../../../../base/common/lifecycle.js';
  25. import { EditorAction, EditorCommand, registerEditorAction, registerEditorCommand, registerEditorContribution } from '../../../browser/editorExtensions.js';
  26. import { ICodeEditorService } from '../../../browser/services/codeEditorService.js';
  27. import { Position } from '../../../common/core/position.js';
  28. import { Range } from '../../../common/core/range.js';
  29. import { EditorContextKeys } from '../../../common/editorContextKeys.js';
  30. import { IMarkerNavigationService } from './markerNavigationService.js';
  31. import * as nls from '../../../../nls.js';
  32. import { MenuId } from '../../../../platform/actions/common/actions.js';
  33. import { IContextKeyService, RawContextKey } from '../../../../platform/contextkey/common/contextkey.js';
  34. import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
  35. import { registerIcon } from '../../../../platform/theme/common/iconRegistry.js';
  36. import { MarkerNavigationWidget } from './gotoErrorWidget.js';
  37. let MarkerController = class MarkerController {
  38. constructor(editor, _markerNavigationService, _contextKeyService, _editorService, _instantiationService) {
  39. this._markerNavigationService = _markerNavigationService;
  40. this._contextKeyService = _contextKeyService;
  41. this._editorService = _editorService;
  42. this._instantiationService = _instantiationService;
  43. this._sessionDispoables = new DisposableStore();
  44. this._editor = editor;
  45. this._widgetVisible = CONTEXT_MARKERS_NAVIGATION_VISIBLE.bindTo(this._contextKeyService);
  46. }
  47. static get(editor) {
  48. return editor.getContribution(MarkerController.ID);
  49. }
  50. dispose() {
  51. this._cleanUp();
  52. this._sessionDispoables.dispose();
  53. }
  54. _cleanUp() {
  55. this._widgetVisible.reset();
  56. this._sessionDispoables.clear();
  57. this._widget = undefined;
  58. this._model = undefined;
  59. }
  60. _getOrCreateModel(uri) {
  61. if (this._model && this._model.matches(uri)) {
  62. return this._model;
  63. }
  64. let reusePosition = false;
  65. if (this._model) {
  66. reusePosition = true;
  67. this._cleanUp();
  68. }
  69. this._model = this._markerNavigationService.getMarkerList(uri);
  70. if (reusePosition) {
  71. this._model.move(true, this._editor.getModel(), this._editor.getPosition());
  72. }
  73. this._widget = this._instantiationService.createInstance(MarkerNavigationWidget, this._editor);
  74. this._widget.onDidClose(() => this.close(), this, this._sessionDispoables);
  75. this._widgetVisible.set(true);
  76. this._sessionDispoables.add(this._model);
  77. this._sessionDispoables.add(this._widget);
  78. // follow cursor
  79. this._sessionDispoables.add(this._editor.onDidChangeCursorPosition(e => {
  80. var _a, _b, _c;
  81. if (!((_a = this._model) === null || _a === void 0 ? void 0 : _a.selected) || !Range.containsPosition((_b = this._model) === null || _b === void 0 ? void 0 : _b.selected.marker, e.position)) {
  82. (_c = this._model) === null || _c === void 0 ? void 0 : _c.resetIndex();
  83. }
  84. }));
  85. // update markers
  86. this._sessionDispoables.add(this._model.onDidChange(() => {
  87. if (!this._widget || !this._widget.position || !this._model) {
  88. return;
  89. }
  90. const info = this._model.find(this._editor.getModel().uri, this._widget.position);
  91. if (info) {
  92. this._widget.updateMarker(info.marker);
  93. }
  94. else {
  95. this._widget.showStale();
  96. }
  97. }));
  98. // open related
  99. this._sessionDispoables.add(this._widget.onDidSelectRelatedInformation(related => {
  100. this._editorService.openCodeEditor({
  101. resource: related.resource,
  102. options: { pinned: true, revealIfOpened: true, selection: Range.lift(related).collapseToStart() }
  103. }, this._editor);
  104. this.close(false);
  105. }));
  106. this._sessionDispoables.add(this._editor.onDidChangeModel(() => this._cleanUp()));
  107. return this._model;
  108. }
  109. close(focusEditor = true) {
  110. this._cleanUp();
  111. if (focusEditor) {
  112. this._editor.focus();
  113. }
  114. }
  115. showAtMarker(marker) {
  116. if (this._editor.hasModel()) {
  117. const model = this._getOrCreateModel(this._editor.getModel().uri);
  118. model.resetIndex();
  119. model.move(true, this._editor.getModel(), new Position(marker.startLineNumber, marker.startColumn));
  120. if (model.selected) {
  121. this._widget.showAtMarker(model.selected.marker, model.selected.index, model.selected.total);
  122. }
  123. }
  124. }
  125. nagivate(next, multiFile) {
  126. var _a, _b;
  127. return __awaiter(this, void 0, void 0, function* () {
  128. if (this._editor.hasModel()) {
  129. const model = this._getOrCreateModel(multiFile ? undefined : this._editor.getModel().uri);
  130. model.move(next, this._editor.getModel(), this._editor.getPosition());
  131. if (!model.selected) {
  132. return;
  133. }
  134. if (model.selected.marker.resource.toString() !== this._editor.getModel().uri.toString()) {
  135. // show in different editor
  136. this._cleanUp();
  137. const otherEditor = yield this._editorService.openCodeEditor({
  138. resource: model.selected.marker.resource,
  139. options: { pinned: false, revealIfOpened: true, selectionRevealType: 2 /* TextEditorSelectionRevealType.NearTop */, selection: model.selected.marker }
  140. }, this._editor);
  141. if (otherEditor) {
  142. (_a = MarkerController.get(otherEditor)) === null || _a === void 0 ? void 0 : _a.close();
  143. (_b = MarkerController.get(otherEditor)) === null || _b === void 0 ? void 0 : _b.nagivate(next, multiFile);
  144. }
  145. }
  146. else {
  147. // show in this editor
  148. this._widget.showAtMarker(model.selected.marker, model.selected.index, model.selected.total);
  149. }
  150. }
  151. });
  152. }
  153. };
  154. MarkerController.ID = 'editor.contrib.markerController';
  155. MarkerController = __decorate([
  156. __param(1, IMarkerNavigationService),
  157. __param(2, IContextKeyService),
  158. __param(3, ICodeEditorService),
  159. __param(4, IInstantiationService)
  160. ], MarkerController);
  161. export { MarkerController };
  162. class MarkerNavigationAction extends EditorAction {
  163. constructor(_next, _multiFile, opts) {
  164. super(opts);
  165. this._next = _next;
  166. this._multiFile = _multiFile;
  167. }
  168. run(_accessor, editor) {
  169. var _a;
  170. return __awaiter(this, void 0, void 0, function* () {
  171. if (editor.hasModel()) {
  172. (_a = MarkerController.get(editor)) === null || _a === void 0 ? void 0 : _a.nagivate(this._next, this._multiFile);
  173. }
  174. });
  175. }
  176. }
  177. export class NextMarkerAction extends MarkerNavigationAction {
  178. constructor() {
  179. super(true, false, {
  180. id: NextMarkerAction.ID,
  181. label: NextMarkerAction.LABEL,
  182. alias: 'Go to Next Problem (Error, Warning, Info)',
  183. precondition: undefined,
  184. kbOpts: {
  185. kbExpr: EditorContextKeys.focus,
  186. primary: 512 /* KeyMod.Alt */ | 66 /* KeyCode.F8 */,
  187. weight: 100 /* KeybindingWeight.EditorContrib */
  188. },
  189. menuOpts: {
  190. menuId: MarkerNavigationWidget.TitleMenu,
  191. title: NextMarkerAction.LABEL,
  192. icon: registerIcon('marker-navigation-next', Codicon.arrowDown, nls.localize('nextMarkerIcon', 'Icon for goto next marker.')),
  193. group: 'navigation',
  194. order: 1
  195. }
  196. });
  197. }
  198. }
  199. NextMarkerAction.ID = 'editor.action.marker.next';
  200. NextMarkerAction.LABEL = nls.localize('markerAction.next.label', "Go to Next Problem (Error, Warning, Info)");
  201. class PrevMarkerAction extends MarkerNavigationAction {
  202. constructor() {
  203. super(false, false, {
  204. id: PrevMarkerAction.ID,
  205. label: PrevMarkerAction.LABEL,
  206. alias: 'Go to Previous Problem (Error, Warning, Info)',
  207. precondition: undefined,
  208. kbOpts: {
  209. kbExpr: EditorContextKeys.focus,
  210. primary: 1024 /* KeyMod.Shift */ | 512 /* KeyMod.Alt */ | 66 /* KeyCode.F8 */,
  211. weight: 100 /* KeybindingWeight.EditorContrib */
  212. },
  213. menuOpts: {
  214. menuId: MarkerNavigationWidget.TitleMenu,
  215. title: PrevMarkerAction.LABEL,
  216. icon: registerIcon('marker-navigation-previous', Codicon.arrowUp, nls.localize('previousMarkerIcon', 'Icon for goto previous marker.')),
  217. group: 'navigation',
  218. order: 2
  219. }
  220. });
  221. }
  222. }
  223. PrevMarkerAction.ID = 'editor.action.marker.prev';
  224. PrevMarkerAction.LABEL = nls.localize('markerAction.previous.label', "Go to Previous Problem (Error, Warning, Info)");
  225. class NextMarkerInFilesAction extends MarkerNavigationAction {
  226. constructor() {
  227. super(true, true, {
  228. id: 'editor.action.marker.nextInFiles',
  229. label: nls.localize('markerAction.nextInFiles.label', "Go to Next Problem in Files (Error, Warning, Info)"),
  230. alias: 'Go to Next Problem in Files (Error, Warning, Info)',
  231. precondition: undefined,
  232. kbOpts: {
  233. kbExpr: EditorContextKeys.focus,
  234. primary: 66 /* KeyCode.F8 */,
  235. weight: 100 /* KeybindingWeight.EditorContrib */
  236. },
  237. menuOpts: {
  238. menuId: MenuId.MenubarGoMenu,
  239. title: nls.localize({ key: 'miGotoNextProblem', comment: ['&& denotes a mnemonic'] }, "Next &&Problem"),
  240. group: '6_problem_nav',
  241. order: 1
  242. }
  243. });
  244. }
  245. }
  246. class PrevMarkerInFilesAction extends MarkerNavigationAction {
  247. constructor() {
  248. super(false, true, {
  249. id: 'editor.action.marker.prevInFiles',
  250. label: nls.localize('markerAction.previousInFiles.label', "Go to Previous Problem in Files (Error, Warning, Info)"),
  251. alias: 'Go to Previous Problem in Files (Error, Warning, Info)',
  252. precondition: undefined,
  253. kbOpts: {
  254. kbExpr: EditorContextKeys.focus,
  255. primary: 1024 /* KeyMod.Shift */ | 66 /* KeyCode.F8 */,
  256. weight: 100 /* KeybindingWeight.EditorContrib */
  257. },
  258. menuOpts: {
  259. menuId: MenuId.MenubarGoMenu,
  260. title: nls.localize({ key: 'miGotoPreviousProblem', comment: ['&& denotes a mnemonic'] }, "Previous &&Problem"),
  261. group: '6_problem_nav',
  262. order: 2
  263. }
  264. });
  265. }
  266. }
  267. registerEditorContribution(MarkerController.ID, MarkerController);
  268. registerEditorAction(NextMarkerAction);
  269. registerEditorAction(PrevMarkerAction);
  270. registerEditorAction(NextMarkerInFilesAction);
  271. registerEditorAction(PrevMarkerInFilesAction);
  272. const CONTEXT_MARKERS_NAVIGATION_VISIBLE = new RawContextKey('markersNavigationVisible', false);
  273. const MarkerCommand = EditorCommand.bindToContribution(MarkerController.get);
  274. registerEditorCommand(new MarkerCommand({
  275. id: 'closeMarkersNavigation',
  276. precondition: CONTEXT_MARKERS_NAVIGATION_VISIBLE,
  277. handler: x => x.close(),
  278. kbOpts: {
  279. weight: 100 /* KeybindingWeight.EditorContrib */ + 50,
  280. kbExpr: EditorContextKeys.focus,
  281. primary: 9 /* KeyCode.Escape */,
  282. secondary: [1024 /* KeyMod.Shift */ | 9 /* KeyCode.Escape */]
  283. }
  284. }));