mirror of
https://github.com/Microsoft/vscode
synced 2024-10-06 03:17:00 +00:00
Add multi-document highlight provider feature (#198467)
* multi-doc api + text provider editor feature + extHost hookup + typescript semantic multi-doc * fix disposable leak, wasn't setting providers to the disposableMap * filter unnecessary models to fix errors with typescript provider * fix nits (todo - doc filter) * fix typo from merge conflict * expose LanguageSelector in multi-doc provider, filter out 0 score models
This commit is contained in:
parent
ab4f71b394
commit
e33219dde3
|
@ -8,8 +8,9 @@
|
|||
"license": "MIT",
|
||||
"aiKey": "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255",
|
||||
"enabledApiProposals": [
|
||||
"mappedEditsProvider",
|
||||
"workspaceTrust"
|
||||
"workspaceTrust",
|
||||
"multiDocumentHighlightProvider",
|
||||
"mappedEditsProvider"
|
||||
],
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": {
|
||||
|
|
|
@ -9,11 +9,43 @@ import type * as Proto from '../tsServer/protocol/protocol';
|
|||
import * as typeConverters from '../typeConverters';
|
||||
import { ITypeScriptServiceClient } from '../typescriptService';
|
||||
|
||||
class TypeScriptDocumentHighlightProvider implements vscode.DocumentHighlightProvider {
|
||||
class TypeScriptDocumentHighlightProvider implements vscode.DocumentHighlightProvider, vscode.MultiDocumentHighlightProvider {
|
||||
public constructor(
|
||||
private readonly client: ITypeScriptServiceClient
|
||||
) { }
|
||||
|
||||
public async provideMultiDocumentHighlights(
|
||||
document: vscode.TextDocument,
|
||||
position: vscode.Position,
|
||||
otherDocuments: vscode.TextDocument[],
|
||||
token: vscode.CancellationToken
|
||||
): Promise<vscode.MultiDocumentHighlight[]> {
|
||||
const allFiles = [document, ...otherDocuments].map(doc => this.client.toOpenTsFilePath(doc)).filter(file => !!file) as string[];
|
||||
const file = this.client.toOpenTsFilePath(document);
|
||||
|
||||
if (!file || allFiles.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const args = {
|
||||
...typeConverters.Position.toFileLocationRequestArgs(file, position),
|
||||
filesToSearch: allFiles
|
||||
};
|
||||
const response = await this.client.execute('documentHighlights', args, token);
|
||||
if (response.type !== 'response' || !response.body) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const result = response.body.map(highlightItem =>
|
||||
new vscode.MultiDocumentHighlight(
|
||||
vscode.Uri.file(highlightItem.file),
|
||||
[...convertDocumentHighlight(highlightItem)]
|
||||
)
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async provideDocumentHighlights(
|
||||
document: vscode.TextDocument,
|
||||
position: vscode.Position,
|
||||
|
@ -48,6 +80,10 @@ export function register(
|
|||
selector: DocumentSelector,
|
||||
client: ITypeScriptServiceClient,
|
||||
) {
|
||||
return vscode.languages.registerDocumentHighlightProvider(selector.syntax,
|
||||
new TypeScriptDocumentHighlightProvider(client));
|
||||
const provider = new TypeScriptDocumentHighlightProvider(client);
|
||||
|
||||
return vscode.Disposable.from(
|
||||
vscode.languages.registerDocumentHighlightProvider(selector.syntax, provider),
|
||||
vscode.languages.registerMultiDocumentHighlightProvider(selector.syntax, provider)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
"include": [
|
||||
"src/**/*",
|
||||
"../../src/vscode-dts/vscode.d.ts",
|
||||
"../../src/vscode-dts/vscode.proposed.workspaceTrust.d.ts",
|
||||
"../../src/vscode-dts/vscode.proposed.multiDocumentHighlightProvider.d.ts",
|
||||
"../../src/vscode-dts/vscode.proposed.mappedEditsProvider.d.ts",
|
||||
"../../src/vscode-dts/vscode.proposed.workspaceTrust.d.ts"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import { ContiguousMultilineTokens } from 'vs/editor/common/tokens/contiguousMul
|
|||
import { localize } from 'vs/nls';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { IMarkerData } from 'vs/platform/markers/common/markers';
|
||||
import { LanguageFilter } from 'vs/editor/common/languageSelector';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
@ -953,6 +954,22 @@ export interface DocumentHighlight {
|
|||
*/
|
||||
kind?: DocumentHighlightKind;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a set of document highlights for a specific URI.
|
||||
*/
|
||||
export interface MultiDocumentHighlight {
|
||||
/**
|
||||
* The URI of the document that the highlights belong to.
|
||||
*/
|
||||
uri: URI;
|
||||
|
||||
/**
|
||||
* The set of highlights for the document.
|
||||
*/
|
||||
highlights: DocumentHighlight[];
|
||||
}
|
||||
|
||||
/**
|
||||
* The document highlight provider interface defines the contract between extensions and
|
||||
* the word-highlight-feature.
|
||||
|
@ -965,13 +982,24 @@ export interface DocumentHighlightProvider {
|
|||
provideDocumentHighlights(model: model.ITextModel, position: Position, token: CancellationToken): ProviderResult<DocumentHighlight[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A provider that can provide document highlights across multiple documents.
|
||||
*/
|
||||
export interface MultiDocumentHighlightProvider {
|
||||
selector: LanguageFilter;
|
||||
|
||||
/**
|
||||
* Provide a Map of URI --> document highlights, like all occurrences of a variable or
|
||||
* all exit-points of a function.
|
||||
*
|
||||
* Used in cases such as split view, notebooks, etc. where there can be multiple documents
|
||||
* with shared symbols.
|
||||
*
|
||||
* @param primaryModel The primary text model.
|
||||
* @param position The position at which to provide document highlights.
|
||||
* @param otherModels The other text models to search for document highlights.
|
||||
* @param token A cancellation token.
|
||||
* @returns A map of URI to document highlights.
|
||||
*/
|
||||
provideMultiDocumentHighlights(primaryModel: model.ITextModel, position: Position, otherModels: model.ITextModel[], token: CancellationToken): ProviderResult<Map<URI, DocumentHighlight[]>>;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { USUAL_WORD_SEPARATORS } from 'vs/editor/common/core/wordHelper';
|
||||
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
|
||||
import { DocumentHighlight, DocumentHighlightKind, MultiDocumentHighlightProvider, ProviderResult } from 'vs/editor/common/languages';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { ResourceMap } from 'vs/base/common/map';
|
||||
import { LanguageFilter } from 'vs/editor/common/languageSelector';
|
||||
|
||||
|
||||
class TextualDocumentHighlightProvider implements MultiDocumentHighlightProvider {
|
||||
|
||||
selector: LanguageFilter = { language: '*' };
|
||||
|
||||
provideMultiDocumentHighlights(primaryModel: ITextModel, position: Position, otherModels: ITextModel[], token: CancellationToken): ProviderResult<ResourceMap<DocumentHighlight[]>> {
|
||||
|
||||
const result = new ResourceMap<DocumentHighlight[]>();
|
||||
|
||||
const word = primaryModel.getWordAtPosition({
|
||||
lineNumber: position.lineNumber,
|
||||
column: position.column
|
||||
});
|
||||
if (!word) {
|
||||
return Promise.resolve(result);
|
||||
}
|
||||
|
||||
|
||||
for (const model of [primaryModel, ...otherModels]) {
|
||||
if (model.isDisposed()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const matches = model.findMatches(word.word, true, false, true, USUAL_WORD_SEPARATORS, false);
|
||||
const highlights = matches.map(m => ({
|
||||
range: m.range,
|
||||
kind: DocumentHighlightKind.Text
|
||||
}));
|
||||
|
||||
if (highlights) {
|
||||
result.set(model.uri, highlights);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class TextualMultiDocumentHighlightFeature extends Disposable {
|
||||
constructor(
|
||||
@ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService,
|
||||
) {
|
||||
super();
|
||||
|
||||
this._register(languageFeaturesService.multiDocumentHighlightProvider.register('*', new TextualDocumentHighlightProvider()));
|
||||
}
|
||||
}
|
|
@ -32,6 +32,9 @@ import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation
|
|||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { ResourceMap } from 'vs/base/common/map';
|
||||
import { score } from 'vs/editor/common/languageSelector';
|
||||
// import { TextualMultiDocumentHighlightFeature } from 'vs/editor/contrib/wordHighlighter/browser/textualHighlightProvider';
|
||||
// import { registerEditorFeature } from 'vs/editor/common/editorFeatures';
|
||||
|
||||
const ctxHasWordHighlights = new RawContextKey<boolean>('hasWordHighlights', false);
|
||||
|
||||
|
@ -61,9 +64,13 @@ export function getOccurrencesAcrossMultipleModels(registry: LanguageFeatureRegi
|
|||
// until someone response with a good result
|
||||
// (good = none empty array)
|
||||
return first<ResourceMap<DocumentHighlight[]> | null | undefined>(orderedByScore.map(provider => () => {
|
||||
return Promise.resolve(provider.provideMultiDocumentHighlights(model, position, otherModels, token))
|
||||
const filteredModels = otherModels.filter(otherModel => {
|
||||
return score(provider.selector, otherModel.uri, otherModel.getLanguageId(), true, undefined, undefined) > 0;
|
||||
});
|
||||
|
||||
return Promise.resolve(provider.provideMultiDocumentHighlights(model, position, filteredModels, token))
|
||||
.then(undefined, onUnexpectedExternalError);
|
||||
}), (t: ResourceMap<DocumentHighlight[]> | null | undefined): t is ResourceMap<DocumentHighlight[]> => t instanceof Map && t.size > 0);
|
||||
}), (t: ResourceMap<DocumentHighlight[]> | null | undefined): t is ResourceMap<DocumentHighlight[]> => t instanceof ResourceMap && t.size > 0);
|
||||
}
|
||||
|
||||
interface IOccurenceAtPositionRequest {
|
||||
|
@ -585,7 +592,10 @@ class WordHighlighter {
|
|||
// multi-doc ON
|
||||
for (const editor of currentEditors) {
|
||||
const tempModel = editor.getModel();
|
||||
if (tempModel && tempModel !== model) {
|
||||
|
||||
const isValidModel = tempModel && tempModel !== model;
|
||||
|
||||
if (isValidModel) {
|
||||
currentModels.push(tempModel);
|
||||
}
|
||||
}
|
||||
|
@ -910,3 +920,4 @@ registerEditorContribution(WordHighlighterContribution.ID, WordHighlighterContri
|
|||
registerEditorAction(NextWordHighlightAction);
|
||||
registerEditorAction(PrevWordHighlightAction);
|
||||
registerEditorAction(TriggerWordHighlightAction);
|
||||
// registerEditorFeature(TextualMultiDocumentHighlightFeature);
|
||||
|
|
24
src/vs/monaco.d.ts
vendored
24
src/vs/monaco.d.ts
vendored
|
@ -7158,6 +7158,20 @@ declare namespace monaco.languages {
|
|||
kind?: DocumentHighlightKind;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a set of document highlights for a specific Uri.
|
||||
*/
|
||||
export interface MultiDocumentHighlight {
|
||||
/**
|
||||
* The Uri of the document that the highlights belong to.
|
||||
*/
|
||||
uri: Uri;
|
||||
/**
|
||||
* The set of highlights for the document.
|
||||
*/
|
||||
highlights: DocumentHighlight[];
|
||||
}
|
||||
|
||||
/**
|
||||
* The document highlight provider interface defines the contract between extensions and
|
||||
* the word-highlight-feature.
|
||||
|
@ -7170,13 +7184,23 @@ declare namespace monaco.languages {
|
|||
provideDocumentHighlights(model: editor.ITextModel, position: Position, token: CancellationToken): ProviderResult<DocumentHighlight[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A provider that can provide document highlights across multiple documents.
|
||||
*/
|
||||
export interface MultiDocumentHighlightProvider {
|
||||
selector: LanguageFilter;
|
||||
/**
|
||||
* Provide a Map of Uri --> document highlights, like all occurrences of a variable or
|
||||
* all exit-points of a function.
|
||||
*
|
||||
* Used in cases such as split view, notebooks, etc. where there can be multiple documents
|
||||
* with shared symbols.
|
||||
*
|
||||
* @param primaryModel The primary text model.
|
||||
* @param position The position at which to provide document highlights.
|
||||
* @param otherModels The other text models to search for document highlights.
|
||||
* @param token A cancellation token.
|
||||
* @returns A map of Uri to document highlights.
|
||||
*/
|
||||
provideMultiDocumentHighlights(primaryModel: editor.ITextModel, position: Position, otherModels: editor.ITextModel[], token: CancellationToken): ProviderResult<Map<Uri, DocumentHighlight[]>>;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ import * as search from 'vs/workbench/contrib/search/common/search';
|
|||
import * as typeh from 'vs/workbench/contrib/typeHierarchy/common/typeHierarchy';
|
||||
import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers';
|
||||
import { ExtHostContext, ExtHostLanguageFeaturesShape, ICallHierarchyItemDto, ICodeActionDto, ICodeActionProviderMetadataDto, IdentifiableInlineCompletion, IdentifiableInlineCompletions, IDocumentDropEditProviderMetadata, IDocumentFilterDto, IIndentationRuleDto, IInlayHintDto, ILanguageConfigurationDto, ILanguageWordDefinitionDto, ILinkDto, ILocationDto, ILocationLinkDto, IOnEnterRuleDto, IPasteEditProviderMetadataDto, IRegExpDto, ISignatureHelpProviderMetadataDto, ISuggestDataDto, ISuggestDataDtoField, ISuggestResultDtoField, ITypeHierarchyItemDto, IWorkspaceSymbolDto, MainContext, MainThreadLanguageFeaturesShape } from '../common/extHost.protocol';
|
||||
import { USUAL_WORD_SEPARATORS } from 'vs/editor/common/core/wordHelper';
|
||||
import { ResourceMap } from 'vs/base/common/map';
|
||||
import { isFalsyOrEmpty } from 'vs/base/common/arrays';
|
||||
|
||||
@extHostNamedCustomer(MainContext.MainThreadLanguageFeatures)
|
||||
|
@ -295,52 +295,35 @@ export class MainThreadLanguageFeatures extends Disposable implements MainThread
|
|||
// --- occurrences
|
||||
|
||||
$registerDocumentHighlightProvider(handle: number, selector: IDocumentFilterDto[]): void {
|
||||
this._registrations.set(handle, combinedDisposable(
|
||||
this._languageFeaturesService.documentHighlightProvider.register(selector, <languages.DocumentHighlightProvider>{
|
||||
provideDocumentHighlights: (model: ITextModel, position: EditorPosition, token: CancellationToken): Promise<languages.DocumentHighlight[] | undefined> => {
|
||||
return this._proxy.$provideDocumentHighlights(handle, model.uri, position, token);
|
||||
}
|
||||
}),
|
||||
this._languageFeaturesService.multiDocumentHighlightProvider.register(selector, <languages.MultiDocumentHighlightProvider>{
|
||||
provideMultiDocumentHighlights: (model: ITextModel, position: EditorPosition, otherModels: ITextModel[], token: CancellationToken): Promise<Map<URI, languages.DocumentHighlight[]>> => {
|
||||
const word = model.getWordAtPosition({
|
||||
lineNumber: position.lineNumber,
|
||||
column: position.column
|
||||
this._registrations.set(handle, this._languageFeaturesService.documentHighlightProvider.register(selector, <languages.DocumentHighlightProvider>{
|
||||
provideDocumentHighlights: (model: ITextModel, position: EditorPosition, token: CancellationToken): Promise<languages.DocumentHighlight[] | undefined> => {
|
||||
return this._proxy.$provideDocumentHighlights(handle, model.uri, position, token);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
$registerMultiDocumentHighlightProvider(handle: number, selector: IDocumentFilterDto[]): void {
|
||||
this._registrations.set(handle, this._languageFeaturesService.multiDocumentHighlightProvider.register(selector, <languages.MultiDocumentHighlightProvider>{
|
||||
selector: selector,
|
||||
provideMultiDocumentHighlights: (model: ITextModel, position: EditorPosition, otherModels: ITextModel[], token: CancellationToken): Promise<Map<URI, languages.DocumentHighlight[]> | undefined> => {
|
||||
return this._proxy.$provideMultiDocumentHighlights(handle, model.uri, position, otherModels.map(model => model.uri), token).then(dto => {
|
||||
if (isFalsyOrEmpty(dto)) {
|
||||
return undefined;
|
||||
}
|
||||
const result = new ResourceMap<languages.DocumentHighlight[]>();
|
||||
dto?.forEach(value => {
|
||||
// check if the URI exists already, if so, combine the highlights, otherwise create a new entry
|
||||
const uri = URI.revive(value.uri);
|
||||
if (result.has(uri)) {
|
||||
result.get(uri)!.push(...value.highlights);
|
||||
} else {
|
||||
result.set(uri, value.highlights);
|
||||
}
|
||||
});
|
||||
|
||||
const res = this._proxy.$provideDocumentHighlights(handle, model.uri, position, token);
|
||||
return res.then(data => {
|
||||
const result = new Map<URI, languages.DocumentHighlight[]>();
|
||||
if (isFalsyOrEmpty(data) || !data) {
|
||||
return result;
|
||||
}
|
||||
result.set(model.uri, data);
|
||||
|
||||
if (!word) {
|
||||
return result;
|
||||
}
|
||||
|
||||
for (const otherModel of otherModels) {
|
||||
if (otherModel.isDisposed()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const matches = otherModel.findMatches(word.word, true, false, true, USUAL_WORD_SEPARATORS, false);
|
||||
const highlights = matches.map(m => ({
|
||||
range: m.range,
|
||||
kind: languages.DocumentHighlightKind.Text
|
||||
}));
|
||||
|
||||
if (highlights) {
|
||||
result.set(otherModel.uri, highlights);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
}
|
||||
})
|
||||
));
|
||||
return result;
|
||||
});
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
// --- linked editing
|
||||
|
|
|
@ -551,6 +551,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||
registerDocumentHighlightProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentHighlightProvider): vscode.Disposable {
|
||||
return extHostLanguageFeatures.registerDocumentHighlightProvider(extension, checkSelector(selector), provider);
|
||||
},
|
||||
registerMultiDocumentHighlightProvider(selector: vscode.DocumentSelector, provider: vscode.MultiDocumentHighlightProvider): vscode.Disposable {
|
||||
return extHostLanguageFeatures.registerMultiDocumentHighlightProvider(extension, checkSelector(selector), provider);
|
||||
},
|
||||
registerLinkedEditingRangeProvider(selector: vscode.DocumentSelector, provider: vscode.LinkedEditingRangeProvider): vscode.Disposable {
|
||||
return extHostLanguageFeatures.registerLinkedEditingRangeProvider(extension, checkSelector(selector), provider);
|
||||
},
|
||||
|
@ -1460,6 +1463,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||
Disposable: extHostTypes.Disposable,
|
||||
DocumentHighlight: extHostTypes.DocumentHighlight,
|
||||
DocumentHighlightKind: extHostTypes.DocumentHighlightKind,
|
||||
MultiDocumentHighlight: extHostTypes.MultiDocumentHighlight,
|
||||
DocumentLink: extHostTypes.DocumentLink,
|
||||
DocumentSymbol: extHostTypes.DocumentSymbol,
|
||||
EndOfLine: extHostTypes.EndOfLine,
|
||||
|
|
|
@ -405,6 +405,7 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable {
|
|||
$registerInlineValuesProvider(handle: number, selector: IDocumentFilterDto[], eventHandle: number | undefined): void;
|
||||
$emitInlineValuesEvent(eventHandle: number, event?: any): void;
|
||||
$registerDocumentHighlightProvider(handle: number, selector: IDocumentFilterDto[]): void;
|
||||
$registerMultiDocumentHighlightProvider(handle: number, selector: IDocumentFilterDto[]): void;
|
||||
$registerLinkedEditingRangeProvider(handle: number, selector: IDocumentFilterDto[]): void;
|
||||
$registerReferenceSupport(handle: number, selector: IDocumentFilterDto[]): void;
|
||||
$registerQuickFixSupport(handle: number, selector: IDocumentFilterDto[], metadata: ICodeActionProviderMetadataDto, displayName: string, supportsResolve: boolean): void;
|
||||
|
@ -2063,6 +2064,7 @@ export interface ExtHostLanguageFeaturesShape {
|
|||
$provideEvaluatableExpression(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<languages.EvaluatableExpression | undefined>;
|
||||
$provideInlineValues(handle: number, resource: UriComponents, range: IRange, context: languages.InlineValueContext, token: CancellationToken): Promise<languages.InlineValue[] | undefined>;
|
||||
$provideDocumentHighlights(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<languages.DocumentHighlight[] | undefined>;
|
||||
$provideMultiDocumentHighlights(handle: number, resource: UriComponents, position: IPosition, otherModels: UriComponents[], token: CancellationToken): Promise<Dto<languages.MultiDocumentHighlight[]> | undefined>;
|
||||
$provideLinkedEditingRanges(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<ILinkedEditingRangesDto | undefined>;
|
||||
$provideReferences(handle: number, resource: UriComponents, position: IPosition, context: languages.ReferenceContext, token: CancellationToken): Promise<ILocationDto[] | undefined>;
|
||||
$provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: languages.CodeActionContext, token: CancellationToken): Promise<ICodeActionListDto | undefined>;
|
||||
|
|
|
@ -327,6 +327,27 @@ class DocumentHighlightAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
class MultiDocumentHighlightAdapter {
|
||||
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.MultiDocumentHighlightProvider
|
||||
) { }
|
||||
|
||||
async provideMultiDocumentHighlights(resource: URI, position: IPosition, otherResources: URI[], token: CancellationToken): Promise<languages.MultiDocumentHighlight[] | undefined> {
|
||||
|
||||
const doc = this._documents.getDocument(resource);
|
||||
const otherDocuments = otherResources.map(r => this._documents.getDocument(r));
|
||||
const pos = typeConvert.Position.to(position);
|
||||
|
||||
const value = await this._provider.provideMultiDocumentHighlights(doc, pos, otherDocuments, token);
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(typeConvert.MultiDocumentHighlight.from);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
class LinkedEditingRangeAdapter {
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
|
@ -1853,8 +1874,9 @@ class MappedEditsAdapter {
|
|||
}
|
||||
|
||||
type Adapter = DocumentSymbolAdapter | CodeLensAdapter | DefinitionAdapter | HoverAdapter
|
||||
| DocumentHighlightAdapter | ReferenceAdapter | CodeActionAdapter | DocumentPasteEditProvider | DocumentFormattingAdapter
|
||||
| RangeFormattingAdapter | OnTypeFormattingAdapter | NavigateTypeAdapter | RenameAdapter
|
||||
| DocumentHighlightAdapter | MultiDocumentHighlightAdapter | ReferenceAdapter | CodeActionAdapter
|
||||
| DocumentPasteEditProvider | DocumentFormattingAdapter | RangeFormattingAdapter
|
||||
| OnTypeFormattingAdapter | NavigateTypeAdapter | RenameAdapter
|
||||
| CompletionsAdapter | SignatureHelpAdapter | LinkProviderAdapter | ImplementationAdapter
|
||||
| TypeDefinitionAdapter | ColorProviderAdapter | FoldingProviderAdapter | DeclarationAdapter
|
||||
| SelectionRangeAdapter | CallHierarchyAdapter | TypeHierarchyAdapter
|
||||
|
@ -1890,6 +1912,7 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
|
|||
this._proxy = mainContext.getProxy(extHostProtocol.MainContext.MainThreadLanguageFeatures);
|
||||
}
|
||||
|
||||
|
||||
private _transformDocumentSelector(selector: vscode.DocumentSelector, extension: IExtensionDescription): Array<extHostProtocol.IDocumentFilterDto> {
|
||||
return typeConvert.DocumentSelector.from(selector, this._uriTransformer, extension);
|
||||
}
|
||||
|
@ -2093,10 +2116,20 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
|
|||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
registerMultiDocumentHighlightProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.MultiDocumentHighlightProvider): vscode.Disposable {
|
||||
const handle = this._addNewAdapter(new MultiDocumentHighlightAdapter(this._documents, provider), extension);
|
||||
this._proxy.$registerMultiDocumentHighlightProvider(handle, this._transformDocumentSelector(selector, extension));
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$provideDocumentHighlights(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise<languages.DocumentHighlight[] | undefined> {
|
||||
return this._withAdapter(handle, DocumentHighlightAdapter, adapter => adapter.provideDocumentHighlights(URI.revive(resource), position, token), undefined, token);
|
||||
}
|
||||
|
||||
$provideMultiDocumentHighlights(handle: number, resource: UriComponents, position: IPosition, otherModels: UriComponents[], token: CancellationToken): Promise<languages.MultiDocumentHighlight[] | undefined> {
|
||||
return this._withAdapter(handle, MultiDocumentHighlightAdapter, adapter => adapter.provideMultiDocumentHighlights(URI.revive(resource), position, otherModels.map(model => URI.revive(model)), token), undefined, token);
|
||||
}
|
||||
|
||||
// --- linked editing
|
||||
|
||||
registerLinkedEditingRangeProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.LinkedEditingRangeProvider): vscode.Disposable {
|
||||
|
|
|
@ -1023,6 +1023,19 @@ export namespace DocumentHighlight {
|
|||
}
|
||||
}
|
||||
|
||||
export namespace MultiDocumentHighlight {
|
||||
export function from(multiDocumentHighlight: vscode.MultiDocumentHighlight): languages.MultiDocumentHighlight {
|
||||
return {
|
||||
uri: multiDocumentHighlight.uri,
|
||||
highlights: multiDocumentHighlight.highlights.map(DocumentHighlight.from)
|
||||
};
|
||||
}
|
||||
|
||||
export function to(multiDocumentHighlight: languages.MultiDocumentHighlight): types.MultiDocumentHighlight {
|
||||
return new types.MultiDocumentHighlight(URI.revive(multiDocumentHighlight.uri), multiDocumentHighlight.highlights.map(DocumentHighlight.to));
|
||||
}
|
||||
}
|
||||
|
||||
export namespace CompletionTriggerKind {
|
||||
export function to(kind: languages.CompletionTriggerKind) {
|
||||
switch (kind) {
|
||||
|
|
|
@ -1227,6 +1227,25 @@ export class DocumentHighlight {
|
|||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class MultiDocumentHighlight {
|
||||
|
||||
uri: URI;
|
||||
highlights: DocumentHighlight[];
|
||||
|
||||
constructor(uri: URI, highlights: DocumentHighlight[]) {
|
||||
this.uri = uri;
|
||||
this.highlights = highlights;
|
||||
}
|
||||
|
||||
toJSON(): any {
|
||||
return {
|
||||
uri: this.uri,
|
||||
highlights: this.highlights.map(h => h.toJSON())
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export enum SymbolKind {
|
||||
File = 0,
|
||||
Module = 1,
|
||||
|
|
|
@ -61,6 +61,7 @@ export const allApiProposals = Object.freeze({
|
|||
ipc: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.ipc.d.ts',
|
||||
languageStatusText: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.languageStatusText.d.ts',
|
||||
mappedEditsProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.mappedEditsProvider.d.ts',
|
||||
multiDocumentHighlightProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.multiDocumentHighlightProvider.d.ts',
|
||||
notebookCellExecutionState: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookCellExecutionState.d.ts',
|
||||
notebookControllerAffinityHidden: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookControllerAffinityHidden.d.ts',
|
||||
notebookDeprecated: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookDeprecated.d.ts',
|
||||
|
|
63
src/vscode-dts/vscode.proposed.multiDocumentHighlightProvider.d.ts
vendored
Normal file
63
src/vscode-dts/vscode.proposed.multiDocumentHighlightProvider.d.ts
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
declare module 'vscode' {
|
||||
|
||||
/**
|
||||
* Represents a collection of document highlights from multiple documents.
|
||||
*/
|
||||
export class MultiDocumentHighlight {
|
||||
|
||||
/**
|
||||
* The URI of the document containing the highlights.
|
||||
*/
|
||||
uri: Uri;
|
||||
|
||||
/**
|
||||
* The highlights for the document.
|
||||
*/
|
||||
highlights: DocumentHighlight[];
|
||||
|
||||
/**
|
||||
* Creates a new instance of MultiDocumentHighlight.
|
||||
* @param uri The URI of the document containing the highlights.
|
||||
* @param highlights The highlights for the document.
|
||||
*/
|
||||
constructor(uri: Uri, highlights: DocumentHighlight[]);
|
||||
}
|
||||
|
||||
export interface MultiDocumentHighlightProvider {
|
||||
|
||||
/**
|
||||
* Provide a set of document highlights, like all occurrences of a variable or
|
||||
* all exit-points of a function.
|
||||
*
|
||||
* @param document The document in which the command was invoked.
|
||||
* @param position The position at which the command was invoked.
|
||||
* @param otherDocuments An array of additional valid documents for which highlights should be provided.
|
||||
* @param token A cancellation token.
|
||||
* @returns A Map containing a mapping of the Uri of a document to the document highlights or a thenable that resolves to such. The lack of a result can be
|
||||
* signaled by returning `undefined`, `null`, or an empty map.
|
||||
*/
|
||||
provideMultiDocumentHighlights(document: TextDocument, position: Position, otherDocuments: TextDocument[], token: CancellationToken): ProviderResult<MultiDocumentHighlight[]>;
|
||||
}
|
||||
|
||||
namespace languages {
|
||||
|
||||
/**
|
||||
* Register a multi document highlight provider.
|
||||
*
|
||||
* Multiple providers can be registered for a language. In that case providers are sorted
|
||||
* by their {@link languages.match score} and groups sequentially asked for document highlights.
|
||||
* The process stops when a provider returns a `non-falsy` or `non-failure` result.
|
||||
*
|
||||
* @param selector A selector that defines the documents this provider is applicable to.
|
||||
* @param provider A multi-document highlight provider.
|
||||
* @returns A {@link Disposable} that unregisters this provider when being disposed.
|
||||
*/
|
||||
export function registerMultiDocumentHighlightProvider(selector: DocumentSelector, provider: MultiDocumentHighlightProvider): Disposable;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue