@@ -12,7 +12,7 @@ import * as uuid from 'uuid/v4';
1212import { Disposable , Event , EventEmitter , Uri } from 'vscode' ;
1313import { CancellationToken } from 'vscode-jsonrpc' ;
1414
15- import { ILiveShareApi } from '../../common/application/types' ;
15+ import { ILiveShareApi , IWorkspaceService } from '../../common/application/types' ;
1616import { Cancellation , CancellationError } from '../../common/cancellation' ;
1717import { traceError , traceInfo , traceWarning } from '../../common/logger' ;
1818import { IConfigurationService , IDisposableRegistry } from '../../common/types' ;
@@ -36,6 +36,7 @@ import {
3636 INotebookServerLaunchInfo ,
3737 InterruptResult
3838} from '../types' ;
39+ import { expandWorkingDir } from './jupyterUtils' ;
3940
4041class CellSubscriber {
4142 private deferred : Deferred < CellState > = createDeferred < CellState > ( ) ;
@@ -139,6 +140,7 @@ export class JupyterNotebookBase implements INotebook {
139140 private ranInitialSetup = false ;
140141 private _resource : Uri ;
141142 private _disposed : boolean = false ;
143+ private _workingDirectory : string | undefined ;
142144
143145 constructor (
144146 _liveShare : ILiveShareApi , // This is so the liveshare mixin works
@@ -149,7 +151,8 @@ export class JupyterNotebookBase implements INotebook {
149151 private launchInfo : INotebookServerLaunchInfo ,
150152 private loggers : INotebookExecutionLogger [ ] ,
151153 resource : Uri ,
152- private getDisposedError : ( ) => Error
154+ private getDisposedError : ( ) => Error ,
155+ private workspace : IWorkspaceService
153156 ) {
154157 this . sessionStartTime = Date . now ( ) ;
155158 this . _resource = resource ;
@@ -183,13 +186,11 @@ export class JupyterNotebookBase implements INotebook {
183186 return ;
184187 }
185188 this . ranInitialSetup = true ;
189+ this . _workingDirectory = undefined ;
186190
187191 try {
188192 // When we start our notebook initial, change to our workspace or user specified root directory
189- if ( this . launchInfo && this . launchInfo . workingDir && this . launchInfo . connectionInfo . localLaunch ) {
190- traceInfo ( `Changing directory for ${ this . resource . toString ( ) } ` ) ;
191- await this . changeDirectoryIfPossible ( this . launchInfo . workingDir ) ;
192- }
193+ await this . updateWorkingDirectory ( ) ;
193194
194195 const settings = this . configService . getSettings ( ) . datascience ;
195196 const matplobInit = ! settings || settings . enablePlotViewer ? CodeSnippits . MatplotLibInitSvg : CodeSnippits . MatplotLibInitPng ;
@@ -249,12 +250,9 @@ export class JupyterNotebookBase implements INotebook {
249250 return deferred . promise ;
250251 }
251252
252- public async setInitialDirectory ( directory : string ) : Promise < void > {
253- // If we launched local and have no working directory call this on add code to change directory
254- if ( this . launchInfo && ! this . launchInfo . workingDir && this . launchInfo . connectionInfo . localLaunch ) {
255- await this . changeDirectoryIfPossible ( directory ) ;
256- this . launchInfo . workingDir = directory ;
257- }
253+ public setLaunchingFile ( file : string ) : Promise < void > {
254+ // Update our working directory if we don't have one set already
255+ return this . updateWorkingDirectory ( file ) ;
258256 }
259257
260258 public executeObservable ( code : string , file : string , line : number , id : string , silent : boolean = false ) : Observable < ICell [ ] > {
@@ -587,6 +585,24 @@ export class JupyterNotebookBase implements INotebook {
587585 } ) ;
588586 }
589587
588+ private async updateWorkingDirectory ( launchingFile ?: string ) : Promise < void > {
589+ if ( this . launchInfo && this . launchInfo . connectionInfo . localLaunch && ! this . _workingDirectory ) {
590+ // See what our working dir is supposed to be
591+ const suggested = this . launchInfo . workingDir ;
592+ if ( suggested && await fs . pathExists ( suggested ) ) {
593+ // We should use the launch info directory. It trumps the possible dir
594+ this . _workingDirectory = suggested ;
595+ return this . changeDirectoryIfPossible ( this . _workingDirectory ) ;
596+ } else if ( launchingFile && await fs . pathExists ( launchingFile ) ) {
597+ // Combine the working directory with this file if possible.
598+ this . _workingDirectory = expandWorkingDir ( this . launchInfo . workingDir , launchingFile , this . workspace ) ;
599+ if ( this . _workingDirectory ) {
600+ return this . changeDirectoryIfPossible ( this . _workingDirectory ) ;
601+ }
602+ }
603+ }
604+ }
605+
590606 private changeDirectoryIfPossible = async ( directory : string ) : Promise < void > => {
591607 if ( this . launchInfo && this . launchInfo . connectionInfo . localLaunch && await fs . pathExists ( directory ) ) {
592608 await this . executeSilently ( `%cd "${ directory } "` ) ;
0 commit comments