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"]
And
FEMenuSetupAdd["StackExchange",
"MSE" :>
FrontEndExecute[{
FrontEnd`NotebookLocate[{
URL["https://mathematica.stackexchange.com"],
None
}]
}]
];
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 =.
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.