Why does insert file not work when playing a quick recorded macro?

Why does insert file not work when playing a quick recorded macro?

21
Basic UserBasic User
21

    Mar 08, 2022#1

    UltraEdit (I am running v28.20) always had very powerful macro recording and editing, so I was surprised when a seemingly simple macro I recorded via Macro menu -> Quick record  did not work. I was trying to delete some lines in the current editor view and then append a named text file to the end of the current file (view/tab) using Insert menu -> File -> Insert File. When I tested the macro it did not work as intended, and when I checked the unnamed macro (= the last Quick record macro) in the Macro List via Modify Macro, the Insert File command and path to that file was not shown in the macro code.

    Is it not possible to insert text files into your current edit view (file tab)?
    Could it be that this just does not work via Quick record and has to actually be programmed by hand into the macro code?

    [I checked the Help -> Index macro command page, and could not find an insert file command.]

    Any help appreciated. Thanks.

    6,603548
    Grand MasterGrand Master
    6,603548

      Mar 08, 2022#2

      There is no macro or script command for the UltraEdit command Insert File. If that action needs to be done with a macro, it is necessary to use the classic method:
      1. Open the file.
      2. Switch to a user clipboard.
      3. Select everything in opened file and copy it to the clipboard.
      4. Close the opened file.
      5. Paste the copied data into active file being hopefully the same as before first step.
      6. Clear the user clipboard and switch to the default clipboard.
      Which file is active after closing the file of which data to insert in active file depends on the configuration setting After current tab is closed, move to: at Advanced - Settings or Configuration - Application layout -  File tabs - Miscellaneous where previously active tab should be selected. Otherwise the macro needs to iterate over the document windows and find the correct file on which to paste the copied data on multiple files opened on running the macro.
      Best regards from an UC/UE/UES for Windows user from Austria

      21
      Basic UserBasic User
      21

        Mar 08, 2022#3

        Thanks. Ah... so no direct "skipping to a named file tab" either. Just checked the macro commands list. I'll have to, as you suggested, loop through the tabs, since I have the file tab I want to insert open already and want to keep it open. I'll need to use IfNameIs for that apparently.

        A real bit of macro programming should be fun though 😋

        Do you think there is any point in putting in a  request with [email protected] for a macro command "Insert File" and another one for "SkipToNamedTab"? (I mean for folks that will be wanting to do those things in the future, I'll be using your workaround.)

        6,603548
        Grand MasterGrand Master
        6,603548

          Mar 09, 2022#4

          I think, a macro/script command for Insert File "...file name..." and SelectTab "...file name..." or ActivateTab "...file name..." would be indeed useful and so it would be good to request such an enhancement by email to UltraEdit support.

          In UltraEdit scripts the document number of active file can be stored in a variable and used later to make the file with this document number again the active file. In UltraEdit scripts it is even possible to use the document number to modify a file which which currently not the active file. I use that possibility often in larger UltraEdit scripts to avoid window updates during script execution by opening a new file with a maximized document window and make the modifications on the initial active file of which window is in background and finally close the new file without saving it. However, this solution is soon not needed anymore with UltraEdit for Windows v2022 coming soon as macros and scripts can be executed without any window update at all.
          Best regards from an UC/UE/UES for Windows user from Austria

          21
          Basic UserBasic User
          21

            Mar 10, 2022#5

            I wondered why I had not thought of using java script and UE, and when I checked I noted that there are 3 scripts in the menu already, but I wrote those 12 years ago. I had simply forgotten about them. Using your tips I wrote the code in java script, created a small function that lets you pass along the name of the view/file tab in question (without path/extension) to then return the id or index number for that view. This way I located the id for the main view I want to edit, and the view with "insertion" text. With those present, I can directly manipulate both views directly, they can be active, but they don't need to. All this works really well and is fast.

            Would there be any interest here at the forums for me to post the code I wrote in this thread?
            (With some practical usage of select all text, changing to clipboard 1 to avoid overwriting what I have in the windows clipboard (as a tip/trick), copy it, directly insert the clipboard contents via ^c, and use a few "key" commands to navigate the cursor.) I used the UE Power Tips that detail how to loop through the view index.

            6,603548
            Grand MasterGrand Master
            6,603548

              Mar 10, 2022#6

              You can publish your UltraEdit scripts in the UltraEdit scripts forum for other UE/UES users interest in. I would definitely review the script code and would tell you what could be improved if I see something to improve at all.

              It is also possible to send the script file by email to support of UltraEdit with asking for publishing it on the page UltraEdit macros and scripts.

              Well, I did for some of my scripts both, sent it by email to UltraEdit support for publishing it on their web server and created an associated forum page for additional information, historical information and possible user feedback.
              Best regards from an UC/UE/UES for Windows user from Austria

              21
              Basic UserBasic User
              21

                Mar 13, 2022#7

                I don't think the bit of code I wrote is worth all the effort to properly "publish" it. It is just an example for folks that might be interested in manipulating/editing several explicitly named file views/tabs in UE. The main function is in 

                function get_view_id( filename )
                and the rest of the code shows how to call up that function to create "method links" to the appropriate file views for further editing.

                Code: Select all

                // Method aliases, to improve readability
                var ue  = UltraEdit;
                
                // Define the names of the files the script will be working on (no extension like ".txt" or path!)
                const txtlist   = "!main file";                 // file to put together
                const txtarc    = "!to insert archive file";    // file to insert into main file
                const ctxt      = "--- current txt ---";        // location you want to insert the arc text into
                
                // What is the id (index number) of the view belonging to filename
                function get_view_id( filename )
                {
                    // Looping through the # of open documents
                    for (var n = 0; n < UltraEdit.document.length; n++)
                    {
                        // Current tab/view's document name matched against filename
                        if( UltraEdit.document[n].isName(filename) )
                            return n;
                    }
                    UltraEdit.messageBox( "Requires the view: '"+filename+"' to be open!",
                                            "Script warning" );
                    return -1;
                }
                
                // Locate the viewer tab index numbers and alias the document "links" to them
                var main_id = get_view_id(txtlist);
                var doc     = ue.document[main_id];     // method alias for main file
                var arc_id  = get_view_id(txtarc);
                var arc     = ue.document[arc_id];      // method alias insert file
                
                // Edit the main file by cleaning (deleting old txts and resetting the file)
                doc.top();                              // Jump to the top of the page, pre-search
                doc.findReplace.searchDown = true;      // Probably default, but just in case
                doc.findReplace.find(ctxt);             // Find the start of the ctxt block, selects the string
                doc.deleteLine();                       // Delete the found line, i.e. start of block
                doc.selectToBottom();                   // Select to the end of the file
                doc.deleteText();                       // Delete the rest of the main file
                
                // Using a script VARIABLE arc_text to transfer data from one view to another
                arc.selectAll();                        // Select all the text on the arc txt page
                var arc_text = arc.selection;           // Copy complete file contents into a script variable
                arc.top();                              // Scroll to the top to deselect select all
                doc.write(arc_text);                    // Insert the arc file to end of main file via variable
                Hope it's of some use.

                Tip: For anyone interested, I'd suggest to copy and then paste my code into a dummy ".js" file in UltraEdit, to let you read the source code with UE's syntax highlighting. That greatly improves readability, IMO.

                6,603548
                Grand MasterGrand Master
                6,603548

                  Mar 13, 2022#8

                  Good coded, nothing really to improve with the exception that I would define all the parameters for the find and do not depend on defaults set by UltraEdit on starting the script.
                  Best regards from an UC/UE/UES for Windows user from Austria

                  21
                  Basic UserBasic User
                  21

                    Mar 13, 2022#9

                    I read your Power Tips from 2009 (List of UltraEdit / UEStudio script commands and most common mistakes). And that was indeed something I was too "lazy" to do in my code (well I did wanted to ensure "searchDown"), i.e. set up all search modes properly. Ideally I'd want to write a script that gets included, and all you do when working with your scripts is include that "set up". I am not quite sure "include" in java script works that well, possibly I am confusing that with Grease Monkey scripts I also tend to work on.

                    If I remember correctly, the find mode settings are only set temporarily for the script's run, and then UE defaults back to what you have set up before your script was launched?

                    (If not, one would want to remember the "pre-script-launch-find-settings", remember those,  set up the few settings you really will want to make sure they are properly set up, use the temp settings, and then at the end of the script reset those settings.)

                    Just as a side note about compact programming:

                    Code: Select all

                    var main_id = get_view_id(txtlist);
                    var doc     = ue.document[main_id];     // method alias for main file
                    
                    or
                    
                    var doc = ue.document[ get_view_id(txtlist) ]; // method alias for main file
                    I was very much thinking of one-lining the two lines of code above, to avoid creating a "redundant" variable called mail_id. I left the code as is to make it a bit easier to read, maybe. What would your preferred approach be in this case [since main_id is not used anywhere else in the code]?

                    6,603548
                    Grand MasterGrand Master
                    6,603548

                      Mar 13, 2022#10

                      AEon wrote:
                      Mar 13, 2022
                      If I remember correctly, the find mode settings are only set temporarily for the script's run, and then UE defaults back to what you have set up before your script was launched?
                      You remember correct. The find/replace parameters set in a script are temporarily for the script execution and do not modify the find/replace parameters used by the user on last manual execution of a find or replace.
                      AEon wrote:
                      Mar 13, 2022
                      Just as a side note about compact programming:

                      Code: Select all

                      var main_id = get_view_id(txtlist);
                      var doc     = ue.document[main_id];     // method alias for main file
                      
                      or
                      
                      var doc = ue.document[ get_view_id(txtlist) ]; // method alias for main file
                      I was very much thinking of one-lining the two lines of code above, to avoid creating a "redundant" variable called mail_id. I left the code as is to make it a bit easier to read, maybe. What would your preferred approach be in this case [since main_id is not used anywhere else in the code]?
                      I prefer for public published and also for private scripts the first syntax. I avoid function calls embedded inside a statement or condition to make it easier for beginners understanding the code and for me on debugging the code perhaps sometimes in the future without the need to rewrite existing lines in script. I do sometimes single step debugging in C/C++ coded programs and I found out in the last 30 years of writing C/C++ code that it is not really good for debugging to embed function calls inside conditions or statements. So I don't do that anymore in no programming and scripting language. Compacting code was too often counterproducive in the past.

                      BTW: Your code misses the error handling on function get_view_id returns -1. There is displayed a message box informing the script user about the error, but the script continues running and accesses the UltraEdit documents array out of bounce resulting in breaking the script execution by the JavaScript core interpreter.
                      Best regards from an UC/UE/UES for Windows user from Austria

                      21
                      Basic UserBasic User
                      21

                        Mar 13, 2022#11

                        Mofi wrote:
                        Mar 13, 2022
                        BTW: Your code misses the error handling on function get_view_id returns -1. There is displayed a message box informing the script user about the error, but the script continues running and accesses the UltraEdit documents array out of bounce resulting in breaking the script execution by the JavaScript core interpreter.
                        You are right. What I actually wanted to do was use code like "exit();" (like I used to do in ANSI C, instead of the return -1;), but looking up on java script that method of stopping code execution does not seem to work / exist. So how does one stop JS code execution "cleanly"?
                        From testing I thought that the UltraEdit.messageBox command let you break any further code execution, so that was a "hack", and not a proper solution, I forgot to look into more.

                        6,603548
                        Grand MasterGrand Master
                        6,603548

                          Apr 23, 2022#12

                          I have overlooked your question:  So how does one stop JS code execution "cleanly"?

                          One solution is embedding the entire main code of the script into a function with a name like main and call the function once in the script at bottom. Then it is possible to use return to exit the function at any time and continue script interpreting after the call of the function which is the end of the script.
                          Best regards from an UC/UE/UES for Windows user from Austria