programmatic control of procedure window contents

Hi all,

I would like to programmatically write to Procedure windows. Igor writes to the built-in procedure window when saving graph/window creation macros. Is there a function that allows a user-defined function to write to the procedure window (or auxiliary procedure windows)?

I was reading about writing to Notebooks using the Notebook operation and I thought I saw something about a function that allowed creation and writing to procedure windows as well. Am I mis-remembering? Note that for some of my use cases, writing to a text file and loading that file as a procedure will not work.

Thanks for the help.
You can't programmatically write to a procedure window. If this were allowed, it would pull the rug out from under Igor while it is executing user functions.

You can write a file to disk and then load it as a procedure file. Execute this for help:
DisplayHelpTopic "Operation Queue"


Usually this kind of trickery is a bad idea. It is very difficult to maintain or debug.

If you explain what your motivation is we may be able to suggest how to achieve it.
hrodstein wrote:
You can't programmatically write to a procedure window. If this were allowed, it would pull the rug out from under Igor while it is executing user functions.


Ok, got it. It seemed to me that writing to a procedure from an IndependentModule might work, as long as the procedure being written to was not part of an IndependentModule. Oh well...

hrodstein wrote:

Usually this kind of trickery is a bad idea. It is very difficult to maintain or debug.

If you explain what your motivation is we may be able to suggest how to achieve it.


So, I actually have two goals:

1) I am writing a unit test framework for Igor (you can see my progress here: https://github.com/yamad/igorunit). To make writing tests non-painful, I am trying to implement a sort of preprocessor step that expands macros into valid Igor code. Unit test frameworks for C, like Unity and Check, use a similar approach. Right now, I have a python script that takes test descriptions from text files, preprocesses the tests and collects them in an *.ipf file. The python script then talks to Igor, asks it to include the test *.ipf, run the tests, and give the results back to python. This works fine right now, but I was trying to play with implementing the preprocessor step in Igor itself. It makes life slightly easier if I can write directly to a new procedure window. But as you say, creating a text file on disk should work too.

2) I also have implemented an emacs mode for Igor. The emacs editor, for me, makes me much much more productive than working directly in Igor. As has been mentioned elsewhere on the forum, Igor's code editor is pretty limited and so I am trying to break out of the Igor editor. The limitations of using an external editor are that 1) Igor locks the procedure file once it has been included, and 2) it requires all procedure code for an experiment to be held in external procedure files (that is, I can't edit built-in procedure code with emacs). Some people in our lab are quite averse to using external procedure files. Being able to break in and out of Igor with the built-in code (think of the It's All Text plugin for Firefox https://addons.mozilla.org/en-US/firefox/addon/its-all-text/) would solve both problems.
Quote:
It seemed to me that writing to a procedure from an IndependentModule might work, as long as the procedure being written to was not part of an IndependentModule.

Yes, I think that is right, but Igor doesn't let you write to the procedure window.

Quote:
I am writing a unit test framework for Igor (you can see my progress here...


I can see that you know what you're doing so you have my blessing to use trickery :)

I think you will have to generate a .ipf file on disk, either by writing a notebook to disk or writing directly using Open/FBinWrite or fPrintf/Close, and then loading the file using Execute/P INSERTINCLUDE or Execute/P LOADFILE followed by Execute/P COMPILEPROCEDURES.
yamad wrote:


2) I also have implemented an emacs mode for Igor.


Could you share with us your emacs-mode code?
Here's how I check if a list of commands in a text wave is syntactically correct.
It works by writing the commands to a procedure file and seeing if it compiles.

Function Pla_checkBatchFile(listWave)
    Wave/t listWave

    string pathToBatchProcedure = specialdirpath("Igor Pro User Files", 0, 0, 0)   
    newpath/o/q/z User_PROCEDURES, pathToBatchProcedure
   
    //first part is to write the listWave to a procedure file
    duplicate/free/t listwave, batchFileChecker
    deletepoints/M=1 0, 1, batchFIleChecker
   
    redimension/n=(-1,0)  batchfileChecker
    insertpoints 0,2,batchfilechecker
    batchfileChecker[0] = "#pragma rtGlobals=1    // Use modern global access method."
    batchfileChecker[1] = "Function test()"
    redimension/n=(numpnts(batchfileChecker)+1) batchFileChecker
    batchfileChecker[inf] = "End"

    Save/o/g/P=User_Procedures batchfileChecker as "batchFileChecker.ipf"
   
    //now do the checking
    string/g diditcompile = ""

    execute/p/z "INSERTINCLUDE \"" + pathToBatchProcedure + "batchFileChecker\""
   
    execute/p/z/q "COMPILEPROCEDURES "
    execute/p/z/q "didItcompile = Functionlist(\"\",\";\",\"\")"

    execute/p/q/z "DELETEINCLUDE \"" + pathToBatchProcedure + "batchFileChecker\""
    execute/p/z/q "COMPILEPROCEDURES "
    execute/p/z/q "Deletefile/P=User_Procedures \"batchFileChecker.ipf\""
    execute/p/q/z "Pla_batchChecker#Pla_compResult(didItCompile)"
End

Function Pla_compresult(val)
    string val
    Variable/g V_flag
   
    if(stringmatch(val,"Procedures Not Compiled;"))
        print "There seems to be something wrong with your list of commands"
        V_flag = 1
    else
        print "Your batch list of commands seems to be syntactically correct"
        V_flag=0
    Endif
end
Andy,

Is your primary use for this method to test new code without disrupting the compilation state of existing code or is it something else? I could see writing new code in a notebook and then testing by your method. Have you considered using a notebook as the front end to your function? Maybe you do this already.

Jeff
wwzhang2, see my new post on the emacs mode here: http://www.igorexchange.com/node/2514

Andy, I am also interested in what you use that code for. I had been considering using notebooks as the "source files" for generating procedures, but I haven't had the time to fully flesh out that idea.
In my case we use Igor to control some instrumentation. As part of the control program we use the concept of a batch file to sequence commands that are sent to the instrument. The control program has to detect when a previous command has finished and then run the next command. In the control program we have a panel containing a listbox. This listbox is where the user can enter the instrument commands. These commands are simply Igor functions, but in the form of strings (coz they're in a listbox/textwave). We needed some way of ensuring that the commands that the user entered were correct. I had the idea of writing all the commands out into a procedure file (adding a dummy function name at the top and end at the bottom). Then you try and include the file, compile procedures, etc. If that compiles, then the commands must have been syntactically correct, otherwise the Igor compiler will stop compiling and tell you which command was not correct. Then you simply uninclude the file and delete the procedure file.
jtigor wrote:
Andy,

Is your primary use for this method to test new code without disrupting the compilation state of existing code or is it something else? I could see writing new code in a notebook and then testing by your method. Have you considered using a notebook as the front end to your function? Maybe you do this already.

Jeff


The code _does_ disrupt the compilation state of existing code (unless it's an independent module). If the new code doesn't compile then the compiler will complain and tell you what didn't work. But then the code unincludes the file anyway.
THe main purpose of this method is to see if all the entries in a textwave would be syntactically correct if you wanted to execute it from the command line.
variable ii
Execute/q/z mylistwaveentry[ii]


yamad wrote:
wwzhang2, see my new post on the emacs mode here: http://www.igorexchange.com/node/2514

Andy, I am also interested in what you use that code for. I had been considering using notebooks as the "source files" for generating procedures, but I haven't had the time to fully flesh out that idea.

It's do-able, but complicated. See the Function Grapher package: Analysis->Packages->FunctionGrapher.ipf. In the procedure file, search for Execute/P.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
yamad wrote:
wwzhang2, see my new post on the emacs mode here: http://www.igorexchange.com/node/2514

Andy, I am also interested in what you use that code for. I had been considering using notebooks as the "source files" for generating procedures, but I haven't had the time to fully flesh out that idea.



Thank you.