Martin Friebe schrieb: >> My vision deviates a bit from this in the sense that TAbstractSynEdit >> would just be an abstraction (or dedicated implementation) of a >> cleaner text manipulation interface (as TStrings won't cut it), which >> would also implement transparent/automatic/implicit 'undo' handling. >> Then each command would be a class, probably inheriting from TAction. >> > Just read this, .... > > I had the same idea, and am in progress with something like this. > I needed it to abstract layers of functionality. for example trimming > trailing spaces. If it should work as a transparent plugin it needs > access to undo/redo.
IMO an abstract base class better should be a viewer, without text manipulation commands. This would allow to sort out problems related to undo/redo for debugging. > My current approach is: > > - I separated SynEdit.Lines from the internal textbuffer (so textbuffer > has no longer a need to be TStrings based (it still is, because i didn't > take the time to change it)) The TStrings approach isn't really bad. The virtual Get method can access any kind of buffer, and we don't have to introduce new names for the basic methods and properties, reducing possible confusion of the users of the component. > - I add a few basic methods such as > InsertText(x,y, substring); DeleteText,(x,y, len) ; BreakLine, > JoinLine (maybe InsertNewLine, DeleteEntireLine) [*] In my CharGrid I use a single basic function for insertion and deletion, with the Len indicating insertion (> 0) or deletion (< 0). This delta can be used to adjust the text size, also with undo/redo operations. It might be necessary to distinguish clearly between display and text positions, where display positions take into account folded blocks, tab expansion etc., which only affect the display. While display coordinates may be separated into row and column, other positions (bookmarks...) better should be given as single text/file offsets. [Where IMO 32 bits are sufficient for *text* file size/positions - a dedicated data type will allow for eventual customization] > - they can deal with undo and redo > - In SynEdit all operations can be reduced to the above (and don't > care about undo/redo) The undo/redo capabilities can be encapsulated in the text buffer object implementation, only the related methods have to be added to the TStrings interface. > Since TrailingSpaces is already a wrapper around the TextBuffer, it can > simply intercept those methods, and deal with them. Such a wrapper IMO disallows to change the trim option at runtime. I'd implement it only in the display code. > ---- > The only flaw I still have with this is, that currently all the > SynEditText* (wrappers around the actual textbuffer, doing, spaces, > tabs, folding....) are combining Display and Edit functionality. > > It would be nice to be able to write a TSynDisplay class first, and > inherit the editor from it.... FACK > [*] > of course insertText could detect newlines, but it adds complexity. It > will be simpler if SynEdit keeps control of this level, and InsertText, > only operates on the current line As mentioned above, a single text offset value is sufficient for all text (buffer) operations. The text buffer must not necessarily be organized by lines, the object *only* has to map between line numbers and text positions for display references. Two such mapping functions are required, one for absolute lines in the entire text (in the text buffer object), and another one for virtual (folded) display row numbers (in the block folding object). DoDi _______________________________________________ Lazarus mailing list [email protected] http://www.lazarus.freepascal.org/mailman/listinfo/lazarus
