Skip to content

Commit

Permalink
Add glob pattern to notebook filters (#1519)
Browse files Browse the repository at this point in the history
  • Loading branch information
dbaeumer authored Jul 9, 2024
1 parent a34b844 commit a2a948f
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 44 deletions.
14 changes: 7 additions & 7 deletions client-node-tests/src/helpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
AnnotatedTextEdit, TextEdit, type RelativePattern
} from 'vscode-languageclient';

import { $GlobPattern } from 'vscode-languageclient/$test/common/diagnostic';
import { matchGlobPattern } from 'vscode-languageclient/$test/common/utils/globPattern';

suite('Protocol Helper Tests', () => {
function rangeEqual(actual: Range, expected: Range) {
Expand Down Expand Up @@ -208,14 +208,14 @@ suite('Protocol Helper Tests', () => {
test('Relative Pattern', () => {
if (process.platform === 'win32') {
const pattern: RelativePattern = { baseUri: Uri.file('C:\\folder1\\folder2').toString(), pattern: '**/*.txt' };
ok($GlobPattern.match(pattern, Uri.file('c:\\folder1\\folder2\\file.txt')));
ok($GlobPattern.match(pattern, Uri.file('c:\\folder1\\folder2\\folder3\\file.txt')));
ok(!$GlobPattern.match(pattern, Uri.file('c:\\folder1\\folder3\\file.txt')));
ok(matchGlobPattern(pattern, Uri.file('c:\\folder1\\folder2\\file.txt')));
ok(matchGlobPattern(pattern, Uri.file('c:\\folder1\\folder2\\folder3\\file.txt')));
ok(!matchGlobPattern(pattern, Uri.file('c:\\folder1\\folder3\\file.txt')));
} else {
const pattern: RelativePattern = { baseUri: Uri.file('/folder1/folder2').toString(), pattern: '**/*.txt' };
ok($GlobPattern.match(pattern, Uri.file('/folder1/folder2/file.txt')));
ok($GlobPattern.match(pattern, Uri.file('/folder1/folder2/folder3/file.txt')));
ok(!$GlobPattern.match(pattern, Uri.file('/folder1/folder3/file.txt')));
ok(matchGlobPattern(pattern, Uri.file('/folder1/folder2/file.txt')));
ok(matchGlobPattern(pattern, Uri.file('/folder1/folder2/folder3/file.txt')));
ok(!matchGlobPattern(pattern, Uri.file('/folder1/folder3/file.txt')));
}
});
});
30 changes: 4 additions & 26 deletions client/src/common/diagnostic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */

import * as minimatch from 'minimatch';

import {
Disposable, languages as Languages, window as Window, workspace as Workspace, CancellationToken, ProviderResult, Diagnostic as VDiagnostic,
CancellationTokenSource, TextDocument, CancellationError, Event as VEvent, EventEmitter, DiagnosticCollection, Uri, workspace, NotebookCell
Expand All @@ -15,11 +13,12 @@ import {
DidSaveTextDocumentNotification, DidCloseTextDocumentNotification, LinkedMap, Touch, RAL, TextDocumentFilter, PreviousResultId,
DiagnosticRegistrationOptions, DiagnosticServerCancellationData, DocumentDiagnosticParams, DocumentDiagnosticRequest, DocumentDiagnosticReportKind,
WorkspaceDocumentDiagnosticReport, WorkspaceDiagnosticRequest, WorkspaceDiagnosticParams, DiagnosticOptions, DiagnosticRefreshRequest, DiagnosticTag,
NotebookDocumentSyncRegistrationType,
type GlobPattern
NotebookDocumentSyncRegistrationType
} from 'vscode-languageserver-protocol';

import { generateUuid } from './utils/uuid';
import { matchGlobPattern } from './utils/globPattern';

import {
TextDocumentLanguageFeature, FeatureClient, LSPCancellationError, type TabsModel
} from './features';
Expand Down Expand Up @@ -756,27 +755,6 @@ class BackgroundScheduler implements Disposable {
}
}

export namespace $GlobPattern {
export function match(pattern: GlobPattern, resource: Uri): boolean {
let miniMatchPattern: string;
if (typeof pattern === 'string') {
miniMatchPattern = pattern.replace(/\\/g, '/');
} else {
try {
const baseUri = Uri.parse(typeof pattern.baseUri === 'string' ? pattern.baseUri : pattern.baseUri.uri);
miniMatchPattern = baseUri.with({ path: baseUri.path + '/' + pattern.pattern }).fsPath.replace(/\\/g, '/');
} catch (error) {
return false;
}
}
const matcher = new minimatch.Minimatch(miniMatchPattern, { noext: true });
if (!matcher.makeRe()) {
return false;
}
return matcher.match(resource.fsPath);
}
}

class DiagnosticFeatureProviderImpl implements DiagnosticProviderShape {

public readonly disposable: Disposable;
Expand All @@ -802,7 +780,7 @@ class DiagnosticFeatureProviderImpl implements DiagnosticProviderShape {
if (filter.scheme !== undefined && filter.scheme !== '*' && filter.scheme !== resource.scheme) {
return false;
}
if (filter.pattern !== undefined && !$GlobPattern.match(filter.pattern, resource)) {
if (filter.pattern !== undefined && !matchGlobPattern(filter.pattern, resource)) {
return false;
}
return true;
Expand Down
10 changes: 3 additions & 7 deletions client/src/common/notebook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
* ------------------------------------------------------------------------------------------ */

import * as vscode from 'vscode';
import * as minimatch from 'minimatch';

import * as proto from 'vscode-languageserver-protocol';
import {
Expand All @@ -18,6 +17,7 @@ import * as Is from './utils/is';
import * as _c2p from './codeConverter';
import * as _p2c from './protocolConverter';
import { DynamicFeature, FeatureClient, RegistrationData, FeatureState } from './features';
import { matchGlobPattern } from './utils/globPattern';


function ensure<T, K extends keyof T>(target: T, key: K): T[K] {
Expand Down Expand Up @@ -285,11 +285,7 @@ namespace $NotebookDocumentFilter {
return false;
}
if (filter.pattern !== undefined) {
const matcher = new minimatch.Minimatch(filter.pattern, { noext: true });
if (!matcher.makeRe()) {
return false;
}
if (!matcher.match(uri.fsPath)) {
if (!matchGlobPattern(filter.pattern, uri)) {
return false;
}
}
Expand All @@ -316,7 +312,7 @@ namespace $NotebookDocumentSyncOptions {
return result;
}

function asDocumentFilter(notebookType: string, scheme: string | undefined, pattern: string | undefined, language: string | undefined): proto.NotebookCellTextDocumentFilter {
function asDocumentFilter(notebookType: string, scheme: string | undefined, pattern: proto.GlobPattern | undefined, language: string | undefined): proto.NotebookCellTextDocumentFilter {
return scheme === undefined && pattern === undefined
? { notebook: notebookType, language }
: { notebook: { notebookType, scheme, pattern }, language };
Expand Down
2 changes: 1 addition & 1 deletion client/src/common/protocolConverter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ export function createConverter(
result.push({notebookType: filter.notebook, language: filter.language});
} else {
const notebookType = filter.notebook.notebookType ?? '*';
result.push({ notebookType: notebookType, scheme: filter.notebook.scheme, pattern: filter.notebook.pattern, language: filter.language });
result.push({ notebookType: notebookType, scheme: filter.notebook.scheme, pattern: asGlobPattern(filter.notebook.pattern), language: filter.language });
}
} else if (TextDocumentFilter.is(filter)) {
result.push({ language: filter.language, scheme: filter.scheme, pattern: asGlobPattern(filter.pattern) });
Expand Down
28 changes: 28 additions & 0 deletions client/src/common/utils/globPattern.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */

import * as minimatch from 'minimatch';

import { Uri } from 'vscode';
import type { GlobPattern } from 'vscode-languageserver-protocol';

export function matchGlobPattern(pattern: GlobPattern, resource: Uri): boolean {
let miniMatchPattern: string;
if (typeof pattern === 'string') {
miniMatchPattern = pattern.replace(/\\/g, '/');
} else {
try {
const baseUri = Uri.parse(typeof pattern.baseUri === 'string' ? pattern.baseUri : pattern.baseUri.uri);
miniMatchPattern = baseUri.with({ path: baseUri.path + '/' + pattern.pattern }).fsPath.replace(/\\/g, '/');
} catch (error) {
return false;
}
}
const matcher = new minimatch.Minimatch(miniMatchPattern, { noext: true });
if (!matcher.makeRe()) {
return false;
}
return matcher.match(resource.fsPath);
}
6 changes: 3 additions & 3 deletions protocol/src/common/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ export type NotebookDocumentFilterNotebookType = {
/**
* A glob pattern.
*/
pattern?: string;
pattern?: GlobPattern;
};

/**
Expand All @@ -272,7 +272,7 @@ export type NotebookDocumentFilterScheme = {
/**
* A glob pattern.
*/
pattern?: string;
pattern?: GlobPattern;
};

/**
Expand All @@ -294,7 +294,7 @@ export type NotebookDocumentFilterPattern = {
/**
* A glob pattern.
*/
pattern: string;
pattern: GlobPattern;
};

/**
Expand Down

0 comments on commit a2a948f

Please sign in to comment.