|
Post by Stefan on Jul 28, 2020 11:04:29 GMT -5
UPDATE: This macro and the associated key mapping has been superceded by enhancements to SPFLite starting with version 2.2.20255. The new OPTIONS GENERAL setting 'Maintain screen position after Line Cmds" now natively implements this capability.
This macro requires (as stated within) a customised <ENTER> key.
For an explanation and rationale, please see the post with subject "Custom Cursor Control - Rationale" in the "Macro Discussion" section of this forum.
' CSR.MACRO ' ---------------------------------------------------------------------------------------- ' This is Edit Macro CSR Stef 05/07/20 ' ' This macro is invoked by a modified <ENTER> key. ' It places the cursor at the line where it was when <ENTER> was pressed. ' This overrules the cursor/page placement resulting from any line commands which will ' have executed already by the time this macro starts. ' ' The KEYMAP string (below) is required to interface with this macro. ' It uses 2 line labels: ' .pt denotes the 'Top of Page' line ' .pc denotes the cursor position line + 1 ' ' Note: We use curpos+1 to allow for pressing <ENTER> on same line as a line command ' ---------------------------------------------------------------------------------------- ' The KEYMAP string used to invoke this macro is entered as a single line, without ' the /* comments */ shown here for explanation. ' (SaveCursor)(NewLine)[.pc] /* .pc label cursor line +1 */ ' (Home)(SetInsert)[CSR ; ](RestoreInsert) /* inject macro call */ ' (CondLineNo)[.pt] /* .pt label TopOfPage */ ' (RestoreCursor)(Enter) /* press <ENTER> */ ' ---------------------------------------------------------------------------------------- ' KNOWN ISSUES: ' - PF12 (RETRIEVE) returns "CSR;". Hit PF12 twice to get actual previous command. ' - DO NOT USE modified <ENTER> key when on File Manager page. ' - The .pt and .pc labels will overwrite any line command or other label placed on the ' Top-Of-Page and cursor line respectively. ' - The .pc label will be placed in error on the "**** Bottom-of-Data ****" line if ' the modified <ENTER> key is used on the last actual data line. ' ---------------------------------------------------------------------------------------- DIM AS NUMBER csrLptr, csrCol, csrLptr, newLptr DIM AS STRING linData /*------------------------------------------------------------------------------------*/ /* If on File Manager page, clean up and do nothing */ /*------------------------------------------------------------------------------------*/ IF Is_FM THEN /* If File Manager */ SPF_CMD("RESET") /* .. Remove KEYMAP labels */ HALT /* .. Bail out */ ENDIF /*------------------------------------------------------------------------------------*/ /* If cursor not in EDIT data area, clean up and do nothing */ /*------------------------------------------------------------------------------------*/ csrLptr = Get_Csr_Lptr /* Get Cursor line at Interrupt */ IF csrLptr < 2 OR csrLptr >= Get_Last_Lptr THEN /* If NOT in EDIT data area */ SPF_CMD("RESET LABEL .pc .pc") /* .. Remove KEYMAP labels */ SPF_CMD("RESET LABEL .pt .pt") HALT /* ..Bail out */ ENDIF /*------------------------------------------------------------------------------------*/ /* Position Top-Of-Page on the line where it was before and remove the labels */ /*------------------------------------------------------------------------------------*/ Set_TopScrn_Lptr(Get_Lptr(".pt")) /* Place Page as per previous ToP */ csrLptr = Get_Lptr(".pc") /* Get pointer to cursor line */ SPF_CMD("RESET LABEL .pc .pc") /* Remove the line labels */ SPF_CMD("RESET LABEL .pt .pt") /*------------------------------------------------------------------------------------*/ /* Determine cursor column position and place the cursor */ /*------------------------------------------------------------------------------------*/ linData = Get_Line$(csrLptr) /* Check indent on cursor line */ csrCol = Verify(linData," ") /* Find first non-blank char or 0 */ IF csrCol = 0 AND csrLptr > 2 THEN /* If line is blank ... */ newLptr = Get_Next_LPtr(csrLptr,-1,"DATA") /* .. try the previous line */ linData = Get_Line$(newLptr) csrCol = Verify(linData," ") ENDIF IF csrCol = 0 AND csrLptr < Get_Last_Lptr - 1 THEN /* If previous line is blank ... */ newLptr = Get_Next_LPtr(csrLptr,+1,"DATA") /* .. try the following line */ linData = Get_Line$(newLptr) csrCol = Verify(linData," ") ENDIF Set_Csr(csrLptr,MAX(csrCol,1)) /* Place cursor as required */ HALT
|
|
|
Post by George on Jul 29, 2020 8:14:32 GMT -5
Stefan: Good job, it shouldn't be this hard but .... it is, as well you know.
George
|
|
|
Post by Stefan on Aug 3, 2020 9:02:51 GMT -5
True George. It's inelegant because I can't check to see which environment I'm in (FM or EDIT) and using Key mapping to label the lines is potentially disruptive to existing labels/line commands. I thought of using a line macro, but that precludes use of other line commands, so key mapping was the only way to 'get in' BEFORE the line commands are processed. But neither the environment check, nor the label complexity would be a challenge if the internal code 'remembered' the Top-of-Page and Cursor lines before executing the line commands and then restored them BEFORE executing the primary commands. Some kind of internal-access-only 'label' or 'handle' would be ideal. It need not be the default - it could be optional via the OPTIONS dialog. But maybe it's just me who uses SPFLite in this 'scroll by mouse or cursor key' way. Its ancestor didn't have this complication because a 3270 'scroll' always required an interrupt, so line commands were always processed before the user left the current view/page. There's a lot that was simpler back then - not necessarily all good.
If you feel generous, maybe my approach will be superceded in time. Until then, it helps keep this user sane a little bit longer.
|
|
|
Post by George on Aug 3, 2020 10:17:35 GMT -5
Stefan: So you'd like an option to save TOS and Cursor loc. and re-establish them after Line processing and before Primary Commands. Possible. The problem is that both these 'saved' values would also need to be adjusted as line processing takes place, and also verified that the lines actually still exist and haven't been totally removed by line processing (like deletes).
I'll have a look after I finish another project I'm working on. It may be a while.
George
|
|
|
Post by Stefan on Aug 3, 2020 11:24:19 GMT -5
George,
I'll take that. You are, as always, awesome.
Effectively you would just do what the mapping+macro already do, but (a) faster), (b) more reliable and (c) avoiding FM issues.
I tackled the 'line processing' issue by labeling the two relevant lines. You already have the ability to maintain the association of a line label with a specific line, regardless of any changes to Line number or Line pointer caused by other mods. So some kind of internal 'label' or maybe 'handle' added to the list of user-defined labels would do what you need. It is a temporary thing - as you can see, I remove the labels after they've done their job in the macro. So the user rarely sees them.
|
|
|
Post by Stefan on Aug 3, 2020 11:40:41 GMT -5
Stefan, a few comments: 1. Instead of labels, you could use tags. Difference between labels and tags is you can define multiple tags with the same name. If you wanted to avoid 'trashing' an existing label, most users don't get into tags that much, so it's relatively safe. If you needed to uniquely identify a line, you could first remove all tags of some given name, then define one tag. 2. The Line Handle facility was intended to provide a means to identify lines by a macro, in a way that would not 'break' any existing labels or tags. In the SPFLite Macro help, this is discussed under "Working with Line Handles". 3. You CAN see which environment you are in. Use the "Is_FM" function. Here is the description for it: "Returns TRUE (1) if the macro was launched in the File Manager tab, If launched in an Edit tab, it returns FALSE."
Hi Robert,
Thanks, but tags don't really help. I only need to identify 2 lines - the top of the current page and the cursor line. And I only need them while the line command processing is being done. So no need for multiple tags of the same name. Placing a tag with a mapped key can be done but has the same issues and limitations as using a label - e.g. what if there is already a label/tag/line command on that line or the attempt falls on the ******* BOTTOM OF DATA ******** line, etc.
The Handle facility doesn't help because I need to label the lines BEFORE the line commands execute. Only way to do this is with a mapped <ENTER> key so handles are not available.
Similarly, I think the IS-FM function is only good in a macro. I do use it in the CSR macro to clear up the mess the mapped key makes when it's used on the FM display. Ideally, I'd need an Is_FM function in the KEYMAP options but, unless I missed it, KEYMAP does not (understandably) offer conditional processing of any kind.
|
|
|
Post by George on Aug 9, 2020 13:07:13 GMT -5
Stefan: Here's a trial version for you to play with and provide comments. The change has no OPTION setting yet - it's hard coded. Maybe you can offer a "Name" for what this option would be called. Basically, it ignores any line/cursor set requests done by the various line commands and re-establishes the state as of the attention interrupt. George SPFLite22.exe (478 KB)
|
|
|
Post by George on Aug 10, 2020 11:08:14 GMT -5
"Attention cursor position" doesn't necessarily seem to include the Top-of-Screen position, so my vote is "Attention Position".
FWIW
===> And, "Attention Position" is shorter and simpler. I think this might be the right description, IMHO. R
|
|
|
Post by Stefan on Aug 19, 2020 17:20:57 GMT -5
Hi George,
I'm very grateful that you're looking at this request.
The change is close, but not quite right. It avoids the user being taken back to some earlier line command in a completely different part ("page") of the text being edited, but "shuffles" the current page and leaves the cursor on the wrong line. This is because it maintains the logical 'top of page' and the cursor line at the same LINE NUMBERs as they had before the attention. If, as is quite likely, the earlier line command(s) have inserted or deleted lines, those line numbers now refer to different lines. For example: (1) Place a D3 line command on line 2 (2) Mouse-scroll forward in the file such that line number 100 is the top line in the display (3) Type 'AAAAA' on line number 100 (just so you can see where it ends up)
(4) Move cursor to line number 115, type 'BBBB' and press <ENTER>
I'd expect (a) the top line of the display to still show the 'AAAAA' line but it would now be line number 97 and (b) the cursor to be under the first non-blank character in the line after the one with 'BBBB' in it (now line number 112), i.e. cursor is under first non-blank char on line number 113.
However the change leaves line number 100 as the 'top of page' line (so the 'AAAAA' line is invisible at line number 97) and the cursor at the end of line number 115 (which is 3 lines too low and hasn't advanced to the next line as usual). You already have some way of ensuring that line labels 'stay' with their assigned line content regardless of what happens to the line numbers or line pointers. Hence I label the 'top of page' line and 'cursor' line+1 and then, after line command processing, re-position the 'top of page' to its label and perform 'normal' cursor position according to the 'cursor' line label, before removing the labels. (by 'normal' cursor processing I mean advance to next line, hugging the indentation level.)
|
|
|
Post by George on Aug 20, 2020 11:37:42 GMT -5
Stefan: OK, got it, needs a bit more logic. Attached below is a corrected version. BTW - Labels, Tags, User, LCmds etc. are all stored in the data structure for each line. (There are about 16 data fields for EACH text line) George SPFLite22.exe (478.5 KB)
|
|
|
Post by mueh on Aug 20, 2020 13:59:19 GMT -5
George: Enabled in OPT Reset screen position after Line Cmds and postioning after Delete/Repeat and scrolling down before Enter works now after 20233 lvl. There is a Problem when Get_Csr_LPtr is issued in Macro ( line and cmd ) . it gets back invalid numbers or 0 . Get_Csr_Col is okay . Thanks for this enhancement
|
|
|
Post by George on Aug 20, 2020 14:47:10 GMT -5
Robert: Basically, if someone does a lot of interactions (line commands etc.) before pressing Enter, they may be positioned far away from where the first of their line cmd interactions was entered. Then when Enter is pressed, the 1st line cmd interaction 'wins' (because it is first) and when Enter is pressed, the screen is positioned where the 1st interaction wants it. Which may be a long way from where the screen was positioned when Enter was pressed. And the user may simply 'not care' about seeing the effect of the command.
e.g. Enter D3 on a line at the top of the file. Scroll down to line 100, alter some text and press Enter. The screen would go back to where the D3 took effect.
This option basically "throws away" the positioning done by the line commands just prior to processing the Primary commands.
I actually like it, Stefan had a good idea in suggesting it.
George
|
|
|
Post by George on Aug 20, 2020 15:01:22 GMT -5
MUEH: Ok here's a version that adjusts the Get_Csr as well, let me know if it seems better. George SPFLite22.exe (478.5 KB)
|
|
|
Post by George on Aug 20, 2020 15:05:47 GMT -5
Robert: The intention is - that if I do a bunch of line commands 'along the way', like D, R, C/A, etc. and am now positioned somewhere else unrelated to those commands, I don't want to be positioned back at those commands to 'review' what happened, I just want to stay 'where I am' when I press (Enter). Like, do I really want to 'see' that some lines were deleted?
===> yeah that does sound reasonable - R
|
|
|
Post by mueh on Aug 21, 2020 0:14:52 GMT -5
 George: Get_Csr_LPtr returns now a negative nr which is the relative position from Top of screen . I'm shure you can solve this . Thanks
|
|