Skip to content

Commit

Permalink
Incorrect interpreter displayed in status bar in with multiple worksp…
Browse files Browse the repository at this point in the history
…ace folders (#785)

Fixes #690
  • Loading branch information
DonJayamanne authored Feb 14, 2018
1 parent 6389ad3 commit 1c8b1a5
Show file tree
Hide file tree
Showing 42 changed files with 1,081 additions and 743 deletions.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"theme": "dark"
},
"engines": {
"vscode": "^1.17.0"
"vscode": "^1.18.0"
},
"recommendations": [
"donjayamanne.jupyter"
Expand Down Expand Up @@ -1748,6 +1748,7 @@
"inversify": "^4.5.2",
"line-by-line": "^0.1.5",
"lodash": "^4.17.4",
"md5": "^2.2.1",
"minimatch": "^3.0.3",
"named-js-regexp": "^1.3.1",
"opn": "^5.1.0",
Expand Down Expand Up @@ -1781,11 +1782,13 @@
"@types/iconv-lite": "0.0.1",
"@types/istanbul": "^0.4.29",
"@types/lodash": "^4.14.74",
"@types/md5": "^2.1.32",
"@types/mocha": "^2.2.43",
"@types/node": "^6.0.40",
"@types/semver": "^5.4.0",
"@types/shortid": "0.0.29",
"@types/sinon": "^2.3.2",
"@types/untildify": "^3.0.0",
"@types/uuid": "^3.3.27",
"@types/winreg": "^1.2.30",
"@types/xml2js": "^0.4.0",
Expand Down
38 changes: 25 additions & 13 deletions src/client/common/application/applicationShell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,28 @@
// Licensed under the MIT License.
'use strict';

// tslint:disable-next-line:no-require-imports no-var-requires
// tslint:disable:no-require-imports no-var-requires no-any unified-signatures
const opn = require('opn');

import { injectable } from 'inversify';
import * as vscode from 'vscode';
import { Disposable, StatusBarAlignment, StatusBarItem, WorkspaceFolder, WorkspaceFolderPickOptions } from 'vscode';
import { IApplicationShell } from './types';

@injectable()
export class ApplicationShell implements IApplicationShell {
public showInformationMessage(message: string, ...items: string[]): Thenable<string> ;
public showInformationMessage(message: string, options: vscode.MessageOptions, ...items: string[]): Thenable<string> ;
public showInformationMessage<T extends vscode.MessageItem>(message: string, ...items: T[]): Thenable<T> ;
public showInformationMessage<T extends vscode.MessageItem>(message: string, options: vscode.MessageOptions, ...items: T[]): Thenable<T> ;
// tslint:disable-next-line:no-any
public showInformationMessage(message: string, options?: any, ...items: any[]): Thenable<any> {
public showInformationMessage(message: string, ...items: string[]): Thenable<string>;
public showInformationMessage(message: string, options: vscode.MessageOptions, ...items: string[]): Thenable<string>;
public showInformationMessage<T extends vscode.MessageItem>(message: string, ...items: T[]): Thenable<T>;
public showInformationMessage<T extends vscode.MessageItem>(message: string, options: vscode.MessageOptions, ...items: T[]): Thenable<T>;
public showInformationMessage(message: string, options?: any, ...items: any[]): Thenable<any> {
return vscode.window.showInformationMessage(message, options, ...items);
}

public showWarningMessage(message: string, ...items: string[]): Thenable<string>;
public showWarningMessage(message: string, options: vscode.MessageOptions, ...items: string[]): Thenable<string>;
public showWarningMessage<T extends vscode.MessageItem>(message: string, ...items: T[]): Thenable<T>;
public showWarningMessage<T extends vscode.MessageItem>(message: string, options: vscode.MessageOptions, ...items: T[]): Thenable<T>;
// tslint:disable-next-line:no-any
public showWarningMessage(message: any, options?: any, ...items: any[]) {
return vscode.window.showWarningMessage(message, options, ...items);
}
Expand All @@ -33,28 +32,41 @@ export class ApplicationShell implements IApplicationShell {
public showErrorMessage(message: string, options: vscode.MessageOptions, ...items: string[]): Thenable<string>;
public showErrorMessage<T extends vscode.MessageItem>(message: string, ...items: T[]): Thenable<T>;
public showErrorMessage<T extends vscode.MessageItem>(message: string, options: vscode.MessageOptions, ...items: T[]): Thenable<T>;
// tslint:disable-next-line:no-any
public showErrorMessage(message: any, options?: any, ...items: any[]) {
return vscode.window.showErrorMessage(message, options, ...items);
}

public showQuickPick(items: string[] | Thenable<string[]>, options?: vscode.QuickPickOptions, token?: vscode.CancellationToken): Thenable<string>;
public showQuickPick<T extends vscode.QuickPickItem>(items: T[] | Thenable<T[]>, options?: vscode.QuickPickOptions, token?: vscode.CancellationToken): Thenable<T>;
// tslint:disable-next-line:no-any
public showQuickPick(items: any, options?: any, token?: any) {
return vscode.window.showQuickPick(items, options, token);
}

public showOpenDialog(options: vscode.OpenDialogOptions): Thenable<vscode.Uri[]> {
public showOpenDialog(options: vscode.OpenDialogOptions): Thenable<vscode.Uri[] | undefined> {
return vscode.window.showOpenDialog(options);
}
public showSaveDialog(options: vscode.SaveDialogOptions): Thenable<vscode.Uri> {
public showSaveDialog(options: vscode.SaveDialogOptions): Thenable<vscode.Uri | undefined> {
return vscode.window.showSaveDialog(options);
}
public showInputBox(options?: vscode.InputBoxOptions, token?: vscode.CancellationToken): Thenable<string> {
public showInputBox(options?: vscode.InputBoxOptions, token?: vscode.CancellationToken): Thenable<string | undefined> {
return vscode.window.showInputBox(options, token);
}
public openUrl(url: string): void {
opn(url);
}

public setStatusBarMessage(text: string, hideAfterTimeout: number): Disposable;
public setStatusBarMessage(text: string, hideWhenDone: Thenable<any>): Disposable;
public setStatusBarMessage(text: string): Disposable;
public setStatusBarMessage(text: string, arg?: any): Disposable {
return vscode.window.setStatusBarMessage(text, arg);
}

public createStatusBarItem(alignment?: StatusBarAlignment, priority?: number): StatusBarItem {
return vscode.window.createStatusBarItem(alignment, priority);
}
public showWorkspaceFolderPick(options?: WorkspaceFolderPickOptions): Thenable<WorkspaceFolder | undefined> {
return vscode.window.showWorkspaceFolderPick(options);
}

}
54 changes: 52 additions & 2 deletions src/client/common/application/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
// tslint:disable:no-any unified-signatures

import * as vscode from 'vscode';
import { CancellationToken, Disposable, Event, FileSystemWatcher, GlobPattern, TextDocument, TextDocumentShowOptions, WorkspaceConfiguration } from 'vscode';
import { CancellationToken, ConfigurationChangeEvent, Disposable, Event, FileSystemWatcher, GlobPattern, TextDocument, TextDocumentShowOptions, WorkspaceConfiguration, WorkspaceFolderPickOptions } from 'vscode';
import { TextEditor, TextEditorEdit, TextEditorOptionsChangeEvent, TextEditorSelectionChangeEvent, TextEditorViewColumnChangeEvent } from 'vscode';
import { StatusBarAlignment, StatusBarItem } from 'vscode';
import { Uri, ViewColumn, WorkspaceFolder, WorkspaceFoldersChangeEvent } from 'vscode';
import { Terminal, TerminalOptions } from 'vscode';

Expand Down Expand Up @@ -197,6 +198,55 @@ export interface IApplicationShell {
* @param url Url to open.
*/
openUrl(url: string): void;

/**
* Set a message to the status bar. This is a short hand for the more powerful
* status bar [items](#window.createStatusBarItem).
*
* @param text The message to show, supports icon substitution as in status bar [items](#StatusBarItem.text).
* @param hideAfterTimeout Timeout in milliseconds after which the message will be disposed.
* @return A disposable which hides the status bar message.
*/
setStatusBarMessage(text: string, hideAfterTimeout: number): Disposable;

/**
* Set a message to the status bar. This is a short hand for the more powerful
* status bar [items](#window.createStatusBarItem).
*
* @param text The message to show, supports icon substitution as in status bar [items](#StatusBarItem.text).
* @param hideWhenDone Thenable on which completion (resolve or reject) the message will be disposed.
* @return A disposable which hides the status bar message.
*/
setStatusBarMessage(text: string, hideWhenDone: Thenable<any>): Disposable;

/**
* Set a message to the status bar. This is a short hand for the more powerful
* status bar [items](#window.createStatusBarItem).
*
* *Note* that status bar messages stack and that they must be disposed when no
* longer used.
*
* @param text The message to show, supports icon substitution as in status bar [items](#StatusBarItem.text).
* @return A disposable which hides the status bar message.
*/
setStatusBarMessage(text: string): Disposable;

/**
* Creates a status bar [item](#StatusBarItem).
*
* @param alignment The alignment of the item.
* @param priority The priority of the item. Higher values mean the item should be shown more to the left.
* @return A new status bar item.
*/
createStatusBarItem(alignment?: StatusBarAlignment, priority?: number): StatusBarItem;
/**
* Shows a selection list of [workspace folders](#workspace.workspaceFolders) to pick from.
* Returns `undefined` if no folder is open.
*
* @param options Configures the behavior of the workspace folder list.
* @return A promise that resolves to the workspace folder or `undefined`.
*/
showWorkspaceFolderPick(options?: WorkspaceFolderPickOptions): Thenable<WorkspaceFolder | undefined>;
}

export const ICommandManager = Symbol('ICommandManager');
Expand Down Expand Up @@ -371,7 +421,7 @@ export interface IWorkspaceService {
/**
* An event that is emitted when the [configuration](#WorkspaceConfiguration) changed.
*/
readonly onDidChangeConfiguration: Event<void>;
readonly onDidChangeConfiguration: Event<ConfigurationChangeEvent>;

/**
* Returns the [workspace folder](#WorkspaceFolder) that contains a given uri.
Expand Down
3 changes: 2 additions & 1 deletion src/client/common/application/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@

import { injectable } from 'inversify';
import * as vscode from 'vscode';
import { ConfigurationChangeEvent } from 'vscode';
import { IWorkspaceService } from './types';

@injectable()
export class WorkspaceService implements IWorkspaceService {
public get onDidChangeConfiguration(): vscode.Event<void> {
public get onDidChangeConfiguration(): vscode.Event<ConfigurationChangeEvent> {
return vscode.workspace.onDidChangeConfiguration;
}
public get rootPath(): string | undefined {
Expand Down
8 changes: 4 additions & 4 deletions src/client/common/process/pythonExecutionFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import { IPythonExecutionFactory, IPythonExecutionService } from './types';
@injectable()
export class PythonExecutionFactory implements IPythonExecutionFactory {
private envVarsService: IEnvironmentVariablesProvider;
constructor( @inject(IServiceContainer) private serviceContainer: IServiceContainer) {
this.envVarsService = serviceContainer.get<IEnvironmentVariablesProvider>(IEnvironmentVariablesProvider);
}
constructor(@inject(IServiceContainer) private serviceContainer: IServiceContainer) {
this.envVarsService = serviceContainer.get<IEnvironmentVariablesProvider>(IEnvironmentVariablesProvider);
}
public async create(resource?: Uri): Promise<IPythonExecutionService> {
return this.envVarsService.getEnvironmentVariables(resource)
.then(customEnvVars => {
return new PythonExecutionService(this.serviceContainer, customEnvVars);
return new PythonExecutionService(this.serviceContainer, customEnvVars, resource);
});
}
}
13 changes: 11 additions & 2 deletions src/client/common/process/pythonProcess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
// Licensed under the MIT License.

import { injectable } from 'inversify';
import { Uri } from 'vscode';
import { IServiceContainer } from '../../ioc/types';
import { ErrorUtils } from '../errors/errorUtils';
import { ModuleNotInstalledError } from '../errors/moduleNotInstalledError';
import { IFileSystem } from '../platform/types';
import { IConfigurationService } from '../types';
import { EnvironmentVariables } from '../variables/types';
import { ExecutionResult, IProcessService, IPythonExecutionService, ObservableExecutionResult, SpawnOptions } from './types';
Expand All @@ -13,17 +15,24 @@ import { ExecutionResult, IProcessService, IPythonExecutionService, ObservableEx
export class PythonExecutionService implements IPythonExecutionService {
private procService: IProcessService;
private configService: IConfigurationService;
private fileSystem: IFileSystem;

constructor(serviceContainer: IServiceContainer, private envVars: EnvironmentVariables | undefined) {
constructor(serviceContainer: IServiceContainer, private envVars: EnvironmentVariables | undefined, private resource?: Uri) {
this.procService = serviceContainer.get<IProcessService>(IProcessService);
this.configService = serviceContainer.get<IConfigurationService>(IConfigurationService);
this.fileSystem = serviceContainer.get<IFileSystem>(IFileSystem);
}

public async getVersion(): Promise<string> {
return this.procService.exec(this.pythonPath, ['--version'], { env: this.envVars, mergeStdOutErr: true })
.then(output => output.stdout.trim());
}
public async getExecutablePath(): Promise<string> {
// If we've passed the python file, then return the file.
// This is because on mac if using the interpreter /usr/bin/python2.7 we can get a different value for the path
if (await this.fileSystem.fileExistsAsync(this.pythonPath)){
return this.pythonPath;
}
return this.procService.exec(this.pythonPath, ['-c', 'import sys;print(sys.executable)'], { env: this.envVars, throwOnStdErr: true })
.then(output => output.stdout.trim());
}
Expand Down Expand Up @@ -71,6 +80,6 @@ export class PythonExecutionService implements IPythonExecutionService {
return result;
}
private get pythonPath(): string {
return this.configService.getSettings().pythonPath;
return this.configService.getSettings(this.resource).pythonPath;
}
}
2 changes: 1 addition & 1 deletion src/client/debugger/Common/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import * as child_process from 'child_process';
import * as fs from 'fs';
import * as path from 'path';
import * as untildify from 'untildify';
import untildify = require('untildify');
import { IPythonModule, IPythonProcess, IPythonThread } from './Contracts';

export const IS_WINDOWS = /^win/.test(process.platform);
Expand Down
12 changes: 4 additions & 8 deletions src/client/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,15 @@ import { PythonInstaller } from './common/installer/pythonInstallation';
import { registerTypes as installerRegisterTypes } from './common/installer/serviceRegistry';
import { registerTypes as platformRegisterTypes } from './common/platform/serviceRegistry';
import { registerTypes as processRegisterTypes } from './common/process/serviceRegistry';
import { IProcessService } from './common/process/types';
import { registerTypes as commonRegisterTypes } from './common/serviceRegistry';
import { GLOBAL_MEMENTO, IDisposableRegistry, ILogger, IMemento, IOutputChannel, IPersistentStateFactory, WORKSPACE_MEMENTO } from './common/types';
import { registerTypes as variableRegisterTypes } from './common/variables/serviceRegistry';
import { BaseConfigurationProvider } from './debugger/configProviders/baseProvider';
import { registerTypes as debugConfigurationRegisterTypes } from './debugger/configProviders/serviceRegistry';
import { IDebugConfigurationProvider } from './debugger/types';
import { registerTypes as formattersRegisterTypes } from './formatters/serviceRegistry';
import { InterpreterSelector } from './interpreter/configuration/interpreterSelector';
import { ICondaService, IInterpreterService, IInterpreterVersionService } from './interpreter/contracts';
import { ShebangCodeLensProvider } from './interpreter/display/shebangCodeLensProvider';
import { IInterpreterSelector } from './interpreter/configuration/types';
import { ICondaService, IInterpreterService, IShebangCodeLensProvider } from './interpreter/contracts';
import { registerTypes as interpretersRegisterTypes } from './interpreter/serviceRegistry';
import { ServiceContainer } from './ioc/container';
import { ServiceManager } from './ioc/serviceManager';
Expand Down Expand Up @@ -116,9 +114,7 @@ export async function activate(context: vscode.ExtensionContext) {
interpreterManager.refresh()
.catch(ex => console.error('Python Extension: interpreterManager.refresh', ex));

const processService = serviceContainer.get<IProcessService>(IProcessService);
const interpreterVersionService = serviceContainer.get<IInterpreterVersionService>(IInterpreterVersionService);
context.subscriptions.push(new InterpreterSelector(interpreterManager, interpreterVersionService, processService));
context.subscriptions.push(serviceContainer.get<IInterpreterSelector>(IInterpreterSelector));
context.subscriptions.push(activateUpdateSparkLibraryProvider());
activateSimplePythonRefactorProvider(context, standardOutputChannel, serviceContainer);
const jediFactory = new JediFactory(context.asAbsolutePath('.'), serviceContainer);
Expand Down Expand Up @@ -156,7 +152,7 @@ export async function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.languages.registerHoverProvider(PYTHON, new PythonHoverProvider(jediFactory)));
context.subscriptions.push(vscode.languages.registerReferenceProvider(PYTHON, new PythonReferenceProvider(jediFactory)));
context.subscriptions.push(vscode.languages.registerCompletionItemProvider(PYTHON, new PythonCompletionItemProvider(jediFactory, serviceContainer), '.'));
context.subscriptions.push(vscode.languages.registerCodeLensProvider(PYTHON, new ShebangCodeLensProvider(processService)));
context.subscriptions.push(vscode.languages.registerCodeLensProvider(PYTHON, serviceContainer.get<IShebangCodeLensProvider>(IShebangCodeLensProvider)));

const symbolProvider = new PythonSymbolProvider(jediFactory);
context.subscriptions.push(vscode.languages.registerDocumentSymbolProvider(PYTHON, symbolProvider));
Expand Down
Loading

0 comments on commit 1c8b1a5

Please sign in to comment.