What I usually suggest for such cases is to use custom environments, inside which you can change the rules of the game. Here is a lexical one for your case:
ClearAll[withNCTimes];
SetAttributes[withNCTimes, HoldAll];
withNCTimes[code_] :=
Unevaluated[code] /. Times -> NonCommutativeMultiply
so that
withNCTimes[a*b*c]
(* a**b**c *)
and here is the dynamic one:
ClearAll[withNCTimesDyn];
SetAttributes[withNCTimesDyn, HoldAll];
withNCTimesDyn[code_] :=
Block[{Times = NonCommutativeMultiply},
code];
which would, for the example above, produce the same result.
Dynamic environments are more dangerous since they affect the full evaluation stack, but also more general. Lexical environments are safer, since their action is lexically localized to code you have inside of them. But, if that code contains function calls where Times
is used, those invocations of Times
won't be affected by the environment, since they are not literally present in the piece of code around which you wrap the environment. I discussed this in a little more detail here.
If you don't want to type the name of an environment every time, you can, in the FrontEnd session, automate that by utilizing $Pre
:
$Pre = withNCTimes;
a*b*c
(* a**b**c *)
$Pre =.
Finally, I would never attempt to overload Times
(or Plus
etc), since these functions are very fundamental to the system, and there is no telling what can happen if you do that. Even for more specialized functions, their overloading can lead to quite strange and unwanted behavior, see e.g. here.
ClearAll[Times]
would work? $\endgroup$