Detailed changes
@@ -20,7 +20,7 @@ pub use crate::jupyter_settings::JupyterSettings;
pub use crate::kernels::{Kernel, KernelSpecification, KernelStatus, PythonEnvKernelSpecification};
pub use crate::repl_editor::*;
pub use crate::repl_sessions_ui::{
- ClearOutputs, Interrupt, ReplSessionsPage, Restart, Run, Sessions, Shutdown,
+ ClearCurrentOutput, ClearOutputs, Interrupt, ReplSessionsPage, Restart, Run, Sessions, Shutdown,
};
pub use crate::repl_settings::ReplSettings;
pub use crate::repl_store::ReplStore;
@@ -14,7 +14,8 @@ use crate::kernels::PythonEnvKernelSpecification;
use crate::repl_store::ReplStore;
use crate::session::SessionEvent;
use crate::{
- ClearOutputs, Interrupt, JupyterSettings, KernelSpecification, Restart, Session, Shutdown,
+ ClearCurrentOutput, ClearOutputs, Interrupt, JupyterSettings, KernelSpecification, Restart,
+ Session, Shutdown,
};
pub fn assign_kernelspec(
@@ -349,6 +350,24 @@ pub fn clear_outputs(editor: WeakEntity<Editor>, cx: &mut App) {
});
}
+pub fn clear_current_output(editor: WeakEntity<Editor>, cx: &mut App) {
+ let Some(editor_entity) = editor.upgrade() else {
+ return;
+ };
+
+ let store = ReplStore::global(cx);
+ let entity_id = editor.entity_id();
+ let Some(session) = store.read(cx).get_session(entity_id).cloned() else {
+ return;
+ };
+
+ let position = editor_entity.read(cx).selections.newest_anchor().head();
+
+ session.update(cx, |session, cx| {
+ session.clear_output_at_position(position, cx);
+ });
+}
+
pub fn interrupt(editor: WeakEntity<Editor>, cx: &mut App) {
let store = ReplStore::global(cx);
let entity_id = editor.entity_id();
@@ -410,6 +429,19 @@ pub fn setup_editor_session_actions(editor: &mut Editor, editor_handle: WeakEnti
})
.detach();
+ editor
+ .register_action({
+ let editor_handle = editor_handle.clone();
+ move |_: &ClearCurrentOutput, _, cx| {
+ if !JupyterSettings::enabled(cx) {
+ return;
+ }
+
+ crate::clear_current_output(editor_handle.clone(), cx);
+ }
+ })
+ .detach();
+
editor
.register_action({
let editor_handle = editor_handle.clone();
@@ -21,6 +21,8 @@ actions!(
RunInPlace,
/// Clears all outputs in the REPL.
ClearOutputs,
+ /// Clears the output of the cell at the current cursor position.
+ ClearCurrentOutput,
/// Opens the REPL sessions panel.
Sessions,
/// Interrupts the currently running kernel.
@@ -514,6 +514,51 @@ impl Session {
self.result_inlays.clear();
}
+ pub fn clear_output_at_position(&mut self, position: Anchor, cx: &mut Context<Self>) {
+ let Some(editor) = self.editor.upgrade() else {
+ return;
+ };
+
+ let (block_id, code_range, msg_id) = {
+ let snapshot = editor.read(cx).buffer().read(cx).read(cx);
+ let pos_range = position..position;
+
+ let block_to_remove = self
+ .blocks
+ .iter()
+ .find(|(_, block)| block.code_range.includes(&pos_range, &snapshot));
+
+ let Some((msg_id, block)) = block_to_remove else {
+ return;
+ };
+
+ (block.block_id, block.code_range.clone(), msg_id.clone())
+ };
+
+ let inlay_to_remove = self.result_inlays.get(&msg_id).map(|(id, _, _)| *id);
+
+ self.blocks.remove(&msg_id);
+ if inlay_to_remove.is_some() {
+ self.result_inlays.remove(&msg_id);
+ }
+
+ self.editor
+ .update(cx, |editor, cx| {
+ let mut block_ids = HashSet::default();
+ block_ids.insert(block_id);
+ editor.remove_blocks(block_ids, None, cx);
+
+ if let Some(inlay_id) = inlay_to_remove {
+ editor.splice_inlays(&[inlay_id], vec![], cx);
+ }
+
+ editor.remove_gutter_highlights::<ReplExecutedRange>(vec![code_range], cx);
+ })
+ .ok();
+
+ cx.notify();
+ }
+
pub fn execute(
&mut self,
code: String,