/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 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; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { Codicon } from '../../../../base/common/codicons.js'; import { DisposableStore } from '../../../../base/common/lifecycle.js'; import { EditorAction, EditorCommand, registerEditorAction, registerEditorCommand, registerEditorContribution } from '../../../browser/editorExtensions.js'; import { ICodeEditorService } from '../../../browser/services/codeEditorService.js'; import { Position } from '../../../common/core/position.js'; import { Range } from '../../../common/core/range.js'; import { EditorContextKeys } from '../../../common/editorContextKeys.js'; import { IMarkerNavigationService } from './markerNavigationService.js'; import * as nls from '../../../../nls.js'; import { MenuId } from '../../../../platform/actions/common/actions.js'; import { IContextKeyService, RawContextKey } from '../../../../platform/contextkey/common/contextkey.js'; import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js'; import { registerIcon } from '../../../../platform/theme/common/iconRegistry.js'; import { MarkerNavigationWidget } from './gotoErrorWidget.js'; let MarkerController = class MarkerController { constructor(editor, _markerNavigationService, _contextKeyService, _editorService, _instantiationService) { this._markerNavigationService = _markerNavigationService; this._contextKeyService = _contextKeyService; this._editorService = _editorService; this._instantiationService = _instantiationService; this._sessionDispoables = new DisposableStore(); this._editor = editor; this._widgetVisible = CONTEXT_MARKERS_NAVIGATION_VISIBLE.bindTo(this._contextKeyService); } static get(editor) { return editor.getContribution(MarkerController.ID); } dispose() { this._cleanUp(); this._sessionDispoables.dispose(); } _cleanUp() { this._widgetVisible.reset(); this._sessionDispoables.clear(); this._widget = undefined; this._model = undefined; } _getOrCreateModel(uri) { if (this._model && this._model.matches(uri)) { return this._model; } let reusePosition = false; if (this._model) { reusePosition = true; this._cleanUp(); } this._model = this._markerNavigationService.getMarkerList(uri); if (reusePosition) { this._model.move(true, this._editor.getModel(), this._editor.getPosition()); } this._widget = this._instantiationService.createInstance(MarkerNavigationWidget, this._editor); this._widget.onDidClose(() => this.close(), this, this._sessionDispoables); this._widgetVisible.set(true); this._sessionDispoables.add(this._model); this._sessionDispoables.add(this._widget); // follow cursor this._sessionDispoables.add(this._editor.onDidChangeCursorPosition(e => { var _a, _b, _c; 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)) { (_c = this._model) === null || _c === void 0 ? void 0 : _c.resetIndex(); } })); // update markers this._sessionDispoables.add(this._model.onDidChange(() => { if (!this._widget || !this._widget.position || !this._model) { return; } const info = this._model.find(this._editor.getModel().uri, this._widget.position); if (info) { this._widget.updateMarker(info.marker); } else { this._widget.showStale(); } })); // open related this._sessionDispoables.add(this._widget.onDidSelectRelatedInformation(related => { this._editorService.openCodeEditor({ resource: related.resource, options: { pinned: true, revealIfOpened: true, selection: Range.lift(related).collapseToStart() } }, this._editor); this.close(false); })); this._sessionDispoables.add(this._editor.onDidChangeModel(() => this._cleanUp())); return this._model; } close(focusEditor = true) { this._cleanUp(); if (focusEditor) { this._editor.focus(); } } showAtMarker(marker) { if (this._editor.hasModel()) { const model = this._getOrCreateModel(this._editor.getModel().uri); model.resetIndex(); model.move(true, this._editor.getModel(), new Position(marker.startLineNumber, marker.startColumn)); if (model.selected) { this._widget.showAtMarker(model.selected.marker, model.selected.index, model.selected.total); } } } nagivate(next, multiFile) { var _a, _b; return __awaiter(this, void 0, void 0, function* () { if (this._editor.hasModel()) { const model = this._getOrCreateModel(multiFile ? undefined : this._editor.getModel().uri); model.move(next, this._editor.getModel(), this._editor.getPosition()); if (!model.selected) { return; } if (model.selected.marker.resource.toString() !== this._editor.getModel().uri.toString()) { // show in different editor this._cleanUp(); const otherEditor = yield this._editorService.openCodeEditor({ resource: model.selected.marker.resource, options: { pinned: false, revealIfOpened: true, selectionRevealType: 2 /* TextEditorSelectionRevealType.NearTop */, selection: model.selected.marker } }, this._editor); if (otherEditor) { (_a = MarkerController.get(otherEditor)) === null || _a === void 0 ? void 0 : _a.close(); (_b = MarkerController.get(otherEditor)) === null || _b === void 0 ? void 0 : _b.nagivate(next, multiFile); } } else { // show in this editor this._widget.showAtMarker(model.selected.marker, model.selected.index, model.selected.total); } } }); } }; MarkerController.ID = 'editor.contrib.markerController'; MarkerController = __decorate([ __param(1, IMarkerNavigationService), __param(2, IContextKeyService), __param(3, ICodeEditorService), __param(4, IInstantiationService) ], MarkerController); export { MarkerController }; class MarkerNavigationAction extends EditorAction { constructor(_next, _multiFile, opts) { super(opts); this._next = _next; this._multiFile = _multiFile; } run(_accessor, editor) { var _a; return __awaiter(this, void 0, void 0, function* () { if (editor.hasModel()) { (_a = MarkerController.get(editor)) === null || _a === void 0 ? void 0 : _a.nagivate(this._next, this._multiFile); } }); } } export class NextMarkerAction extends MarkerNavigationAction { constructor() { super(true, false, { id: NextMarkerAction.ID, label: NextMarkerAction.LABEL, alias: 'Go to Next Problem (Error, Warning, Info)', precondition: undefined, kbOpts: { kbExpr: EditorContextKeys.focus, primary: 512 /* KeyMod.Alt */ | 66 /* KeyCode.F8 */, weight: 100 /* KeybindingWeight.EditorContrib */ }, menuOpts: { menuId: MarkerNavigationWidget.TitleMenu, title: NextMarkerAction.LABEL, icon: registerIcon('marker-navigation-next', Codicon.arrowDown, nls.localize('nextMarkerIcon', 'Icon for goto next marker.')), group: 'navigation', order: 1 } }); } } NextMarkerAction.ID = 'editor.action.marker.next'; NextMarkerAction.LABEL = nls.localize('markerAction.next.label', "Go to Next Problem (Error, Warning, Info)"); class PrevMarkerAction extends MarkerNavigationAction { constructor() { super(false, false, { id: PrevMarkerAction.ID, label: PrevMarkerAction.LABEL, alias: 'Go to Previous Problem (Error, Warning, Info)', precondition: undefined, kbOpts: { kbExpr: EditorContextKeys.focus, primary: 1024 /* KeyMod.Shift */ | 512 /* KeyMod.Alt */ | 66 /* KeyCode.F8 */, weight: 100 /* KeybindingWeight.EditorContrib */ }, menuOpts: { menuId: MarkerNavigationWidget.TitleMenu, title: PrevMarkerAction.LABEL, icon: registerIcon('marker-navigation-previous', Codicon.arrowUp, nls.localize('previousMarkerIcon', 'Icon for goto previous marker.')), group: 'navigation', order: 2 } }); } } PrevMarkerAction.ID = 'editor.action.marker.prev'; PrevMarkerAction.LABEL = nls.localize('markerAction.previous.label', "Go to Previous Problem (Error, Warning, Info)"); class NextMarkerInFilesAction extends MarkerNavigationAction { constructor() { super(true, true, { id: 'editor.action.marker.nextInFiles', label: nls.localize('markerAction.nextInFiles.label', "Go to Next Problem in Files (Error, Warning, Info)"), alias: 'Go to Next Problem in Files (Error, Warning, Info)', precondition: undefined, kbOpts: { kbExpr: EditorContextKeys.focus, primary: 66 /* KeyCode.F8 */, weight: 100 /* KeybindingWeight.EditorContrib */ }, menuOpts: { menuId: MenuId.MenubarGoMenu, title: nls.localize({ key: 'miGotoNextProblem', comment: ['&& denotes a mnemonic'] }, "Next &&Problem"), group: '6_problem_nav', order: 1 } }); } } class PrevMarkerInFilesAction extends MarkerNavigationAction { constructor() { super(false, true, { id: 'editor.action.marker.prevInFiles', label: nls.localize('markerAction.previousInFiles.label', "Go to Previous Problem in Files (Error, Warning, Info)"), alias: 'Go to Previous Problem in Files (Error, Warning, Info)', precondition: undefined, kbOpts: { kbExpr: EditorContextKeys.focus, primary: 1024 /* KeyMod.Shift */ | 66 /* KeyCode.F8 */, weight: 100 /* KeybindingWeight.EditorContrib */ }, menuOpts: { menuId: MenuId.MenubarGoMenu, title: nls.localize({ key: 'miGotoPreviousProblem', comment: ['&& denotes a mnemonic'] }, "Previous &&Problem"), group: '6_problem_nav', order: 2 } }); } } registerEditorContribution(MarkerController.ID, MarkerController); registerEditorAction(NextMarkerAction); registerEditorAction(PrevMarkerAction); registerEditorAction(NextMarkerInFilesAction); registerEditorAction(PrevMarkerInFilesAction); const CONTEXT_MARKERS_NAVIGATION_VISIBLE = new RawContextKey('markersNavigationVisible', false); const MarkerCommand = EditorCommand.bindToContribution(MarkerController.get); registerEditorCommand(new MarkerCommand({ id: 'closeMarkersNavigation', precondition: CONTEXT_MARKERS_NAVIGATION_VISIBLE, handler: x => x.close(), kbOpts: { weight: 100 /* KeybindingWeight.EditorContrib */ + 50, kbExpr: EditorContextKeys.focus, primary: 9 /* KeyCode.Escape */, secondary: [1024 /* KeyMod.Shift */ | 9 /* KeyCode.Escape */] } }));