mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 13:00:58 +00:00
generalize limit indicator and use for color decorators (#173730)
* generalize limit indicator and use for color decorators * remove updateDebounceInfo max
This commit is contained in:
parent
cb671d149a
commit
911f119120
|
@ -114,6 +114,10 @@
|
||||||
"name": "vs/workbench/contrib/languageStatus",
|
"name": "vs/workbench/contrib/languageStatus",
|
||||||
"project": "vscode-workbench"
|
"project": "vscode-workbench"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "vs/workbench/contrib/limitIndicator",
|
||||||
|
"project": "vscode-workbench"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "vs/workbench/contrib/keybindings",
|
"name": "vs/workbench/contrib/keybindings",
|
||||||
"project": "vscode-workbench"
|
"project": "vscode-workbench"
|
||||||
|
|
|
@ -18,7 +18,7 @@ import {
|
||||||
|
|
||||||
|
|
||||||
import { hash } from './utils/hash';
|
import { hash } from './utils/hash';
|
||||||
import { createDocumentColorsLimitItem, createDocumentSymbolsLimitItem, createLanguageStatusItem, createLimitStatusItem } from './languageStatus';
|
import { createDocumentSymbolsLimitItem, createLanguageStatusItem, createLimitStatusItem } from './languageStatus';
|
||||||
|
|
||||||
namespace VSCodeContentRequest {
|
namespace VSCodeContentRequest {
|
||||||
export const type: RequestType<string, string, any> = new RequestType('vscode/content');
|
export const type: RequestType<string, string, any> = new RequestType('vscode/content');
|
||||||
|
@ -59,6 +59,8 @@ type Settings = {
|
||||||
resultLimit?: number;
|
resultLimit?: number;
|
||||||
jsonFoldingLimit?: number;
|
jsonFoldingLimit?: number;
|
||||||
jsoncFoldingLimit?: number;
|
jsoncFoldingLimit?: number;
|
||||||
|
jsonColorDecoratorLimit?: number;
|
||||||
|
jsoncColorDecoratorLimit?: number;
|
||||||
};
|
};
|
||||||
http?: {
|
http?: {
|
||||||
proxy?: string;
|
proxy?: string;
|
||||||
|
@ -79,9 +81,12 @@ export namespace SettingIds {
|
||||||
export const enableValidation = 'json.validate.enable';
|
export const enableValidation = 'json.validate.enable';
|
||||||
export const enableSchemaDownload = 'json.schemaDownload.enable';
|
export const enableSchemaDownload = 'json.schemaDownload.enable';
|
||||||
export const maxItemsComputed = 'json.maxItemsComputed';
|
export const maxItemsComputed = 'json.maxItemsComputed';
|
||||||
|
export const editorFoldingMaximumRegions = 'editor.foldingMaximumRegions';
|
||||||
|
export const editorColorDecoratorsLimit = 'editor.colorDecoratorsLimit';
|
||||||
|
|
||||||
export const editorSection = 'editor';
|
export const editorSection = 'editor';
|
||||||
export const foldingMaximumRegions = 'foldingMaximumRegions';
|
export const foldingMaximumRegions = 'foldingMaximumRegions';
|
||||||
|
export const colorDecoratorsLimit = 'colorDecoratorsLimit';
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TelemetryReporter {
|
export interface TelemetryReporter {
|
||||||
|
@ -109,6 +114,8 @@ export const languageServerDescription = l10n.t('JSON Language Server');
|
||||||
let resultLimit = 5000;
|
let resultLimit = 5000;
|
||||||
let jsonFoldingLimit = 5000;
|
let jsonFoldingLimit = 5000;
|
||||||
let jsoncFoldingLimit = 5000;
|
let jsoncFoldingLimit = 5000;
|
||||||
|
let jsonColorDecoratorLimit = 5000;
|
||||||
|
let jsoncColorDecoratorLimit = 5000;
|
||||||
|
|
||||||
export async function startClient(context: ExtensionContext, newLanguageClient: LanguageClientConstructor, runtime: Runtime): Promise<BaseLanguageClient> {
|
export async function startClient(context: ExtensionContext, newLanguageClient: LanguageClientConstructor, runtime: Runtime): Promise<BaseLanguageClient> {
|
||||||
|
|
||||||
|
@ -129,8 +136,7 @@ export async function startClient(context: ExtensionContext, newLanguageClient:
|
||||||
let isClientReady = false;
|
let isClientReady = false;
|
||||||
|
|
||||||
const documentSymbolsLimitStatusbarItem = createLimitStatusItem((limit: number) => createDocumentSymbolsLimitItem(documentSelector, SettingIds.maxItemsComputed, limit));
|
const documentSymbolsLimitStatusbarItem = createLimitStatusItem((limit: number) => createDocumentSymbolsLimitItem(documentSelector, SettingIds.maxItemsComputed, limit));
|
||||||
const documentColorsLimitStatusbarItem = createLimitStatusItem((limit: number) => createDocumentColorsLimitItem(documentSelector, SettingIds.maxItemsComputed, limit));
|
toDispose.push(documentSymbolsLimitStatusbarItem);
|
||||||
toDispose.push(documentSymbolsLimitStatusbarItem, documentColorsLimitStatusbarItem);
|
|
||||||
|
|
||||||
toDispose.push(commands.registerCommand('json.clearCache', async () => {
|
toDispose.push(commands.registerCommand('json.clearCache', async () => {
|
||||||
if (isClientReady && runtime.schemaRequests.clearCache) {
|
if (isClientReady && runtime.schemaRequests.clearCache) {
|
||||||
|
@ -225,20 +231,11 @@ export async function startClient(context: ExtensionContext, newLanguageClient:
|
||||||
return r;
|
return r;
|
||||||
},
|
},
|
||||||
provideDocumentColors(document: TextDocument, token: CancellationToken, next: ProvideDocumentColorsSignature) {
|
provideDocumentColors(document: TextDocument, token: CancellationToken, next: ProvideDocumentColorsSignature) {
|
||||||
function checkLimit(r: ColorInformation[] | null | undefined): ColorInformation[] | null | undefined {
|
|
||||||
if (Array.isArray(r) && r.length > resultLimit) {
|
|
||||||
r.length = resultLimit; // truncate
|
|
||||||
documentColorsLimitStatusbarItem.update(document, resultLimit);
|
|
||||||
} else {
|
|
||||||
documentColorsLimitStatusbarItem.update(document, false);
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
const r = next(document, token);
|
const r = next(document, token);
|
||||||
if (isThenable<ColorInformation[] | null | undefined>(r)) {
|
if (isThenable<ColorInformation[] | null | undefined>(r)) {
|
||||||
return r.then(checkLimit);
|
return r;
|
||||||
}
|
}
|
||||||
return checkLimit(r);
|
return r;
|
||||||
},
|
},
|
||||||
provideDocumentSymbols(document: TextDocument, token: CancellationToken, next: ProvideDocumentSymbolsSignature) {
|
provideDocumentSymbols(document: TextDocument, token: CancellationToken, next: ProvideDocumentSymbolsSignature) {
|
||||||
type T = SymbolInformation[] | DocumentSymbol[];
|
type T = SymbolInformation[] | DocumentSymbol[];
|
||||||
|
@ -375,6 +372,8 @@ export async function startClient(context: ExtensionContext, newLanguageClient:
|
||||||
updateFormatterRegistration();
|
updateFormatterRegistration();
|
||||||
} else if (e.affectsConfiguration(SettingIds.enableSchemaDownload)) {
|
} else if (e.affectsConfiguration(SettingIds.enableSchemaDownload)) {
|
||||||
updateSchemaDownloadSetting();
|
updateSchemaDownloadSetting();
|
||||||
|
} else if (e.affectsConfiguration(SettingIds.editorFoldingMaximumRegions) || e.affectsConfiguration(SettingIds.editorColorDecoratorsLimit)) {
|
||||||
|
client.sendNotification(DidChangeConfigurationNotification.type, { settings: getSettings() });
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -470,8 +469,13 @@ function getSettings(): Settings {
|
||||||
const normalizeLimit = (settingValue: any) => Math.trunc(Math.max(0, Number(settingValue))) || 5000;
|
const normalizeLimit = (settingValue: any) => Math.trunc(Math.max(0, Number(settingValue))) || 5000;
|
||||||
|
|
||||||
resultLimit = normalizeLimit(workspace.getConfiguration().get(SettingIds.maxItemsComputed));
|
resultLimit = normalizeLimit(workspace.getConfiguration().get(SettingIds.maxItemsComputed));
|
||||||
jsonFoldingLimit = normalizeLimit(workspace.getConfiguration(SettingIds.editorSection, { languageId: 'json' }).get(SettingIds.foldingMaximumRegions));
|
const editorJSONSettings = workspace.getConfiguration(SettingIds.editorSection, { languageId: 'json' });
|
||||||
jsoncFoldingLimit = normalizeLimit(workspace.getConfiguration(SettingIds.editorSection, { languageId: 'jsonc' }).get(SettingIds.foldingMaximumRegions));
|
const editorJSONCSettings = workspace.getConfiguration(SettingIds.editorSection, { languageId: 'jsonc' });
|
||||||
|
|
||||||
|
jsonFoldingLimit = normalizeLimit(editorJSONSettings.get(SettingIds.foldingMaximumRegions));
|
||||||
|
jsoncFoldingLimit = normalizeLimit(editorJSONCSettings.get(SettingIds.foldingMaximumRegions));
|
||||||
|
jsonColorDecoratorLimit = normalizeLimit(editorJSONSettings.get(SettingIds.colorDecoratorsLimit));
|
||||||
|
jsoncColorDecoratorLimit = normalizeLimit(editorJSONCSettings.get(SettingIds.colorDecoratorsLimit));
|
||||||
|
|
||||||
const schemas: JSONSchemaSettings[] = [];
|
const schemas: JSONSchemaSettings[] = [];
|
||||||
|
|
||||||
|
@ -487,7 +491,9 @@ function getSettings(): Settings {
|
||||||
schemas,
|
schemas,
|
||||||
resultLimit: resultLimit + 1, // ask for one more so we can detect if the limit has been exceeded
|
resultLimit: resultLimit + 1, // ask for one more so we can detect if the limit has been exceeded
|
||||||
jsonFoldingLimit: jsonFoldingLimit + 1,
|
jsonFoldingLimit: jsonFoldingLimit + 1,
|
||||||
jsoncFoldingLimit: jsoncFoldingLimit + 1
|
jsoncFoldingLimit: jsoncFoldingLimit + 1,
|
||||||
|
jsonColorDecoratorLimit: jsonColorDecoratorLimit + 1,
|
||||||
|
jsoncColorDecoratorLimit: jsoncColorDecoratorLimit + 1
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -272,19 +272,10 @@ export function createDocumentSymbolsLimitItem(documentSelector: string[], setti
|
||||||
const statusItem = languages.createLanguageStatusItem('json.documentSymbolsStatus', documentSelector);
|
const statusItem = languages.createLanguageStatusItem('json.documentSymbolsStatus', documentSelector);
|
||||||
statusItem.name = l10n.t('JSON Outline Status');
|
statusItem.name = l10n.t('JSON Outline Status');
|
||||||
statusItem.severity = LanguageStatusSeverity.Warning;
|
statusItem.severity = LanguageStatusSeverity.Warning;
|
||||||
statusItem.text = l10n.t('Outline Limited');
|
statusItem.text = l10n.t('Outline');
|
||||||
statusItem.detail = l10n.t('only {0} document symbols shown', limit);
|
statusItem.detail = l10n.t('only {0} document symbols shown for performance reasons', limit);
|
||||||
statusItem.command = { command: openSettingsCommand, arguments: [settingId], title: configureSettingsLabel };
|
statusItem.command = { command: openSettingsCommand, arguments: [settingId], title: configureSettingsLabel };
|
||||||
return Disposable.from(statusItem);
|
return Disposable.from(statusItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createDocumentColorsLimitItem(documentSelector: string[], settingId: string, limit: number): Disposable {
|
|
||||||
const statusItem = languages.createLanguageStatusItem('json.documentColorsStatus', documentSelector);
|
|
||||||
statusItem.name = l10n.t('JSON Color Symbol Status');
|
|
||||||
statusItem.severity = LanguageStatusSeverity.Warning;
|
|
||||||
statusItem.text = l10n.t('Color Symbols Limited');
|
|
||||||
statusItem.detail = l10n.t('only {0} color decorators shown', limit);
|
|
||||||
statusItem.command = { command: openSettingsCommand, arguments: [settingId], title: configureSettingsLabel };
|
|
||||||
return Disposable.from(statusItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,10 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
||||||
let resultLimit = Number.MAX_VALUE;
|
let resultLimit = Number.MAX_VALUE;
|
||||||
let jsonFoldingRangeLimit = Number.MAX_VALUE;
|
let jsonFoldingRangeLimit = Number.MAX_VALUE;
|
||||||
let jsoncFoldingRangeLimit = Number.MAX_VALUE;
|
let jsoncFoldingRangeLimit = Number.MAX_VALUE;
|
||||||
|
let jsonColorDecoratorLimit = Number.MAX_VALUE;
|
||||||
|
let jsoncColorDecoratorLimit = Number.MAX_VALUE;
|
||||||
|
|
||||||
|
|
||||||
let formatterMaxNumberOfEdits = Number.MAX_VALUE;
|
let formatterMaxNumberOfEdits = Number.MAX_VALUE;
|
||||||
|
|
||||||
let diagnosticsSupport: DiagnosticsSupport | undefined;
|
let diagnosticsSupport: DiagnosticsSupport | undefined;
|
||||||
|
@ -190,6 +194,8 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
||||||
resultLimit?: number;
|
resultLimit?: number;
|
||||||
jsonFoldingLimit?: number;
|
jsonFoldingLimit?: number;
|
||||||
jsoncFoldingLimit?: number;
|
jsoncFoldingLimit?: number;
|
||||||
|
jsonColorDecoratorLimit?: number;
|
||||||
|
jsoncColorDecoratorLimit?: number;
|
||||||
};
|
};
|
||||||
http?: {
|
http?: {
|
||||||
proxy?: string;
|
proxy?: string;
|
||||||
|
@ -225,6 +231,8 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
||||||
resultLimit = sanitizeLimitSetting(settings.json?.resultLimit || Number.MAX_VALUE);
|
resultLimit = sanitizeLimitSetting(settings.json?.resultLimit || Number.MAX_VALUE);
|
||||||
jsonFoldingRangeLimit = sanitizeLimitSetting(settings.json?.jsonFoldingLimit || foldingRangeLimitDefault);
|
jsonFoldingRangeLimit = sanitizeLimitSetting(settings.json?.jsonFoldingLimit || foldingRangeLimitDefault);
|
||||||
jsoncFoldingRangeLimit = sanitizeLimitSetting(settings.json?.jsoncFoldingLimit || foldingRangeLimitDefault);
|
jsoncFoldingRangeLimit = sanitizeLimitSetting(settings.json?.jsoncFoldingLimit || foldingRangeLimitDefault);
|
||||||
|
jsonColorDecoratorLimit = sanitizeLimitSetting(settings.json?.jsonColorDecoratorLimit || Number.MAX_VALUE);
|
||||||
|
jsoncColorDecoratorLimit = sanitizeLimitSetting(settings.json?.jsoncColorDecoratorLimit || Number.MAX_VALUE);
|
||||||
|
|
||||||
// dynamically enable & disable the formatter
|
// dynamically enable & disable the formatter
|
||||||
if (dynamicFormatterRegistration) {
|
if (dynamicFormatterRegistration) {
|
||||||
|
@ -422,6 +430,7 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
||||||
if (document) {
|
if (document) {
|
||||||
|
|
||||||
const jsonDocument = getJSONDocument(document);
|
const jsonDocument = getJSONDocument(document);
|
||||||
|
const resultLimit = document.languageId === 'jsonc' ? jsoncColorDecoratorLimit : jsonColorDecoratorLimit;
|
||||||
return languageService.findDocumentColors(document, jsonDocument, { resultLimit });
|
return languageService.findDocumentColors(document, jsonDocument, { resultLimit });
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
import { CancelablePromise, createCancelablePromise, TimeoutTimer } from 'vs/base/common/async';
|
import { CancelablePromise, createCancelablePromise, TimeoutTimer } from 'vs/base/common/async';
|
||||||
import { RGBA } from 'vs/base/common/color';
|
import { RGBA } from 'vs/base/common/color';
|
||||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||||
|
import { Emitter, Event } from 'vs/base/common/event';
|
||||||
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||||
import { StopWatch } from 'vs/base/common/stopwatch';
|
import { StopWatch } from 'vs/base/common/stopwatch';
|
||||||
import { noBreakWhitespace } from 'vs/base/common/strings';
|
import { noBreakWhitespace } from 'vs/base/common/strings';
|
||||||
|
@ -46,6 +47,8 @@ export class ColorDetector extends Disposable implements IEditorContribution {
|
||||||
|
|
||||||
private readonly _ruleFactory = new DynamicCssRules(this._editor);
|
private readonly _ruleFactory = new DynamicCssRules(this._editor);
|
||||||
|
|
||||||
|
private readonly _decoratorLimitReporter = new DecoratorLimitReporter();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly _editor: ICodeEditor,
|
private readonly _editor: ICodeEditor,
|
||||||
@IConfigurationService private readonly _configurationService: IConfigurationService,
|
@IConfigurationService private readonly _configurationService: IConfigurationService,
|
||||||
|
@ -97,8 +100,8 @@ export class ColorDetector extends Disposable implements IEditorContribution {
|
||||||
return this._editor.getOption(EditorOption.colorDecorators);
|
return this._editor.getOption(EditorOption.colorDecorators);
|
||||||
}
|
}
|
||||||
|
|
||||||
private getDecoratorLimit(): number {
|
public get limitReporter() {
|
||||||
return this._editor.getOption(EditorOption.colorDecoratorsLimit);
|
return this._decoratorLimitReporter;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get(editor: ICodeEditor): ColorDetector | null {
|
static get(editor: ICodeEditor): ColorDetector | null {
|
||||||
|
@ -191,7 +194,9 @@ export class ColorDetector extends Disposable implements IEditorContribution {
|
||||||
|
|
||||||
const decorations: IModelDeltaDecoration[] = [];
|
const decorations: IModelDeltaDecoration[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < colorData.length && decorations.length < this.getDecoratorLimit(); i++) {
|
const limit = this._editor.getOption(EditorOption.colorDecoratorsLimit);
|
||||||
|
|
||||||
|
for (let i = 0; i < colorData.length && decorations.length < limit; i++) {
|
||||||
const { red, green, blue, alpha } = colorData[i].colorInfo.color;
|
const { red, green, blue, alpha } = colorData[i].colorInfo.color;
|
||||||
const rgba = new RGBA(Math.round(red * 255), Math.round(green * 255), Math.round(blue * 255), alpha);
|
const rgba = new RGBA(Math.round(red * 255), Math.round(green * 255), Math.round(blue * 255), alpha);
|
||||||
const color = `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${rgba.a})`;
|
const color = `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${rgba.a})`;
|
||||||
|
@ -220,6 +225,8 @@ export class ColorDetector extends Disposable implements IEditorContribution {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
const limited = limit < colorData.length ? limit : false;
|
||||||
|
this._decoratorLimitReporter.update(colorData.length, limited);
|
||||||
|
|
||||||
this._colorDecoratorIds.set(decorations);
|
this._colorDecoratorIds.set(decorations);
|
||||||
}
|
}
|
||||||
|
@ -253,4 +260,25 @@ export class ColorDetector extends Disposable implements IEditorContribution {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class DecoratorLimitReporter {
|
||||||
|
private _onDidChange = new Emitter<void>();
|
||||||
|
public readonly onDidChange: Event<void> = this._onDidChange.event;
|
||||||
|
|
||||||
|
private _computed: number = 0;
|
||||||
|
private _limited: number | false = false;
|
||||||
|
public get computed(): number {
|
||||||
|
return this._computed;
|
||||||
|
}
|
||||||
|
public get limited(): number | false {
|
||||||
|
return this._limited;
|
||||||
|
}
|
||||||
|
public update(computed: number, limited: number | false) {
|
||||||
|
if (computed !== this._computed || limited !== this._limited) {
|
||||||
|
this._computed = computed;
|
||||||
|
this._limited = limited;
|
||||||
|
this._onDidChange.fire();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
registerEditorContribution(ColorDetector.ID, ColorDetector, EditorContributionInstantiation.AfterFirstRender);
|
registerEditorContribution(ColorDetector.ID, ColorDetector, EditorContributionInstantiation.AfterFirstRender);
|
||||||
|
|
|
@ -59,12 +59,7 @@ interface FoldingStateMemento {
|
||||||
|
|
||||||
export interface FoldingLimitReporter {
|
export interface FoldingLimitReporter {
|
||||||
readonly limit: number;
|
readonly limit: number;
|
||||||
report(limitInfo: FoldingLimitInfo): void;
|
update(computed: number, limited: number | false): void;
|
||||||
}
|
|
||||||
|
|
||||||
export interface FoldingLimitInfo {
|
|
||||||
computed: number;
|
|
||||||
limited: number | false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FoldingRangeProviderSelector = (provider: FoldingRangeProvider[], document: ITextModel) => FoldingRangeProvider[] | undefined;
|
export type FoldingRangeProviderSelector = (provider: FoldingRangeProvider[], document: ITextModel) => FoldingRangeProvider[] | undefined;
|
||||||
|
@ -96,7 +91,6 @@ export class FoldingController extends Disposable implements IEditorContribution
|
||||||
private _restoringViewState: boolean;
|
private _restoringViewState: boolean;
|
||||||
private _foldingImportsByDefault: boolean;
|
private _foldingImportsByDefault: boolean;
|
||||||
private _currentModelHasFoldedImports: boolean;
|
private _currentModelHasFoldedImports: boolean;
|
||||||
private _foldingLimitReporter: FoldingLimitReporter;
|
|
||||||
|
|
||||||
private readonly foldingDecorationProvider: FoldingDecorationProvider;
|
private readonly foldingDecorationProvider: FoldingDecorationProvider;
|
||||||
|
|
||||||
|
@ -116,13 +110,7 @@ export class FoldingController extends Disposable implements IEditorContribution
|
||||||
private readonly localToDispose = this._register(new DisposableStore());
|
private readonly localToDispose = this._register(new DisposableStore());
|
||||||
private mouseDownInfo: { lineNumber: number; iconClicked: boolean } | null;
|
private mouseDownInfo: { lineNumber: number; iconClicked: boolean } | null;
|
||||||
|
|
||||||
private _onDidChangeFoldingLimit = new Emitter<FoldingLimitInfo>();
|
public readonly _foldingLimitReporter: RangesLimitReporter;
|
||||||
public readonly onDidChangeFoldingLimit: Event<FoldingLimitInfo> = this._onDidChangeFoldingLimit.event;
|
|
||||||
|
|
||||||
private _foldingLimitInfo: FoldingLimitInfo | undefined;
|
|
||||||
public get foldingLimitInfo() {
|
|
||||||
return this._foldingLimitInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
editor: ICodeEditor,
|
editor: ICodeEditor,
|
||||||
|
@ -134,6 +122,9 @@ export class FoldingController extends Disposable implements IEditorContribution
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this.editor = editor;
|
this.editor = editor;
|
||||||
|
|
||||||
|
this._foldingLimitReporter = new RangesLimitReporter(editor);
|
||||||
|
|
||||||
const options = this.editor.getOptions();
|
const options = this.editor.getOptions();
|
||||||
this._isEnabled = options.get(EditorOption.folding);
|
this._isEnabled = options.get(EditorOption.folding);
|
||||||
this._useFoldingProviders = options.get(EditorOption.foldingStrategy) !== 'indentation';
|
this._useFoldingProviders = options.get(EditorOption.foldingStrategy) !== 'indentation';
|
||||||
|
@ -141,17 +132,6 @@ export class FoldingController extends Disposable implements IEditorContribution
|
||||||
this._restoringViewState = false;
|
this._restoringViewState = false;
|
||||||
this._currentModelHasFoldedImports = false;
|
this._currentModelHasFoldedImports = false;
|
||||||
this._foldingImportsByDefault = options.get(EditorOption.foldingImportsByDefault);
|
this._foldingImportsByDefault = options.get(EditorOption.foldingImportsByDefault);
|
||||||
this._foldingLimitReporter = {
|
|
||||||
get limit() {
|
|
||||||
return editor.getOptions().get(EditorOption.foldingMaximumRegions);
|
|
||||||
},
|
|
||||||
report: (info: FoldingLimitInfo) => {
|
|
||||||
if (!this._foldingLimitInfo || (info.limited !== this._foldingLimitInfo.limited)) {
|
|
||||||
this._foldingLimitInfo = info;
|
|
||||||
this._onDidChangeFoldingLimit.fire(info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.updateDebounceInfo = languageFeatureDebounceService.for(languageFeaturesService.foldingRangeProvider, 'Folding', { min: 200 });
|
this.updateDebounceInfo = languageFeatureDebounceService.for(languageFeaturesService.foldingRangeProvider, 'Folding', { min: 200 });
|
||||||
|
|
||||||
this.foldingModel = null;
|
this.foldingModel = null;
|
||||||
|
@ -200,6 +180,10 @@ export class FoldingController extends Disposable implements IEditorContribution
|
||||||
this.onModelChanged();
|
this.onModelChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get limitReporter() {
|
||||||
|
return this._foldingLimitReporter;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store view state.
|
* Store view state.
|
||||||
*/
|
*/
|
||||||
|
@ -529,6 +513,34 @@ export class FoldingController extends Disposable implements IEditorContribution
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class RangesLimitReporter implements FoldingLimitReporter {
|
||||||
|
constructor(private readonly editor: ICodeEditor) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public get limit() {
|
||||||
|
return this.editor.getOptions().get(EditorOption.foldingMaximumRegions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _onDidChange = new Emitter<void>();
|
||||||
|
public readonly onDidChange: Event<void> = this._onDidChange.event;
|
||||||
|
|
||||||
|
private _computed: number = 0;
|
||||||
|
private _limited: number | false = false;
|
||||||
|
public get computed(): number {
|
||||||
|
return this._computed;
|
||||||
|
}
|
||||||
|
public get limited(): number | false {
|
||||||
|
return this._limited;
|
||||||
|
}
|
||||||
|
public update(computed: number, limited: number | false) {
|
||||||
|
if (computed !== this._computed || limited !== this._limited) {
|
||||||
|
this._computed = computed;
|
||||||
|
this._limited = limited;
|
||||||
|
this._onDidChange.fire();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
abstract class FoldingAction<T> extends EditorAction {
|
abstract class FoldingAction<T> extends EditorAction {
|
||||||
|
|
||||||
abstract invoke(foldingController: FoldingController, foldingModel: FoldingModel, editor: ICodeEditor, args: T, languageConfigurationService: ILanguageConfigurationService): void;
|
abstract invoke(foldingController: FoldingController, foldingModel: FoldingModel, editor: ICodeEditor, args: T, languageConfigurationService: ILanguageConfigurationService): void;
|
||||||
|
@ -1232,7 +1244,7 @@ CommandsRegistry.registerCommand('_executeFoldingRangeProvider', async function
|
||||||
get limit() {
|
get limit() {
|
||||||
return <number>configurationService.getValue('editor.foldingMaximumRegions', { resource });
|
return <number>configurationService.getValue('editor.foldingMaximumRegions', { resource });
|
||||||
},
|
},
|
||||||
report: (info: FoldingLimitInfo) => { }
|
update: (computed: number, limited: number | false) => { }
|
||||||
};
|
};
|
||||||
|
|
||||||
const indentRangeProvider = new IndentRangeProvider(model, languageConfigurationService, foldingLimitReporter);
|
const indentRangeProvider = new IndentRangeProvider(model, languageConfigurationService, foldingLimitReporter);
|
||||||
|
|
|
@ -66,7 +66,7 @@ class RangesCollector {
|
||||||
public toIndentRanges(model: ITextModel) {
|
public toIndentRanges(model: ITextModel) {
|
||||||
const limit = this._foldingRangesLimit.limit;
|
const limit = this._foldingRangesLimit.limit;
|
||||||
if (this._length <= limit) {
|
if (this._length <= limit) {
|
||||||
this._foldingRangesLimit.report({ limited: false, computed: this._length });
|
this._foldingRangesLimit.update(this._length, false);
|
||||||
|
|
||||||
// reverse and create arrays of the exact length
|
// reverse and create arrays of the exact length
|
||||||
const startIndexes = new Uint32Array(this._length);
|
const startIndexes = new Uint32Array(this._length);
|
||||||
|
@ -77,7 +77,7 @@ class RangesCollector {
|
||||||
}
|
}
|
||||||
return new FoldingRegions(startIndexes, endIndexes);
|
return new FoldingRegions(startIndexes, endIndexes);
|
||||||
} else {
|
} else {
|
||||||
this._foldingRangesLimit.report({ limited: limit, computed: this._length });
|
this._foldingRangesLimit.update(this._length, limit);
|
||||||
|
|
||||||
let entries = 0;
|
let entries = 0;
|
||||||
let maxIndent = this._indentOccurrences.length;
|
let maxIndent = this._indentOccurrences.length;
|
||||||
|
@ -120,7 +120,7 @@ interface PreviousRegion {
|
||||||
|
|
||||||
const foldingRangesLimitDefault: FoldingLimitReporter = {
|
const foldingRangesLimitDefault: FoldingLimitReporter = {
|
||||||
limit: MAX_FOLDING_REGIONS_FOR_INDENT_DEFAULT,
|
limit: MAX_FOLDING_REGIONS_FOR_INDENT_DEFAULT,
|
||||||
report: () => { }
|
update: () => { }
|
||||||
};
|
};
|
||||||
|
|
||||||
export function computeRanges(model: ITextModel, offSide: boolean, markers?: FoldingMarkers, foldingRangesLimit: FoldingLimitReporter = foldingRangesLimitDefault): FoldingRegions {
|
export function computeRanges(model: ITextModel, offSide: boolean, markers?: FoldingMarkers, foldingRangesLimit: FoldingLimitReporter = foldingRangesLimitDefault): FoldingRegions {
|
||||||
|
|
|
@ -122,7 +122,7 @@ class RangesCollector {
|
||||||
public toIndentRanges() {
|
public toIndentRanges() {
|
||||||
const limit = this._foldingRangesLimit.limit;
|
const limit = this._foldingRangesLimit.limit;
|
||||||
if (this._length <= limit) {
|
if (this._length <= limit) {
|
||||||
this._foldingRangesLimit.report({ limited: false, computed: this._length });
|
this._foldingRangesLimit.update(this._length, false);
|
||||||
|
|
||||||
const startIndexes = new Uint32Array(this._length);
|
const startIndexes = new Uint32Array(this._length);
|
||||||
const endIndexes = new Uint32Array(this._length);
|
const endIndexes = new Uint32Array(this._length);
|
||||||
|
@ -132,7 +132,7 @@ class RangesCollector {
|
||||||
}
|
}
|
||||||
return new FoldingRegions(startIndexes, endIndexes, this._types);
|
return new FoldingRegions(startIndexes, endIndexes, this._types);
|
||||||
} else {
|
} else {
|
||||||
this._foldingRangesLimit.report({ limited: limit, computed: this._length });
|
this._foldingRangesLimit.update(this._length, limit);
|
||||||
|
|
||||||
let entries = 0;
|
let entries = 0;
|
||||||
let maxLevel = this._nestingLevelCounts.length;
|
let maxLevel = this._nestingLevelCounts.length;
|
||||||
|
|
|
@ -42,7 +42,7 @@ suite('FoldingRanges', () => {
|
||||||
lines.push('#endregion');
|
lines.push('#endregion');
|
||||||
}
|
}
|
||||||
const model = createTextModel(lines.join('\n'));
|
const model = createTextModel(lines.join('\n'));
|
||||||
const actual = computeRanges(model, false, markers, { limit: MAX_FOLDING_REGIONS, report: () => { } });
|
const actual = computeRanges(model, false, markers, { limit: MAX_FOLDING_REGIONS, update: () => { } });
|
||||||
assert.strictEqual(actual.length, nRegions, 'len');
|
assert.strictEqual(actual.length, nRegions, 'len');
|
||||||
for (let i = 0; i < nRegions; i++) {
|
for (let i = 0; i < nRegions; i++) {
|
||||||
assert.strictEqual(actual.getStartLineNumber(i), i + 1, 'start' + i);
|
assert.strictEqual(actual.getStartLineNumber(i), i + 1, 'start' + i);
|
||||||
|
|
|
@ -51,7 +51,7 @@ suite('Indentation Folding', () => {
|
||||||
|
|
||||||
function assertLimit(maxEntries: number, expectedRanges: IndentRange[], message: string) {
|
function assertLimit(maxEntries: number, expectedRanges: IndentRange[], message: string) {
|
||||||
let reported: number | false = false;
|
let reported: number | false = false;
|
||||||
const indentRanges = computeRanges(model, true, undefined, { limit: maxEntries, report: r => reported = r.limited });
|
const indentRanges = computeRanges(model, true, undefined, { limit: maxEntries, update: (computed, limited) => reported = limited });
|
||||||
assert.ok(indentRanges.length <= maxEntries, 'max ' + message);
|
assert.ok(indentRanges.length <= maxEntries, 'max ' + message);
|
||||||
const actual: IndentRange[] = [];
|
const actual: IndentRange[] = [];
|
||||||
for (let i = 0; i < indentRanges.length; i++) {
|
for (let i = 0; i < indentRanges.length; i++) {
|
||||||
|
|
|
@ -76,7 +76,7 @@ suite('Syntax folding', () => {
|
||||||
|
|
||||||
async function assertLimit(maxEntries: number, expectedRanges: IndentRange[], message: string) {
|
async function assertLimit(maxEntries: number, expectedRanges: IndentRange[], message: string) {
|
||||||
let reported: number | false = false;
|
let reported: number | false = false;
|
||||||
const foldingRangesLimit: FoldingLimitReporter = { limit: maxEntries, report: r => reported = r.limited };
|
const foldingRangesLimit: FoldingLimitReporter = { limit: maxEntries, update: (computed, limited) => reported = limited };
|
||||||
const indentRanges = await new SyntaxRangeProvider(model, providers, () => { }, foldingRangesLimit, undefined).compute(CancellationToken.None);
|
const indentRanges = await new SyntaxRangeProvider(model, providers, () => { }, foldingRangesLimit, undefined).compute(CancellationToken.None);
|
||||||
const actual: IndentRange[] = [];
|
const actual: IndentRange[] = [];
|
||||||
if (indentRanges) {
|
if (indentRanges) {
|
||||||
|
|
|
@ -3,12 +3,8 @@
|
||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
import { Disposable } from 'vs/base/common/lifecycle';
|
||||||
import Severity from 'vs/base/common/severity';
|
import { FoldingController } from 'vs/editor/contrib/folding/browser/folding';
|
||||||
import { getCodeEditor } from 'vs/editor/browser/editorBrowser';
|
|
||||||
import { FoldingController, FoldingLimitInfo } from 'vs/editor/contrib/folding/browser/folding';
|
|
||||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
|
||||||
import { ILanguageStatus, ILanguageStatusService } from 'vs/workbench/services/languageStatus/common/languageStatusService';
|
|
||||||
import * as nls from 'vs/nls';
|
import * as nls from 'vs/nls';
|
||||||
import { Registry } from 'vs/platform/registry/common/platform';
|
import { Registry } from 'vs/platform/registry/common/platform';
|
||||||
import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry, IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry, IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||||
|
@ -21,86 +17,6 @@ import { ITextModel } from 'vs/editor/common/model';
|
||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||||
|
|
||||||
const openSettingsCommand = 'workbench.action.openSettings';
|
|
||||||
const configureSettingsLabel = nls.localize('status.button.configure', "Configure");
|
|
||||||
|
|
||||||
const foldingMaximumRegionsSettingsId = 'editor.foldingMaximumRegions';
|
|
||||||
|
|
||||||
export class FoldingLimitIndicatorContribution extends Disposable implements IWorkbenchContribution {
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
@IEditorService private readonly editorService: IEditorService,
|
|
||||||
@ILanguageStatusService private readonly languageStatusService: ILanguageStatusService
|
|
||||||
) {
|
|
||||||
super();
|
|
||||||
|
|
||||||
let changeListener: IDisposable | undefined;
|
|
||||||
let control: any;
|
|
||||||
|
|
||||||
const onActiveEditorChanged = () => {
|
|
||||||
const activeControl = editorService.activeTextEditorControl;
|
|
||||||
if (activeControl === control) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
control = undefined;
|
|
||||||
if (changeListener) {
|
|
||||||
changeListener.dispose();
|
|
||||||
changeListener = undefined;
|
|
||||||
}
|
|
||||||
const editor = getCodeEditor(activeControl);
|
|
||||||
if (editor) {
|
|
||||||
const controller = FoldingController.get(editor);
|
|
||||||
if (controller) {
|
|
||||||
const info = controller.foldingLimitInfo;
|
|
||||||
this.updateLimitInfo(info);
|
|
||||||
control = activeControl;
|
|
||||||
changeListener = controller.onDidChangeFoldingLimit(info => {
|
|
||||||
this.updateLimitInfo(info);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.updateLimitInfo(undefined);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.updateLimitInfo(undefined);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this._register(this.editorService.onDidActiveEditorChange(onActiveEditorChanged));
|
|
||||||
|
|
||||||
onActiveEditorChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
private _limitStatusItem: IDisposable | undefined;
|
|
||||||
|
|
||||||
private updateLimitInfo(info: FoldingLimitInfo | undefined) {
|
|
||||||
if (this._limitStatusItem) {
|
|
||||||
this._limitStatusItem.dispose();
|
|
||||||
this._limitStatusItem = undefined;
|
|
||||||
}
|
|
||||||
if (info && info.limited !== false) {
|
|
||||||
const status: ILanguageStatus = {
|
|
||||||
id: 'foldingLimitInfo',
|
|
||||||
selector: '*',
|
|
||||||
name: nls.localize('foldingRangesStatusItem.name', 'Folding Status'),
|
|
||||||
severity: Severity.Warning,
|
|
||||||
label: nls.localize('status.limitedFoldingRanges.short', 'Folding Ranges Limited'),
|
|
||||||
detail: nls.localize('status.limitedFoldingRanges.details', 'only {0} folding ranges shown for performance reasons', info.limited),
|
|
||||||
command: { id: openSettingsCommand, arguments: [foldingMaximumRegionsSettingsId], title: configureSettingsLabel },
|
|
||||||
accessibilityInfo: undefined,
|
|
||||||
source: nls.localize('foldingRangesStatusItem.source', 'Folding'),
|
|
||||||
busy: false
|
|
||||||
};
|
|
||||||
this._limitStatusItem = this.languageStatusService.addStatus(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(
|
|
||||||
FoldingLimitIndicatorContribution,
|
|
||||||
LifecyclePhase.Restored
|
|
||||||
);
|
|
||||||
|
|
||||||
class DefaultFoldingRangeProvider extends Disposable implements IWorkbenchContribution {
|
class DefaultFoldingRangeProvider extends Disposable implements IWorkbenchContribution {
|
||||||
|
|
||||||
static readonly configName = 'editor.defaultFoldingRangeProvider';
|
static readonly configName = 'editor.defaultFoldingRangeProvider';
|
||||||
|
|
|
@ -0,0 +1,161 @@
|
||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||||
|
import Severity from 'vs/base/common/severity';
|
||||||
|
import { ICodeEditor, getCodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||||
|
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
|
import { ILanguageStatus, ILanguageStatusService } from 'vs/workbench/services/languageStatus/common/languageStatusService';
|
||||||
|
import { Registry } from 'vs/platform/registry/common/platform';
|
||||||
|
import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry, IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||||
|
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
|
||||||
|
import { Event } from 'vs/base/common/event';
|
||||||
|
import * as nls from 'vs/nls';
|
||||||
|
|
||||||
|
import { FoldingController } from 'vs/editor/contrib/folding/browser/folding';
|
||||||
|
import { ColorDetector } from 'vs/editor/contrib/colorPicker/browser/colorDetector';
|
||||||
|
|
||||||
|
const openSettingsCommand = 'workbench.action.openSettings';
|
||||||
|
const configureSettingsLabel = nls.localize('status.button.configure', "Configure");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses that language status indicator to show information which language features have been limited for performance reasons.
|
||||||
|
* Currently this is used for folding ranges and for color decorators.
|
||||||
|
*/
|
||||||
|
export class LimitIndicatorContribution extends Disposable implements IWorkbenchContribution {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@IEditorService editorService: IEditorService,
|
||||||
|
@ILanguageStatusService languageStatusService: ILanguageStatusService
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
const accessors = [new ColorDecorationAccessor(), new FoldingRangeAccessor()];
|
||||||
|
const statusEntries = accessors.map(indicator => new LanguageStatusEntry(languageStatusService, indicator));
|
||||||
|
statusEntries.forEach(entry => this._register(entry));
|
||||||
|
|
||||||
|
let control: any;
|
||||||
|
|
||||||
|
const onActiveEditorChanged = () => {
|
||||||
|
const activeControl = editorService.activeTextEditorControl;
|
||||||
|
if (activeControl === control) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
control = activeControl;
|
||||||
|
const editor = getCodeEditor(activeControl);
|
||||||
|
|
||||||
|
statusEntries.forEach(statusEntry => statusEntry.onActiveEditorChanged(editor));
|
||||||
|
};
|
||||||
|
this._register(editorService.onDidActiveEditorChange(onActiveEditorChanged));
|
||||||
|
|
||||||
|
onActiveEditorChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface LimitInfo {
|
||||||
|
readonly onDidChange: Event<void>;
|
||||||
|
|
||||||
|
readonly computed: number;
|
||||||
|
readonly limited: number | false;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LanguageFeatureAccessor {
|
||||||
|
readonly id: string;
|
||||||
|
readonly name: string;
|
||||||
|
readonly label: string;
|
||||||
|
readonly source: string;
|
||||||
|
readonly settingsId: string;
|
||||||
|
getLimitReporter(editor: ICodeEditor): LimitInfo | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ColorDecorationAccessor implements LanguageFeatureAccessor {
|
||||||
|
readonly id = 'decoratorsLimitInfo';
|
||||||
|
readonly name = nls.localize('colorDecoratorsStatusItem.name', 'Color Decorator Status');
|
||||||
|
readonly label = nls.localize('status.limitedColorDecorators.short', 'Color Decorators');
|
||||||
|
readonly source = nls.localize('colorDecoratorsStatusItem.source', 'Color Decorators');
|
||||||
|
readonly settingsId = 'editor.colorDecoratorsLimit';
|
||||||
|
|
||||||
|
getLimitReporter(editor: ICodeEditor): LimitInfo | undefined {
|
||||||
|
return ColorDetector.get(editor)?.limitReporter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FoldingRangeAccessor implements LanguageFeatureAccessor {
|
||||||
|
readonly id = 'foldingLimitInfo';
|
||||||
|
readonly name = nls.localize('foldingRangesStatusItem.name', 'Folding Status');
|
||||||
|
readonly label = nls.localize('status.limitedFoldingRanges.short', 'Folding Ranges');
|
||||||
|
readonly source = nls.localize('foldingRangesStatusItem.source', 'Folding');
|
||||||
|
readonly settingsId = 'editor.foldingMaximumRegions';
|
||||||
|
|
||||||
|
getLimitReporter(editor: ICodeEditor): LimitInfo | undefined {
|
||||||
|
return FoldingController.get(editor)?.limitReporter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LanguageStatusEntry {
|
||||||
|
|
||||||
|
private _limitStatusItem: IDisposable | undefined;
|
||||||
|
private _indicatorChangeListener: IDisposable | undefined;
|
||||||
|
|
||||||
|
constructor(private languageStatusService: ILanguageStatusService, private accessor: LanguageFeatureAccessor) {
|
||||||
|
}
|
||||||
|
|
||||||
|
onActiveEditorChanged(editor: ICodeEditor | null): boolean {
|
||||||
|
if (this._indicatorChangeListener) {
|
||||||
|
this._indicatorChangeListener.dispose();
|
||||||
|
this._indicatorChangeListener = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
let info: LimitInfo | undefined;
|
||||||
|
if (editor) {
|
||||||
|
info = this.accessor.getLimitReporter(editor);
|
||||||
|
}
|
||||||
|
this.updateStatusItem(info);
|
||||||
|
if (info) {
|
||||||
|
this._indicatorChangeListener = info.onDidChange(_ => {
|
||||||
|
this.updateStatusItem(info);
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private updateStatusItem(info: LimitInfo | undefined) {
|
||||||
|
if (this._limitStatusItem) {
|
||||||
|
this._limitStatusItem.dispose();
|
||||||
|
this._limitStatusItem = undefined;
|
||||||
|
}
|
||||||
|
if (info && info.limited !== false) {
|
||||||
|
const status: ILanguageStatus = {
|
||||||
|
id: this.accessor.id,
|
||||||
|
selector: '*',
|
||||||
|
name: this.accessor.name,
|
||||||
|
severity: Severity.Warning,
|
||||||
|
label: this.accessor.label,
|
||||||
|
detail: nls.localize('status.limited.details', 'only {0} shown for performance reasons', info.limited),
|
||||||
|
command: { id: openSettingsCommand, arguments: [this.accessor.settingsId], title: configureSettingsLabel },
|
||||||
|
accessibilityInfo: undefined,
|
||||||
|
source: this.accessor.source,
|
||||||
|
busy: false
|
||||||
|
};
|
||||||
|
this._limitStatusItem = this.languageStatusService.addStatus(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public dispose() {
|
||||||
|
this._limitStatusItem?.dispose;
|
||||||
|
this._limitStatusItem = undefined;
|
||||||
|
this._indicatorChangeListener?.dispose;
|
||||||
|
this._indicatorChangeListener = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(
|
||||||
|
LimitIndicatorContribution,
|
||||||
|
LifecyclePhase.Restored
|
||||||
|
);
|
|
@ -20,7 +20,7 @@ type RegionFilterWithLevel = (r: FoldingRegion, level: number) => boolean;
|
||||||
|
|
||||||
const foldingRangeLimit: FoldingLimitReporter = {
|
const foldingRangeLimit: FoldingLimitReporter = {
|
||||||
limit: 5000,
|
limit: 5000,
|
||||||
report: () => { }
|
update: () => { }
|
||||||
};
|
};
|
||||||
|
|
||||||
export class FoldingModel implements IDisposable {
|
export class FoldingModel implements IDisposable {
|
||||||
|
|
|
@ -268,9 +268,12 @@ import 'vs/workbench/contrib/snippets/browser/snippets.contribution';
|
||||||
// Formatter Help
|
// Formatter Help
|
||||||
import 'vs/workbench/contrib/format/browser/format.contribution';
|
import 'vs/workbench/contrib/format/browser/format.contribution';
|
||||||
|
|
||||||
// Folding Limit Indicator
|
// Folding
|
||||||
import 'vs/workbench/contrib/folding/browser/folding.contribution';
|
import 'vs/workbench/contrib/folding/browser/folding.contribution';
|
||||||
|
|
||||||
|
// Limit Indicator
|
||||||
|
import 'vs/workbench/contrib/limitIndicator/browser/limitIndicator.contribution';
|
||||||
|
|
||||||
// Inlay Hint Accessibility
|
// Inlay Hint Accessibility
|
||||||
import 'vs/workbench/contrib/inlayHints/browser/inlayHintsAccessibilty';
|
import 'vs/workbench/contrib/inlayHints/browser/inlayHintsAccessibilty';
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue