Skip to content

Commit e42e2cc

Browse files
authored
Notebook clear all output (#5497)
Depends on the merger of #5426. Addresses #5492 Adds a simple clear-all-outputs button that does what it says on the tin. <img width="546" alt="Screenshot 2024-11-25 at 3 44 30 PM" src="https://github.com/user-attachments/assets/5cf432aa-fb5c-4202-93e1-01380158972d"> ### QA Notes The clear-all button should work to clear any outputs that are currently visible in a notebook. Clearing should persist after closing and opening the notebook. <!-- Add additional information for QA on how to validate the change, paying special attention to the level of risk, adjacent areas that could be affected by the change, and any important contextual information not present in the linked issues. -->
1 parent 281dba7 commit e42e2cc

File tree

5 files changed

+100
-1
lines changed

5 files changed

+100
-1
lines changed
964 Bytes
Binary file not shown.

src/vs/base/common/codiconsLibrary.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,9 @@ export const codiconsLibrary = {
578578
goToSearch: register('go-to-search', 0xec32),
579579
percentage: register('percentage', 0xec33),
580580
attach: register('attach', 0xec34),
581+
goToEditingSession: register('go-to-editing-session', 0xec35),
582+
editSession: register('edit-session', 0xec36),
583+
codeReview: register('code-review', 0xec37),
581584
sortPercentage: register('sort-percentage', 0xec33),
582585
positronNew: register('positron-new', 0xf230),
583586
positronOpen: register('positron-open', 0xf231),
@@ -670,4 +673,5 @@ export const codiconsLibrary = {
670673
positronTableConnection: register('positron-table-connection', 0xf288),
671674
positronCatalogConnection: register('positron-catalog-connection', 0xf289),
672675
positronViewConnection: register('positron-view-connection', 0xf28a),
676+
positronClean: register('positron-clean', 0xf28b),
673677
} as const;

src/vs/workbench/contrib/positronNotebook/browser/PositronNotebookHeader.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ export function PositronNotebookHeader({ notebookInstance }: { notebookInstance:
1818
label={(() => localize('runAllCellsShort', 'Run All'))()}
1919
fullLabel={(() => localize('runAllCellsLong', 'Run All Cells'))()}
2020
onClick={() => { notebookInstance.runAllCells(); }} />
21+
<IconedButton
22+
codicon='positron-clean'
23+
label={(() => localize('clearAllCellOutputsShort', 'Clear Outputs'))()}
24+
fullLabel={(() => localize('clearAllCellOutputsLong', 'Clear All Cell Outputs'))()}
25+
onClick={() => { notebookInstance.clearAllCellOutputs(); }} />
2126
<div style={{ marginLeft: 'auto' }}></div>
2227
<AddCodeCellButton notebookInstance={notebookInstance} index={0} />
2328
<AddMarkdownCellButton notebookInstance={notebookInstance} index={0} />

src/vs/workbench/contrib/positronNotebook/browser/PositronNotebookInstance.ts

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { ILogService } from 'vs/platform/log/common/log';
1414
import { IActiveNotebookEditorDelegate, IBaseCellEditorOptions, INotebookEditorCreationOptions, INotebookEditorViewState } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
1515
import { NotebookOptions } from 'vs/workbench/contrib/notebook/browser/notebookOptions';
1616
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
17-
import { CellEditType, CellKind, ICellReplaceEdit, ISelectionState, SelectionStateType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
17+
import { CellEditType, CellKind, ICellEditOperation, ISelectionState, SelectionStateType, ICellReplaceEdit, NotebookCellExecutionState } from 'vs/workbench/contrib/notebook/common/notebookCommon';
1818
import { INotebookExecutionService } from 'vs/workbench/contrib/notebook/common/notebookExecutionService';
1919
import { INotebookExecutionStateService } from 'vs/workbench/contrib/notebook/common/notebookExecutionStateService';
2020
import { createNotebookCell } from './PositronNotebookCells/createNotebookCell';
@@ -35,6 +35,7 @@ import { ILanguageRuntimeSession, IRuntimeSessionService } from 'vs/workbench/se
3535
import { isEqual } from 'vs/base/common/resources';
3636
import { IPositronWebviewPreloadService } from 'vs/workbench/services/positronWebviewPreloads/browser/positronWebviewPreloadService';
3737

38+
3839
interface IPositronNotebookInstanceRequiredTextModel extends IPositronNotebookInstance {
3940
textModel: NotebookTextModel;
4041
}
@@ -724,6 +725,90 @@ export class PositronNotebookInstance extends Disposable implements IPositronNot
724725
this._modelStore.clear();
725726
}
726727

728+
/**
729+
* Clears the output of a specific cell in the notebook.
730+
* @param cell The cell to clear outputs from. If not provided, uses the currently selected cell.
731+
* @param skipContentEvent If true, won't fire the content change event (useful for batch operations)
732+
*/
733+
clearCellOutput(cell?: IPositronNotebookCell, skipContentEvent: boolean = false): void {
734+
this._assertTextModel();
735+
736+
const targetCell = cell ?? this.selectionStateMachine.getSelectedCell();
737+
if (!targetCell) {
738+
return;
739+
}
740+
741+
const cellIndex = this.textModel.cells.indexOf(targetCell.cellModel as NotebookCellTextModel);
742+
if (cellIndex === -1) {
743+
return;
744+
}
745+
746+
const computeUndoRedo = !this.isReadOnly;
747+
this.textModel.applyEdits([{
748+
editType: CellEditType.Output,
749+
index: cellIndex,
750+
outputs: [],
751+
append: false
752+
}], true, undefined, () => undefined, undefined, computeUndoRedo);
753+
754+
if (!skipContentEvent) {
755+
this._onDidChangeContent.fire();
756+
}
757+
}
758+
759+
/**
760+
* Clears the outputs of all cells in the notebook.
761+
*/
762+
clearAllCellOutputs(): void {
763+
this._assertTextModel();
764+
765+
try {
766+
const computeUndoRedo = !this.isReadOnly;
767+
768+
// Clear outputs from all cells
769+
this.textModel.cells.forEach((cell, index) => {
770+
this.clearCellOutput(this._cells[index], true);
771+
});
772+
773+
// Clear execution metadata for non-executing cells
774+
const clearExecutionMetadataEdits = this.textModel.cells.map((cell, index) => {
775+
const runState = this.notebookExecutionStateService.getCellExecution(cell.uri)?.state;
776+
if (runState !== NotebookCellExecutionState.Executing) {
777+
return {
778+
editType: CellEditType.PartialInternalMetadata,
779+
index,
780+
internalMetadata: {
781+
runStartTime: null,
782+
runStartTimeAdjustment: null,
783+
runEndTime: null,
784+
executionOrder: null,
785+
lastRunSuccess: null
786+
}
787+
};
788+
}
789+
return undefined;
790+
}).filter((edit): edit is ICellEditOperation & {
791+
editType: CellEditType.PartialInternalMetadata;
792+
index: number;
793+
internalMetadata: {
794+
runStartTime: null;
795+
runStartTimeAdjustment: null;
796+
runEndTime: null;
797+
executionOrder: null;
798+
lastRunSuccess: null;
799+
};
800+
} => !!edit);
801+
802+
if (clearExecutionMetadataEdits.length) {
803+
this.textModel.applyEdits(clearExecutionMetadataEdits, true, undefined, () => undefined, undefined, computeUndoRedo);
804+
}
805+
806+
} finally {
807+
// Fire a single content change event
808+
this._onDidChangeContent.fire();
809+
}
810+
}
811+
727812
// #endregion
728813
}
729814

src/vs/workbench/services/positronNotebook/browser/IPositronNotebookInstance.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ export interface IPositronNotebookInstance {
102102
*/
103103
runAllCells(): Promise<void>;
104104

105+
/**
106+
* Clears all output from all cells in the notebook.
107+
*/
108+
clearAllCellOutputs(): void;
109+
105110
/**
106111
* Creates and inserts a new cell into the notebook.
107112
*

0 commit comments

Comments
 (0)