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:

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:

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.

OnLog is ONLY for EControl engine.Yes its useless.I made another oneTATStrings.OnChange, TATStringsChangeEvent = procedure(Sender: TObject; ALine: integer; AChange: TATLineChangeKind) of object;it's here for long. It needs more params?

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.

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.