开发者

How to delete the input cell upon evaluation?

开发者 https://www.devze.com 2023-03-04 14:05 出处:网络
I would like to accomplish the following: upon evaluation of an input cell, it should self-destruct (i.e. delete itself).I tried to hack something together with SelectionMove and NotebookDelete, but d

I would like to accomplish the following: upon evaluation of an input cell, it should self-destruct (i.e. delete itself). I tried to hack something together with SelectionMove and NotebookDelete, but didn't quite get what I wanted.

Here are potential use cases:

  • the command might be a shorthand for a series of other commands that will be generated dynamically and inserted into the notebook

  • the command mi开发者_开发问答ght only be used for side effects (e.g. to set a notebook option or to open a new notebook); leaving the command in the notebook after evaluation serves no purpose and creates clutter

Edit: As per Mr. Wizard, the answer is SelectionMove[EvaluationNotebook[], Previous, Cell]; NotebookDelete[];. I don't know why it wasn't working for me before. Here is some code that uses this idiom.

writeAndEval[nb_, boxExpr_] := (NotebookWrite[nb, 
    CellGroupData[{Cell[BoxData[boxExpr], "Input"]}]];
   SelectionMove[nb, Previous, Cell];
   SelectionMove[nb, Next, Cell];
   SelectionEvaluate[nb]);

addTwoAndTwo[] := Module[{boxExpr},
  boxExpr = RowBox[{"2", "+", "2"}];
  SelectionMove[EvaluationNotebook[], Previous, Cell];
  NotebookDelete[];
  writeAndEval[EvaluationNotebook[], boxExpr];
  ]

Now, running addTwoAndTwo[] deletes the original input and makes it look as if you've evaluated "2+2". Of course, you can do all sorts of things instead and not necessarily print to the notebook.

Edit 2: Sasha's abstraction is quite elegant. If you are curious about "real-world" usage of this, check out the code I posted in the "what's in your toolbag" question: What is in your Mathematica tool bag?


To affect all Input cells, evaluate this is the notebook:

SetOptions[EvaluationNotebook[], CellEvaluationFunction -> 
  ( (
    SelectionMove[EvaluationNotebook[], All, EvaluationCell]; NotebookDelete[];
    ToExpression@#
  )&)
]

If you only want to affect one cell, then select the cell and use the Options Inspector to set CellEvaluationFunction as above.


Or, building on Mr. Wizard's solution, you can create a function SelfDestruct, which will delete the input cell, if you intend to only do this occasionally:

SetAttributes[SelfDestruct, HoldAllComplete];
SelfDestruct[e_] := (If[$FrontEnd =!= $Failed,
   SelectionMove[EvaluationNotebook[], All, EvaluationCell]; 
   NotebookDelete[]]; e)

Then evaluating 2+3//SelfDestruct outputs 5 and deletes the input cell. This usage scenario seems more appealing to me.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号