| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496 |
- /*---------------------------------------------------------------------------------------------
- * 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 * as dom from '../../../../../base/browser/dom.js';
- import { Sizing, SplitView } from '../../../../../base/browser/ui/splitview/splitview.js';
- import { Color } from '../../../../../base/common/color.js';
- import { Emitter, Event } from '../../../../../base/common/event.js';
- import { DisposableStore, dispose } from '../../../../../base/common/lifecycle.js';
- import { Schemas } from '../../../../../base/common/network.js';
- import { basenameOrAuthority, dirname } from '../../../../../base/common/resources.js';
- import './referencesWidget.css';
- import { EmbeddedCodeEditorWidget } from '../../../../browser/widget/embeddedCodeEditorWidget.js';
- import { Range } from '../../../../common/core/range.js';
- import { ModelDecorationOptions, TextModel } from '../../../../common/model/textModel.js';
- import { ILanguageConfigurationService } from '../../../../common/languages/languageConfigurationRegistry.js';
- import { PLAINTEXT_LANGUAGE_ID } from '../../../../common/languages/modesRegistry.js';
- import { ILanguageService } from '../../../../common/languages/language.js';
- import { ITextModelService } from '../../../../common/services/resolverService.js';
- import { AccessibilityProvider, DataSource, Delegate, FileReferencesRenderer, IdentityProvider, OneReferenceRenderer, StringRepresentationProvider } from './referencesTree.js';
- import * as peekView from '../../../peekView/browser/peekView.js';
- import * as nls from '../../../../../nls.js';
- import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js';
- import { IKeybindingService } from '../../../../../platform/keybinding/common/keybinding.js';
- import { ILabelService } from '../../../../../platform/label/common/label.js';
- import { WorkbenchAsyncDataTree } from '../../../../../platform/list/browser/listService.js';
- import { IThemeService } from '../../../../../platform/theme/common/themeService.js';
- import { IUndoRedoService } from '../../../../../platform/undoRedo/common/undoRedo.js';
- import { FileReferences, OneReference } from '../referencesModel.js';
- class DecorationsManager {
- constructor(_editor, _model) {
- this._editor = _editor;
- this._model = _model;
- this._decorations = new Map();
- this._decorationIgnoreSet = new Set();
- this._callOnDispose = new DisposableStore();
- this._callOnModelChange = new DisposableStore();
- this._callOnDispose.add(this._editor.onDidChangeModel(() => this._onModelChanged()));
- this._onModelChanged();
- }
- dispose() {
- this._callOnModelChange.dispose();
- this._callOnDispose.dispose();
- this.removeDecorations();
- }
- _onModelChanged() {
- this._callOnModelChange.clear();
- const model = this._editor.getModel();
- if (!model) {
- return;
- }
- for (const ref of this._model.references) {
- if (ref.uri.toString() === model.uri.toString()) {
- this._addDecorations(ref.parent);
- return;
- }
- }
- }
- _addDecorations(reference) {
- if (!this._editor.hasModel()) {
- return;
- }
- this._callOnModelChange.add(this._editor.getModel().onDidChangeDecorations(() => this._onDecorationChanged()));
- const newDecorations = [];
- const newDecorationsActualIndex = [];
- for (let i = 0, len = reference.children.length; i < len; i++) {
- const oneReference = reference.children[i];
- if (this._decorationIgnoreSet.has(oneReference.id)) {
- continue;
- }
- if (oneReference.uri.toString() !== this._editor.getModel().uri.toString()) {
- continue;
- }
- newDecorations.push({
- range: oneReference.range,
- options: DecorationsManager.DecorationOptions
- });
- newDecorationsActualIndex.push(i);
- }
- this._editor.changeDecorations((changeAccessor) => {
- const decorations = changeAccessor.deltaDecorations([], newDecorations);
- for (let i = 0; i < decorations.length; i++) {
- this._decorations.set(decorations[i], reference.children[newDecorationsActualIndex[i]]);
- }
- });
- }
- _onDecorationChanged() {
- const toRemove = [];
- const model = this._editor.getModel();
- if (!model) {
- return;
- }
- for (const [decorationId, reference] of this._decorations) {
- const newRange = model.getDecorationRange(decorationId);
- if (!newRange) {
- continue;
- }
- let ignore = false;
- if (Range.equalsRange(newRange, reference.range)) {
- continue;
- }
- if (Range.spansMultipleLines(newRange)) {
- ignore = true;
- }
- else {
- const lineLength = reference.range.endColumn - reference.range.startColumn;
- const newLineLength = newRange.endColumn - newRange.startColumn;
- if (lineLength !== newLineLength) {
- ignore = true;
- }
- }
- if (ignore) {
- this._decorationIgnoreSet.add(reference.id);
- toRemove.push(decorationId);
- }
- else {
- reference.range = newRange;
- }
- }
- for (let i = 0, len = toRemove.length; i < len; i++) {
- this._decorations.delete(toRemove[i]);
- }
- this._editor.removeDecorations(toRemove);
- }
- removeDecorations() {
- this._editor.removeDecorations([...this._decorations.keys()]);
- this._decorations.clear();
- }
- }
- DecorationsManager.DecorationOptions = ModelDecorationOptions.register({
- description: 'reference-decoration',
- stickiness: 1 /* TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges */,
- className: 'reference-decoration'
- });
- export class LayoutData {
- constructor() {
- this.ratio = 0.7;
- this.heightInLines = 18;
- }
- static fromJSON(raw) {
- let ratio;
- let heightInLines;
- try {
- const data = JSON.parse(raw);
- ratio = data.ratio;
- heightInLines = data.heightInLines;
- }
- catch (_a) {
- //
- }
- return {
- ratio: ratio || 0.7,
- heightInLines: heightInLines || 18
- };
- }
- }
- class ReferencesTree extends WorkbenchAsyncDataTree {
- }
- /**
- * ZoneWidget that is shown inside the editor
- */
- let ReferenceWidget = class ReferenceWidget extends peekView.PeekViewWidget {
- constructor(editor, _defaultTreeKeyboardSupport, layoutData, themeService, _textModelResolverService, _instantiationService, _peekViewService, _uriLabel, _undoRedoService, _keybindingService, _languageService, _languageConfigurationService) {
- super(editor, { showFrame: false, showArrow: true, isResizeable: true, isAccessible: true, supportOnTitleClick: true }, _instantiationService);
- this._defaultTreeKeyboardSupport = _defaultTreeKeyboardSupport;
- this.layoutData = layoutData;
- this._textModelResolverService = _textModelResolverService;
- this._instantiationService = _instantiationService;
- this._peekViewService = _peekViewService;
- this._uriLabel = _uriLabel;
- this._undoRedoService = _undoRedoService;
- this._keybindingService = _keybindingService;
- this._languageService = _languageService;
- this._languageConfigurationService = _languageConfigurationService;
- this._disposeOnNewModel = new DisposableStore();
- this._callOnDispose = new DisposableStore();
- this._onDidSelectReference = new Emitter();
- this.onDidSelectReference = this._onDidSelectReference.event;
- this._dim = new dom.Dimension(0, 0);
- this._applyTheme(themeService.getColorTheme());
- this._callOnDispose.add(themeService.onDidColorThemeChange(this._applyTheme.bind(this)));
- this._peekViewService.addExclusiveWidget(editor, this);
- this.create();
- }
- dispose() {
- this.setModel(undefined);
- this._callOnDispose.dispose();
- this._disposeOnNewModel.dispose();
- dispose(this._preview);
- dispose(this._previewNotAvailableMessage);
- dispose(this._tree);
- dispose(this._previewModelReference);
- this._splitView.dispose();
- super.dispose();
- }
- _applyTheme(theme) {
- const borderColor = theme.getColor(peekView.peekViewBorder) || Color.transparent;
- this.style({
- arrowColor: borderColor,
- frameColor: borderColor,
- headerBackgroundColor: theme.getColor(peekView.peekViewTitleBackground) || Color.transparent,
- primaryHeadingColor: theme.getColor(peekView.peekViewTitleForeground),
- secondaryHeadingColor: theme.getColor(peekView.peekViewTitleInfoForeground)
- });
- }
- show(where) {
- super.show(where, this.layoutData.heightInLines || 18);
- }
- focusOnReferenceTree() {
- this._tree.domFocus();
- }
- focusOnPreviewEditor() {
- this._preview.focus();
- }
- isPreviewEditorFocused() {
- return this._preview.hasTextFocus();
- }
- _onTitleClick(e) {
- if (this._preview && this._preview.getModel()) {
- this._onDidSelectReference.fire({
- element: this._getFocusedReference(),
- kind: e.ctrlKey || e.metaKey || e.altKey ? 'side' : 'open',
- source: 'title'
- });
- }
- }
- _fillBody(containerElement) {
- this.setCssClass('reference-zone-widget');
- // message pane
- this._messageContainer = dom.append(containerElement, dom.$('div.messages'));
- dom.hide(this._messageContainer);
- this._splitView = new SplitView(containerElement, { orientation: 1 /* Orientation.HORIZONTAL */ });
- // editor
- this._previewContainer = dom.append(containerElement, dom.$('div.preview.inline'));
- const options = {
- scrollBeyondLastLine: false,
- scrollbar: {
- verticalScrollbarSize: 14,
- horizontal: 'auto',
- useShadows: true,
- verticalHasArrows: false,
- horizontalHasArrows: false,
- alwaysConsumeMouseWheel: false
- },
- overviewRulerLanes: 2,
- fixedOverflowWidgets: true,
- minimap: {
- enabled: false
- }
- };
- this._preview = this._instantiationService.createInstance(EmbeddedCodeEditorWidget, this._previewContainer, options, this.editor);
- dom.hide(this._previewContainer);
- this._previewNotAvailableMessage = new TextModel(nls.localize('missingPreviewMessage', "no preview available"), PLAINTEXT_LANGUAGE_ID, TextModel.DEFAULT_CREATION_OPTIONS, null, this._undoRedoService, this._languageService, this._languageConfigurationService);
- // tree
- this._treeContainer = dom.append(containerElement, dom.$('div.ref-tree.inline'));
- const treeOptions = {
- keyboardSupport: this._defaultTreeKeyboardSupport,
- accessibilityProvider: new AccessibilityProvider(),
- keyboardNavigationLabelProvider: this._instantiationService.createInstance(StringRepresentationProvider),
- identityProvider: new IdentityProvider(),
- openOnSingleClick: true,
- selectionNavigation: true,
- overrideStyles: {
- listBackground: peekView.peekViewResultsBackground
- }
- };
- if (this._defaultTreeKeyboardSupport) {
- // the tree will consume `Escape` and prevent the widget from closing
- this._callOnDispose.add(dom.addStandardDisposableListener(this._treeContainer, 'keydown', (e) => {
- if (e.equals(9 /* KeyCode.Escape */)) {
- this._keybindingService.dispatchEvent(e, e.target);
- e.stopPropagation();
- }
- }, true));
- }
- this._tree = this._instantiationService.createInstance(ReferencesTree, 'ReferencesWidget', this._treeContainer, new Delegate(), [
- this._instantiationService.createInstance(FileReferencesRenderer),
- this._instantiationService.createInstance(OneReferenceRenderer),
- ], this._instantiationService.createInstance(DataSource), treeOptions);
- // split stuff
- this._splitView.addView({
- onDidChange: Event.None,
- element: this._previewContainer,
- minimumSize: 200,
- maximumSize: Number.MAX_VALUE,
- layout: (width) => {
- this._preview.layout({ height: this._dim.height, width });
- }
- }, Sizing.Distribute);
- this._splitView.addView({
- onDidChange: Event.None,
- element: this._treeContainer,
- minimumSize: 100,
- maximumSize: Number.MAX_VALUE,
- layout: (width) => {
- this._treeContainer.style.height = `${this._dim.height}px`;
- this._treeContainer.style.width = `${width}px`;
- this._tree.layout(this._dim.height, width);
- }
- }, Sizing.Distribute);
- this._disposables.add(this._splitView.onDidSashChange(() => {
- if (this._dim.width) {
- this.layoutData.ratio = this._splitView.getViewSize(0) / this._dim.width;
- }
- }, undefined));
- // listen on selection and focus
- const onEvent = (element, kind) => {
- if (element instanceof OneReference) {
- if (kind === 'show') {
- this._revealReference(element, false);
- }
- this._onDidSelectReference.fire({ element, kind, source: 'tree' });
- }
- };
- this._tree.onDidOpen(e => {
- if (e.sideBySide) {
- onEvent(e.element, 'side');
- }
- else if (e.editorOptions.pinned) {
- onEvent(e.element, 'goto');
- }
- else {
- onEvent(e.element, 'show');
- }
- });
- dom.hide(this._treeContainer);
- }
- _onWidth(width) {
- if (this._dim) {
- this._doLayoutBody(this._dim.height, width);
- }
- }
- _doLayoutBody(heightInPixel, widthInPixel) {
- super._doLayoutBody(heightInPixel, widthInPixel);
- this._dim = new dom.Dimension(widthInPixel, heightInPixel);
- this.layoutData.heightInLines = this._viewZone ? this._viewZone.heightInLines : this.layoutData.heightInLines;
- this._splitView.layout(widthInPixel);
- this._splitView.resizeView(0, widthInPixel * this.layoutData.ratio);
- }
- setSelection(selection) {
- return this._revealReference(selection, true).then(() => {
- if (!this._model) {
- // disposed
- return;
- }
- // show in tree
- this._tree.setSelection([selection]);
- this._tree.setFocus([selection]);
- });
- }
- setModel(newModel) {
- // clean up
- this._disposeOnNewModel.clear();
- this._model = newModel;
- if (this._model) {
- return this._onNewModel();
- }
- return Promise.resolve();
- }
- _onNewModel() {
- if (!this._model) {
- return Promise.resolve(undefined);
- }
- if (this._model.isEmpty) {
- this.setTitle('');
- this._messageContainer.innerText = nls.localize('noResults', "No results");
- dom.show(this._messageContainer);
- return Promise.resolve(undefined);
- }
- dom.hide(this._messageContainer);
- this._decorationsManager = new DecorationsManager(this._preview, this._model);
- this._disposeOnNewModel.add(this._decorationsManager);
- // listen on model changes
- this._disposeOnNewModel.add(this._model.onDidChangeReferenceRange(reference => this._tree.rerender(reference)));
- // listen on editor
- this._disposeOnNewModel.add(this._preview.onMouseDown(e => {
- const { event, target } = e;
- if (event.detail !== 2) {
- return;
- }
- const element = this._getFocusedReference();
- if (!element) {
- return;
- }
- this._onDidSelectReference.fire({
- element: { uri: element.uri, range: target.range },
- kind: (event.ctrlKey || event.metaKey || event.altKey) ? 'side' : 'open',
- source: 'editor'
- });
- }));
- // make sure things are rendered
- this.container.classList.add('results-loaded');
- dom.show(this._treeContainer);
- dom.show(this._previewContainer);
- this._splitView.layout(this._dim.width);
- this.focusOnReferenceTree();
- // pick input and a reference to begin with
- return this._tree.setInput(this._model.groups.length === 1 ? this._model.groups[0] : this._model);
- }
- _getFocusedReference() {
- const [element] = this._tree.getFocus();
- if (element instanceof OneReference) {
- return element;
- }
- else if (element instanceof FileReferences) {
- if (element.children.length > 0) {
- return element.children[0];
- }
- }
- return undefined;
- }
- revealReference(reference) {
- return __awaiter(this, void 0, void 0, function* () {
- yield this._revealReference(reference, false);
- this._onDidSelectReference.fire({ element: reference, kind: 'goto', source: 'tree' });
- });
- }
- _revealReference(reference, revealParent) {
- return __awaiter(this, void 0, void 0, function* () {
- // check if there is anything to do...
- if (this._revealedReference === reference) {
- return;
- }
- this._revealedReference = reference;
- // Update widget header
- if (reference.uri.scheme !== Schemas.inMemory) {
- this.setTitle(basenameOrAuthority(reference.uri), this._uriLabel.getUriLabel(dirname(reference.uri)));
- }
- else {
- this.setTitle(nls.localize('peekView.alternateTitle', "References"));
- }
- const promise = this._textModelResolverService.createModelReference(reference.uri);
- if (this._tree.getInput() === reference.parent) {
- this._tree.reveal(reference);
- }
- else {
- if (revealParent) {
- this._tree.reveal(reference.parent);
- }
- yield this._tree.expand(reference.parent);
- this._tree.reveal(reference);
- }
- const ref = yield promise;
- if (!this._model) {
- // disposed
- ref.dispose();
- return;
- }
- dispose(this._previewModelReference);
- // show in editor
- const model = ref.object;
- if (model) {
- const scrollType = this._preview.getModel() === model.textEditorModel ? 0 /* ScrollType.Smooth */ : 1 /* ScrollType.Immediate */;
- const sel = Range.lift(reference.range).collapseToStart();
- this._previewModelReference = ref;
- this._preview.setModel(model.textEditorModel);
- this._preview.setSelection(sel);
- this._preview.revealRangeInCenter(sel, scrollType);
- }
- else {
- this._preview.setModel(this._previewNotAvailableMessage);
- ref.dispose();
- }
- });
- }
- };
- ReferenceWidget = __decorate([
- __param(3, IThemeService),
- __param(4, ITextModelService),
- __param(5, IInstantiationService),
- __param(6, peekView.IPeekViewService),
- __param(7, ILabelService),
- __param(8, IUndoRedoService),
- __param(9, IKeybindingService),
- __param(10, ILanguageService),
- __param(11, ILanguageConfigurationService)
- ], ReferenceWidget);
- export { ReferenceWidget };
|