Time oriented undo

Last updated:

there are two kinds of undo system in common use. both have problems.

the first and most frequently used is the stack-based undo, where changes are pushed to a stack and undoing pops the last change from the stack. making a new change after undoing discards all popped items and adds to the stack from where the user had undone to. this is usually fine until it isn't, and then it's really frustrating.

imagine a user undoes some changes, starts making new edits and then regrets the decision. they can't revert to the state past the undo.

imagine a user is undoing and then accidentally makes a change. they've unintentionally lost access to the forward part of their undo history.

web browser history is the same principle. it's common to search something and then look in and out of web pages. it's also common to then be frustrated that you cannot see the actual path you took through results, because every time you back out to the results and click a new link, the page you backed out from is removed and you have to head to the browser history page, which is inevitably (though not necessarily) terribly designed.

this because both undo and browser history are really trees, not stacks, which has been noticed by various people and implemented in various programs, usually those designed for "advanced users".

that leads us to the issue with the tree: especially in the case of undo, it's usually clumsy to navigate. especially when you factor in the fact that advanced users like keyboard shortcuts, suddenly there a bunch more that are necessary.

there are also questions that arise: where to go when a user tries to redo at a final node when there were more changes further down the line in a different branch? surely there must be a good way to corroborate the changes (or maybe not).

both of these solutions violate the harrison human interface guidelines, either by not treating user input and discarding it without explicit consent (which is also something that should be avoided), or by being too complicated.

my proposed solution is a riff on the emacs way. emacs treats the act of undoing as a reversible editor action just like anything else which manipulates buffer text. so to redo, you actually undo the undo. this is powerful but unintuitive, which is why janky tree view solutions have been built on top of it.

actually emacs has the right idea, but like a lot of emacs the exposed interface is terrible.

i propose that instead, we keep the linear system, but make it time-oriented. here's how it works:

1. the user is always at the end of the timeline after manipulating a buffer.
2. to undo, they move backwards along the timeline, change by change. this is identical to how standard undo works.
3. from any point on the timeline, they can move forward again, as redo would allow.
4. if they manipulate a buffer, that must become the end of the timeline. instead of discarding anything further along, every change between the current point and the end is duplicated, its order reversed, and the new manipulation added.

time is linear, so keep the history linear. that's a guiding principle i just came up with. if we're calling it an undo history, a browser history, it should respect time first and foremost.

but won't clicking undo will get tiresome if my history keeps getting duplicated like that? probably. i discovered recently that the mechanical keyboard community were getting quite into rotary encoders (that's twisty knobs in everyday language). that article mentioned scrolling as one use case. i thought that was pretty cool actually, and since i want documents in celeste to only be scrollable in one dimension (up and down) seemed like a good use case. most documents are quite flexible in that regard. well, how amazing would it be to be able to scroll through space as well as time? extremely cool i thought.

(note: i just noticed that "history scrubbing" is listed on that page already. guess i need to improve my reading comprehension).

seeing as this proposal is probably not going to get picked up in the mainstream, i may as well propose an alterate reality (celeste) where things were different. one of those things is that scrolling through time with a handy knob is established functionality.