|
Post by George on Nov 30, 2023 12:53:06 GMT -5
I've just corrected the "N" bug.
'I' will insert the MASK and position to the 1st Mask Char. If the mask is empty, it positions to the previous line's indent and if the previous line is blank, it goes to column 1.
'N' does the same, but ignores the MASK data.
George
|
|
|
Post by George on Nov 30, 2023 13:01:20 GMT -5
Stefan: I'm just wrapping up another project, so I'll have a go shortly. It's going to be tricky, those KB routines always seem to be trivial till you get right in there and go "OMG what a mess"!
I think one starting rule is that TabBNDS being active overrules normal BNDS setting. There's no way I'm going to 'interleave' those. And basically BNDS is used mainly to put a fence around CHANGE ALL type activity.
George
|
|
|
Post by Stefan on Nov 30, 2023 13:08:39 GMT -5
Sounds fine.
I thought the normal BOUNDS setting only affected commands like FIND, CHANGE, etc., that use the universal 'search' routine and data-shifting line commands like >> and )).
Maybe the coding of the latter is also involved in the Insert and Delete primitives.
|
|
|
Post by George on Nov 30, 2023 13:13:21 GMT -5
Stefan: I agree on that, I'm sure they have no effect on normal KB data entry. Just a comment that if I run into a collision, I have chosen which way to go.
George
|
|
|
Post by Robert on Nov 30, 2023 13:22:04 GMT -5
George,
I am concerned about your main assumption: "When multiple TAB stops are specified, the data is treated as being in columns, with the bounds of each column defined by the TAB stops."
You know how long I have used SPF editors. I can tell that it is likely under 1% of all editing I have ever done needed or treated tab stops as the boundaries of columns. Rather, the overwhelming lion's share of my tab stops were used for two reasons:
(1) Move the cursor quickly to fixed columns for things like Cobol PIC and VALUE clauses (2) Move the cursor to get to a desired comment region
Maybe I am missing something, but based on as much of your writeup as I understand, I don't think I would ever use this feature. Could someone explain to me why such things are needed. I'd pay a (US) dollar for a clue.
---
Stefan,
in my Keymap, I use {N} for Ctrl-Enter. Whenever I want to get some blank lines, I use Ctrl-Enter. I pretty much never use an actual N line command (and actually NEVER use the I command). Just Ctrl-Enter. So, not ALL of us have your keyboard expectations. I did use "I" at first as a new user of SPFLite, but when I got into the mode of heavily influencing George, the N command was one of the first new things he did for me. I never looked back.
I don't understand one thing you said. I3 is perfectly legal and produces 3 temporary blank lines. Yes, you do need enter, otherwise "I" won't know you asked for it, just like all other line commands.
I think if you're ever going to get exactly what you want, and you want some VERY specific actions, you need to precisely list them all out.
R
|
|
|
Post by George on Nov 30, 2023 13:38:47 GMT -5
Robert: This is one of those items much like a lot of the suggestions from you over the years. I would indicate that it doesn't interest me in the slightest, and you would come back with - well, you shouldn't reject an idea just because you wouldn't use it.
I would use this with a single tab stop in my comment column. Then I could edit the code on the left hand side without the comments moving left and right while I edit.
George
|
|
|
Post by Robert on Nov 30, 2023 14:08:27 GMT -5
Of course, even adding such primitives wouldn't end the issue, because then, you'd have to keymap it. If there were a primitive I could set to some fixed column for a comment, I might want to put it on Alt C, but that one I have reserved for Power Copy within Power Typing mode. It's too late for me to change.
Am I saying you shouldn't implement because I personally won't use it? No. To be honest, a lot of stuff you have done recently are things I wouldn't use, but as long as you don't break stuff I do care about, it won't shake my faith in you.
But, it seems like there ought to be a way to enhance the (Column/nn) primitive to do what you wanted. Here's a crazy idea. Suppose this primitive could be made symbolic, so that you could do something like,
(Column/comment)
and then, you could make a SET value like,
SET COLUMN.COMMENT = 21
Then you could tweak it as needed. Perhaps (COLUMN/nn) could be parameterized by other things, such as the TAB positions you describe above.
Just ideas to kick around ...
R
|
|
|
Post by George on Dec 1, 2023 11:14:39 GMT -5
I've been thinking about this, and the handling of (Tab) really should be left alone, so I think a new (TabShift) will be neded. So, the revised suggestion looks like this: (See items in RED below)When multiple TAB stops are specified, the data is treated as being in columns, with the bounds of each column defined by the TAB stops. (TabBNDS)
This will toggle ( ON / OFF) a new internal Edit flag. This will affect the operation of the following other KB Primitives. If ON it will show in the StatusBar box which contains INS/OVR/DIN, as TABINS/TABOVR/TABDIN. Editing functions will be altered to be sensitive to these Tab-Columns. The affected primitives will be: (EraseEOL)When TabBNDS is active, it will replace data from cursor position to the end of the current Tab-Column with blanks. If no more tab stops, it behaves like normal (EraseEOL). (Delete)When TabBNDS is active, it will delete data only within the current tab-column. If no more tab stops, it behaves like normal (Delete). (DataDelete)
When TabBNDS is active, it will delete data (in DataDelete mode) only within the current tab-column. If no more tab stops, it behaves like normal (Delete). (Tab) The (Tab) key will be unaffected by TabBNDS. it will act just as it does currently
(TabShift)
When TabBNDS is active, this new primitive will, instead of just moving the cursor, insert blanks so the data at the cursor position is shifted with the cursor to the next tab stop. If no more tab stops, or when TabBNDS is inactive, (TabShift) acts as a (Tab) key. Resetting TabBNDS TabBNDS mode is reset by a 2nd (TabBNDS) key or by any of the (SetINS) (SetOVR) (SetDIN) or (ClearInsert) primitives. Typing Characters- When TabBNDS are Active
- In TABINS Mode
- Acts as if a BNDS SCol ECol were in effect, where SCol and ECol are the bounds of the current tab-column. Current data is shifted right. If the data exceeds the tab column width, then the SCol/ECol bnds are removed and shifting continues into the next tab column (which will set new SCol ECol bounds for the next column).
- TABOVR Mode
- There is no change to typing in TABOVR mode
- TABDIN Mode
- Acts as if a BNDS SCol ECol were in effect, where SCol and ECol are the bounds of the current tab column range. Current data is shifted right in DataInsert Mode; that is, stretches of blanks within the column are 'used up' to accommodate shifting. If the data exceeds the tab column width, then the SCol/ECol bnds are removed and DataInsert type shifting continues into the next tab-column (which will set new SCol ECol bounds for the next column).
More comments invited. George
|
|
|
Post by Stefan on Dec 1, 2023 12:44:37 GMT -5
George, I have a question about (TabSHift) (Tab) is a "one-shot" primitive that moves the cursor. It is unaffected by (TabBNDS). If you want jump over several tabs, you must press it repeatedly. Why would (TabShift) be different, or, put another way, why does (TabShift) require (TABBNDS) to be in effect to 'do its thing'? Afterall, (TabShift) is just like (Tab) but it moves the data as well. The (TABBNDS) is therefore temporarily implied. Otherwise, folks would have to use something like "Save current Insert mode - Enable TabBnds - Do Tabshift - Restore-previous Insert mode.
Given the relative proximity of the TAB, SHIFT and CTRL keys on the left of the keyboard, users would probably assign the TAB key as: Normal: (TAB) - SPFLite default, unchanged Shift: (BackTab) - SPFLite default, unchanged Ctrl: (TabShift) - new function
|
|
|
Post by Robert on Dec 1, 2023 12:52:07 GMT -5
For me, I have Ctrl tab mapped to SWAP PRIOR, which comes in real handy, and ctrl shift tab is unused (too many keys to type for me)
r
|
|
|
Post by George on Dec 1, 2023 13:26:24 GMT -5
Stefan: My thought was that the TAB key (normal) could be mapped to (TabShift), meaning no 'free' key would need to be assigned. When (TabBNDS) is OFF, it's just the plain old (Tab) key, when (TabBNDS) is active, it becomes (TabShift)
When I realized that modifying (Tab) handling when (TabBNDS) was on meant no normal (Tab) availability I wanted to keep it around somehow. I was just trying to picture what KB activity would be like if working in columns.
Assuming (TabShift) was uniquely mapped works as well. I'll revise the description again.
That's what comments are for.
George
|
|
|
Post by Robert on Dec 1, 2023 13:31:45 GMT -5
You know, George, I have often thought that it would be cool if keyboard primitives could be conditional. Kind of like:
(If)(IsTabBnds)(Tab)(Else)(TabShift)(EndIf)
Yes, I know. But, you have to admit, it's kinda cool.
R
|
|
|
Post by Stefan on Dec 2, 2023 4:13:24 GMT -5
George,
I'm still trying to understand EXACTLY how (TabBnds) affects existing INS/DIN/OVR typing modes and their related cousins, the (Delete) and (DataDelete) primitives.
Help me out here, please, am I missing something?
OVR mode As it happens, my "default" typing mode is OVR. If I want to insert data, I switch to DIN or sometimes INS, depending on the effect I desire, and cancel the insertion mode by either (ClearInsert) or let (Enter) do it for me. In OVR mode, typed characters replace existing characters; nothing shifts left or right. I think the 'end-point' is irrelevant in this scenario, especially as we already decided that, even with (TabBnds) ON, when you reach the 'end-point' you can just keep typing.
DIN mode Has the ability to 'shift' data to the right, compressing sequences of blank characters within the current data. There either ARE blanks at the end of the data within the current tab field, or NOT.
I think the 'end-point' is irrelevant in this scenario as well, especially as we already decided that, even with (TabBnds) ON, when you reach the 'end-point' you can just keep typing/shifting.
INS mode Has the ability to 'shift' data to the right and hence needs to 'compress' multiple blanks at the end of the current tab field. If there are none, the 'keep typing' or in this case 'keep shifting' rule applies.
So the 'end-point' IS relevant for INS.
(Delete) Has the ability to 'shift' data to the left and hence needs to 'add' blanks at the end of the current tab field. So the 'end-point' IS relevant for (Delete).
(DataDelete) Has the ability to 'shift' data to the left and hence may(!) need to 'add' blanks at the end of the current tab field. So the 'end-point' IS relevant for (DataDelete).
In short, I think (TabBnds) only applies to: a) INS mode, which has the ability to 'shift' data to the right and hence needs to 'compress' blanks at the end of the current tab field. b) (Delete) and (DataDelete), which have the ability to 'shift' data to the left, so need to 'know' where to add the blanks.
I appreciate that in the case of (Delete) and (DataDelete), you may not need to add any blanks if there is no further data on the same line, but I expect those primitives already handle that scenario.
What do you think?
|
|
|
Post by George on Dec 2, 2023 10:19:58 GMT -5
Stefan: You may be right, stuff like this usually 'falls out' when actually making the change and you look at the first code attempt and realize chunks of it simply don't apply.
It's very hard to visualize and describe each process accurately. It's sort of "I know what's a reasonable expectation when I see it". If it's put into detailed verbiage it usually takes so much that it's hard to grasp the basic intent.
This will certainly become a "let's try it out" and adjust based on experience type operation.
George
Further thoughts re Typing through a column boundary in DIN mode.
Should there be a distinction between "typing through" when the cursor itself is at the boundary, and "typing through" when the cursor is to the left and is 'pushing' characters across the boundary?
G.
|
|
|
Post by Stefan on Dec 3, 2023 6:34:02 GMT -5
George, I was also pondering the 'typing through' situations. it's untidy.
A bit of History...
My 3270 days are long since past and memory is unreliable, but I do recall that ISPF offered 'soft' tabs and 'hard' tabs. Soft tabs were just logical column tabs and (i think!) just allowed the 'cursor jumping' from tab stop to tab stop. They had no effect on the data. Really only useful for initial data entry, not so much for data EDITing. A remnant of the type-writer days.
This kind of setup is already available in SPFLite. (can you feel the BUT coming.... ok, here it is...)
But I always used 'hard' tabs (ie. 3270 attribute byte to start a new field) with NULLS ON to allow INSERT mode to work properly. This config meant that the 3270 would not allow inserted data to shift non-blank/NULL chars beyond the tab stop. If you tried, the keyboard would lock, requiring a RESET. This was perfect for column-oriented data like JCL (tabs at 12, 16 & 72), to code statements consistently without stuff accidentally spilling into col 72. If you did need continuous data, I think(!) you could to 'remove' the offending (or all?) hard tabs from that line with " Cursor on attr-byte & ENTER". The above behaviour is still useful for SPFlite users who use the product to edit mainframe data. As things stand, SPFLite doesn't provide what we/I had way back then.
And our initial 'type through' approach doesn't help.
What we're implementing in SPFLite is similar to the ISPF hard stop provision, except for the 'hard stop removal aspect'. We also have an opportunity to improve data entry support for example for files of fixed LRECL, avoid accidental spill beyond the desired record length, or pretect col 72 in JCL deck, etc.
An enhanced 'just type through'...
I'm unfamiliar with the practicalities and constraints inherent in the 'typing' code section, so I (happily) leave the possible implementation approach to you. However, let me suggest something like...
New concepts: (1) "Block" the keyboard when the chosen 'insert' mode cannot shift or enter any more data within the current tab field. By 'block' I mean "do not accept any keystrokes that enter a character". With (TabBnds) ON, this should be automatic. To visually alert the user to the 'block', perhaps you could EITHER - HIGHLITE the text within the current tab (plus a Beep?) OR
- Change the shape/size of the cursor Any such 'highlite' and 'blockage' should be removed when the cursor navigates away from the current tab.
(Alternatively, the 'alert' could be an error message like "Field full at column x", but I expect that requires screen redraw and thus an ATTN event with potentially undesirable side effects (line/primary commands, etc)).
(2) To continue typing on the same line, I suggest a (TabRelease) primitive to release the 'block', mappable to any user-chosen key or mouse button. This removes ALL tabs on this line, enabling 'type-through' as before, but with a twist!!
(TabRelease <c>) also removes ALL tabs on this line, except <n> refers to the column number which acts as a remaining Tab stop.
In files whose profile specifies a non-zero LRECL, (TabRelease) defaults to (TabRelease <LRECL+1>). If users also add a tab stop at LRECL+1 in the profile for files of fixed length, this will address a long-standing bug bear with fixed length data entry.
(3) Especially given the potential for handling fixed length records... - I think TABBNDS ON/OFF should be a profile setting as opposed to a primitive? It would activate/deactivate according to file type. - Should profiles specifying a non-zero LRECL, automagically inherit TABBNDS ON and a tab stop in column LRECL+1?
What do you think?
|
|