Save upon compile any or all procedure files in procedure windows
These two functions allow specified procedure file windows to save automatically upon procedure compilation. I'm often writing out new code in a procedure window, and I hate losing code that I compiled but forgot to save. I think that Igor at least warns upon an attempt to close an experiment with a procedure file that's been modified without save, but that doesn't avoid losing new code due to an Igor or computer crash. It would be nice if Igor offered a built-in option to save upon compile--perhaps it does and I haven't found it yet. Even so, this function would allow one to save a back up automatically in a different file.
I originally imagined using this to automatically re-save my procedure in its associated file, but this can cause Igor 7 to think that the file was modified externally, leading to issues that are discussed in the code comments. It would be nice if there was one day a built in saveproc function that got around this issue. (To my knowledge the closest thing is closeproc/SAVE, but I don't want the procedure to close or the scroll position in the procedure window(s) to shift).
There are likely to be text encoding issues that I haven't worked out. I've only used this on Windows so far.
//Saves any procedures displayed in a procedure window. Include the AfterCompiledHook function below to call this after compiling procedure files //In limited testing, UTF-8 encoding (#pragma TextEncoding = "UTF-8") re-opens better than Windows-1252 after saving in the way this procedure does (via fprintf with strings) function saveProcs() //some default settings String procsToBackup="*;" //list (semi-colon delimited) any procedures that should be saved. ".ipf" should end each list item* //*with one exception; to save the main procedure window, one list item should be "Procedure" //to save the main procedure window and any other procedure window, use procsToBackup = "*" //To save procedures named myProcs0 and myProcs1, use procsToBackup="myProcs0;myProcs1;" (or procsToBackup="myProcs*;") String saveAppendStr = "_bu" //optionally specify a string to append to each save file name //In Igor7, it's probably best to specify a saveAppendStr or choose a directory other than one currently containing the to-be-saved procedure file(s). //Using saveAppendStr="" and saving into the procedure file-containing directory will cause Igor7 to think the procedure file was modified externally. //Igor7 will keep trying to resolve the conflict after each compile, and when you choose to resolve it, each procedure needs to be recompiled, causing //them to save again, re-call this function, and so on. There might be some settings where this is advantageous: putting off the conflict resolution, a reload from //file is like restoring to the last compile point while using file->"save procedure as..." would allow new updates to be saved Variable numCharsPerWrite=500 //this has to below the limit of fprintf..not sure what that limit is, but 500 is ok String saveExtension = ".ipf" //I've also tested ".txt". The txt files can be copied into a procedure file and then work fine. The code might display properly in a txt file opened with proper encoding settings? //find procedures that should be backed up according to procsToBackup variable i,j; string saveList="", matchList, match, allProcWins=winlist("*",";","WIN:128") for (i=0;i<itemsinlist(procsToBackup);i+=1) matchList= ListMatch(allProcWins, stringfromlist(i,procsToBackup)) for (j=0;j<itemsinlist(matchList);j+=1) match = stringfromlist(j,matchList) if (whichListItem(match,saveList) < 0) saveList += match + ";" endif endfor endfor if (!itemsinlist(saveList)) return 0 //do nothing if no procedures match the list in procsToBackup endif //choose a file to save backup(s) to; only necessary once per experiment //use newpath/O saveProcFiles_path to choose a new path pathinfo saveProcFiles_path if (!V_flag) newpath/O saveProcFiles_path if (V_flag) Print "saveProcFiles(): user aborted selection of a folder for saving procedures; aborting" endif endif //write each procedure to its save file with fprintf Variable saveLen,strIndex,numFullWrites,fileRefNum,writeIndexDelta=numCharsPerWrite-1 String procWinName,saveStr,fileName for (i=0;i<itemsinlist(saveList);i+=1) procWinName = stringfromlist(i,saveList) saveStr = ProcedureText("" , inf, procWinName) saveLen = strlen(saveStr) if (stringmatch(procWinName,"*.ipf")) fileName=procWinName[0,strlen(procWinName)-strlen(".ipf")-1] else fileName=procWinName endif fileName = fileName+saveAppendStr+saveExtension numFullWrites=floor(saveLen/numCharsPerWrite) Open/Z/P=saveProcFiles_path fileRefNum as fileName if (V_flag) Print "saveProcs(): failed to identify procedure file save location. Aborting." close fileRefNum return 0 endif for (j=0;j<numFullWrites;j+=1) strIndex=j*numCharsPerWrite fprintf fileRefNum,"%s",saveStr[strIndex,strIndex+writeIndexDelta] endfor strIndex+=numCharsPerWrite fprintf fileRefNum,"%s",saveStr[strIndex,inf] close fileRefNum endfor end static function AfterCompiledHook() saveProcs() return 0 end