# Obtain input expression from history without evaluating

I typed and evaluated an expression, but deleted it from the notebook. For instance, suppose it was

In[1]:= Round@SessionTime[]
Out[1]= 2


I now want to retrieve the input so that I can edit it again.

I know Mathematica keeps the history of evaluated expressions in In. But if I try to access it directly In[123], rather than giving the unevaluated input expression, it evaluates it again:

In[2]:= In[1]
Out[2]= 10


If I use Hold to suppress evaluation, then In[...] doesn't get evaluated, so I don't see the input:

In[3]:= Hold[In[1]]
Out[3]= Hold[In[1]]


How can I retrieve the input expression in an editable form, without evaluating it?

-

The input is stored as a downvalue in the definition of In. If you've only typed a few expressions, run

Definition@In


which prints a list of all the values associated with the symbol In, and copy from the line In[1] := Round[SessionTime[]].

But if you've typed hundreds of expressions, or expressions whose plain-text representations are long (like images), this is hard to use. To extract only a specific input number, use pattern matching:

In[4]:= Hold[In[1]] /. DownValues[In]
Out[4]= Hold[Round[SessionTime[]]]

-

In addition to assigning to In, the Mathematica main loop assigns the input to InString before it is parsed as an expression. You can then retrieve InString[1] and parse the result with ToExpression, wrapping it in Defer to prevent it from evaluating immediately:

In[5]:= ToExpression[InString[1], StandardForm, Defer]
Out[5]= Round[SessionTime[]]


You can then edit and evaluate the resulting expression.

If you want to process the output programmatically, it will be more convenient to use Hold in place of Defer.

Also, note that InString is listable, so if you're not sure of the exact input number you can pass a range, like InString[Range[10, 20]].

-
How can I actually get copy-pasteable text? If I use your example on itself, In[6]:= ToExpression[InString[1], StandardForm, Defer], I get Out[6]:= RowBox[{"ToExpression", "[", RowBox[{RowBox[{"InString", "[", "5", "]"}], ",", "StandardForm", ",", "Defer"}], "]"}]. I don't want all those RowBox's and whatnot. What I actually want is Out[6]:= ToExpression[InString[1], StandardForm, Defer] (perhaps wrapped with some sort of Hold-like container.) – Jess Riedel Mar 21 at 20:58
OK: just figured it out. See my top-level answer. – Jess Riedel Mar 21 at 21:03