* * *

Author Topic: TATSynEdit -- a bit of rearchitecture?  (Read 1130 times)

EganSolo

  • Jr. Member
  • **
  • Posts: 98
TATSynEdit -- a bit of rearchitecture?
« on: January 23, 2017, 03:22:10 am »
I like the way TATSynEdit is architected. It's relatively straightforward and makes a lot of sense. Please see the UML class diagram attached below to see what I mean. There's one area that might benefit from a bit of improvement. Currently, text events are published using the OnLog event handler. The problem is that the event being published does not represent a logical unit of work. Consider the following bit of hypothetical code in an editor using the TATSynEdit component:

Code: Java  [Select]
  1.    a := b ; }
  2.  

Suppose the user now selects the 'a' and replaces it with 'c':
Code: Java  [Select]
  1.   c := b ; }
  2.  

This one action results in two events being fired: One that deletes the original line and a second that sets the line to the modified content, but the logical unit of work is that 'a' has been replaced with 'c'. 

Instead, if we have an OnLog event as follows OnLog(set_TextReplaced, 100, 3, 1, 1, 'a','c'), where set_TextReplaced is a value in a StringEventType enumeration then we would be able to react to the logical unit of work. This would be more efficient and easier to code for.

So, what I am suggesting is to enrich the TATStringsLogEvent as follows:
Code: Pascal  [Select]
  1.     TATSTringLogEvent =  procedure(Sender: TObject; anEventType : StringsEventType;
  2.                                                     const aLineIndex, aColdIndex, anInitialLength, aNewLength: integer;
  3.                                                     const anInitialText, aNewText: String);
  4.  

The new event type would then tell us
  • eventType: The type of event: set_TextReplaced, set_TextDeleted, set_TextInserted, set_LineSplit, set_LineJoined
  • anIndex: The index of a line[. In case of a line break, that is the index of the line being broken. In case of a line merge, that is the index of the line being merged with the previous line.
  • aStartCol: The index of the starting column. In case of a line break, that would be the column where the break is happening. In case of a line merge, that is set to 0.
  • anInitialLen: the length of the affected text. In case of set_TextReplaced and set_TextDeleted, that's the length of the text being replaced or deleted. Otherwise, it's zero.
  • aNewLen: In case of set_TextInserted, set_TextSplit and set_LineJoined, that would be the length of the text inserted, or the portion of the text moved to the new line, or the length of the text that's moving to the previous line.
  • anInitialText, aNewText are self explantory

This would then require that this event be fired from outside of SetLine since it is more holistic. It would require changes to the TATStrings class and perhaps to the DoCommand in TATSynEdit. But I don't think those changes are very significant in terms of code. I think I can introduce those changes myself but I don't want to touch this code before I hear back from Alex.

Any thoughts?



Alextp

  • Sr. Member
  • ****
  • Posts: 417
    • UVViewSoft
Re: TATSynEdit -- a bit of rearchitecture?
« Reply #1 on: January 24, 2017, 01:25:12 am »
OnLog is ONLY for EControl engine.Yes its useless.I made another one
TATStrings.OnChange,  TATStringsChangeEvent = procedure(Sender: TObject; ALine: integer; AChange: TATLineChangeKind) of object;
it's here for long. It needs more params?

EganSolo

  • Jr. Member
  • **
  • Posts: 98
Re: TATSynEdit -- a bit of rearchitecture?
« Reply #2 on: January 24, 2017, 05:40:55 am »
Hey Alex,

Thanks for the reply and for addingOnChange. I just downloaded the new version. It is definitely an improvement on OnLog. If I'm understanding this correctly, you have:
  • cLineChangeEdited: the content of the line has been modified but the line was neither inserted nor deleted.
  • cLineChangeAdded: A brand new line has been added.
  • cLineChangeDeleted: A line has been deleted.
  • cLineChangeDeletedAll: I suspect that this means all lines have been deleted? Would that be equivalent to cLineChangeCleared?
Now consider the following bit of code.
Code: Pascal  [Select]
  1.    If a < b then begin //current line

Suppose the user hits enter before then. You would get the following:
Code: Pascal  [Select]
  1.    If a <  b
  2.   then begin

Three events take:
  • The initial line was changed.
  • A line was inserted and
  • The indentation changed that line.
But in truth, it's one user event: the line was split. The logical unit of work is that one line was split, but OnChange will fire at least twice, one for the line that was changed and a second time for the line that was inserted and these two events do not seem related but in fact they are.

I would suggest you extend the event types to include:
  • cLineChangeSplit: Occurs when the user splits a line (hits enter. Naturally, I could override DoCommand and intercept that action but an event from TATString would be more consistent).
  • clineChangeMerged: occurs when a user hits the backspace as the first character or when they delete a block of characters from the end of line to the start of the second.
Also, for cLineChangeEdited, cLineChangeSplit it would be great to indicate at which column the change started and its length. Reacting to an event because the user hit one key (which is the most common event) does not require as much work as when the user paste a string.

What do you think?

Alextp

  • Sr. Member
  • ****
  • Posts: 417
    • UVViewSoft
Re: TATSynEdit -- a bit of rearchitecture?
« Reply #3 on: January 24, 2017, 10:08:20 am »
Quote
>cLineChangeSplit: Occurs when the user splits a line (hits enter. Naturally, I could override DoCommand and intercept that action but an event from TATString would be more consistent).
Its hard to do it in Strings. Strings gets LOW level acts. Hitting enter is HIGH level act: only ATSynEdit knows about it, ATStrings dont know

OnChangeEx needed? not in Strings.

EganSolo

  • Jr. Member
  • **
  • Posts: 98
Re: TATSynEdit -- a bit of rearchitecture?
« Reply #4 on: January 24, 2017, 08:22:20 pm »
I agree. The way I'd go about it is to (a) add the OnChangeEx to the DoCommand_XXX methods in TATSynEdit. Also, I would add two more commands one for splitting a line and another for joining two lines and add the event handler there.

DoCommand_XXX implement the user's action as an atomic operation. Capturing that event would be extremely helpful for implementing a highlighter that does not depend on EC-Control.

Alextp

  • Sr. Member
  • ****
  • Posts: 417
    • UVViewSoft
Re: TATSynEdit -- a bit of rearchitecture?
« Reply #5 on: January 24, 2017, 08:33:28 pm »
So you want to add OnChangeEx to DoCommand_nnn. not sure i need, not sure how app can read OnChangeEx+OnChange. you may test it first.

I dont get - what about hiliter?

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus