Merge pull request #145106 from microsoft/joh/notebookFilter2

This commit is contained in:
Johannes Rieken 2022-03-15 11:06:44 +01:00 committed by GitHub
commit 1dd72e5d6e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 51 additions and 30 deletions

View file

@ -26,8 +26,27 @@ function isExclusive(selector: LanguageSelector): boolean {
}
}
export interface NotebookTypeResolver {
(uri: URI): string | undefined;
export interface NotebookInfo {
readonly uri: URI;
readonly type: string;
}
export interface NotebookInfoResolver {
(uri: URI): NotebookInfo | undefined;
}
class MatchCandidate {
constructor(
readonly uri: URI,
readonly languageId: string,
readonly notebookType: string | undefined
) { }
equals(other: MatchCandidate): boolean {
return this.notebookType === other.notebookType
&& this.languageId === other.languageId
&& this.uri.toString() === other.uri.toString();
}
}
export class LanguageFeatureRegistry<T> {
@ -38,7 +57,7 @@ export class LanguageFeatureRegistry<T> {
private readonly _onDidChange = new Emitter<number>();
readonly onDidChange = this._onDidChange.event;
constructor(private readonly _notebookTypeResolver?: NotebookTypeResolver) { }
constructor(private readonly _notebookInfoResolver?: NotebookInfoResolver) { }
register(selector: LanguageSelector, provider: T): IDisposable {
@ -123,24 +142,19 @@ export class LanguageFeatureRegistry<T> {
}
}
private _lastCandidate: { uri: string; language: string; notebookType?: string } | undefined;
private _lastCandidate: MatchCandidate | undefined;
private _updateScores(model: ITextModel): void {
const notebookType = this._notebookTypeResolver?.(model.uri);
const notebookInfo = this._notebookInfoResolver?.(model.uri);
const candidate = {
uri: model.uri.toString(),
language: model.getLanguageId(),
notebookType
};
if (this._lastCandidate
&& this._lastCandidate.language === candidate.language
&& this._lastCandidate.uri === candidate.uri
&& this._lastCandidate.notebookType === candidate.notebookType
) {
// use the uri (scheme, pattern) of the notebook info iff we have one
// otherwise it's the model's/document's uri
const candidate = notebookInfo
? new MatchCandidate(notebookInfo.uri, model.getLanguageId(), notebookInfo.type)
: new MatchCandidate(model.uri, model.getLanguageId(), undefined);
if (this._lastCandidate?.equals(candidate)) {
// nothing has changed
return;
}
@ -148,7 +162,7 @@ export class LanguageFeatureRegistry<T> {
this._lastCandidate = candidate;
for (let entry of this._entries) {
entry._score = score(entry.selector, model.uri, model.getLanguageId(), shouldSynchronizeModel(model), notebookType);
entry._score = score(entry.selector, candidate.uri, candidate.languageId, shouldSynchronizeModel(model), candidate.notebookType);
if (isExclusive(entry.selector) && entry._score > 0) {
// support for one exclusive selector that overwrites

View file

@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { LanguageFeatureRegistry, NotebookTypeResolver } from 'vs/editor/common/languageFeatureRegistry';
import { LanguageFeatureRegistry, NotebookInfoResolver } from 'vs/editor/common/languageFeatureRegistry';
import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider } from 'vs/editor/common/languages';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
@ -69,5 +69,5 @@ export interface ILanguageFeaturesService {
// --
setNotebookTypeResolver(resolver: NotebookTypeResolver | undefined): void;
setNotebookTypeResolver(resolver: NotebookInfoResolver | undefined): void;
}

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { URI } from 'vs/base/common/uri';
import { LanguageFeatureRegistry, NotebookTypeResolver } from 'vs/editor/common/languageFeatureRegistry';
import { LanguageFeatureRegistry, NotebookInfo, NotebookInfoResolver } from 'vs/editor/common/languageFeatureRegistry';
import { CodeActionProvider, CodeLensProvider, CompletionItemProvider, DeclarationProvider, DefinitionProvider, DocumentColorProvider, DocumentFormattingEditProvider, DocumentHighlightProvider, DocumentRangeFormattingEditProvider, DocumentRangeSemanticTokensProvider, DocumentSemanticTokensProvider, DocumentSymbolProvider, EvaluatableExpressionProvider, FoldingRangeProvider, HoverProvider, ImplementationProvider, InlayHintsProvider, InlineCompletionsProvider, InlineValuesProvider, LinkedEditingRangeProvider, LinkProvider, OnTypeFormattingEditProvider, ReferenceProvider, RenameProvider, SelectionRangeProvider, SignatureHelpProvider, TypeDefinitionProvider } from 'vs/editor/common/languages';
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
@ -42,13 +42,13 @@ export class LanguageFeaturesService implements ILanguageFeaturesService {
readonly documentSemanticTokensProvider = new LanguageFeatureRegistry<DocumentSemanticTokensProvider>(this._score.bind(this));
private _notebookTypeResolver?: NotebookTypeResolver;
private _notebookTypeResolver?: NotebookInfoResolver;
setNotebookTypeResolver(resolver: NotebookTypeResolver | undefined) {
setNotebookTypeResolver(resolver: NotebookInfoResolver | undefined) {
this._notebookTypeResolver = resolver;
}
private _score(uri: URI): string | undefined {
private _score(uri: URI): NotebookInfo | undefined {
return this._notebookTypeResolver?.(uri);
}

View file

@ -105,6 +105,7 @@ suite('LanguageSelector', function () {
assert.strictEqual(score('javascript', obj.uri, obj.langId, true, undefined), 10);
assert.strictEqual(score('javascript', obj.uri, obj.langId, true, obj.notebookType), 10);
assert.strictEqual(score({ notebookType: 'fooBook' }, obj.uri, obj.langId, true, obj.notebookType), 10);
assert.strictEqual(score({ notebookType: 'fooBook', language: 'javascript', scheme: 'file' }, obj.uri, obj.langId, true, obj.notebookType), 10);
assert.strictEqual(score({ notebookType: 'fooBook', language: '*' }, obj.uri, obj.langId, true, obj.notebookType), 10);
assert.strictEqual(score({ notebookType: '*', language: '*' }, obj.uri, obj.langId, true, obj.notebookType), 5);
assert.strictEqual(score({ notebookType: '*', language: 'javascript' }, obj.uri, obj.langId, true, obj.notebookType), 10);

View file

@ -103,6 +103,7 @@ import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/mode
import { PLAINTEXT_LANGUAGE_ID } from 'vs/editor/common/languages/modesRegistry';
import { INotebookExecutionStateService } from 'vs/workbench/contrib/notebook/common/notebookExecutionStateService';
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import { NotebookInfo } from 'vs/editor/common/languageFeatureRegistry';
/*--------------------------------------------------------------------------------------------- */
@ -617,10 +618,10 @@ class NotebookLanguageSelectorScoreRefine {
@INotebookService private readonly _notebookService: INotebookService,
@ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService,
) {
languageFeaturesService.setNotebookTypeResolver(this._getNotebookType.bind(this));
languageFeaturesService.setNotebookTypeResolver(this._getNotebookInfo.bind(this));
}
private _getNotebookType(uri: URI): string | undefined {
private _getNotebookInfo(uri: URI): NotebookInfo | undefined {
const cellUri = CellUri.parse(uri);
if (!cellUri) {
return undefined;
@ -629,7 +630,10 @@ class NotebookLanguageSelectorScoreRefine {
if (!notebook) {
return undefined;
}
return notebook.viewType;
return {
uri: notebook.uri,
type: notebook.viewType
};
}
}

View file

@ -2065,12 +2065,14 @@ declare module 'vscode' {
readonly language?: string;
/**
* The {@link NotebookDocument.notebookType type} of a notebook, like `jupyter`. This allows
* The {@link NotebookDocument.notebookType type} of a notebook, like `jupyter-notebook`. This allows
* to narrow down on the type of a notebook that a {@link NotebookCell.document cell document} belongs to.
*
* *Note* that combining `notebookType` and {@link DocumentFilter.scheme `scheme`} with a value
* different than `"vscode-notebook-cell"` or `undefined` is invalid and will not match
* any document.
* *Note* that setting the `notebookType`-property changes how `scheme` and `pattern` are interpreted. When set
* they are evaluated against the {@link NotebookDocument.uri notebook uri}, not the document uri.
*
* @example <caption>Match python document inside jupyter notebook that aren't stored yet</caption>
* { language: 'python', notebookType: 'jupyter-notebook', scheme: 'untitled' }
*/
readonly notebookType?: string;