diff --git a/package.nls.json b/package.nls.json
index e7c83e63aae5..0072adee4ec6 100644
--- a/package.nls.json
+++ b/package.nls.json
@@ -221,10 +221,15 @@
"StartPage.folderDesc": "- Open a
Folder
- Open a Workspace
",
"StartPage.badWebPanelFormatString": "{0} is not a valid file name
",
"Jupyter.extensionRequired": "The Jupyter extension is required to perform that task. Click Yes to open the Jupyter extension installation page.",
- "TensorBoard.logDirectoryPrompt" : "Please select a log directory to start TensorBoard with.",
+ "TensorBoard.useCurrentWorkingDirectory": "Use current working directory",
+ "TensorBoard.currentDirectory": "Current: {0}",
+ "TensorBoard.logDirectoryPrompt" : "Select a log directory to start TensorBoard with",
"TensorBoard.progressMessage" : "Starting TensorBoard session...",
"TensorBoard.failedToStartSessionError" : "We failed to start a TensorBoard session due to the following error: {0}",
- "TensorBoard.nativeTensorBoardPrompt" : "VS Code now has native TensorBoard support. Would you like to launch TensorBoard?",
- "TensorBoard.usingCurrentWorkspaceFolder": "We are using the current workspace folder as the log directory for your TensorBoard session.",
- "TensorBoard.selectAFolder": "Select a folder"
+ "TensorBoard.nativeTensorBoardPrompt" : "VS Code now has native TensorBoard support. Would you like to launch TensorBoard? (Tip: Launch TensorBoard anytime by opening the command palette and searching for \"Launch TensorBoard\".)",
+ "TensorBoard.selectAFolder": "Select a folder",
+ "TensorBoard.selectAnotherFolder": "Select another folder",
+ "TensorBoard.selectAFolderDetail": "Select a log directory containing tfevent files",
+ "TensorBoard.selectAnotherFolderDetail": "Use the file explorer to select another folder",
+ "TensorBoard.useCurrentWorkingDirectoryDetail": "TensorBoard will search for tfevent files in all subdirectories of the current working directory"
}
diff --git a/src/client/common/utils/localize.ts b/src/client/common/utils/localize.ts
index 7a5b67065cc4..ab4e3410dcb1 100644
--- a/src/client/common/utils/localize.ts
+++ b/src/client/common/utils/localize.ts
@@ -134,9 +134,18 @@ export namespace Jupyter {
}
export namespace TensorBoard {
+ export const useCurrentWorkingDirectoryDetail = localize(
+ 'TensorBoard.useCurrentWorkingDirectoryDetail',
+ 'TensorBoard will search for tfevent files in all subdirectories of the current working directory'
+ );
+ export const useCurrentWorkingDirectory = localize(
+ 'TensorBoard.useCurrentWorkingDirectory',
+ 'Use current working directory'
+ );
+ export const currentDirectory = localize('TensorBoard.currentDirectory', 'Current: {0}');
export const logDirectoryPrompt = localize(
'TensorBoard.logDirectoryPrompt',
- 'Please select a log directory to start TensorBoard with.'
+ 'Select a log directory to start TensorBoard with'
);
export const progressMessage = localize('TensorBoard.progressMessage', 'Starting TensorBoard session...');
export const failedToStartSessionError = localize(
@@ -145,13 +154,18 @@ export namespace TensorBoard {
);
export const nativeTensorBoardPrompt = localize(
'TensorBoard.nativeTensorBoardPrompt',
- 'VS Code now has native TensorBoard support. Would you like to launch TensorBoard?'
- );
- export const usingCurrentWorkspaceFolder = localize(
- 'TensorBoard.usingCurrentWorkspaceFolder',
- 'We are using the current workspace folder as the log directory for your TensorBoard session.'
+ 'VS Code now has native TensorBoard support. Would you like to launch TensorBoard? (Tip: Launch TensorBoard anytime by opening the command palette and searching for "Launch TensorBoard".)'
);
export const selectAFolder = localize('TensorBoard.selectAFolder', 'Select a folder');
+ export const selectAFolderDetail = localize(
+ 'TensorBoard.selectAFolderDetail',
+ 'Select a log directory containing tfevent files'
+ );
+ export const selectAnotherFolder = localize('TensorBoard.selectAnotherFolder', 'Select another folder');
+ export const selectAnotherFolderDetail = localize(
+ 'TensorBoard.selectAnotherFolderDetail',
+ 'Use the file explorer to select another folder'
+ );
}
export namespace LanguageService {
diff --git a/src/client/tensorBoard/tensorBoardSession.ts b/src/client/tensorBoard/tensorBoardSession.ts
index c03ee1207669..b646f0d9df34 100644
--- a/src/client/tensorBoard/tensorBoardSession.ts
+++ b/src/client/tensorBoard/tensorBoardSession.ts
@@ -9,6 +9,7 @@ import {
Progress,
ProgressLocation,
ProgressOptions,
+ QuickPickItem,
ViewColumn,
WebviewPanel,
window
@@ -20,7 +21,7 @@ import { _SCRIPTS_DIR, tensorboardLauncher } from '../common/process/internal/sc
import { IProcessServiceFactory, ObservableExecutionResult } from '../common/process/types';
import { IInstaller, InstallerResponse, Product } from '../common/types';
import { createDeferred, sleep } from '../common/utils/async';
-import { Common, TensorBoard } from '../common/utils/localize';
+import { TensorBoard } from '../common/utils/localize';
import { IInterpreterService } from '../interpreter/contracts';
/**
@@ -101,20 +102,56 @@ export class TensorBoardSession {
}
}
- // Display a prompt asking the user to acknowledge our autopopulated log directory or
+ private getQuickPickItems(logDir: string | undefined) {
+ if (logDir) {
+ const useCwd = {
+ label: TensorBoard.useCurrentWorkingDirectory(),
+ detail: TensorBoard.useCurrentWorkingDirectoryDetail()
+ };
+ const selectAnotherFolder = {
+ label: TensorBoard.selectAnotherFolder(),
+ detail: TensorBoard.selectAnotherFolderDetail()
+ };
+ return [useCwd, selectAnotherFolder];
+ } else {
+ const selectAFolder = {
+ label: TensorBoard.selectAFolder(),
+ detail: TensorBoard.selectAFolderDetail()
+ };
+ return [selectAFolder];
+ }
+ }
+
+ // Display a quickpick asking the user to acknowledge our autopopulated log directory or
// select a new one using the file picker. Default this to the folder that is open in
// the editor, if any, then the directory that the active text editor is in, if any.
private async askUserForLogDir(): Promise {
const logDir = this.autopopulateLogDirectoryPath();
- const gotIt = Common.gotIt();
+ const useCurrentWorkingDirectory = TensorBoard.useCurrentWorkingDirectory();
const selectAFolder = TensorBoard.selectAFolder();
- const message = logDir ? TensorBoard.usingCurrentWorkspaceFolder() : TensorBoard.logDirectoryPrompt();
- const prompts = logDir ? [gotIt, selectAFolder] : [selectAFolder];
- const selection = await window.showInformationMessage(message, ...prompts);
- switch (selection) {
- case gotIt:
+ const selectAnotherFolder = TensorBoard.selectAnotherFolder();
+ const items: QuickPickItem[] = this.getQuickPickItems(logDir);
+ const quickPick = window.createQuickPick();
+ quickPick.title = TensorBoard.logDirectoryPrompt();
+ quickPick.canSelectMany = false;
+ quickPick.enabled = false;
+ quickPick.items = items;
+ if (logDir) {
+ quickPick.placeholder = TensorBoard.currentDirectory().format(logDir);
+ }
+ const selection = createDeferred();
+ quickPick.onDidAccept(() => {
+ quickPick.hide();
+ selection.resolve(quickPick.selectedItems[0]);
+ });
+ quickPick.show();
+ const item = await selection.promise;
+ quickPick.dispose();
+ switch (item.label) {
+ case useCurrentWorkingDirectory:
return logDir;
case selectAFolder:
+ case selectAnotherFolder:
return this.showFilePicker();
default:
return undefined;
@@ -125,7 +162,6 @@ export class TensorBoardSession {
// Times out if it hasn't started up after 1 minute.
// Hold on to the process so we can kill it when the webview is closed.
private async startTensorboardSession(logDir: string): Promise {
- const cwd = this.getFullyQualifiedLogDirectory(logDir);
const pythonExecutable = await this.interpreterService.getActiveInterpreter();
if (!pythonExecutable) {
return false;
@@ -145,12 +181,12 @@ export class TensorBoardSession {
const processService = await this.processServiceFactory.create();
const args = tensorboardLauncher([logDir]);
- const observable = processService.execObservable(pythonExecutable.path, args, { cwd });
+ const observable = processService.execObservable(pythonExecutable.path, args);
const result = await window.withProgress(
progressOptions,
(_progress: Progress<{}>, token: CancellationToken) => {
- traceInfo(`Starting TensorBoard with log directory ${cwd}...`);
+ traceInfo(`Starting TensorBoard with log directory ${logDir}...`);
const spawnTensorBoard = this.waitForTensorBoardStart(observable);
const userCancellation = createPromiseFromCancellation({
@@ -247,24 +283,6 @@ export class TensorBoardSession {
}
}
- // TensorBoard accepts absolute or relative log directory paths to tfevent files.
- // It uses these files to populate its visualizations. If given a relative path,
- // TensorBoard resolves them against the current working directory. Make the
- // chosen filepath explicit in our logs. If a workspace folder is open, ensure
- // we pass it as cwd to the spawned process. If there is no rootPath available,
- // explicitly pass process.cwd, which is what `spawn` would use by default anyway.
- private getFullyQualifiedLogDirectory(logDir: string) {
- if (path.isAbsolute(logDir)) {
- return logDir;
- }
- const rootPath = this.workspaceService.rootPath;
- if (rootPath) {
- return path.resolve(rootPath, logDir);
- } else {
- return path.resolve(process.cwd(), logDir);
- }
- }
-
private autopopulateLogDirectoryPath(): string | undefined {
if (this.workspaceService.rootPath) {
return this.workspaceService.rootPath;