/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { ITextModel } from 'vs/editor/common/model'; import { onUnexpectedExternalError } from 'vs/base/common/errors'; import { mergeSort } from 'vs/base/common/arrays'; import { Event } from 'vs/base/common/event'; import { CancellationToken } from 'vs/base/common/cancellation'; import { LanguageFeatureRegistry } from 'vs/editor/common/modes/languageFeatureRegistry'; import { ProviderResult } from 'vs/editor/common/modes'; import { IRange } from 'vs/editor/common/core/range'; export interface ICodeInsetSymbol { id: string; range: IRange; height?: number; } export interface CodeInsetProvider { onDidChange?: Event; provideCodeInsets(model: ITextModel, token: CancellationToken): ProviderResult; resolveCodeInset(model: ITextModel, codeInset: ICodeInsetSymbol, token: CancellationToken): ProviderResult; } export const CodeInsetProviderRegistry = new LanguageFeatureRegistry(); export interface ICodeInsetData { symbol: ICodeInsetSymbol; provider: CodeInsetProvider; resolved?: boolean; } export function getCodeInsetData(model: ITextModel, token: CancellationToken): Promise { const symbols: ICodeInsetData[] = []; const providers = CodeInsetProviderRegistry.ordered(model); const promises = providers.map(provider => Promise.resolve(provider.provideCodeInsets(model, token)).then(result => { if (Array.isArray(result)) { for (let symbol of result) { symbols.push({ symbol, provider }); } } }).catch(onUnexpectedExternalError)); return Promise.all(promises).then(() => { return mergeSort(symbols, (a, b) => { // sort by lineNumber, provider-rank, and column if (a.symbol.range.startLineNumber < b.symbol.range.startLineNumber) { return -1; } else if (a.symbol.range.startLineNumber > b.symbol.range.startLineNumber) { return 1; } else if (providers.indexOf(a.provider) < providers.indexOf(b.provider)) { return -1; } else if (providers.indexOf(a.provider) > providers.indexOf(b.provider)) { return 1; } else if (a.symbol.range.startColumn < b.symbol.range.startColumn) { return -1; } else if (a.symbol.range.startColumn > b.symbol.range.startColumn) { return 1; } else { return 0; } }); }); }