Skip to content

Commit f5e494e

Browse files
committed
reverted notebook/IW changes
1 parent 6d4d5a5 commit f5e494e

File tree

8 files changed

+107
-37
lines changed

8 files changed

+107
-37
lines changed

src/vs/base/common/network.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export namespace Schemas {
6060
export const vscodeNotebookCell = 'vscode-notebook-cell';
6161
export const vscodeNotebookCellMetadata = 'vscode-notebook-cell-metadata';
6262
export const vscodeNotebookCellOutput = 'vscode-notebook-cell-output';
63+
export const vscodeInteractive = 'vscode-interactive';
6364
export const vscodeInteractiveInput = 'vscode-interactive-input';
6465

6566
export const vscodeSettings = 'vscode-settings';

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

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import { IInteractiveDocumentService, InteractiveDocumentService } from 'vs/work
5151
import { InteractiveEditor } from 'vs/workbench/contrib/interactive/browser/interactiveEditor';
5252
import { InteractiveEditorInput } from 'vs/workbench/contrib/interactive/browser/interactiveEditorInput';
5353
import { IInteractiveHistoryService, InteractiveHistoryService } from 'vs/workbench/contrib/interactive/browser/interactiveHistoryService';
54+
import { InteractiveWindowFileSystem } from 'vs/workbench/contrib/interactive/browser/interactiveWindowFileSystem';
5455
import { NOTEBOOK_EDITOR_WIDGET_ACTION_WEIGHT } from 'vs/workbench/contrib/notebook/browser/controller/coreActions';
5556
import { INotebookEditorOptions } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
5657
import { NotebookEditorWidget } from 'vs/workbench/contrib/notebook/browser/notebookEditorWidget';
@@ -95,6 +96,9 @@ export class InteractiveDocumentContribution extends Disposable implements IWork
9596
cellContentMetadata: {}
9697
};
9798

99+
const interactiveWindowFS = new InteractiveWindowFileSystem();
100+
this._register(fileService.registerProvider(Schemas.vscodeInteractive, interactiveWindowFS));
101+
98102
const serializer: INotebookSerializer = {
99103
options: contentOptions,
100104
dataToNotebook: async (data: VSBuffer): Promise<NotebookData> => {
@@ -201,9 +205,7 @@ export class InteractiveDocumentContribution extends Disposable implements IWork
201205
priority: RegisteredEditorPriority.exclusive
202206
},
203207
{
204-
canSupportResource: uri =>
205-
(uri.scheme === Schemas.untitled && extname(uri) === '.interactive') ||
206-
(uri.scheme === Schemas.vscodeNotebookCell && extname(uri) === '.interactive'),
208+
canSupportResource: uri => uri.scheme === Schemas.vscodeInteractive || (uri.scheme === Schemas.vscodeNotebookCell && extname(uri) === '.interactive'),
207209
singlePerResource: true
208210
},
209211
{
@@ -369,7 +371,7 @@ registerAction2(class extends Action2 {
369371
preserveFocus: typeof showOptions !== 'number' ? (showOptions?.preserveFocus ?? false) : false
370372
};
371373

372-
if (resource && extname(resource) === '.interactive') {
374+
if (resource && resource.scheme === Schemas.vscodeInteractive) {
373375
logService.debug('Open interactive window from resource:', resource.toString());
374376
const resourceUri = URI.revive(resource);
375377
const editors = editorService.findEditors(resourceUri).filter(id => id.editor instanceof InteractiveEditorInput && id.editor.resource?.toString() === resourceUri.toString());
@@ -399,7 +401,7 @@ registerAction2(class extends Action2 {
399401
let inputUri: URI | undefined = undefined;
400402
let counter = 1;
401403
do {
402-
notebookUri = URI.from({ scheme: Schemas.untitled, path: `/Interactive-${counter}.interactive` });
404+
notebookUri = URI.from({ scheme: Schemas.vscodeInteractive, path: `/Interactive-${counter}.interactive` });
403405
inputUri = URI.from({ scheme: Schemas.vscodeInteractiveInput, path: `/InteractiveInput-${counter}` });
404406

405407
counter++;
@@ -433,7 +435,7 @@ registerAction2(class extends Action2 {
433435
category: interactiveWindowCategory,
434436
keybinding: {
435437
// when: NOTEBOOK_CELL_LIST_FOCUSED,
436-
when: ContextKeyExpr.equals('activeEditor', 'workbench.editor.interactive'),
438+
when: ContextKeyExpr.equals('resourceScheme', Schemas.vscodeInteractive),
437439
primary: KeyMod.WinCtrl | KeyCode.Enter,
438440
win: {
439441
primary: KeyMod.CtrlCmd | KeyCode.Enter
@@ -467,14 +469,15 @@ registerAction2(class extends Action2 {
467469
const notebookEditorService = accessor.get(INotebookEditorService);
468470
let editorControl: { notebookEditor: NotebookEditorWidget | undefined; codeEditor: CodeEditorWidget } | undefined;
469471
if (context) {
470-
const resourceUri = URI.revive(context);
471-
const editors = editorService.findEditors(resourceUri)
472-
.filter(id => id.editor instanceof InteractiveEditorInput && id.editor.resource?.toString() === resourceUri.toString());
473-
if (editors.length) {
474-
const editorInput = editors[0].editor as InteractiveEditorInput;
475-
const currentGroup = editors[0].groupId;
476-
const editor = await editorService.openEditor(editorInput, currentGroup);
477-
editorControl = editor?.getControl() as { notebookEditor: NotebookEditorWidget | undefined; codeEditor: CodeEditorWidget } | undefined;
472+
if (context.scheme === Schemas.vscodeInteractive) {
473+
const resourceUri = URI.revive(context);
474+
const editors = editorService.findEditors(resourceUri).filter(id => id.editor instanceof InteractiveEditorInput && id.editor.resource?.toString() === resourceUri.toString());
475+
if (editors.length) {
476+
const editorInput = editors[0].editor as InteractiveEditorInput;
477+
const currentGroup = editors[0].groupId;
478+
const editor = await editorService.openEditor(editorInput, currentGroup);
479+
editorControl = editor?.getControl() as { notebookEditor: NotebookEditorWidget | undefined; codeEditor: CodeEditorWidget } | undefined;
480+
}
478481
}
479482
}
480483
else {
@@ -575,7 +578,7 @@ registerAction2(class extends Action2 {
575578
f1: false,
576579
keybinding: {
577580
when: ContextKeyExpr.and(
578-
ContextKeyExpr.equals('activeEditor', 'workbench.editor.interactive'),
581+
ContextKeyExpr.equals('resourceScheme', Schemas.vscodeInteractive),
579582
INTERACTIVE_INPUT_CURSOR_BOUNDARY.notEqualsTo('bottom'),
580583
INTERACTIVE_INPUT_CURSOR_BOUNDARY.notEqualsTo('none'),
581584
SuggestContext.Visible.toNegated()
@@ -614,7 +617,7 @@ registerAction2(class extends Action2 {
614617
f1: false,
615618
keybinding: {
616619
when: ContextKeyExpr.and(
617-
ContextKeyExpr.equals('activeEditor', 'workbench.editor.interactive'),
620+
ContextKeyExpr.equals('resourceScheme', Schemas.vscodeInteractive),
618621
INTERACTIVE_INPUT_CURSOR_BOUNDARY.notEqualsTo('top'),
619622
INTERACTIVE_INPUT_CURSOR_BOUNDARY.notEqualsTo('none'),
620623
SuggestContext.Visible.toNegated()
@@ -651,7 +654,7 @@ registerAction2(class extends Action2 {
651654
id: 'interactive.scrollToTop',
652655
title: localize('interactiveScrollToTop', 'Scroll to Top'),
653656
keybinding: {
654-
when: ContextKeyExpr.equals('activeEditor', 'workbench.editor.interactive'),
657+
when: ContextKeyExpr.equals('resourceScheme', Schemas.vscodeInteractive),
655658
primary: KeyMod.CtrlCmd | KeyCode.Home,
656659
mac: { primary: KeyMod.CtrlCmd | KeyCode.UpArrow },
657660
weight: KeybindingWeight.WorkbenchContrib
@@ -680,7 +683,7 @@ registerAction2(class extends Action2 {
680683
id: 'interactive.scrollToBottom',
681684
title: localize('interactiveScrollToBottom', 'Scroll to Bottom'),
682685
keybinding: {
683-
when: ContextKeyExpr.equals('activeEditor', 'workbench.editor.interactive'),
686+
when: ContextKeyExpr.equals('resourceScheme', Schemas.vscodeInteractive),
684687
primary: KeyMod.CtrlCmd | KeyCode.End,
685688
mac: { primary: KeyMod.CtrlCmd | KeyCode.DownArrow },
686689
weight: KeybindingWeight.WorkbenchContrib
@@ -747,9 +750,9 @@ registerAction2(class extends Action2 {
747750
category: interactiveWindowCategory,
748751
menu: {
749752
id: MenuId.CommandPalette,
750-
when: ContextKeyExpr.equals('activeEditor', 'workbench.editor.interactive'),
753+
when: ContextKeyExpr.equals('resourceScheme', Schemas.vscodeInteractive),
751754
},
752-
precondition: ContextKeyExpr.equals('activeEditor', 'workbench.editor.interactive'),
755+
precondition: ContextKeyExpr.equals('resourceScheme', Schemas.vscodeInteractive),
753756
});
754757
}
755758

src/vs/workbench/contrib/interactive/browser/interactiveEditorInput.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { isEqual } from 'vs/base/common/resources';
1111
import { URI } from 'vs/base/common/uri';
1212
import { IResolvedTextEditorModel, ITextModelService } from 'vs/editor/common/services/resolverService';
1313
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
14-
import { EditorInputCapabilities, IUntypedEditorInput } from 'vs/workbench/common/editor';
14+
import { IUntypedEditorInput } from 'vs/workbench/common/editor';
1515
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
1616
import { IInteractiveDocumentService } from 'vs/workbench/contrib/interactive/browser/interactiveDocumentService';
1717
import { IInteractiveHistoryService } from 'vs/workbench/contrib/interactive/browser/interactiveHistoryService';
@@ -113,10 +113,8 @@ export class InteractiveEditorInput extends EditorInput implements ICompositeNot
113113
this._register(this.primary.onDidChangeCapabilities(() => this._onDidChangeCapabilities.fire()));
114114
}
115115

116-
override get capabilities(): EditorInputCapabilities {
117-
return EditorInputCapabilities.Untitled
118-
| EditorInputCapabilities.Readonly
119-
| EditorInputCapabilities.Scratchpad;
116+
override isDirty() {
117+
return false;
120118
}
121119

122120
private async _resolveEditorModel() {
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { Emitter, Event } from 'vs/base/common/event';
7+
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
8+
import { URI } from 'vs/base/common/uri';
9+
import { FileSystemProviderCapabilities, FileType, IFileChange, IFileDeleteOptions, IFileOverwriteOptions, IFileSystemProvider, IFileWriteOptions, IStat, IWatchOptions } from 'vs/platform/files/common/files';
10+
11+
export class InteractiveWindowFileSystem implements IFileSystemProvider {
12+
13+
capabilities: FileSystemProviderCapabilities = FileSystemProviderCapabilities.FileReadWrite;
14+
15+
constructor(private disposableFactory: () => IDisposable = () => Disposable.None) { }
16+
17+
async readFile(_resource: URI): Promise<Uint8Array> {
18+
return new Uint8Array();
19+
}
20+
21+
async writeFile(_resource: URI, _content: Uint8Array, _opts: IFileWriteOptions): Promise<void> { }
22+
23+
async stat(_resource: URI): Promise<IStat> {
24+
return {
25+
type: FileType.File,
26+
ctime: 0,
27+
mtime: 0,
28+
size: 0,
29+
};
30+
}
31+
async mkdir(_resource: URI): Promise<void> { }
32+
33+
async readdir(_resource: URI): Promise<[string, FileType][]> {
34+
return [['', FileType.Unknown]];
35+
}
36+
37+
async delete(_resource: URI, _opts: IFileDeleteOptions): Promise<void> { }
38+
39+
async rename(_from: URI, _to: URI, _opts: IFileOverwriteOptions): Promise<void> { }
40+
41+
private readonly _onDidChangeCapabilities = new Emitter<void>();
42+
readonly onDidChangeCapabilities: Event<void> = this._onDidChangeCapabilities.event;
43+
44+
private readonly _onDidChangeFile = new Emitter<readonly IFileChange[]>();
45+
readonly onDidChangeFile: Event<readonly IFileChange[]> = this._onDidChangeFile.event;
46+
47+
onDidWatchError?: Event<string> | undefined;
48+
49+
emitFileChangeEvents(changes: IFileChange[]): void {
50+
this._onDidChangeFile.fire(changes);
51+
}
52+
53+
setCapabilities(capabilities: FileSystemProviderCapabilities): void {
54+
this.capabilities = capabilities;
55+
56+
this._onDidChangeCapabilities.fire();
57+
}
58+
59+
watch(_resource: URI, _opts: IWatchOptions): IDisposable { return this.disposableFactory(); }
60+
}

src/vs/workbench/contrib/notebook/browser/controller/executeActions.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import { Iterable } from 'vs/base/common/iterator';
77
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
8+
import { Schemas } from 'vs/base/common/network';
89
import { isEqual } from 'vs/base/common/resources';
910
import { ThemeIcon } from 'vs/base/common/themables';
1011
import { URI, UriComponents } from 'vs/base/common/uri';
@@ -597,7 +598,7 @@ registerAction2(class InterruptNotebook extends CancelNotebook {
597598
when: ContextKeyExpr.and(
598599
NOTEBOOK_HAS_SOMETHING_RUNNING,
599600
NOTEBOOK_INTERRUPTIBLE_KERNEL,
600-
ContextKeyExpr.equals('activeEditor', 'workbench.editor.interactive')
601+
ContextKeyExpr.equals('resourceScheme', Schemas.vscodeInteractive)
601602
),
602603
group: 'navigation/execute'
603604
}
@@ -640,7 +641,7 @@ registerAction2(class RevealRunningCellAction extends NotebookAction {
640641
id: MenuId.InteractiveToolbar,
641642
when: ContextKeyExpr.and(
642643
NOTEBOOK_HAS_RUNNING_CELL,
643-
ContextKeyExpr.equals('activeEditor', 'workbench.editor.interactive')
644+
ContextKeyExpr.equals('resourceScheme', Schemas.vscodeInteractive)
644645
),
645646
group: 'navigation',
646647
order: 10

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import { Schemas } from 'vs/base/common/network';
77
import { IDisposable, Disposable, DisposableStore, dispose } from 'vs/base/common/lifecycle';
88
import { parse } from 'vs/base/common/marshalling';
9-
import { extname, isEqual } from 'vs/base/common/resources';
9+
import { isEqual } from 'vs/base/common/resources';
1010
import { assertType } from 'vs/base/common/types';
1111
import { URI } from 'vs/base/common/uri';
1212
import { toFormattedString } from 'vs/base/common/jsonFormatter';
@@ -580,7 +580,7 @@ class NotebookEditorManager implements IWorkbenchContribution {
580580
private _openMissingDirtyNotebookEditors(models: IResolvedNotebookEditorModel[]): void {
581581
const result: IResourceEditorInput[] = [];
582582
for (const model of models) {
583-
if (model.isDirty() && !this._editorService.isOpened({ resource: model.resource, typeId: NotebookEditorInput.ID, editorId: model.viewType }) && extname(model.resource) !== '.interactive') {
583+
if (model.isDirty() && !this._editorService.isOpened({ resource: model.resource, typeId: NotebookEditorInput.ID, editorId: model.viewType }) && model.resource.scheme !== Schemas.vscodeInteractive) {
584584
result.push({
585585
resource: model.resource,
586586
options: { inactive: true, preserveFocus: true, pinned: true, override: model.viewType }

src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { getExtensionForMimeType } from 'vs/base/common/mime';
1313
import { FileAccess, Schemas } from 'vs/base/common/network';
1414
import { equals } from 'vs/base/common/objects';
1515
import { isMacintosh, isWeb } from 'vs/base/common/platform';
16-
import { dirname, extname, isEqual, joinPath } from 'vs/base/common/resources';
16+
import { dirname, isEqual, joinPath } from 'vs/base/common/resources';
1717
import { URI } from 'vs/base/common/uri';
1818
import * as UUID from 'vs/base/common/uuid';
1919
import { TokenizationRegistry } from 'vs/editor/common/languages';
@@ -513,7 +513,7 @@ export class BackLayerWebView<T extends ICommonCellInfo> extends Themable {
513513
}
514514

515515
private getNotebookBaseUri() {
516-
if (this.documentUri.scheme === Schemas.untitled) {
516+
if (this.documentUri.scheme === Schemas.untitled || this.documentUri.scheme === Schemas.vscodeInteractive) {
517517
const folder = this.workspaceContextService.getWorkspaceFolder(this.documentUri);
518518
if (folder) {
519519
return folder.uri;
@@ -1031,7 +1031,7 @@ export class BackLayerWebView<T extends ICommonCellInfo> extends Themable {
10311031
return;
10321032
}
10331033

1034-
const defaultDir = extname(this.documentUri) === '.interactive' ?
1034+
const defaultDir = this.documentUri.scheme === Schemas.vscodeInteractive ?
10351035
this.workspaceContextService.getWorkspace().folders[0]?.uri ?? await this.fileDialogService.defaultFilePath() :
10361036
dirname(this.documentUri);
10371037
let defaultName: string;

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

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { Emitter, Event } from 'vs/base/common/event';
1010
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
1111
import { Schemas } from 'vs/base/common/network';
1212
import { filter } from 'vs/base/common/objects';
13-
import { extname } from 'vs/base/common/resources';
1413
import { assertType } from 'vs/base/common/types';
1514
import { URI } from 'vs/base/common/uri';
1615
import { IRevertOptions, ISaveOptions, IUntypedEditorInput } from 'vs/workbench/common/editor';
@@ -41,7 +40,6 @@ export class SimpleNotebookEditorModel extends EditorModel implements INotebookE
4140

4241
private _workingCopy?: IStoredFileWorkingCopy<NotebookFileWorkingCopyModel> | IUntitledFileWorkingCopy<NotebookFileWorkingCopyModel>;
4342
private readonly _workingCopyListeners = this._register(new DisposableStore());
44-
private readonly scratchPad: boolean;
4543

4644
constructor(
4745
readonly resource: URI,
@@ -53,7 +51,16 @@ export class SimpleNotebookEditorModel extends EditorModel implements INotebookE
5351
) {
5452
super();
5553

56-
this.scratchPad = viewType === 'interactive';
54+
if (this.viewType === 'interactive') {
55+
lifecycleService.onBeforeShutdown(async e => e.veto(this.onBeforeShutdown(), 'veto.InteractiveWindow'));
56+
}
57+
}
58+
59+
private async onBeforeShutdown() {
60+
if (this._workingCopy?.isDirty()) {
61+
await this._workingCopy.save();
62+
}
63+
return false;
5764
}
5865

5966
override dispose(): void {
@@ -119,7 +126,7 @@ export class SimpleNotebookEditorModel extends EditorModel implements INotebookE
119126
if (this._hasAssociatedFilePath) {
120127
this._workingCopy = await this._workingCopyManager.resolve({ associatedResource: this.resource });
121128
} else {
122-
this._workingCopy = await this._workingCopyManager.resolve({ untitledResource: this.resource, isScratchpad: this.scratchPad });
129+
this._workingCopy = await this._workingCopyManager.resolve({ untitledResource: this.resource });
123130
}
124131
} else {
125132
this._workingCopy = await this._workingCopyManager.resolve(this.resource, options?.forceReadFromFile ? { reload: { async: false, force: true } } : undefined);
@@ -284,7 +291,7 @@ export class NotebookFileWorkingCopyModelFactory implements IStoredFileWorkingCo
284291
metadata: {},
285292
cells: []
286293
};
287-
if (extname(resource) !== '.interactive') {
294+
if (resource.scheme !== Schemas.vscodeInteractive) {
288295
const bytes = await streamToBuffer(stream);
289296
data = await info.serializer.dataToNotebook(bytes);
290297
}

0 commit comments

Comments
 (0)