|
Post by Stefan on Mar 17, 2022 5:23:16 GMT -5
...well, you decide ;-)
George,
In no particular order, would you consider adding support for
(1) Windows Environment variables e.g. SAVEAS %USERPROFILE%\DESKTOP\FileNam.EXT expands the %<variable>% to build the filename
I quite understand that this could be a wide-ranging code change and thus provide a marginal return on investment
(2) EMACRO in the file profile. The EMACRO would work like IMACRO, but is triggered on SAVE or END processig. Some indication of which request triggered it would be useful.
There are some occasions when some automatic pre-SAVE or pre-tab-closure processing would be useful.
|
|
|
Post by George on Mar 17, 2022 9:29:22 GMT -5
Stefan: For the %xx% variables, if this is inside a macro there's Get_SYSVAR to fetch them. Otherwise it becomes more of a search and hunt for all the places where the substitution needs to be done.
Robert: I doubt the % would cause a problem. a) If they aren't bracketed, nothing is done. b) If they are, and no such variable exists, nothing is done. I highly doubt anyone would be attempting to use a filename that just 'happens' to include a %xxx% string which also 'happens' to be a valid Environ variable.
EMACRO shouldn't be too hard, another one of those "exactly where to insert the code" exercises. Bigger effort is needed to create the new Profile variable in all its various places.
George
|
|
|
Post by George on Mar 17, 2022 11:01:55 GMT -5
Stefan: Environ variable substitution is now in place. I'll have a look at EMACRO.
George
|
|
|
Post by Stefan on Mar 17, 2022 11:09:58 GMT -5
Thanks George,
/UPDATE: Darn it - you beat me to it... Again. I can't keep up with your implementation speed!
My usual approach would be to have a macro with the same name as the command I wish to 'enhance'. That would work for CREATE because CRE is a valid abbreviation for CREATE.
A simple CRE.MACRO can easily examine Get_Arg_TextLit$(1) for %...% variable(s), resolve it/them and then issue SPF_CMD("CREATE....") passing the completed filename plus the other operands. With the latest changes, REPLACE could be covered simply via a SET ALIAS.REPLACE = CRE REP entry.
Unfortunately, the SAVEAS command offes no alternative/abbreviation to invoke it, making it hard to effectively "front-end' the native command with a bit of macro logic. And my most recent attempts to issue SPF_CMD("SAVEAS ...") from within a macro, invariably culminate in a SPFLite crash or hang.
As I'm typing this post, it occurs to me that the crash/hang may be related to the 'kill this tab and open in a new tab' feature while the macro is still running, so a POST_DO(...) may fix that. But I would still need to invent (and train this old dog to use!!!) a command other than SAVEAS to 'front-end' the real SAVEAS command. (I had hoped SAVE# or SAVE% might be usedful, but SET ALIAS accepts neither. I guess SAVEX is an option.
-------------------------------------
Maybe a third and more flexibile suggestion is an equivalent to the ISPF's 'BUILTIN' feature. It could perhaps be implemented in the form of a SPF_NativeCMD("...") or SPF_BuiltinCMD("...") call.
It's effect would be to bypass search sequence, thus ignoring SET.ALIAS entries and any macro of the same name and directly invoke the requested routine.
|
|
|
Post by George on Mar 17, 2022 11:26:48 GMT -5
Stefan: You shouldn't need to use an alternate name. If you call your macro SAVEAS.MACRO it should get invoked first. Then if the macro issues a SPF_CMD(SAVEAS ...) it will invoke the REAL SAVEAS command. Thats the way it's supposed to work.
George
|
|
|
Post by Stefan on Mar 17, 2022 13:45:13 GMT -5
Ahh, that's good news. No BUILTIN or NATIVE call required. So SPF_CMD("XXXX ...") will always call the SPFLite XXXX command and NOT disappear up it's own behind back into the XXXX.MACRO that contained the call. I didn't know that. In fact, I so sure that it would create a loop, I've never even tried it! Sorry!
|
|
|
Post by George on Mar 17, 2022 13:55:43 GMT -5
Stefan: I think EMACRO is now working.
a) I can not pass anything to indicate SAVE or END. Have to think about that. b) If a MEDIT session (not common), the macro is called for EACH file being saved, it will have to be prepared for that (or ignore it)
I'll try and wrap it up and issue a Beta.
George
|
|
|
Post by George on Mar 18, 2022 12:05:19 GMT -5
Robert: There is already a Get_Session_Type$ function.
I have added a new Get_Primary_Cmd$ to fetch the last command. (e.g. END or SAVE)
I can't provide for the macro interfering in whether the SAVE should proceed or not, it's too deep in the process at that point. Remember SAVE is also called by other processes, like the Crash Save routine, the ACTION SAVE process, SAVEALL.
George
|
|
|
Post by George on Mar 18, 2022 13:54:30 GMT -5
Robert: Capturing those commands right in command processing is no good. It would miss all the other calls to SAVE, miss out on SAVE COND skipping the whole save, miss the individual MEdit file saves etc. etc.
As I said when I gave up on merging SAVE/CREATE/REPLACE/SAVEAS into one - we have a very complex set of internals, not to be toyed with easily.
George
|
|
|
Post by Stefan on Mar 19, 2022 4:46:47 GMT -5
I have added a new Get_Primary_Cmd$ to fetch the last command. (e.g. END or SAVE) I can't provide for the macro interfering in whether the SAVE should proceed or not, it's too deep in the process at that point. Remember SAVE is also called by other processes, like the Crash Save routine, the ACTION SAVE process, SAVEALL. George,
Thank you for the Get_Primary_Cmd$ function.
I have also realised that I was a 'bad' customer having suggested an extension to the product without thinking through all the likely requirements!! I was also about to request that the Emacro could return a boolean value to either abort or continue with whatever primary command caused it to be invoked. But I see from your above post that is not practical.
No worries.
Robert, I believe SPF_CMD("END") does not behave as you would like. From past experience, I think SPF_CMD("END") is simply ignored. For one, the END would execute at the time of the SPF_CMD call and at that time the macro is still active. You can issue an 'END' command from within a macro via SPF_POST_DO("END"), which is fine, especially when the next statement is HALT. And, if required, you can 'chain' commands like this: SPF_POST_DO("(Home)[END](enter)[CLIP](enter)")
It is a little inelegant though as the user will see the screen flash as individual comamnds are entered. Lastly,
SPF_POST_DO("(Home)[END ; CLIP](enter)") does away with the screen flashes caused by 2x(enter), but it also doesn't leave you looking at the CLIP session tab. Might be useful though depending on what the second command is.
|
|
|
Post by George on Mar 19, 2022 11:03:01 GMT -5
Robert: END is not allowed from an SPF_CMD, it would end up crashing as the tab disappears and the macro's data areas are freed.
You'd have to do this:
' xend.macro ' Do whatever is needed ' If END is to be issued, do the following SPF_Post_Do("(Home)(EraseEOL)[END](Enter)") Halt(0)
|
|
|
Post by George on Mar 19, 2022 14:22:23 GMT -5
Robert: Yes, stacked commands are processed IN the tab where they were issued. When END is done, the stacked command disappears along with all the other tab related data. That's why you can't do SWAP;F fred etc.
I've been toying with having the command line be supported 'higher up', i.e. more globally above individual tab stuff, but it's a pretty major internal structure change, I've never even got it straight in my mind, let alone in code.
George
|
|
|
Post by George on Mar 19, 2022 14:54:10 GMT -5
Robert: Basically, no way. The whole DO process injects the commands at a very, very early point in the keyboard handling. Trying to affect HOW the injected commands are handled downstream is very doubtful.
George
|
|
|
Post by George on Mar 19, 2022 15:57:32 GMT -5
Robert: The problem is that "Quiet" implies a more global suppression, I'm not sure there's a easy point to accomplish that. Besides, it's another little 'here-there-and-everywhere' type change, depending on the commands being issued.
Sometimes I'd love to go back and re-code this whole mess, but that's never going to happen, I've toyed with re-writing certain aspects and bailed out after thinking seriously about what it really means. We've created a seriously convoluted piece of code, we just have to live with what we have.
George
|
|
|
Post by Stefan on Mar 21, 2022 5:54:14 GMT -5
Hmm.... Both the two commands I listed... SPF_POST_DO("(Home)[END](enter)[CLIP](enter)") SPF_POST_DO("(Home)[END ; CLIP](enter)")...allow the chaining and are correctly performed despite the END command terminating the current Tab. It is EITHER... ... a timing fluke (unlikely as SPFLite isn't multi-threaded internally), OR... ... more likely the result of CLIP being a valid command on an FM screen too, so it executes successfully. Other commands may well not chain correctly. I believe the window flashes result from the screen redraw brought about by the (enter) primitive. If there's two, you'll perceive the double re-draw as a 'flash'. With just one (enter) this isn't an issue.
Robert:
As for the use of "!" as the initial character, I understood it to be merely a 'short form' for the (Home)(EraseEOL) sequence of directives. I do note that SPF_POST_DO("END;CLIP"), without the '!' doesn't work either but wrapping the chained commands in proper directives is fine.
That said, I haven't actually tried SPF_POST_DO("(Home)(EraseEOL)[END ; CLIP](enter)"), so it may well be the 'erase' part that scuppers the chaining.
|
|