It seems that I have solved the problem. Here is the function:
In[1]:=
getLastInput := Module[{num, f},
f = Function[{u, v},
{u /. {In -> num, HoldPattern -> First}, HoldForm[v]}, HoldAllComplete];
First@Cases[
Block[{RuleDelayed = f}, DownValues[In]],
{$Line - 1, x_} -> x, {1}, 1]]
In[2]:=
Unevaluated[2+2]
getLastInput
Out[2]=
Unevaluated[2+2]
Out[3]=
Unevaluated[2+2]
And I just have got the answer to the question on InString
in MathLink
mode from Todd Gayley (Wolfram Research):
InString is only assigned when using
EnterTextPacket, not
EnterExpressionPacket. There is no
string form of the input when sending
EnterExpressionPacket (whose content
is, by definition, already an
expression).
EDIT:
I just have found that my code does not work with input expressions with head Evaluate
. The solution is to replace HoldForm
by HoldComplete
in my code:
getLastInput := Module[{num, f},
f = Function[{u, v},
{u /. {In -> num, HoldPattern -> First}, HoldComplete[v]}, HoldAllComplete];
First@Cases[
Block[{RuleDelayed = f}, DownValues[In]],
{$Line - 1, x_} -> x, {1}, 1]]
This works well. Another approach would be to unprotect HoldForm
and set up attribute HoldAllComplete
on it. I'm wondering why HoldForm
does not have this attribute by default?
EDIT 2:
In the comments for the main question Leonid Shifrin suggested much better solution:
getLastInput :=
Block[{RuleDelayed},SetAttributes[RuleDelayed,HoldAllComplete];
With[{line=$Line-1},HoldComplete[In[line]]/.DownValues[In]]]
See comments for details.
EDIT 3:
The last code can be made even better for by replacing HoldComplete
by double HoldForm
:
getLastInput :=
Block[{RuleDelayed},SetAttributes[RuleDelayed,HoldAllComplete];
With[{line=$Line-1},HoldForm@HoldForm[In[line]]/.DownValues[In]]]
The idea is taken from presentation by Robby Villegas of Wolfram Research at the 1999 Developer Conference. See subsection "HoldCompleteForm: a non-printing variant of HoldComplete (just as HoldForm is to Hold)" in "Working With Unevaluated Expressions" notebook posted here.