Skip to content

Commit 723280c

Browse files
committed
wip
1 parent 49013de commit 723280c

File tree

6 files changed

+82
-14
lines changed

6 files changed

+82
-14
lines changed

extensions/positron-supervisor/src/KallichoreSession.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -330,18 +330,21 @@ export class KallichoreSession implements JupyterLanguageRuntimeSession {
330330
this._kernelSpec = kernelSpec;
331331
const varActions = await this.buildEnvVarActions(false);
332332

333-
// Prepare the working directory; use the workspace root if available,
334-
// otherwise the home directory
335-
let workingDir = vscode.workspace.workspaceFolders?.[0].uri.fsPath || os.homedir();
336-
337-
// If we have a notebook URI, use its parent directory as the working
338-
// directory instead. Note that not all notebooks have valid on-disk
339-
// URIs since they may be transient or not yet saved; for these, we fall
340-
// back to the workspace root or home directory.
341-
if (this.metadata.notebookUri?.fsPath) {
342-
const notebookPath = this.metadata.notebookUri.fsPath;
343-
if (fs.existsSync(notebookPath)) {
344-
workingDir = path.dirname(notebookPath);
333+
let workingDir = this.metadata.workingDirectory;
334+
335+
if (!workingDir) {
336+
// Use the workspace root if available, otherwise the home directory
337+
workingDir = vscode.workspace.workspaceFolders?.[0].uri.fsPath || os.homedir();
338+
339+
// If we have a notebook URI, use its parent directory as the working
340+
// directory instead. Note that not all notebooks have valid on-disk
341+
// URIs since they may be transient or not yet saved; for these, we fall
342+
// back to the workspace root or home directory.
343+
if (this.metadata.notebookUri?.fsPath) {
344+
const notebookPath = this.metadata.notebookUri.fsPath;
345+
if (fs.existsSync(notebookPath)) {
346+
workingDir = path.dirname(notebookPath);
347+
}
345348
}
346349
}
347350

src/positron-dts/positron.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,9 @@ declare module 'positron' {
540540

541541
/** The URI of the notebook document associated with the session, if any */
542542
readonly notebookUri?: vscode.Uri;
543+
544+
/** The starting working directory of the session, if any */
545+
readonly workingDirectory?: string;
543546
}
544547

545548
/**

src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ import { IModelService } from '../../../../editor/common/services/model.js';
1515
import { ILanguageSelection, ILanguageService } from '../../../../editor/common/languages/language.js';
1616
import { ITextModelContentProvider, ITextModelService } from '../../../../editor/common/services/resolverService.js';
1717
import * as nls from '../../../../nls.js';
18+
// --- Start Positron ---
19+
// eslint-disable-next-line no-duplicate-imports
20+
import { ConfigurationScope } from '../../../../platform/configuration/common/configurationRegistry.js';
21+
// --- End Positron ---
1822
import { Extensions, IConfigurationPropertySchema, IConfigurationRegistry } from '../../../../platform/configuration/common/configurationRegistry.js';
1923
import { SyncDescriptor } from '../../../../platform/instantiation/common/descriptors.js';
2024
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
@@ -1311,6 +1315,12 @@ configurationRegistry.registerConfiguration({
13111315
type: 'string',
13121316
default: '',
13131317
tags: ['notebookLayout']
1318+
},
1319+
[NotebookSetting.workingDirectory]: {
1320+
markdownDescription: nls.localize('notebook.workingDirectory', "Default working directory for notebook kernels. Supports variables like `${workspaceFolder}`. When empty, uses the notebook file's directory. Any change to this setting will apply to future opened notebooks."),
1321+
type: 'string',
1322+
default: '',
1323+
scope: ConfigurationScope.RESOURCE
13141324
}
13151325
}
13161326
});

src/vs/workbench/contrib/notebook/common/notebookCommon.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,7 @@ export const NotebookSetting = {
10651065
outputBackupSizeLimit: 'notebook.backup.sizeLimit',
10661066
multiCursor: 'notebook.multiCursor.enabled',
10671067
markupFontFamily: 'notebook.markup.fontFamily',
1068+
workingDirectory: 'notebook.workingDirectory',
10681069
} as const;
10691070

10701071
export const enum CellStatusbarAlignment {

src/vs/workbench/services/runtimeSession/common/runtimeSession.ts

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ import { INotificationService, Severity } from '../../../../platform/notificatio
2727
import { localize } from '../../../../nls.js';
2828
import { UiClientInstance } from '../../languageRuntime/common/languageRuntimeUiClient.js';
2929
import { IWorkbenchEnvironmentService } from '../../environment/common/environmentService.js';
30+
import { IConfigurationResolverService } from '../../configurationResolver/common/configurationResolver.js';
31+
import { IWorkspaceContextService } from '../../../../platform/workspace/common/workspace.js';
32+
import { NotebookSetting } from '../../../contrib/notebook/common/notebookCommon.js';
3033

3134
/**
3235
* The maximum number of active sessions a user can have running at a time.
@@ -170,7 +173,9 @@ export class RuntimeSessionService extends Disposable implements IRuntimeSession
170173
@IExtensionService private readonly _extensionService: IExtensionService,
171174
@IStorageService private readonly _storageService: IStorageService,
172175
@IUpdateService private readonly _updateService: IUpdateService,
173-
@IWorkbenchEnvironmentService private readonly _environmentService: IWorkbenchEnvironmentService
176+
@IWorkbenchEnvironmentService private readonly _environmentService: IWorkbenchEnvironmentService,
177+
@IConfigurationResolverService private readonly _configurationResolverService: IConfigurationResolverService,
178+
@IWorkspaceContextService private readonly _workspaceContextService: IWorkspaceContextService
174179
) {
175180

176181
super();
@@ -387,6 +392,44 @@ export class RuntimeSessionService extends Disposable implements IRuntimeSession
387392
return Array.from(this._activeSessionsBySessionId.values());
388393
}
389394

395+
/**
396+
* Resolves the working directory configuration with variable substitution.
397+
*
398+
* @param notebookUri The URI of the notebook, if any, for resource-scoped configuration
399+
* @returns The resolved working directory or undefined if not configured
400+
*/
401+
private async resolveWorkingDirectory(notebookUri?: URI): Promise<string | undefined> {
402+
// Get the working directory configuration
403+
const configValue = this._configurationService.getValue<string>(
404+
NotebookSetting.workingDirectory,
405+
notebookUri ? { resource: notebookUri } : {}
406+
);
407+
408+
// If no configuration value is set, return undefined
409+
if (!configValue || configValue.trim() === '') {
410+
return undefined;
411+
}
412+
413+
// Get the workspace folder for variable resolution
414+
const workspaceFolder = notebookUri
415+
? this._workspaceContextService.getWorkspaceFolder(notebookUri)
416+
: this._workspaceContextService.getWorkspace().folders[0];
417+
418+
try {
419+
// Resolve variables in the configuration value
420+
const resolvedValue = await this._configurationResolverService.resolveAsync(
421+
workspaceFolder || undefined,
422+
configValue
423+
);
424+
425+
return resolvedValue;
426+
} catch (error) {
427+
// Log the error and return the original value as fallback
428+
this._logService.warn(`Failed to resolve working directory variables in '${configValue}':`, error);
429+
return configValue;
430+
}
431+
}
432+
390433
/**
391434
* Select a session for the provided runtime.
392435
*
@@ -1535,10 +1578,15 @@ export class RuntimeSessionService extends Disposable implements IRuntimeSession
15351578
}
15361579

15371580
const sessionId = this.generateNewSessionId(runtimeMetadata, sessionMode === LanguageRuntimeSessionMode.Notebook);
1581+
1582+
// Resolve the working directory configuration
1583+
const workingDirectory = await this.resolveWorkingDirectory(notebookUri);
1584+
15381585
const sessionMetadata: IRuntimeSessionMetadata = {
15391586
sessionId,
15401587
sessionMode,
15411588
notebookUri,
1589+
workingDirectory,
15421590
createdTimestamp: Date.now(),
15431591
startReason: source
15441592
};
@@ -1645,7 +1693,7 @@ export class RuntimeSessionService extends Disposable implements IRuntimeSession
16451693
* @param runtime The runtime to get the manager for.
16461694
* @returns The session manager that manages the runtime.
16471695
*
1648-
* Throws an errror if no session manager is found for the runtime.
1696+
* Throws an error if no session manager is found for the runtime.
16491697
*/
16501698
private async getManagerForRuntime(runtime: ILanguageRuntimeMetadata): Promise<ILanguageRuntimeSessionManager> {
16511699
// Look for the session manager that manages the runtime.

src/vs/workbench/services/runtimeSession/common/runtimeSessionService.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ export interface IRuntimeSessionMetadata {
8585
/** The notebook associated with the session, if any */
8686
readonly notebookUri: URI | undefined;
8787

88+
/** The starting working directory of the session, if any */
89+
readonly workingDirectory?: string;
90+
8891
/**
8992
* A timestamp (in milliseconds since the Epoch) representing the time at
9093
* which the runtime session was created.

0 commit comments

Comments
 (0)