提交 fff9302b 编写于 作者: M Martin Aeschlimann

folding: provider event to signal that folding ranges have changed. Fixes #99914

上级 df696e3a
......@@ -1293,6 +1293,12 @@ export interface FoldingContext {
* A provider of folding ranges for editor models.
*/
export interface FoldingRangeProvider {
/**
* An optional event to signal that the folding ranges from this provider have changed.
*/
onDidChange?: Event<this>;
/**
* Provides the folding ranges for a specific model.
*/
......
......@@ -264,7 +264,7 @@ export class FoldingController extends Disposable implements IEditorContribution
}, 30000);
return rangeProvider; // keep memento in case there are still no foldingProviders on the next request.
} else if (foldingProviders.length > 0) {
this.rangeProvider = new SyntaxRangeProvider(editorModel, foldingProviders);
this.rangeProvider = new SyntaxRangeProvider(editorModel, foldingProviders, () => this.onModelContentChanged());
}
}
this.foldingStateMemento = null;
......
......@@ -9,6 +9,7 @@ import { ITextModel } from 'vs/editor/common/model';
import { RangeProvider } from './folding';
import { MAX_LINE_NUMBER, FoldingRegions } from './foldingRanges';
import { CancellationToken } from 'vs/base/common/cancellation';
import { DisposableStore } from 'vs/base/common/lifecycle';
const MAX_FOLDING_REGIONS = 5000;
......@@ -25,7 +26,17 @@ export class SyntaxRangeProvider implements RangeProvider {
readonly id = ID_SYNTAX_PROVIDER;
constructor(private readonly editorModel: ITextModel, private providers: FoldingRangeProvider[], private limit = MAX_FOLDING_REGIONS) {
readonly disposables: DisposableStore | undefined;
constructor(private readonly editorModel: ITextModel, private providers: FoldingRangeProvider[], handleFoldingRangesChange: () => void, private limit = MAX_FOLDING_REGIONS) {
for (const provider of providers) {
if (typeof provider.onDidChange === 'function') {
if (!this.disposables) {
this.disposables = new DisposableStore();
}
this.disposables.add(provider.onDidChange(handleFoldingRangesChange));
}
}
}
compute(cancellationToken: CancellationToken): Promise<FoldingRegions | null> {
......@@ -39,8 +50,8 @@ export class SyntaxRangeProvider implements RangeProvider {
}
dispose() {
this.disposables?.dispose();
}
}
function collectSyntaxRanges(providers: FoldingRangeProvider[], model: ITextModel, cancellationToken: CancellationToken): Promise<IFoldingRangeData[] | null> {
......
......@@ -74,7 +74,7 @@ suite('Syntax folding', () => {
let providers = [new TestFoldingRangeProvider(model, ranges)];
async function assertLimit(maxEntries: number, expectedRanges: IndentRange[], message: string) {
let indentRanges = await new SyntaxRangeProvider(model, providers, maxEntries).compute(CancellationToken.None);
let indentRanges = await new SyntaxRangeProvider(model, providers, () => { }, maxEntries).compute(CancellationToken.None);
let actual: IndentRange[] = [];
if (indentRanges) {
for (let i = 0; i < indentRanges.length; i++) {
......
......@@ -6137,6 +6137,10 @@ declare namespace monaco.languages {
* A provider of folding ranges for editor models.
*/
export interface FoldingRangeProvider {
/**
* An optional event to signal that the folding ranges from this provider have changed.
*/
onDidChange?: IEvent<this>;
/**
* Provides the folding ranges for a specific model.
*/
......
......@@ -2190,4 +2190,15 @@ declare module 'vscode' {
canReply: boolean;
}
//#endregion
//#region https://github.com/microsoft/vscode/issues/108929 FoldingRangeProvider.onDidChangeFoldingRanges @aeschli
export interface FoldingRangeProvider2 extends FoldingRangeProvider {
/**
* An optional event to signal that the folding ranges from this provider have changed.
*/
onDidChangeFoldingRanges?: Event<void>;
}
//#endregion
}
......@@ -571,13 +571,27 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
// --- folding
$registerFoldingRangeProvider(handle: number, selector: IDocumentFilterDto[]): void {
const proxy = this._proxy;
this._registrations.set(handle, modes.FoldingRangeProviderRegistry.register(selector, <modes.FoldingRangeProvider>{
$registerFoldingRangeProvider(handle: number, selector: IDocumentFilterDto[], eventHandle: number | undefined): void {
const provider = <modes.FoldingRangeProvider>{
provideFoldingRanges: (model, context, token) => {
return proxy.$provideFoldingRanges(handle, model.uri, context, token);
return this._proxy.$provideFoldingRanges(handle, model.uri, context, token);
}
}));
};
if (typeof eventHandle === 'number') {
const emitter = new Emitter<modes.FoldingRangeProvider>();
this._registrations.set(eventHandle, emitter);
provider.onDidChange = emitter.event;
}
this._registrations.set(handle, modes.FoldingRangeProviderRegistry.register(selector, provider));
}
$emitFoldingRangeEvent(eventHandle: number, event?: any): void {
const obj = this._registrations.get(eventHandle);
if (obj instanceof Emitter) {
obj.fire(event);
}
}
// -- smart select
......
......@@ -398,7 +398,8 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable {
$registerSignatureHelpProvider(handle: number, selector: IDocumentFilterDto[], metadata: ISignatureHelpProviderMetadataDto): void;
$registerDocumentLinkProvider(handle: number, selector: IDocumentFilterDto[], supportsResolve: boolean): void;
$registerDocumentColorProvider(handle: number, selector: IDocumentFilterDto[]): void;
$registerFoldingRangeProvider(handle: number, selector: IDocumentFilterDto[]): void;
$registerFoldingRangeProvider(handle: number, selector: IDocumentFilterDto[], eventHandle: number | undefined): void;
$emitFoldingRangeEvent(eventHandle: number, event?: any): void;
$registerSelectionRangeProvider(handle: number, selector: IDocumentFilterDto[]): void;
$registerCallHierarchyProvider(handle: number, selector: IDocumentFilterDto[]): void;
$setLanguageConfiguration(handle: number, languageId: string, configuration: ILanguageConfigurationDto): void;
......
......@@ -1810,10 +1810,20 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
return this._withAdapter(handle, ColorProviderAdapter, adapter => adapter.provideColorPresentations(URI.revive(resource), colorInfo, token), undefined);
}
registerFoldingRangeProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.FoldingRangeProvider): vscode.Disposable {
const handle = this._addNewAdapter(new FoldingProviderAdapter(this._documents, provider), extension);
this._proxy.$registerFoldingRangeProvider(handle, this._transformDocumentSelector(selector));
return this._createDisposable(handle);
registerFoldingRangeProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.FoldingRangeProvider2): vscode.Disposable {
const handle = this._nextHandle();
const eventHandle = typeof provider.onDidChangeFoldingRanges === 'function' ? this._nextHandle() : undefined;
this._adapter.set(handle, new AdapterData(new FoldingProviderAdapter(this._documents, provider), extension));
this._proxy.$registerFoldingRangeProvider(handle, this._transformDocumentSelector(selector), eventHandle);
let result = this._createDisposable(handle);
if (eventHandle !== undefined) {
const subscription = provider.onDidChangeFoldingRanges!(_ => this._proxy.$emitFoldingRangeEvent(eventHandle));
result = Disposable.from(result, subscription);
}
return result;
}
$provideFoldingRanges(handle: number, resource: UriComponents, context: vscode.FoldingContext, token: CancellationToken): Promise<modes.FoldingRange[] | undefined> {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册