Re: Saving selection into undo history

Neil Hodgson <[email protected]> Sat, 1 Feb 2025 03:31:04 -0800 (PST)
Newsgroups gmane.comp.lib.scintilla.devel
Message-ID <[email protected]>
   There's an updated version of this feature that fixes some bugs and uses 
less memory.

   Instead of an 80-byte (plus at least 40 bytes of linked data) 
SelectionSimple structure based on the Selection structure used for the 
active selection, selections are saved in a text form that often takes 24 
bytes. A single selection from positions 12 to 34 with 5 virtual spaces may 
look like "12-34v5". There's provision for multiple selections and 
rectangular selections and some other details.

   This string format is also an easy way of storing the shape and ranges 
of selections when switching documents so there are new APIs 
SCI_GETSELECTIONSERIALIZED and SCI_SETSELECTIONSERIALIZED and SciTE now 
uses them. I'm a bit conflicted on these APIs as they are convenient but 
not strictly necessary which is something I've tried to avoid in Scintilla 
since expanding the API scope adds to maintenance costs. Exposing a 'little 
language' for selections raises concerns with maintaining compatibility so, 
for now, they are documented for use within a session but the format may 
change between Scintilla releases. Search SciTE for "SelectionSerialized" 
for some example code.

   One of the issues that scared me off implementing undo selection history 
earlier was that selections are view state and there may be multiple views 
on a document. The implementation places this data in the Document indexed 
by the view (EditModel object). This works by adding a ViewState base class 
to Document.h then each Document holds a map of void* to 
shared_ptr<ViewState> where the void* is actually the address of the view 
object. The EditModel then defines a ModelState subclass of ViewState to 
hold any data (currently just the undo selection history) that the view 
needs to associate with a Document. That allows the view to retrieve the 
history whenever a Document is attached to that view.

   There is a TruncateUndo method on ViewState that allows the Document to 
tell the ViewState/ModelState that undo steps have been deleted so it can 
delete any selections associated with the steps. That was a problem during 
development as I initially wanted a mechanism that could be implemented in 
the application if the application had more needs (like associating 
explanations with undo steps) but that was more difficult. Because 
shared_ptr is used, the ModelState will be freed when the Document is 
freed. However, if a Document is still live but a view is deleted then the 
ModelState for the view is not freed. This case should be rare in practice 
as most applications have simple view lifetimes - either a separate view is 
allocated for each document or a fixed set of views are created that switch 
between documents. It could be fixed with a central repository of 
View/Document relationships but sharing more state between subsystems looks 
like a jump in complexity to me.

The committed changes can be examined either in the repositories

hg clone http://hg.code.sf.net/p/scintilla/code scintilla 
hg clone http://hg.code.sf.net/p/scintilla/scite 

or from 

https://www.scintilla.org/scite.zip Source 
https://www.scintilla.org/wscite.zip Windows executable (64-bit) 

Neil

-- 
You received this message because you are subscribed to the Google Groups "scintilla-interest" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To view this discussion visit https://groups.google.com/d/msgid/scintilla-interest/f6947bf7-b7f6-48e4-9b87-a2ad7fd37b1bn%40googlegroups.com.