[Edit: As noted in the comments, you're probably better off using Hold,ReleaseHold etc. to solve your problem, since Inactivate was never designed for this use case. Having said that, below you'll find one possible attempt to replicate the desired behaviour as closely as possible]
The goal
For this answer, I'll try to address the following requirements for a new function myInactivate:
myInactivate should replicate the behaviour of Inactivate for cases where there are no Hold attributes at play. This includes:
- Nice typesetting
- Localized inactivation in the sense that parts are inactivated separately
- A way to activate only parts again (see possible extensions below)
- Inactivated symbols should still have the same
Hold attributes as the original symbol
Examples
You can find the code for myInactivate,myActivate, etc. at the end of the answer.
myInactivate can be used just like Inactivate:
a = 1;
myInactivate[a = 2]
(* myInactive[Set][a, 2] *)
myActivate[%]
(* 2 *)
It also supports the typesetting of Inactive expressions:
myInactivate[Sum[f[a = 2, z], {n, 1, 2}]]

You can filter out all inactive heads using myInactiveQ:
myInactivate[Sum[f[a = 2, z], {n, 1, 2}]] //
Cases[#, _?myInactiveQ, All, Heads -> True] &
(* {myInactive[Sum], myInactive[f], myInactive[Set]} *)
You can also manually create inactive symbols using myInactive:
myInactive[Set][a, 2]

Possible extensions
To make something like this really something with more control than Hold and related functions, one would need to implement the two argument forms of Inactivate and Activate (i.e. filtering of what gets inactivated). This would then allow for selective inactivation, something that is difficult to achieve with Hold and friends.
How it works
As noted in the comments, composite heads (e.g. Inactive[Set]) are out, as they can't have any attributes. So the only thing we can to is to replace the heads with a new, inert symbol. This is exactly what myInactive does (let sym be the symbol to inactivate):
- If not already done, it creates a new symbol (e.g.
inactivesym), with the same attributes as sym (except Protected and Locked, for obvious reasons).
- It adds the new symbol
inactivesym to inactSymbols, the replacement list to revert inactivation.
- It adds a typesetting rule to typeset
inactivesym[...] as Inactive[sym][...] (wrapped in an InterpretationBox, to ensure that the output can be copied)
- It adds a typesetting rule to typeset
inactivesym as myInactive[sym]
- It marks
inactivesym as myInactiveQ
You'll also notice the special casing of List and Rule: Apparently, Inactivate doesn't touch some inert heads such as List and Rule, so I've added them here as well.
Code
inactSymbols = <||>;
Attributes[myInactiveQ] = {HoldFirst};
myInactiveQ[_] := False
Attributes[myInactive] = {HoldFirst};
myInactive[h_] := myInactive[h] = With[
{s = Unique["inact" <> SymbolName@Unevaluated@h]},
Attributes[s] = Complement[Attributes[h], {Protected, Locked}];
MakeBoxes[s[args___], frm_] ^:= With[
{b = MakeBoxes[Inactive[h][args], frm]},
InterpretationBox[b, s[args]]
];
AppendTo[inactSymbols, s -> h];
MakeBoxes[s, frm_] ^:= MakeBoxes[myInactive[h], frm];
myInactiveQ[s] ^= True;
s
]
myInactive[s_?myInactiveQ] := s
myInactive[s : List | Rule] := s
Attributes[myInactivate] = {HoldFirst};
myInactivate[expr_] := Replace[
Unevaluated@expr,
{
i : HoldPattern[myInactive[h_][args___]] :> i,
h_Symbol[args___] :> With[
{in = myInactive[h]},
in[args] /; True
]
},
All
]
myActivate[expr_] := expr /. inactSymbols
Function[...], but there is no way to prevent expressions of the formFunction[...][...]from evaluating. You could of course use a different way to inactivate the heads, but making them composite seems like the best way if one wants to preserve the structure of the expression. – Lukas Lang Jan 15 '19 at 12:58Setso it behaves as it wasn't there. If you don't wan't it, what do you expect fromInactivate? – Kuba Jan 15 '19 at 13:01Activate[Inactivate[Inactive[a] = 2]]? – kglr Jan 15 '19 at 13:02HoldandReleaseHold? – Michael E2 Jan 15 '19 at 13:32Inactive[Set]that has theHoldFirstattribute ofSet. But sinceInactive[Set]is a composite head, it cannot have attributes, as far as I know. – Sjoerd Smit Jan 15 '19 at 16:33Inactiveat all but some sort of guidance for Hold family of functions. – Kuba Jan 16 '19 at 09:15