Support Multi Editor/Model Highlighting (#196024)

* support multi-editor highlighting

* Add experimental multi-document occurrences highlighting option

* highlight accross notebook cells even without multi-doc setting

* otherModels helper + ResourceMap + fixed removeDecorations

* combine textual to just `TextualOccurenceRequest`

* fix aggressive dispose/decoration clearing, introduce query interface
This commit is contained in:
Michael Lively
2023-10-24 06:27:02 +02:00
committed by GitHub
parent 9e597d3227
commit 7dff07893a
10 changed files with 603 additions and 272 deletions
@@ -33,6 +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';
@extHostNamedCustomer(MainContext.MainThreadLanguageFeatures)
export class MainThreadLanguageFeatures extends Disposable implements MainThreadLanguageFeaturesShape {
@@ -293,11 +294,51 @@ export class MainThreadLanguageFeatures extends Disposable implements MainThread
// --- occurrences
$registerDocumentHighlightProvider(handle: number, selector: IDocumentFilterDto[]): void {
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);
}
}));
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 res = this._proxy.$provideDocumentHighlights(handle, model.uri, position, token);
if (!res) {
return Promise.resolve(new Map<URI, languages.DocumentHighlight[]>());
}
return res.then(data => {
const result = new Map<URI, languages.DocumentHighlight[]>();
if (data) {
result.set(model.uri, data);
}
const word = model.getWordAtPosition({
lineNumber: position.lineNumber,
column: position.column
});
if (!word) {
return new Map<URI, languages.DocumentHighlight[]>();
}
for (const otherModel of otherModels) {
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;
});
}
})
));
}
// --- linked editing