Skip to content

Commit b73b746

Browse files
committed
1 parent 7a9cfb3 commit b73b746

4 files changed

Lines changed: 69 additions & 11 deletions

File tree

extensions/vscode-notebook-tests/src/notebook.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,25 @@ suite('regression', () => {
893893
await vscode.commands.executeCommand('workbench.action.files.newUntitledFile', { viewType: "notebookCoreTest" });
894894
assert.notEqual(vscode.notebook.activeNotebookEditor, undefined, 'untitled notebook editor is not undefined');
895895
});
896+
897+
test('#102423 - copy/paste shares the same text buffer', async function () {
898+
const resource = vscode.Uri.file(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
899+
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
900+
901+
let activeCell = vscode.notebook.activeNotebookEditor!.selection;
902+
assert.equal(activeCell?.document.getText(), 'test');
903+
904+
await vscode.commands.executeCommand('notebook.cell.copyDown');
905+
await vscode.commands.executeCommand('notebook.cell.edit');
906+
activeCell = vscode.notebook.activeNotebookEditor!.selection;
907+
assert.equal(vscode.notebook.activeNotebookEditor!.document.cells.indexOf(activeCell!), 1);
908+
assert.equal(activeCell?.document.getText(), 'test');
909+
910+
await vscode.commands.executeCommand('default:type', { text: 'var abc = 0;' });
911+
912+
assert.equal(vscode.notebook.activeNotebookEditor!.document.cells.length, 2);
913+
assert.notEqual(vscode.notebook.activeNotebookEditor!.document.cells[0].document.getText(), vscode.notebook.activeNotebookEditor!.document.cells[1].document.getText())
914+
});
896915
});
897916

898917
suite('webview', () => {

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

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { CellKind, NOTEBOOK_EDITOR_CURSOR_BOUNDARY, NotebookCellRunState } from
2323
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
2424
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
2525
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
26+
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
2627

2728
// Notebook Commands
2829
const EXECUTE_NOTEBOOK_COMMAND_ID = 'notebook.execute';
@@ -745,7 +746,7 @@ registerAction2(class extends NotebookAction {
745746
const clipboardService = accessor.get<IClipboardService>(IClipboardService);
746747
const notebookService = accessor.get<INotebookService>(INotebookService);
747748
clipboardService.writeText(context.cell.getText());
748-
notebookService.setToCopy([context.cell.model]);
749+
notebookService.setToCopy([context.cell.model], true);
749750
}
750751
});
751752

@@ -774,7 +775,7 @@ registerAction2(class extends NotebookAction {
774775
}
775776

776777
viewModel.deleteCell(viewModel.getCellIndex(context.cell), true);
777-
notebookService.setToCopy([context.cell.model]);
778+
notebookService.setToCopy([context.cell.model], false);
778779
}
779780
});
780781

@@ -794,17 +795,33 @@ registerAction2(class extends NotebookAction {
794795

795796
async runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext) {
796797
const notebookService = accessor.get<INotebookService>(INotebookService);
797-
const pasteCells = notebookService.getToCopy() || [];
798+
const pasteCells = notebookService.getToCopy();
798799

799800
const viewModel = context.notebookEditor.viewModel;
800801

801802
if (!viewModel) {
802803
return;
803804
}
804805

806+
if (!pasteCells) {
807+
return;
808+
}
809+
805810
const currCellIndex = viewModel.getCellIndex(context!.cell);
806811

807-
pasteCells.reverse().forEach(pasteCell => {
812+
pasteCells.items.reverse().map(cell => {
813+
if (pasteCells.isCopy) {
814+
return viewModel.notebookDocument.createCellTextModel(
815+
cell.getValue(),
816+
cell.language,
817+
cell.cellKind,
818+
[],
819+
cell.metadata
820+
);
821+
} else {
822+
return cell;
823+
}
824+
}).forEach(pasteCell => {
808825
viewModel.insertCell(currCellIndex, pasteCell, true);
809826
return;
810827
});
@@ -826,17 +843,33 @@ registerAction2(class extends NotebookAction {
826843

827844
async runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext) {
828845
const notebookService = accessor.get<INotebookService>(INotebookService);
829-
const pasteCells = notebookService.getToCopy() || [];
846+
const pasteCells = notebookService.getToCopy();
830847

831848
const viewModel = context.notebookEditor.viewModel;
832849

833850
if (!viewModel) {
834851
return;
835852
}
836853

854+
if (!pasteCells) {
855+
return;
856+
}
857+
837858
const currCellIndex = viewModel.getCellIndex(context!.cell);
838859

839-
pasteCells.reverse().forEach(pasteCell => {
860+
pasteCells.items.reverse().map(cell => {
861+
if (pasteCells.isCopy) {
862+
return viewModel.notebookDocument.createCellTextModel(
863+
cell.getValue(),
864+
cell.language,
865+
cell.cellKind,
866+
[],
867+
cell.metadata
868+
);
869+
} else {
870+
return cell;
871+
}
872+
}).forEach(pasteCell => {
840873
viewModel.insertCell(currCellIndex + 1, pasteCell, true);
841874
return;
842875
});

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ export class NotebookService extends Disposable implements INotebookService, ICu
190190
private readonly _onDidChangeKernels = new Emitter<void>();
191191
onDidChangeKernels: Event<void> = this._onDidChangeKernels.event;
192192
private cutItems: NotebookCellTextModel[] | undefined;
193+
private _lastClipboardIsCopy: boolean = true;
193194

194195
private _displayOrder: { userOrder: string[], defaultOrder: string[] } = Object.create(null);
195196

@@ -728,12 +729,17 @@ export class NotebookService extends Disposable implements INotebookService, ICu
728729
this._onDidChangeVisibleEditors.fire(alreadyCreated);
729730
}
730731

731-
setToCopy(items: NotebookCellTextModel[]) {
732+
setToCopy(items: NotebookCellTextModel[], isCopy: boolean) {
732733
this.cutItems = items;
734+
this._lastClipboardIsCopy = isCopy;
733735
}
734736

735-
getToCopy(): NotebookCellTextModel[] | undefined {
736-
return this.cutItems;
737+
getToCopy(): { items: NotebookCellTextModel[], isCopy: boolean; } | undefined {
738+
if (this.cutItems) {
739+
return { items: this.cutItems, isCopy: this._lastClipboardIsCopy };
740+
}
741+
742+
return undefined;
737743
}
738744

739745
async save(viewType: string, resource: URI, token: CancellationToken): Promise<boolean> {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ export interface INotebookService {
6666
saveAs(viewType: string, resource: URI, target: URI, token: CancellationToken): Promise<boolean>;
6767
backup(viewType: string, uri: URI, token: CancellationToken): Promise<string | undefined>;
6868
onDidReceiveMessage(viewType: string, editorId: string, rendererType: string | undefined, message: unknown): void;
69-
setToCopy(items: NotebookCellTextModel[]): void;
70-
getToCopy(): NotebookCellTextModel[] | undefined;
69+
setToCopy(items: NotebookCellTextModel[], isCopy: boolean): void;
70+
getToCopy(): { items: NotebookCellTextModel[], isCopy: boolean; } | undefined;
7171

7272
// editor events
7373
addNotebookEditor(editor: IEditor): void;

0 commit comments

Comments
 (0)