incorperate folding api feedback

This commit is contained in:
Martin Aeschlimann 2018-04-18 15:26:43 +02:00
parent 89163a5f59
commit a1bb202eb6
18 changed files with 232 additions and 180 deletions

View file

@ -8,7 +8,7 @@ import * as path from 'path';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
import { languages, window, commands, ExtensionContext, Range, Position, TextDocument, CompletionItem, CompletionItemKind, TextEdit, SnippetString, FoldingRangeList, FoldingRange, FoldingContext, CancellationToken } from 'vscode';
import { languages, window, commands, ExtensionContext, Range, Position, TextDocument, CompletionItem, CompletionItemKind, TextEdit, SnippetString, FoldingRangeKind, FoldingRange, FoldingContext, CancellationToken } from 'vscode';
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, Disposable } from 'vscode-languageclient';
import { FoldingRangeRequest, FoldingRangeRequestParam, FoldingRangeClientCapabilities } from 'vscode-languageserver-protocol-foldingprovider';
@ -117,14 +117,26 @@ export function activate(context: ExtensionContext) {
}
function initFoldingProvider(): Disposable {
return languages.registerFoldingProvider(documentSelector, {
const kinds: { [value: string]: FoldingRangeKind } = Object.create(null);
function getKind(value: string | undefined) {
if (!value) {
return void 0;
}
let kind = kinds[value];
if (!kind) {
kind = new FoldingRangeKind(value);
kinds[value] = kind;
}
return kind;
}
return languages.registerFoldingRangeProvider(documentSelector, {
provideFoldingRanges(document: TextDocument, context: FoldingContext, token: CancellationToken) {
const param: FoldingRangeRequestParam = {
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document)
};
return client.sendRequest(FoldingRangeRequest.type, param, token).then(ranges => {
if (Array.isArray(ranges)) {
return new FoldingRangeList(ranges.map(r => new FoldingRange(r.startLine, r.endLine, r.kind)));
return ranges.map(r => new FoldingRange(r.startLine, r.endLine, getKind(r.kind)));
}
return null;
}, error => {

View file

@ -8,7 +8,7 @@ import * as path from 'path';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
import { languages, ExtensionContext, IndentAction, Position, TextDocument, Range, CompletionItem, CompletionItemKind, SnippetString, FoldingRangeList, FoldingRange, FoldingContext } from 'vscode';
import { languages, ExtensionContext, IndentAction, Position, TextDocument, Range, CompletionItem, CompletionItemKind, SnippetString, FoldingRangeKind, FoldingRange, FoldingContext } from 'vscode';
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, RequestType, TextDocumentPositionParams, Disposable, CancellationToken } from 'vscode-languageclient';
import { EMPTY_ELEMENTS } from './htmlEmptyTagsShared';
import { activateTagClosing } from './tagClosing';
@ -174,14 +174,26 @@ export function activate(context: ExtensionContext) {
});
function initFoldingProvider(): Disposable {
return languages.registerFoldingProvider(documentSelector, {
const kinds: { [value: string]: FoldingRangeKind } = Object.create(null);
function getKind(value: string | undefined) {
if (!value) {
return void 0;
}
let kind = kinds[value];
if (!kind) {
kind = new FoldingRangeKind(value);
kinds[value] = kind;
}
return kind;
}
return languages.registerFoldingRangeProvider(documentSelector, {
provideFoldingRanges(document: TextDocument, context: FoldingContext, token: CancellationToken) {
const param: FoldingRangeRequestParam = {
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document)
};
return client.sendRequest(FoldingRangeRequest.type, param, token).then(ranges => {
if (Array.isArray(ranges)) {
return new FoldingRangeList(ranges.map(r => new FoldingRange(r.startLine, r.endLine, r.kind)));
return ranges.map(r => new FoldingRange(r.startLine, r.endLine, getKind(r.kind)));
}
return null;
}, error => {

View file

@ -8,7 +8,7 @@ import * as path from 'path';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
import { workspace, languages, ExtensionContext, extensions, Uri, LanguageConfiguration, TextDocument, FoldingRangeList, FoldingRange, Disposable, FoldingContext } from 'vscode';
import { workspace, languages, ExtensionContext, extensions, Uri, LanguageConfiguration, TextDocument, FoldingRangeKind, FoldingRange, Disposable, FoldingContext } from 'vscode';
import { LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType, DidChangeConfigurationNotification, CancellationToken } from 'vscode-languageclient';
import TelemetryReporter from 'vscode-extension-telemetry';
@ -156,14 +156,26 @@ export function activate(context: ExtensionContext) {
languages.setLanguageConfiguration('jsonc', languageConfiguration);
function initFoldingProvider(): Disposable {
return languages.registerFoldingProvider(documentSelector, {
const kinds: { [value: string]: FoldingRangeKind } = Object.create(null);
function getKind(value: string | undefined) {
if (!value) {
return void 0;
}
let kind = kinds[value];
if (!kind) {
kind = new FoldingRangeKind(value);
kinds[value] = kind;
}
return kind;
}
return languages.registerFoldingRangeProvider(documentSelector, {
provideFoldingRanges(document: TextDocument, context: FoldingContext, token: CancellationToken) {
const param: FoldingRangeRequestParam = {
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document)
};
return client.sendRequest(FoldingRangeRequest.type, param, token).then(ranges => {
if (Array.isArray(ranges)) {
return new FoldingRangeList(ranges.map(r => new FoldingRange(r.startLine, r.endLine, r.kind)));
return ranges.map(r => new FoldingRange(r.startLine, r.endLine, getKind(r.kind)));
}
return null;
}, error => {

View file

@ -39,7 +39,7 @@ export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.languages.registerDocumentSymbolProvider(selector, symbolProvider));
context.subscriptions.push(vscode.languages.registerDocumentLinkProvider(selector, new LinkProvider()));
context.subscriptions.push(vscode.languages.registerFoldingProvider(selector, new MarkdownFoldingProvider(engine)));
context.subscriptions.push(vscode.languages.registerFoldingRangeProvider(selector, new MarkdownFoldingProvider(engine)));
context.subscriptions.push(vscode.languages.registerWorkspaceSymbolProvider(new MarkdownWorkspaceSymbolProvider(symbolProvider)));
const previewSecuritySelector = new PreviewSecuritySelector(cspArbiter, previewManager);

View file

@ -8,7 +8,9 @@ import * as vscode from 'vscode';
import { MarkdownEngine } from '../markdownEngine';
import { TableOfContentsProvider } from '../tableOfContentsProvider';
export default class MarkdownFoldingProvider implements vscode.FoldingProvider {
const rangeLimit = 5000;
export default class MarkdownFoldingProvider implements vscode.FoldingRangeProvider {
constructor(
private readonly engine: MarkdownEngine
@ -16,13 +18,13 @@ export default class MarkdownFoldingProvider implements vscode.FoldingProvider {
public async provideFoldingRanges(
document: vscode.TextDocument,
context: vscode.FoldingContext,
_: vscode.FoldingContext,
_token: vscode.CancellationToken
): Promise<vscode.FoldingRangeList> {
): Promise<vscode.FoldingRange[]> {
const tocProvider = new TableOfContentsProvider(this.engine, document);
let toc = await tocProvider.getToc();
if (context.maxRanges && toc.length > context.maxRanges) {
toc = toc.slice(0, context.maxRanges);
if (toc.length > rangeLimit) {
toc = toc.slice(0, rangeLimit);
}
const foldingRanges = toc.map((entry, startIndex) => {
@ -43,6 +45,6 @@ export default class MarkdownFoldingProvider implements vscode.FoldingProvider {
});
return new vscode.FoldingRangeList(foldingRanges);
return foldingRanges;
}
}

View file

@ -16,7 +16,7 @@ const testFileName = vscode.Uri.parse('test.md');
suite('markdown.FoldingProvider', () => {
test('Should not return anything for empty document', async () => {
const folds = await getFoldsForDocument(``);
assert.strictEqual(folds.ranges.length, 0);
assert.strictEqual(folds.length, 0);
});
test('Should not return anything for document without headers', async () => {
@ -24,7 +24,7 @@ suite('markdown.FoldingProvider', () => {
**b** afas
a#b
a`);
assert.strictEqual(folds.ranges.length, 0);
assert.strictEqual(folds.length, 0);
});
test('Should fold from header to end of document', async () => {
@ -32,10 +32,10 @@ a`);
# b
c
d`);
assert.strictEqual(folds.ranges.length, 1);
const firstFold = folds.ranges[0];
assert.strictEqual(firstFold.startLine, 1);
assert.strictEqual(firstFold.endLine, 3);
assert.strictEqual(folds.length, 1);
const firstFold = folds[0];
assert.strictEqual(firstFold.start, 1);
assert.strictEqual(firstFold.end, 3);
});
test('Should leave single newline before next header', async () => {
@ -45,10 +45,10 @@ x
# b
y`);
assert.strictEqual(folds.ranges.length, 2);
const firstFold = folds.ranges[0];
assert.strictEqual(firstFold.startLine, 1);
assert.strictEqual(firstFold.endLine, 3);
assert.strictEqual(folds.length, 2);
const firstFold = folds[0];
assert.strictEqual(firstFold.start, 1);
assert.strictEqual(firstFold.end, 3);
});
test('Should collapse multuple newlines to single newline before next header', async () => {
@ -60,10 +60,10 @@ x
# b
y`);
assert.strictEqual(folds.ranges.length, 2);
const firstFold = folds.ranges[0];
assert.strictEqual(firstFold.startLine, 1);
assert.strictEqual(firstFold.endLine, 5);
assert.strictEqual(folds.length, 2);
const firstFold = folds[0];
assert.strictEqual(firstFold.start, 1);
assert.strictEqual(firstFold.end, 5);
});
test('Should not collapse if there is no newline before next header', async () => {
@ -72,10 +72,10 @@ y`);
x
# b
y`);
assert.strictEqual(folds.ranges.length, 2);
const firstFold = folds.ranges[0];
assert.strictEqual(firstFold.startLine, 1);
assert.strictEqual(firstFold.endLine, 2);
assert.strictEqual(folds.length, 2);
const firstFold = folds[0];
assert.strictEqual(firstFold.start, 1);
assert.strictEqual(firstFold.end, 2);
});
});

View file

@ -9,7 +9,7 @@ import * as Proto from '../protocol';
import * as typeConverters from '../utils/typeConverters';
import { ITypeScriptServiceClient } from '../typescriptService';
export default class TypeScriptFoldingProvider implements vscode.FoldingProvider {
export default class TypeScriptFoldingProvider implements vscode.FoldingRangeProvider {
public constructor(
private readonly client: ITypeScriptServiceClient
) { }
@ -18,7 +18,7 @@ export default class TypeScriptFoldingProvider implements vscode.FoldingProvider
document: vscode.TextDocument,
_context: vscode.FoldingContext,
token: vscode.CancellationToken
): Promise<vscode.FoldingRangeList | undefined> {
): Promise<vscode.FoldingRange[] | undefined> {
if (!this.client.apiVersion.has280Features()) {
return;
}
@ -34,13 +34,13 @@ export default class TypeScriptFoldingProvider implements vscode.FoldingProvider
return;
}
return new vscode.FoldingRangeList(response.body.map(span => {
return response.body.map(span => {
const range = typeConverters.Range.fromTextSpan(span.textSpan);
// workaround for #47240
if (range.end.character > 0 && document.getText(new vscode.Range(range.end.translate(0, -1), range.end)) === '}') {
return new vscode.FoldingRange(range.start.line, Math.max(range.end.line - 1, range.start.line));
}
return new vscode.FoldingRange(range.start.line, range.end.line);
}));
});
}
}

View file

@ -159,7 +159,7 @@ export default class LanguageProvider {
let enable = workspace.getConfiguration().get(foldingSetting, false);
if (enable && this.client.apiVersion.has280Features()) {
if (!this.foldingProviderRegistration) {
this.foldingProviderRegistration = languages.registerFoldingProvider(this.documentSelector, new (await import('./features/foldingProvider')).default(this.client));
this.foldingProviderRegistration = languages.registerFoldingRangeProvider(this.documentSelector, new (await import('./features/foldingProvider')).default(this.client));
}
} else {
if (this.foldingProviderRegistration) {

View file

@ -835,7 +835,6 @@ export interface DocumentColorProvider {
* @internal
*/
export interface FoldingContext {
maxRanges?: number;
}
/**
@ -844,59 +843,61 @@ export interface FoldingContext {
/**
* @internal
*/
export interface FoldingProvider {
export interface FoldingRangeProvider {
/**
* Provides the color ranges for a specific model.
*/
provideFoldingRanges(model: model.ITextModel, context: FoldingContext, token: CancellationToken): IFoldingRangeList | Thenable<IFoldingRangeList>;
provideFoldingRanges(model: model.ITextModel, context: FoldingContext, token: CancellationToken): IFoldingRange[] | Thenable<IFoldingRange[]>;
}
/**
* @internal
*/
export interface IFoldingRangeList {
ranges: IFoldingRange[];
}
/**
* @internal
*/
export interface IFoldingRange {
/**
* The start line number
* The zero-based start line of the range to fold. The folded area starts after the line's last character.
*/
startLineNumber: number;
start: number;
/**
* The end line number
* The zero-based end line of the range to fold. The folded area ends with the line's last character.
*/
endLineNumber: number;
end: number;
/**
* The optional type of the folding range
* Describes the [Kind](#FoldingRangeKind) of the folding range such as [Comment](#FoldingRangeKind.Comment) or
* [Region](#FoldingRangeKind.Region). The kind is used to categorize folding ranges and used by commands
* like 'Fold all comments'. See
* [FoldingRangeKind](#FoldingRangeKind) for an enumeration of standardized kinds.
*/
type?: FoldingRangeType | string;
// auto-collapse
// header span
kind?: FoldingRangeKind;
}
/**
* @internal
*/
export enum FoldingRangeType {
export class FoldingRangeKind {
/**
* Folding range for a comment
* Kind for folding range representing a comment. The value of the kind is 'comment'.
*/
Comment = 'comment',
static readonly Comment = new FoldingRangeKind('comment');
/**
* Folding range for a imports or includes
* Kind for folding range representing a import. The value of the kind is 'imports'.
*/
Imports = 'imports',
static readonly Imports = new FoldingRangeKind('imports');
/**
* Folding range for a region (e.g. `#region`)
* Kind for folding range representing regions (for example marked by `#region`, `#endregion`).
* The value of the kind is 'region'.
*/
Region = 'region'
static readonly Region = new FoldingRangeKind('region');
/**
* Creates a new [FoldingRangeKind](#FoldingRangeKind).
*
* @param value of the kind.
*/
public constructor(public value: string) {
}
}
/**
@ -1047,7 +1048,7 @@ export const ColorProviderRegistry = new LanguageFeatureRegistry<DocumentColorPr
/**
* @internal
*/
export const FoldingProviderRegistry = new LanguageFeatureRegistry<FoldingProvider>();
export const FoldingRangeProviderRegistry = new LanguageFeatureRegistry<FoldingRangeProvider>();
/**
* @internal

View file

@ -28,7 +28,7 @@ import { IRange } from 'vs/editor/common/core/range';
import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry';
import { IndentRangeProvider } from 'vs/editor/contrib/folding/indentRangeProvider';
import { IPosition } from 'vs/editor/common/core/position';
import { FoldingProviderRegistry, FoldingRangeType } from 'vs/editor/common/modes';
import { FoldingRangeProviderRegistry, FoldingRangeKind } from 'vs/editor/common/modes';
import { SyntaxRangeProvider } from './syntaxRangeProvider';
import { CancellationToken } from 'vs/base/common/cancellation';
@ -82,7 +82,7 @@ export class FoldingController implements IEditorContribution {
this.foldingDecorationProvider.autoHideFoldingControls = this._autoHideFoldingControls;
this.globalToDispose.push(this.editor.onDidChangeModel(() => this.onModelChanged()));
this.globalToDispose.push(FoldingProviderRegistry.onDidChange(() => this.onFoldingStrategyChanged()));
this.globalToDispose.push(FoldingRangeProviderRegistry.onDidChange(() => this.onFoldingStrategyChanged()));
this.globalToDispose.push(this.editor.onDidChangeConfiguration((e: IConfigurationChangedEvent) => {
if (e.contribInfo) {
@ -205,7 +205,7 @@ export class FoldingController implements IEditorContribution {
private getRangeProvider(): RangeProvider {
if (!this.rangeProvider) {
if (this._useFoldingProviders) {
let foldingProviders = FoldingProviderRegistry.ordered(this.foldingModel.textModel);
let foldingProviders = FoldingRangeProviderRegistry.ordered(this.foldingModel.textModel);
this.rangeProvider = foldingProviders.length ? new SyntaxRangeProvider(foldingProviders) : new IndentRangeProvider();
} else {
this.rangeProvider = new IndentRangeProvider();
@ -584,7 +584,7 @@ class FoldAllBlockCommentsAction extends FoldingAction<void> {
invoke(foldingController: FoldingController, foldingModel: FoldingModel, editor: ICodeEditor): void {
if (foldingModel.regions.hasTypes()) {
setCollapseStateForType(foldingModel, FoldingRangeType.Comment, true);
setCollapseStateForType(foldingModel, FoldingRangeKind.Comment.value, true);
} else {
let comments = LanguageConfigurationRegistry.getComments(editor.getModel().getLanguageIdentifier().id);
if (comments && comments.blockCommentStartToken) {
@ -612,7 +612,7 @@ class FoldAllRegionsAction extends FoldingAction<void> {
invoke(foldingController: FoldingController, foldingModel: FoldingModel, editor: ICodeEditor): void {
if (foldingModel.regions.hasTypes()) {
setCollapseStateForType(foldingModel, FoldingRangeType.Region, true);
setCollapseStateForType(foldingModel, FoldingRangeKind.Region.value, true);
} else {
let foldingRules = LanguageConfigurationRegistry.getFoldingRules(editor.getModel().getLanguageIdentifier().id);
if (foldingRules && foldingRules.markers && foldingRules.markers.start) {
@ -640,7 +640,7 @@ class UnfoldAllRegionsAction extends FoldingAction<void> {
invoke(foldingController: FoldingController, foldingModel: FoldingModel, editor: ICodeEditor): void {
if (foldingModel.regions.hasTypes()) {
setCollapseStateForType(foldingModel, FoldingRangeType.Region, false);
setCollapseStateForType(foldingModel, FoldingRangeKind.Region.value, false);
} else {
let foldingRules = LanguageConfigurationRegistry.getFoldingRules(editor.getModel().getLanguageIdentifier().id);
if (foldingRules && foldingRules.markers && foldingRules.markers.start) {

View file

@ -5,7 +5,7 @@
'use strict';
import { FoldingProvider, IFoldingRange, FoldingContext } from 'vs/editor/common/modes';
import { FoldingRangeProvider, IFoldingRange, FoldingContext } from 'vs/editor/common/modes';
import { onUnexpectedExternalError } from 'vs/base/common/errors';
import { toThenable } from 'vs/base/common/async';
import { ITextModel } from 'vs/editor/common/model';
@ -26,7 +26,7 @@ const foldingContext: FoldingContext = {
export class SyntaxRangeProvider implements RangeProvider {
constructor(private providers: FoldingProvider[]) {
constructor(private providers: FoldingRangeProvider[]) {
}
compute(model: ITextModel, cancellationToken: CancellationToken): Thenable<FoldingRegions> {
@ -41,23 +41,23 @@ export class SyntaxRangeProvider implements RangeProvider {
}
function collectSyntaxRanges(providers: FoldingProvider[], model: ITextModel, cancellationToken: CancellationToken): Thenable<IFoldingRangeData[] | null> {
function collectSyntaxRanges(providers: FoldingRangeProvider[], model: ITextModel, cancellationToken: CancellationToken): Thenable<IFoldingRangeData[] | null> {
let promises = providers.map(provider => toThenable(provider.provideFoldingRanges(model, foldingContext, cancellationToken)));
return TPromise.join(promises).then(lists => {
return TPromise.join(promises).then(results => {
let rangeData: IFoldingRangeData[] = null;
if (cancellationToken.isCancellationRequested) {
return null;
}
for (let i = 0; i < lists.length; i++) {
let list = lists[i];
if (list && Array.isArray(list.ranges)) {
for (let i = 0; i < results.length; i++) {
let ranges = results[i];
if (Array.isArray(ranges)) {
if (!Array.isArray(rangeData)) {
rangeData = [];
}
let nLines = model.getLineCount();
for (let r of list.ranges) {
if (r.startLineNumber > 0 && r.endLineNumber > r.startLineNumber && r.endLineNumber <= nLines) {
rangeData.push({ startLineNumber: r.startLineNumber, endLineNumber: r.endLineNumber, rank: i, type: r.type });
for (let r of ranges) {
if (r.start > 0 && r.end > r.start && r.end <= nLines) {
rangeData.push({ start: r.start, end: r.end, rank: i, kind: r.kind });
}
}
}
@ -145,7 +145,7 @@ export class RangesCollector {
export function sanitizeRanges(rangeData: IFoldingRangeData[]): FoldingRegions {
let sorted = rangeData.sort((d1, d2) => {
let diff = d1.startLineNumber - d2.startLineNumber;
let diff = d1.start - d2.start;
if (diff === 0) {
diff = d1.rank - d2.rank;
}
@ -158,20 +158,20 @@ export function sanitizeRanges(rangeData: IFoldingRangeData[]): FoldingRegions {
for (let entry of sorted) {
if (!top) {
top = entry;
collector.add(entry.startLineNumber, entry.endLineNumber, entry.type, previous.length);
collector.add(entry.start, entry.end, entry.kind && entry.kind.value, previous.length);
} else {
if (entry.startLineNumber > top.startLineNumber) {
if (entry.endLineNumber <= top.endLineNumber) {
if (entry.start > top.start) {
if (entry.end <= top.end) {
previous.push(top);
top = entry;
collector.add(entry.startLineNumber, entry.endLineNumber, entry.type, previous.length);
} else if (entry.startLineNumber > top.endLineNumber) {
collector.add(entry.start, entry.end, entry.kind && entry.kind.value, previous.length);
} else if (entry.start > top.end) {
do {
top = previous.pop();
} while (top && entry.startLineNumber > top.endLineNumber);
} while (top && entry.start > top.end);
previous.push(top);
top = entry;
collector.add(entry.startLineNumber, entry.endLineNumber, entry.type, previous.length);
collector.add(entry.start, entry.end, entry.kind && entry.kind.value, previous.length);
}
}
}

View file

@ -13,88 +13,104 @@ declare module 'vscode' {
//#region Aeschli: folding
export class FoldingRangeList {
/**
* The folding ranges.
*/
ranges: FoldingRange[];
/**
* Creates new folding range list.
*
* @param ranges The folding ranges
*/
constructor(ranges: FoldingRange[]);
}
export class FoldingRange {
/**
* The start line number (zero-based) of the range to fold. The hidden area starts after the last character of that line.
* The zero-based start line of the range to fold. The folded area starts after the line's last character.
*/
startLine: number;
start: number;
/**
* The end line number (0-based) of the range to fold. The hidden area ends at the last character of that line.
* The zero-based end line of the range to fold. The folded area ends with the line's last character.
*/
endLine: number;
end: number;
/**
* The actual color value for this color range.
* Describes the [Kind](#FoldingRangeKind) of the folding range such as [Comment](#FoldingRangeKind.Comment) or
* [Region](#FoldingRangeKind.Region). The kind is used to categorize folding ranges and used by commands
* like 'Fold all comments'. See
* [FoldingRangeKind](#FoldingRangeKind) for an enumeration of standardized kinds.
*/
type?: FoldingRangeType | string;
kind?: FoldingRangeKind;
/**
* Creates a new folding range.
*
* @param startLineNumber The first line of the fold
* @param type The last line of the fold
* @param start The start line of the folded range.
* @param end The end line of the folded range.
* @param kind The kind of the folding range.
*/
constructor(startLineNumber: number, endLineNumber: number, type?: FoldingRangeType | string);
constructor(start: number, end: number, kind?: FoldingRangeKind);
}
export enum FoldingRangeType {
export class FoldingRangeKind {
/**
* Folding range for a comment
* Kind for folding range representing a comment. The value of the kind is 'comment'.
*/
Comment = 'comment',
static readonly Comment: FoldingRangeKind;
/**
* Folding range for a imports or includes
* Kind for folding range representing a import. The value of the kind is 'imports'.
*/
Imports = 'imports',
static readonly Imports: FoldingRangeKind;
/**
* Folding range for a region (e.g. `#region`)
* Kind for folding range representing regions (for example a folding range marked by `#region` and `#endregion`).
* The value of the kind is 'region'.
*/
Region = 'region'
static readonly Region: FoldingRangeKind;
/**
* String value of the kind, e.g. `comment`.
*/
readonly value: string;
/**
* Creates a new [FoldingRangeKind](#FoldingRangeKind).
*
* @param value of the kind.
*/
public constructor(value: string);
}
export namespace languages {
/**
* Register a folding provider.
* Register a folding range provider.
*
* Multiple folding can be registered for a language. In that case providers are sorted
* by their [score](#languages.match) and the best-matching provider is used. Failure
* of the selected provider will cause a failure of the whole operation.
*
* @param selector A selector that defines the documents this provider is applicable to.
* @param provider A folding provider.
* @param provider A folding range provider.
* @param metadata Metadata about the kind of code actions the provider providers.
* @return A [disposable](#Disposable) that unregisters this provider when being disposed.
*/
export function registerFoldingProvider(selector: DocumentSelector, provider: FoldingProvider): Disposable;
export function registerFoldingRangeProvider(selector: DocumentSelector, provider: FoldingRangeProvider, metadata?: FoldingRangeProviderMetadata): Disposable;
}
export interface FoldingContext {
maxRanges?: number;
}
export interface FoldingProvider {
/**
* Metadata about the kind of folding ranges that a [FoldingRangeProvider](#FoldingRangeProvider) providers uses.
*/
export interface FoldingRangeProviderMetadata {
/**
* Returns a list of folding ranges or null if the provider does not want to participate or was cancelled.
* [FoldingRangeKind](#FoldingRangeKind) that this provider may return.
*/
provideFoldingRanges(document: TextDocument, context: FoldingContext, token: CancellationToken): ProviderResult<FoldingRangeList>;
readonly providedFoldingRangeKinds?: ReadonlyArray<FoldingRangeKind>;
}
/**
* Folding context (for future use)
*/
export interface FoldingContext {
}
export interface FoldingRangeProvider {
/**
* Returns a list of folding ranges or null and undefined if the provider
* does not want to participate or was cancelled.
* @param document The document in which the command was invoked.
* @param context Additional context information (for future use)
* @param token A cancellation token.
*/
provideFoldingRanges(document: TextDocument, context: FoldingContext, token: CancellationToken): ProviderResult<FoldingRange[]>;
}
//#endregion
@ -242,9 +258,9 @@ declare module 'vscode' {
readonly onDidChangeFile: Event<FileChange2[]>;
/**
* Subscribe to events in the file or folder denoted by `uri`.
* @param uri
* @param options
* Subscribe to events in the file or folder denoted by `uri`.
* @param uri
* @param options
*/
watch(uri: Uri, options: { recursive?: boolean; excludes?: string[] }): Disposable;
@ -269,7 +285,7 @@ declare module 'vscode' {
/**
* Create a new directory. *Note* that new files are created via `write`-calls.
*
*
* @param uri The uri of the *new* folder.
* @param token A cancellation token.
*/

View file

@ -349,9 +349,9 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
// --- folding
$registerFoldingProvider(handle: number, selector: ISerializedDocumentFilter[]): void {
$registerFoldingRangeProvider(handle: number, selector: ISerializedDocumentFilter[]): void {
const proxy = this._proxy;
this._registrations[handle] = modes.FoldingProviderRegistry.register(toLanguageSelector(selector), <modes.FoldingProvider>{
this._registrations[handle] = modes.FoldingRangeProviderRegistry.register(toLanguageSelector(selector), <modes.FoldingRangeProvider>{
provideFoldingRanges: (model, context, token) => {
return wireCancellationToken(token, proxy.$provideFoldingRanges(handle, model.uri, context));
}

View file

@ -328,8 +328,8 @@ export function createApiFactory(
registerColorProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentColorProvider): vscode.Disposable {
return extHostLanguageFeatures.registerColorProvider(checkSelector(selector), provider);
},
registerFoldingProvider: proposedApiFunction(extension, (selector: vscode.DocumentSelector, provider: vscode.FoldingProvider): vscode.Disposable => {
return extHostLanguageFeatures.registerFoldingProvider(checkSelector(selector), provider);
registerFoldingRangeProvider: proposedApiFunction(extension, (selector: vscode.DocumentSelector, provider: vscode.FoldingRangeProvider): vscode.Disposable => {
return extHostLanguageFeatures.registerFoldingRangeProvider(checkSelector(selector), provider);
}),
setLanguageConfiguration: (language: string, configuration: vscode.LanguageConfiguration): vscode.Disposable => {
return extHostLanguageFeatures.setLanguageConfiguration(language, configuration);
@ -714,9 +714,8 @@ export function createApiFactory(
FileType2: extHostTypes.FileType2,
FileOpenFlags: files.FileOpenFlags,
FileError: files.FileError,
FoldingRangeList: extHostTypes.FoldingRangeList,
FoldingRange: extHostTypes.FoldingRange,
FoldingRangeType: extHostTypes.FoldingRangeType
FoldingRangeKind: extHostTypes.FoldingRangeKind
};
};
}

View file

@ -283,7 +283,7 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable {
$registerSignatureHelpProvider(handle: number, selector: ISerializedDocumentFilter[], triggerCharacter: string[]): void;
$registerDocumentLinkProvider(handle: number, selector: ISerializedDocumentFilter[]): void;
$registerDocumentColorProvider(handle: number, selector: ISerializedDocumentFilter[]): void;
$registerFoldingProvider(handle: number, selector: ISerializedDocumentFilter[]): void;
$registerFoldingRangeProvider(handle: number, selector: ISerializedDocumentFilter[]): void;
$setLanguageConfiguration(handle: number, languageId: string, configuration: ISerializedLanguageConfiguration): void;
}
@ -722,7 +722,7 @@ export interface ExtHostLanguageFeaturesShape {
$resolveDocumentLink(handle: number, link: modes.ILink): TPromise<modes.ILink>;
$provideDocumentColors(handle: number, resource: UriComponents): TPromise<IRawColorInfo[]>;
$provideColorPresentations(handle: number, resource: UriComponents, colorInfo: IRawColorInfo): TPromise<modes.IColorPresentation[]>;
$provideFoldingRanges(handle: number, resource: UriComponents, context: modes.FoldingContext): TPromise<modes.IFoldingRangeList>;
$provideFoldingRanges(handle: number, resource: UriComponents, context: modes.FoldingContext): TPromise<modes.IFoldingRange[]>;
}
export interface ExtHostQuickOpenShape {

View file

@ -817,16 +817,16 @@ class FoldingProviderAdapter {
constructor(
private _documents: ExtHostDocuments,
private _provider: vscode.FoldingProvider
private _provider: vscode.FoldingRangeProvider
) { }
provideFoldingRanges(resource: URI, context: modes.FoldingContext): TPromise<modes.IFoldingRangeList> {
provideFoldingRanges(resource: URI, context: modes.FoldingContext): TPromise<modes.IFoldingRange[]> {
const doc = this._documents.getDocumentData(resource).document;
return asWinJsPromise(token => this._provider.provideFoldingRanges(doc, context, token)).then(list => {
if (!Array.isArray(list.ranges)) {
return asWinJsPromise(token => this._provider.provideFoldingRanges(doc, context, token)).then(ranges => {
if (!Array.isArray(ranges)) {
return void 0;
}
return TypeConverters.FoldingRangeList.from(list);
return ranges.map(TypeConverters.FoldingRange.from);
});
}
}
@ -1178,13 +1178,13 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
return this._withAdapter(handle, ColorProviderAdapter, adapter => adapter.provideColorPresentations(URI.revive(resource), colorInfo));
}
registerFoldingProvider(selector: vscode.DocumentSelector, provider: vscode.FoldingProvider): vscode.Disposable {
registerFoldingRangeProvider(selector: vscode.DocumentSelector, provider: vscode.FoldingRangeProvider): vscode.Disposable {
const handle = this._addNewAdapter(new FoldingProviderAdapter(this._documents, provider));
this._proxy.$registerFoldingProvider(handle, this._transformDocumentSelector(selector));
this._proxy.$registerFoldingRangeProvider(handle, this._transformDocumentSelector(selector));
return this._createDisposable(handle);
}
$provideFoldingRanges(handle: number, resource: UriComponents, context: vscode.FoldingContext): TPromise<modes.IFoldingRangeList> {
$provideFoldingRanges(handle: number, resource: UriComponents, context: vscode.FoldingContext): TPromise<modes.IFoldingRange[]> {
return this._withAdapter(handle, FoldingProviderAdapter, adapter => adapter.provideFoldingRanges(URI.revive(resource), context));
}

View file

@ -623,11 +623,9 @@ export namespace ProgressLocation {
}
}
export namespace FoldingRangeList {
export function from(rangeList: vscode.FoldingRangeList): modes.IFoldingRangeList {
return {
ranges: rangeList.ranges.map(r => ({ startLineNumber: r.startLine + 1, endLineNumber: r.endLine + 1, type: r.type }))
};
export namespace FoldingRange {
export function from(r: vscode.FoldingRange): modes.IFoldingRange {
return { start: r.start + 1, end: r.end + 1, kind: r.kind };
}
}

View file

@ -1841,43 +1841,43 @@ export enum FileType2 {
//#region folding api
export class FoldingRangeList {
ranges: FoldingRange[];
constructor(ranges: FoldingRange[]) {
this.ranges = ranges;
}
}
export class FoldingRange {
startLine: number;
start: number;
endLine: number;
end: number;
type?: FoldingRangeType | string;
kind?: FoldingRangeKind;
constructor(startLine: number, endLine: number, type?: FoldingRangeType | string) {
this.startLine = startLine;
this.endLine = endLine;
this.type = type;
constructor(start: number, end: number, kind?: FoldingRangeKind) {
this.start = start;
this.end = end;
this.kind = kind;
}
}
export enum FoldingRangeType {
export class FoldingRangeKind {
/**
* Folding range for a comment
* Kind for folding range representing a comment. The value of the kind is 'comment'.
*/
Comment = 'comment',
static readonly Comment = new FoldingRangeKind('comment');
/**
* Folding range for a imports or includes
* Kind for folding range representing a import. The value of the kind is 'imports'.
*/
Imports = 'imports',
static readonly Imports = new FoldingRangeKind('imports');
/**
* Folding range for a region (e.g. `#region`)
* Kind for folding range representing regions (for example marked by `#region`, `#endregion`).
* The value of the kind is 'region'.
*/
Region = 'region'
static readonly Region = new FoldingRangeKind('region');
/**
* Creates a new [FoldingRangeKind](#FoldingRangeKind).
*
* @param value of the kind.
*/
public constructor(public value: string) {
}
}
//#endregion