I have discovered that InString[]
does not work in MathLink
mode when sending input with EnterExpressionPacket
header. So I need to define my own function that returns previous input line. One way I have developed here
does not work in some cases:
In[1]:= Unevaluated[2 + 2]
With[{line = $Line - 1}, HoldForm[In[line]]] /. (DownValues[In])
Out[1]= Unevaluated[2 + 2]
Out[2]= 2 + 2
This is because RuleDelayed
has no HoldAllComplete
attribute. Adding this attribute makes this OK:
In[1]:= Unprotect[RuleDelayed];
SetAttributes[RuleDelayed, HoldAllComplete];
Protect[RuleDelayed];
Unevaluated[2 + 2]
With[{line = $Line - 1}, HoldForm[In[line]]] /. DownValues[In]
Out[4]= Unevaluated[2 + 2]
Out[5]= Unevaluated[2 + 2]
But modifying built-in functions generally is not a good idea. Is there a better way to do this?
It seems that I have solved the problem. Here is the function:
And I just have got the answer to the question on
InString
inMathLink
mode from Todd Gayley (Wolfram Research):EDIT:
I just have found that my code does not work with input expressions with head
Evaluate
. The solution is to replaceHoldForm
byHoldComplete
in my code:This works well. Another approach would be to unprotect
HoldForm
and set up attributeHoldAllComplete
on it. I'm wondering whyHoldForm
does not have this attribute by default?EDIT 2:
In the comments for the main question Leonid Shifrin suggested much better solution:
See comments for details.
EDIT 3: The last code can be made even better for by replacing
HoldComplete
by doubleHoldForm
: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.
I would use
$Pre
and$Line
for this; unlike$PreRead
, it's applied to input expressions, not input strings or box forms. All you need is to assign it a function that has theHoldAllComplete
attribute, like this one which I've adapted from the example in the documentation:I tested this with MathLink, and the behavior seems to be what you desired (I've elided some of the transcript to highlight the key point):
I just have found simpler but dangerous way:
Does anybody know a way to make it safe?