Breaking infinite loops in MEL & a better ScriptEditor

I found this post linked to on the CGTalk forums, about a way to recover from an infinite loop in MEL; using a filetest inside the loop see if a ‘kill’ file existed, if it did then the loop would end. It got me thinking about other ways to help mitigiate this problem, and also about how I don’t really like the script editor as it is (Why does it delete the script if it’s not selected when I execute?).

This article uses commands that were added in Maya 2008, if you’re still using an earlier version it should still be possible to use a similar technique but more scripts would need to be written to fill in the gaps.

Problem 1. Backing up the ScriptEditor contents

The first problem is for when you’ve forgotten to put in a check for loops, or used the above method to get out of it, we obviously don’t want to loose the script we are working on when Maya has hung. Maya already saves the contents of the script editor when it shuts down, and the commands that accomplish this are in “scripts\startup\scriptEditorPanel.mel”, specifically the command “syncExecuterBackupFiles()”. So we could just add this command to the top of our script, and everytime we run it the editor is backed up.

But this could cause us some problems when we start Maya up again; this command saves out a file for each tab in the editor, however if we added or removed any tabs then this wouldn’t be saved when we killed Maya. When we opened up Maya again it would try and copy the saved contents back into the tabs, and if they had changed it might put mel files in a python tab, or just miss out some altogether. We wouldn’t loose anything, the contents would still be in the preferences folder, but it could be a pain to try and sort them out again so it’s not ideal. We could just run “SavePreferences” to save the layout of the tabs, unfortunately this takes a few seconds and spams the script history so it’s not a great solution either.

There are a couple of different approaches now, the simplest would be to create our own version of “syncExecuterBackupFiles()” that saved the contents out to our own directory, then if there was a crash you just check this folder and retreive the scripts manually.

Another option is to continue to use “SavePreferences” but instead of calling this everytime we execute a script, we call it whenever we alter the tabs themselves. There are three commands that create or remove tabs, (addNewExecuterTab, removeOtherExecuterTabs, removeCurrentExecuterTab) we just need to add “SavePreferences” as the last line in each. This is probably the ‘safe’ way to do it, all we’re doing is calling Mayas own back up commands, and it’s how it’s set up for me. But I still don’t really like it; it seems messy having to save all preferences, when all you’ve done is added a new tab in the editor.

My other idea involves altering the backup command so that as well as saving the contents of the editor, it also saved out the tab information. This would also require altering the code that builds the tabs so that it used this file instead of the normal user preferences. I think this would be a more elegant solution, the end user wouldn’t notice any difference and nothing would get printed to the script output. I might look into this further if I get a chance, for now the previous solution will be fine.

Problem 2. Better Execute Command

The other big issue I have is with the command to actually execute the script; I normally press “Ctrl+a” then “Ctrl+Enter” to select all and execute. I just want a single button to press that executes without removing the script, and it would be nice if we didn’t have to add the command to backup our script editor contents manually, it should just do it when you execute, maybe it would be useful to save the scene automatically before too.

I thought this should be fairly easy, but now all the problems start :(

The first issue that I didn’t anticipate was that the command to store the contents of the script editor also selects all the text, loosing our previous selection. This means we can’t do a backup when we just want to execute a selection of our script. We could do a check to see if there is a selection, and then not do the backup in that case; but I don’t really like the inconsistency, sometimes you get a backup, sometimes not. The only way I could come up with to solve this would be to create our own backup command, bypassing the store command built into the editor. I’ll return to this in another post I think.

Second issue is about hotkeys, or the lack of them when in the ScriptEditor. As far as I can tell the hotkeys that control the ScriptEditor are seperate from the normal hotkeys, and are hardcoded somewhere I can’t access. This means I can’t change Ctrl+Enter to run our command, and I can’t create new hotkeys either. Bah.

So what can we change?

The execute command can be altered a little so that if there is no selection it will do an executeAll instead. This stops it removing the script if nothing was selected. Unfortunately editing this will only affect the execute button, and the command in the menu, Ctrl+Enter bypasses this.

We can add a ‘Backup Scripts’ button which we can hit to save the contents of the editor. This is just a button with the ‘syncExecuterBackupFiles’ that I mentioned earlier. I also added a ‘SavePreferences’ command, and ‘SaveScene’ to the button, so I can uses it as a ‘I’m about to do something dangerous’ button.

And there is the inconsistent backup and execute button that was already mentioned.

So I managed to add a couple of useful features, even if it’s not the pure awesomeness I had hoped for. :) I’ll go away and have bit more of a think about it.

Download: scriptEditorPanel