How can I customize my menus without reloading MenuSetup.tr?

Real-time Reloading of Menus

The answer to the first one is very simple. After you make changes to your MenuSetup.tr file simply call

FrontEndExecute@{
  FrontEnd`FlushTextResourceCaches[],
  ResetMenusPacket[{Automatic, Automatic}]
  }

This will reload the menus.

The first part gets the MenuSetup.tr loaded and the second applies the actual changes. If you add palettes/stylesheets or a new FE directory, etc, the second call will load those resources too.

Temporary Menus

The question of temporary-ness is also not bad.

All we have to do there is prepend a new directory to which will contain our MenuSetup.tr

CurrentValue[$FrontEndSession, {PrivatePaths, "TextResources"}]

By setting this to, say $TemporaryDirectory we get what we need for temporary-ness.

If instead we place it in a standard directory already on that path or, instead, set loading of that path in the Autoload directory we can make the changes permanent.

Convenient editing (package only)

Go here for all of this dumped as a package

But we can do yet one better.

Looking at the structure of the menu expressions we can note they're generally tree-like (with some complications) so we should be able to edit them like a nested Association. All we really need to do it unspool them into an Association structure.

Note that this will be made harder by things like MenuItems that share a title (but differ in their MenuKey expression) and AlternateItems and LinkedItems expressions, but overall it's not too bad. And for good measure we'll want a respooling mechanism.

In the attached code package these are the functions feUnspoolMenuExpr and feRespoolMenuExpr respectively.

Then we'll link into the *.tr editing structure I outlined here so we can conveniently specify where to dump our MenuSetup.tr file and simplify the dump procedure itself.

The main useful piece of functionality there is the $FEMenuSetupDirectory constant which is a FrontEnd`FileName specifying where the data should go.

We then unspool the standard Menu structure into the constant (well, constant interface) $FEMenuSetup and we simply use our respooler and some front-end processing to dump an appropriate string-form for our MenuSetup.tr. (feMenuSetupExport)

And then by providing edit functions on $FEMenuSetup (FEMenuSetupAdd, FEMenuSetupDrop) we can very quickly and easily perform interesting edits, such as:

FEMenuSetupDrop["Palettes"]

before after

And

FEMenuSetupAdd["StackExchange",
  "MSE" :>
   FrontEndExecute[{
     FrontEnd`NotebookLocate[{
       URL["https://mathematica.stackexchange.com"],
       None
       }]
     }]
  ];

StackExchange

And clicking on that opens up the main MSE page.

None of this required a restart or anything of that nature. It's just a simple edit like this.

One still needs to know how the front-end evaluates things (e.g. use the FrontEnd` functions), but it allows for greater flexibility and customization.

And if you don't like your changes reverting is as simple as deleting and reloading, which has its own convenience function (FEResetMenuSetup) and syntax:

$FEMenuSetup =.

reset

My implementation of this is in the package I linked to earlier to play with.


I do this differently to @MB1965.

SetOptions[$FrontEndSession,
  MenuConfigurationFile -> "path/to/alternative/MenuSetup.tr"
  ];

and then to restore the menus:

SetOptions[$FrontEndSession,
  MenuConfigurationFile -> Inherited
  ];

I find this easy and can be done readily on the fly, switched on and off with buttons etc.