Skip to content

Commit 8cd1485

Browse files
authored
Preserve code in cells during execution and edits (#10981)
* Preserve code in cells during execution and edits * Oops
1 parent 00f85cf commit 8cd1485

File tree

8 files changed

+24
-8
lines changed

8 files changed

+24
-8
lines changed

news/2 Fixes/10949.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Ensure user code in cell is preserved between cell execution and cell edits.

src/client/datascience/interactive-common/interactiveBase.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ export abstract class InteractiveBase extends WebViewHost<IInteractiveWindowMapp
669669

670670
case CellState.executing:
671671
// Tell the react controls we have an update
672-
this.postMessage(InteractiveWindowMessages.UpdateCell, cell).ignoreErrors();
672+
this.postMessage(InteractiveWindowMessages.UpdateCellWithExecutionResults, cell).ignoreErrors();
673673
break;
674674

675675
case CellState.error:

src/client/datascience/interactive-common/interactiveWindowTypes.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import { BaseReduxActionPayload } from './types';
3030
export enum InteractiveWindowMessages {
3131
StartCell = 'start_cell',
3232
FinishCell = 'finish_cell',
33-
UpdateCell = 'update_cell',
33+
UpdateCellWithExecutionResults = 'UpdateCellWithExecutionResults',
3434
GotoCodeCell = 'gotocell_code',
3535
CopyCodeCell = 'copycell_code',
3636
NotebookExecutionActivated = 'notebook_execution_activated',
@@ -497,7 +497,7 @@ export class IInteractiveWindowMapping {
497497
public [IPyWidgetMessages.IPyWidgets_mirror_execute]: { id: string; msg: KernelMessage.IExecuteRequestMsg };
498498
public [InteractiveWindowMessages.StartCell]: ICell;
499499
public [InteractiveWindowMessages.FinishCell]: ICell;
500-
public [InteractiveWindowMessages.UpdateCell]: ICell;
500+
public [InteractiveWindowMessages.UpdateCellWithExecutionResults]: ICell;
501501
public [InteractiveWindowMessages.GotoCodeCell]: IGotoCode;
502502
public [InteractiveWindowMessages.CopyCodeCell]: ICopyCode;
503503
public [InteractiveWindowMessages.NotebookExecutionActivated]: string;

src/client/datascience/interactive-common/synchronization.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ const messageWithMessageTypes: MessageMapping<IInteractiveWindowMapping> & Messa
166166
[InteractiveWindowMessages.Sync]: MessageType.other,
167167
[InteractiveWindowMessages.Undo]: MessageType.other,
168168
[InteractiveWindowMessages.UnfocusedCellEditor]: MessageType.syncWithLiveShare,
169-
[InteractiveWindowMessages.UpdateCell]: MessageType.syncAcrossSameNotebooks | MessageType.syncWithLiveShare,
169+
[InteractiveWindowMessages.UpdateCellWithExecutionResults]:
170+
MessageType.syncAcrossSameNotebooks | MessageType.syncWithLiveShare,
170171
[InteractiveWindowMessages.UpdateModel]: MessageType.syncAcrossSameNotebooks | MessageType.syncWithLiveShare,
171172
[InteractiveWindowMessages.UpdateKernel]: MessageType.syncAcrossSameNotebooks | MessageType.syncWithLiveShare,
172173
[InteractiveWindowMessages.UpdateDisplayData]: MessageType.syncWithLiveShare,

src/client/datascience/interactive-ipynb/nativeEditor.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,20 @@ export class NativeEditor extends InteractiveBase implements INotebookEditor {
449449
const modified = filtered.filter((c) => c.state === CellState.finished || c.state === CellState.error);
450450
const unmodified = this.model?.cells.filter((c) => modified.find((m) => m.id === c.id));
451451
if (modified.length > 0 && unmodified && this.model) {
452+
// As this point, we're updating the model because of changes to the cell as a result of execution.
453+
// The output and execution count change, however we're just going to update everything.
454+
// But, we should not update the `source`. The only time source can change is when a request comes from the UI.
455+
// Perhaps we need a finer grained update (update only output and execution count along with `source=execution`).
456+
// For now retain source from previous model.
457+
// E.g. user executes a cell, in the mean time they update the text. Now model contains new value.
458+
// However once execution has completed, this code will update the model with results from previous execution (prior to edit).
459+
// We now need to give preference to the text in the model, over the old one that was executed.
460+
modified.forEach((modifiedCell) => {
461+
const originalCell = unmodified.find((unmodifiedCell) => unmodifiedCell.id === modifiedCell.id);
462+
if (originalCell) {
463+
modifiedCell.data.source = originalCell.data.source;
464+
}
465+
});
452466
this.model.update({
453467
source: 'user',
454468
kind: 'modify',

src/datascience-ui/history-react/redux/reducers/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export const reducerMap: Partial<IInteractiveActionMapping> = {
4747
[InteractiveWindowMessages.Redo]: Execution.redo,
4848
[InteractiveWindowMessages.StartCell]: Creation.startCell,
4949
[InteractiveWindowMessages.FinishCell]: Creation.finishCell,
50-
[InteractiveWindowMessages.UpdateCell]: Creation.updateCell,
50+
[InteractiveWindowMessages.UpdateCellWithExecutionResults]: Creation.updateCell,
5151
[InteractiveWindowMessages.Activate]: CommonEffects.activate,
5252
[InteractiveWindowMessages.RestartKernel]: Kernel.handleRestarted,
5353
[CssMessages.GetCssResponse]: CommonEffects.handleCss,

src/datascience-ui/interactive-common/redux/reducers/helpers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export namespace Helpers {
8383

8484
// Prevent updates to the source, as its possible we have recieved a response for a cell execution
8585
// and the user has updated the cell text since then.
86-
const newVM = {
86+
const newVM: ICellViewModel = {
8787
...newVMs[index],
8888
hasBeenRun: true,
8989
cell: {
@@ -95,7 +95,7 @@ export namespace Helpers {
9595
}
9696
}
9797
};
98-
newVMs[index] = asCellViewModel(newVM);
98+
newVMs[index] = newVM;
9999

100100
return {
101101
...arg.prevState,

src/datascience-ui/native-editor/redux/reducers/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export const reducerMap: Partial<INativeEditorActionMapping> = {
6464
// Messages from the webview (some are ignored)
6565
[InteractiveWindowMessages.StartCell]: Creation.startCell,
6666
[InteractiveWindowMessages.FinishCell]: Creation.finishCell,
67-
[InteractiveWindowMessages.UpdateCell]: Creation.updateCell,
67+
[InteractiveWindowMessages.UpdateCellWithExecutionResults]: Creation.updateCell,
6868
[InteractiveWindowMessages.NotebookDirty]: CommonEffects.notebookDirty,
6969
[InteractiveWindowMessages.NotebookClean]: CommonEffects.notebookClean,
7070
[InteractiveWindowMessages.LoadAllCells]: Creation.loadAllCells,

0 commit comments

Comments
 (0)