Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news/2 Fixes/5333.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Restrict files from being processed by `Language Server` only when in a mult-root workspace.
29 changes: 17 additions & 12 deletions src/client/activation/languageServer/analysisOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

import { inject, injectable, named } from 'inversify';
import * as path from 'path';
import { CancellationToken, CompletionContext, ConfigurationChangeEvent, Disposable, Event, EventEmitter, OutputChannel, Position, TextDocument } from 'vscode';
import { LanguageClientOptions, ProvideCompletionItemsSignature, RevealOutputChannelOn } from 'vscode-languageclient';
import { CancellationToken, CompletionContext, ConfigurationChangeEvent, Disposable, Event, EventEmitter, OutputChannel, Position, TextDocument, WorkspaceFolder } from 'vscode';
import { DocumentFilter, DocumentSelector, LanguageClientOptions, ProvideCompletionItemsSignature, RevealOutputChannelOn } from 'vscode-languageclient';
import { IWorkspaceService } from '../../common/application/types';
import { isTestExecution, PYTHON_LANGUAGE, STANDARD_OUTPUT_CHANNEL } from '../../common/constants';
import { traceDecorators, traceError } from '../../common/logger';
Expand Down Expand Up @@ -103,17 +103,10 @@ export class LanguageServerAnalysisOptions implements ILanguageServerAnalysisOpt
this.excludedFiles = this.getExcludedFiles();
this.typeshedPaths = this.getTypeshedPaths();
const workspaceFolder = this.workspace.getWorkspaceFolder(this.resource);
const documentSelector = [
{ scheme: 'file', language: PYTHON_LANGUAGE },
{ scheme: 'untitled', language: PYTHON_LANGUAGE }
];
if (workspaceFolder) {
// tslint:disable-next-line:no-any
(documentSelector[0] as any).pattern = `${workspaceFolder.uri.fsPath}/**/*`;
}
// Options to control the language client
const documentSelector = this.getDocumentSelector(workspaceFolder);
// Options to control the language client.
return {
// Register the server for Python documents
// Register the server for Python documents.
documentSelector,
workspaceFolder,
synchronize: {
Expand Down Expand Up @@ -148,6 +141,18 @@ export class LanguageServerAnalysisOptions implements ILanguageServerAnalysisOpt
}
};
}
protected getDocumentSelector(workspaceFolder?: WorkspaceFolder): DocumentSelector {
const documentSelector: DocumentFilter[] = [
{ scheme: 'file', language: PYTHON_LANGUAGE },
{ scheme: 'untitled', language: PYTHON_LANGUAGE }
];
// Set the document selector only when in a multi-root workspace scenario.
if (workspaceFolder && Array.isArray(this.workspace.workspaceFolders) && this.workspace.workspaceFolders!.length > 1) {
Comment thread
DonJayamanne marked this conversation as resolved.
// tslint:disable-next-line:no-any
documentSelector[0].pattern = `${workspaceFolder.uri.fsPath}/**/*`;
}
return documentSelector;
}
protected getExcludedFiles(): string[] {
const list: string[] = ['**/Lib/**', '**/site-packages/**'];
this.getVsCodeExcludeSection('search.exclude', list);
Expand Down
46 changes: 45 additions & 1 deletion src/test/activation/languageServer/analysisOptions.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
import { expect } from 'chai';
import { instance, mock, verify, when } from 'ts-mockito';
import * as typemoq from 'typemoq';
import { ConfigurationChangeEvent, Uri } from 'vscode';
import { ConfigurationChangeEvent, Uri, WorkspaceFolder } from 'vscode';
import { DocumentSelector } from 'vscode-languageclient';
import { LanguageServerAnalysisOptions } from '../../../client/activation/languageServer/analysisOptions';
import { LanguageServerFolderService } from '../../../client/activation/languageServer/languageServerFolderService';
import { ILanguageServerFolderService } from '../../../client/activation/types';
import { IWorkspaceService } from '../../../client/common/application/types';
import { WorkspaceService } from '../../../client/common/application/workspace';
import { ConfigurationService } from '../../../client/common/configuration/service';
import { PYTHON_LANGUAGE } from '../../../client/common/constants';
import { PathUtils } from '../../../client/common/platform/pathUtils';
import { IConfigurationService, IDisposable, IExtensionContext, IOutputChannel, IPathUtils, IPythonExtensionBanner } from '../../../client/common/types';
import { EnvironmentVariablesProvider } from '../../../client/common/variables/environmentVariablesProvider';
Expand All @@ -26,6 +28,9 @@ import { sleep } from '../../core';

suite('Language Server - Analysis Options', () => {
class TestClass extends LanguageServerAnalysisOptions {
public getDocumentSelector(workspaceFolder?: WorkspaceFolder): DocumentSelector {
return super.getDocumentSelector(workspaceFolder);
}
public getExcludedFiles(): string[] {
return super.getExcludedFiles();
}
Expand Down Expand Up @@ -199,4 +204,43 @@ suite('Language Server - Analysis Options', () => {

expect(settingsChangedInvokedCount).to.be.equal(1);
});
test('Ensure search pattern is not provided when there are no workspaces', () => {
when(workspace.workspaceFolders).thenReturn([]);

const expectedSelector = [
{ scheme: 'file', language: PYTHON_LANGUAGE },
{ scheme: 'untitled', language: PYTHON_LANGUAGE }
];

const selector = analysisOptions.getDocumentSelector();

expect(selector).to.deep.equal(expectedSelector);
});
test('Ensure search pattern is not provided in single-root workspaces', () => {
const workspaceFolder: WorkspaceFolder = { name: '', index: 0, uri: Uri.file(__dirname) };
when(workspace.workspaceFolders).thenReturn([workspaceFolder]);

const expectedSelector = [
{ scheme: 'file', language: PYTHON_LANGUAGE },
{ scheme: 'untitled', language: PYTHON_LANGUAGE }
];

const selector = analysisOptions.getDocumentSelector(workspaceFolder);

expect(selector).to.deep.equal(expectedSelector);
});
test('Ensure search pattern is provided in a multi-root workspace', () => {
const workspaceFolder1 = { name: '1', index: 0, uri: Uri.file(__dirname) };
const workspaceFolder2 = { name: '2', index: 1, uri: Uri.file(__dirname) };
when(workspace.workspaceFolders).thenReturn([workspaceFolder1, workspaceFolder2]);

const expectedSelector = [
{ scheme: 'file', language: PYTHON_LANGUAGE, pattern: `${workspaceFolder1.uri.fsPath}/**/*` },
{ scheme: 'untitled', language: PYTHON_LANGUAGE }
];

const selector = analysisOptions.getDocumentSelector(workspaceFolder1);

expect(selector).to.deep.equal(expectedSelector);
});
});