Elegant Replace Hold combination?

With

com[x__Plus, y_] := Distribute[Inactive[com][x, y]] // Activate

you get, for example,

com[Plus[a, b], c]

com[a, c] + com[b, c]


com[x__Plus, y_] := Block[{com}, Distribute[com[x, y]]]

This Blocks the evaluation of com until after Distribute has done its work by momentarily treating com as a variable local to the Block scoping construct and hence momentarily losing all of its definitions and Attributes.


I think you can just use Unevaluated here:

com[x__Plus, y_] := Distribute[Unevaluated @ com[x, y]]

Examples:

com[a+b, c]
com[a+b, c+d+e, f]

com[a, c] + com[b, c]

com[a, c, f] + com[a, d, f] + com[a, e, f] + com[b, c, f] + com[b, d, f] + com[b, e, f]