info about undo/redo stack

146 views
Skip to first unread message

Stefan Küng

unread,
Aug 4, 2022, 11:51:32 AM8/4/22
to scintilla-interest
Currently Scintilla does not provide an API to get a list of undos. It's only possible to check whether an undo is possible (i.e., something is in the undo buffer), and then do one undo at a time.
I'd like to propose an enhancement: provide a list of every undo, with a flag/description of what each undo would undo.
This would also apply to possible redos of course.
That way it would be possible to implement something like this:
Screenshot 2022-08-04 174517.pngScreenshot 2022-08-04 174553.png

(screenshot from VisualStudio)

I would prefer this implemented in Scintilla directly, but if that's not something feasible then a notification like SC_UNDO_ADDED/_REMOVED/_CLEARED, SC_REDO_ADDED/_REMOVED/_CLEARED with additional info about what got added/removed to/from the stacks might help to implement this outside Scintilla.

Neil Hodgson

unread,
Aug 5, 2022, 11:26:03 PM8/5/22
to Scintilla mailing list
Stefan Küng:

> I would prefer this implemented in Scintilla directly, but if that's not something feasible then a notification like SC_UNDO_ADDED/_REMOVED/_CLEARED, SC_REDO_ADDED/_REMOVED/_CLEARED with additional info about what got added/removed to/from the stacks might help to implement this outside Scintilla.

Exposing undo history may make it more difficult to change the implementation of undo.

An issue here is that undo actions may also change even though they currently don't. Currently, a sequence of adjacent changes of one type may be interpreted as a single undo step. A future version of this may amend an action with additional insertions/deletions. The text of each change is currently stored but this isn't always necessary (insertions are available from the document) so may be changed for better memory efficiency.

Identifying particular actions in history is an area of uncertainty and the recent change history feature tried a couple of approaches (action index and an incrementing ticket vendor) before finding that something simpler (original/modified/saved) was sufficient for that feature.

In the future, undo may be a tree instead of a stack in order to preserve abandoned branches and ensure no changes are lost. Current step, save point, and detach point (where connection to the save point is lost) information may also be needed.

> with a flag/description of what each undo would undo.

Which code would implement the description (Scintilla or app) and what would the API be? How would it deal with grouped actions?

> notification like SC_UNDO_ADDED/_REMOVED/_CLEARED, SC_REDO_ADDED/_REMOVED/_CLEARED

This needs more details including what context information goes into the notification. How does it sequence actions - when a branch is abandoned do the _REMOVEDs go from first to last or the reverse.

Neil

seasoned_geek

unread,
Aug 7, 2022, 5:45:54 AM8/7/22
to scintilla-interest
Not that my opinion matters, but I need to concur with Neil here.  For my own editor the places where I needed something like this I ended up creating my own storage and tied those to different keys.

Your screen shot looks really nice and quaint. I don't say that to be condescending or insulting if it seems to come across that way.

The problem is Undo has to Undo large thousand+ line selections that got cut. A change case over a selected range. A substitution over a selected range. These are in addition to the simpler stuff you listed.

What's the purpose of the list? So a user can pick the Undo they want, right? How can you Undo change case over a selected range when one of the Undos you skipped to get there nuked part of the range? The range currently associated with the Undo is invalid. There may well be characters now filling up that range, but they weren't part the original "Do" so the Undo will now be invalid.

I understand the sentiment. I've used Scintilla based editors and wondered "Is the thing I want to Undo still in the Undo buffer?" Thankfully I was able to design around that for my Scintilla based editor because I modeled EDT __and__ implemented a deep backup history.

backup-history.png

Every save creates a backup of the previous image up to a user controlled depth. You can look at your history and if you remember about when you did it you can open the file to select out what you need to "undo" your oops! Eventually I will get around to providing DIFF capability across the backup versions and current code. Just not there yet. Have other things to get done and a life to lead. Btw, this should pair well with Neil's new Scintilla feature that I haven't completely read up on yet. That version control diffing thing or whatever. Need to put that on my never ending todo list.

There is more than one way to skin a cat.

Exposing an Undo list is just fraught with peril. What happens when it is a cut with control characters in it because the user is editing a binary file?

A not too risky compromise, since an end user really has not idea when their editor clears the Undo list, would be to provide a CURRENT_UNDO_AVAILABLE_DEPTH. Name could be whatever, but knowing there are only 4 could save the user some pain if they remember more than 4 changes have happened since what they want.

Don't forget, Undo includes character typing . . . There's a lot more in the Undo can-o-worms than people realize.

Neil Hodgson

unread,
Aug 7, 2022, 5:59:19 PM8/7/22
to Scintilla mailing list
Another reason that some want access to undo history is to restore that history when the app is restarted.

Its likely that access to undo history will be implemented in the future but its not obvious how to do this well.

Neil

Austin Green

unread,
Aug 7, 2022, 6:36:03 PM8/7/22
to scintilla...@googlegroups.com
On Thu, 4 Aug 2022 08:51:32 -0700 (PDT)
Stefan Küng <torto...@gmail.com> wrote:

> ... a notification like
> SC_UNDO_ADDED/_REMOVED/_CLEARED, SC_REDO_ADDED/_REMOVED/_CLEARED with
> additional info about what got added/removed to/from the stacks might help
> to implement this outside Scintilla.

I would be keen to get these notifications too, for the purpose of synchronising the cursor position with undo/redo actions. Of course it would be nice if Scintilla did that for me, but I gather (having asked before) that there are difficulties in some complex scenarios; nevertheless I could implement it locally for my simple case.

Austin.

seasoned_geek

unread,
Aug 8, 2022, 5:22:45 AM8/8/22
to scintilla-interest
On Sunday, August 7, 2022 at 4:59:19 PM UTC-5 Neil Hodgson wrote:
Another reason that some want access to undo history is to restore that history when the app is restarted.

Its likely that access to undo history will be implemented in the future but its not obvious how to do this well.
 

That's the other reason I went with backup file versions. Well, the FILES-11 system that existed for both RSTS/E and OpenVMS had file versioning by default. I also have live cache files so getting Undo back isn't that big of a deal.

Since my editor is based on grace and functionality of EDT I will tell you from the 10,000 foot level how EDT "solved" this problem.

EDT started out in the PDP-11 world. No user process ever had more than 64K WORDS to operate in. That was for OS, Executable, and data. The "undo history" was stored in a .JOU (journal) file. It was basically an RMS indexed file with variable length records. (We didn't have to deal with the possibility of 10K line cut because the compilers of the day couldn't feed that many lines in.)

Whenever your process got shot out of the saddle for whatever reason, this would leave the .JOU file laying around. Old hands would perform a DIRectory and look for the .JOU file. When found

EDT/RECOVER fred.cob

This would then entertain the developer by loading the "current" source file version and then visually replaying every modification stored in the .JOU file until it displayed the message "file recovered" or some failure message.

Too many young whipersnappers didn't bother to do this so EDT itself got modified to always check for the .JOU file. It would prompt in its little prompt-line region

JOURNAL FILE FOUND . . . would you like to recover (Y/n)?

Answering yes allowed you to be entertained as your 4+ hour edit session that failed to save got replayed before your eyes. Every navigation, every character typed, deleted, blocks moved/deleted, etc. EDT was a multi-buffer editor. You edited a single file, but you could manually create as many buffers as your user quota allowed for RAM and file handles. Unlike later PC editors that believed they were such hot stuff because they allowed a developer to have cut buffers 1-99 they could choose to paste back in, our only real limit to these were how many 6-character-not-starting-with-a-number names we could come up with.

The x86 platform chose not to provide native indexed files. Today you could probably use SQLite with the last column being a BLOB. Theoretically you could do an in-memory database, but I wouldn't. Somewhere someone will have a machine with < 4GB of RAM yet need to edit a really big file.

SQLite insulates the world from additions (but not deletions) of columns and tables.

Despite what many in the x86 world believe, it's not a sin to write to disk.

Stefan Küng

unread,
Aug 10, 2022, 3:13:32 PM8/10/22
to scintilla-interest
On Sunday, August 7, 2022 at 11:45:54 AM UTC+2 rol...@logikalsolutions.com wrote:
Not that my opinion matters, but I need to concur with Neil here.  For my own editor the places where I needed something like this I ended up creating my own storage and tied those to different keys.

Your screen shot looks really nice and quaint. I don't say that to be condescending or insulting if it seems to come across that way.

The problem is Undo has to Undo large thousand+ line selections that got cut. A change case over a selected range. A substitution over a selected range. These are in addition to the simpler stuff you listed.

What's the purpose of the list? So a user can pick the Undo they want, right? How can you Undo change case over a selected range when one of the Undos you skipped to get there nuked part of the range? The range currently associated with the Undo is invalid. There may well be characters now filling up that range, but they weren't part the original "Do" so the Undo will now be invalid.

just to be clear: the list is shown so that if a user selects an item way down the list, all items above get selected as well.
That means that if the user selects an item way down the list, all items up to that item will get undone, not just the clicked item.

The use case is that users can select an item way down the list and undo all at once instead of hitting Ctrl+Z repeatedly.
 
Reply all
Reply to author
Forward
0 new messages