diff --git a/src/vs/editor/common/modes.ts b/src/vs/editor/common/modes.ts index 8ad364cad9d..345889c9744 100644 --- a/src/vs/editor/common/modes.ts +++ b/src/vs/editor/common/modes.ts @@ -1036,7 +1036,7 @@ export interface SelectionRangeProvider { /** * Provide ranges that should be selected from the given position. */ - provideSelectionRanges(model: model.ITextModel, position: Position, token: CancellationToken): ProviderResult; + provideSelectionRanges(model: model.ITextModel, position: Position, token: CancellationToken): ProviderResult; } export interface FoldingContext { diff --git a/src/vs/editor/contrib/smartSelect/smartSelect.ts b/src/vs/editor/contrib/smartSelect/smartSelect.ts index 912f44c25be..06ad8b73d77 100644 --- a/src/vs/editor/contrib/smartSelect/smartSelect.ts +++ b/src/vs/editor/contrib/smartSelect/smartSelect.ts @@ -223,7 +223,7 @@ export function provideSelectionRanges(model: ITextModel, position: Position, to if (arrays.isNonEmptyArray(res)) { for (const range of res) { if (Range.isIRange(range) && Range.containsPosition(range, position)) { - ranges.push({ range, rank }); + ranges.push({ range: Range.lift(range), rank }); } } } diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 13e9d5eb9b8..7760bd43b91 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -5303,7 +5303,7 @@ declare namespace monaco.languages { /** * Provide ranges that should be selected from the given position. */ - provideSelectionRanges(model: editor.ITextModel, position: Position, token: CancellationToken): ProviderResult; + provideSelectionRanges(model: editor.ITextModel, position: Position, token: CancellationToken): ProviderResult; } export interface FoldingContext { diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 386afb912b2..7e13ec58c38 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -20,6 +20,18 @@ declare module 'vscode' { export function sampleFunction(): Thenable; } + //#region Joh - selection range provider + + export interface SelectionRangeProvider { + provideSelectionRanges(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; + } + + export namespace languages { + export function registerSelectionRangeProvider(selector: DocumentSelector, provider: SelectionRangeProvider): Disposable; + } + + //#endregion + //#region Joh - read/write in chunks export interface FileSystemProvider { diff --git a/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts b/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts index 2d31b7541ab..a78ff21c63a 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts @@ -379,6 +379,16 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha }); } + // -- smart select + + $registerSelectionRangeProvider(handle: number, selector: ISerializedDocumentFilter[]): void { + this._registrations[handle] = modes.SelectionRangeRegistry.register(typeConverters.LanguageSelector.from(selector), { + provideSelectionRanges: (model, position, token) => { + return this._proxy.$provideSelectionRanges(handle, model.uri, position, token); + } + }); + } + // --- configuration private static _reviveRegExp(regExp: ISerializedRegExp): RegExp { diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index b58819bc96a..576bbcaea6e 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -354,6 +354,9 @@ export function createApiFactory( registerFoldingRangeProvider(selector: vscode.DocumentSelector, provider: vscode.FoldingRangeProvider): vscode.Disposable { return extHostLanguageFeatures.registerFoldingRangeProvider(extension, checkSelector(selector), provider); }, + registerSelectionRangeProvider(selector: vscode.DocumentSelector, provider: vscode.SelectionRangeProvider): vscode.Disposable { + return extHostLanguageFeatures.registerSelectionRangeProvider(extension, selector, provider); + }, setLanguageConfiguration: (language: string, configuration: vscode.LanguageConfiguration): vscode.Disposable => { return extHostLanguageFeatures.setLanguageConfiguration(language, configuration); } diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index c58857be4ff..f1f5a4156ab 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -308,6 +308,7 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable { $registerDocumentLinkProvider(handle: number, selector: ISerializedDocumentFilter[]): void; $registerDocumentColorProvider(handle: number, selector: ISerializedDocumentFilter[]): void; $registerFoldingRangeProvider(handle: number, selector: ISerializedDocumentFilter[]): void; + $registerSelectionRangeProvider(handle: number, selector: ISerializedDocumentFilter[]): void; $setLanguageConfiguration(handle: number, languageId: string, configuration: ISerializedLanguageConfiguration): void; } @@ -885,6 +886,7 @@ export interface ExtHostLanguageFeaturesShape { $provideDocumentColors(handle: number, resource: UriComponents, token: CancellationToken): Thenable; $provideColorPresentations(handle: number, resource: UriComponents, colorInfo: IRawColorInfo, token: CancellationToken): Thenable; $provideFoldingRanges(handle: number, resource: UriComponents, context: modes.FoldingContext, token: CancellationToken): Thenable; + $provideSelectionRanges(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Thenable; } export interface ExtHostQuickOpenShape { diff --git a/src/vs/workbench/api/node/extHostLanguageFeatures.ts b/src/vs/workbench/api/node/extHostLanguageFeatures.ts index 6416510e26b..fd9008b2815 100644 --- a/src/vs/workbench/api/node/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/node/extHostLanguageFeatures.ts @@ -850,11 +850,31 @@ class FoldingProviderAdapter { } } +class SelectionRangeAdapter { + + constructor( + private readonly _documents: ExtHostDocuments, + private readonly _provider: vscode.SelectionRangeProvider + ) { } + + provideSelectionRanges(resource: URI, position: IPosition, token: CancellationToken): Promise { + const { document } = this._documents.getDocumentData(resource); + const pos = typeConvert.Position.to(position); + return asThenable(() => this._provider.provideSelectionRanges(document, pos, token)).then(ranges => { + if (isNonEmptyArray(ranges)) { + return ranges.map(typeConvert.Range.from); + } else { + return undefined; + } + }); + } +} + type Adapter = OutlineAdapter | CodeLensAdapter | DefinitionAdapter | HoverAdapter | DocumentHighlightAdapter | ReferenceAdapter | CodeActionAdapter | DocumentFormattingAdapter | RangeFormattingAdapter | OnTypeFormattingAdapter | NavigateTypeAdapter | RenameAdapter | SuggestAdapter | SignatureHelpAdapter | LinkProviderAdapter | ImplementationAdapter | TypeDefinitionAdapter - | ColorProviderAdapter | FoldingProviderAdapter | DeclarationAdapter; + | ColorProviderAdapter | FoldingProviderAdapter | DeclarationAdapter | SelectionRangeAdapter; class AdapterData { constructor( @@ -1248,6 +1268,18 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return this._withAdapter(handle, FoldingProviderAdapter, adapter => adapter.provideFoldingRanges(URI.revive(resource), context, token)); } + // --- smart select + + registerSelectionRangeProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.SelectionRangeProvider): vscode.Disposable { + const handle = this._addNewAdapter(new SelectionRangeAdapter(this._documents, provider), extension); + this._proxy.$registerSelectionRangeProvider(handle, this._transformDocumentSelector(selector)); + return this._createDisposable(handle); + } + + $provideSelectionRanges(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Thenable { + return this._withAdapter(handle, SelectionRangeAdapter, adapter => adapter.provideSelectionRanges(URI.revive(resource), position, token)); + } + // --- configuration private static _serializeRegExp(regExp: RegExp): ISerializedRegExp {