Skip to content

Commit 2597c39

Browse files
authored
Use a document selector pattern only in multi-root (#5334)
* Use a document selector pattern only in multi-root * Typo * Address code review comments * Code review comments * Fix linter
1 parent f4f9f96 commit 2597c39

3 files changed

Lines changed: 63 additions & 13 deletions

File tree

news/2 Fixes/5333.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Restrict files from being processed by `Language Server` only when in a mult-root workspace.

src/client/activation/languageServer/analysisOptions.ts

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
import { inject, injectable, named } from 'inversify';
77
import * as path from 'path';
8-
import { CancellationToken, CompletionContext, ConfigurationChangeEvent, Disposable, Event, EventEmitter, OutputChannel, Position, TextDocument } from 'vscode';
9-
import { LanguageClientOptions, ProvideCompletionItemsSignature, RevealOutputChannelOn } from 'vscode-languageclient';
8+
import { CancellationToken, CompletionContext, ConfigurationChangeEvent, Disposable, Event, EventEmitter, OutputChannel, Position, TextDocument, WorkspaceFolder } from 'vscode';
9+
import { DocumentFilter, DocumentSelector, LanguageClientOptions, ProvideCompletionItemsSignature, RevealOutputChannelOn } from 'vscode-languageclient';
1010
import { IWorkspaceService } from '../../common/application/types';
1111
import { isTestExecution, PYTHON_LANGUAGE, STANDARD_OUTPUT_CHANNEL } from '../../common/constants';
1212
import { traceDecorators, traceError } from '../../common/logger';
@@ -103,17 +103,10 @@ export class LanguageServerAnalysisOptions implements ILanguageServerAnalysisOpt
103103
this.excludedFiles = this.getExcludedFiles();
104104
this.typeshedPaths = this.getTypeshedPaths();
105105
const workspaceFolder = this.workspace.getWorkspaceFolder(this.resource);
106-
const documentSelector = [
107-
{ scheme: 'file', language: PYTHON_LANGUAGE },
108-
{ scheme: 'untitled', language: PYTHON_LANGUAGE }
109-
];
110-
if (workspaceFolder) {
111-
// tslint:disable-next-line:no-any
112-
(documentSelector[0] as any).pattern = `${workspaceFolder.uri.fsPath}/**/*`;
113-
}
114-
// Options to control the language client
106+
const documentSelector = this.getDocumentSelector(workspaceFolder);
107+
// Options to control the language client.
115108
return {
116-
// Register the server for Python documents
109+
// Register the server for Python documents.
117110
documentSelector,
118111
workspaceFolder,
119112
synchronize: {
@@ -148,6 +141,18 @@ export class LanguageServerAnalysisOptions implements ILanguageServerAnalysisOpt
148141
}
149142
};
150143
}
144+
protected getDocumentSelector(workspaceFolder?: WorkspaceFolder): DocumentSelector {
145+
const documentSelector: DocumentFilter[] = [
146+
{ scheme: 'file', language: PYTHON_LANGUAGE },
147+
{ scheme: 'untitled', language: PYTHON_LANGUAGE }
148+
];
149+
// Set the document selector only when in a multi-root workspace scenario.
150+
if (workspaceFolder && Array.isArray(this.workspace.workspaceFolders) && this.workspace.workspaceFolders!.length > 1) {
151+
// tslint:disable-next-line:no-any
152+
documentSelector[0].pattern = `${workspaceFolder.uri.fsPath}/**/*`;
153+
}
154+
return documentSelector;
155+
}
151156
protected getExcludedFiles(): string[] {
152157
const list: string[] = ['**/Lib/**', '**/site-packages/**'];
153158
this.getVsCodeExcludeSection('search.exclude', list);

src/test/activation/languageServer/analysisOptions.unit.test.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66
import { expect } from 'chai';
77
import { instance, mock, verify, when } from 'ts-mockito';
88
import * as typemoq from 'typemoq';
9-
import { ConfigurationChangeEvent, Uri } from 'vscode';
9+
import { ConfigurationChangeEvent, Uri, WorkspaceFolder } from 'vscode';
10+
import { DocumentSelector } from 'vscode-languageclient';
1011
import { LanguageServerAnalysisOptions } from '../../../client/activation/languageServer/analysisOptions';
1112
import { LanguageServerFolderService } from '../../../client/activation/languageServer/languageServerFolderService';
1213
import { ILanguageServerFolderService } from '../../../client/activation/types';
1314
import { IWorkspaceService } from '../../../client/common/application/types';
1415
import { WorkspaceService } from '../../../client/common/application/workspace';
1516
import { ConfigurationService } from '../../../client/common/configuration/service';
17+
import { PYTHON_LANGUAGE } from '../../../client/common/constants';
1618
import { PathUtils } from '../../../client/common/platform/pathUtils';
1719
import { IConfigurationService, IDisposable, IExtensionContext, IOutputChannel, IPathUtils, IPythonExtensionBanner } from '../../../client/common/types';
1820
import { EnvironmentVariablesProvider } from '../../../client/common/variables/environmentVariablesProvider';
@@ -26,6 +28,9 @@ import { sleep } from '../../core';
2628

2729
suite('Language Server - Analysis Options', () => {
2830
class TestClass extends LanguageServerAnalysisOptions {
31+
public getDocumentSelector(workspaceFolder?: WorkspaceFolder): DocumentSelector {
32+
return super.getDocumentSelector(workspaceFolder);
33+
}
2934
public getExcludedFiles(): string[] {
3035
return super.getExcludedFiles();
3136
}
@@ -199,4 +204,43 @@ suite('Language Server - Analysis Options', () => {
199204

200205
expect(settingsChangedInvokedCount).to.be.equal(1);
201206
});
207+
test('Ensure search pattern is not provided when there are no workspaces', () => {
208+
when(workspace.workspaceFolders).thenReturn([]);
209+
210+
const expectedSelector = [
211+
{ scheme: 'file', language: PYTHON_LANGUAGE },
212+
{ scheme: 'untitled', language: PYTHON_LANGUAGE }
213+
];
214+
215+
const selector = analysisOptions.getDocumentSelector();
216+
217+
expect(selector).to.deep.equal(expectedSelector);
218+
});
219+
test('Ensure search pattern is not provided in single-root workspaces', () => {
220+
const workspaceFolder: WorkspaceFolder = { name: '', index: 0, uri: Uri.file(__dirname) };
221+
when(workspace.workspaceFolders).thenReturn([workspaceFolder]);
222+
223+
const expectedSelector = [
224+
{ scheme: 'file', language: PYTHON_LANGUAGE },
225+
{ scheme: 'untitled', language: PYTHON_LANGUAGE }
226+
];
227+
228+
const selector = analysisOptions.getDocumentSelector(workspaceFolder);
229+
230+
expect(selector).to.deep.equal(expectedSelector);
231+
});
232+
test('Ensure search pattern is provided in a multi-root workspace', () => {
233+
const workspaceFolder1 = { name: '1', index: 0, uri: Uri.file(__dirname) };
234+
const workspaceFolder2 = { name: '2', index: 1, uri: Uri.file(__dirname) };
235+
when(workspace.workspaceFolders).thenReturn([workspaceFolder1, workspaceFolder2]);
236+
237+
const expectedSelector = [
238+
{ scheme: 'file', language: PYTHON_LANGUAGE, pattern: `${workspaceFolder1.uri.fsPath}/**/*` },
239+
{ scheme: 'untitled', language: PYTHON_LANGUAGE }
240+
];
241+
242+
const selector = analysisOptions.getDocumentSelector(workspaceFolder1);
243+
244+
expect(selector).to.deep.equal(expectedSelector);
245+
});
202246
});

0 commit comments

Comments
 (0)