Okay, the caffeine hasn't fully kicked in, but this rattled around in my skull while I was out for my 4 mile walk yesterday and it won't leave until it comes out my fingers at a keyboard.
Admittedly Scintilla currently knows nothing about the file. We almost all have something along these lines in our code.
m_editWidget->setText(file.readAll().constData());
file.close();
m_editWidget->setUndoCollection(true);
m_editWidget->emptyUndoBuffer();
m_editWidget->setSavePoint();
m_editWidget->gotoPos(0);
m_isDirty = false;
In order to fix this, "history" problem and satisfy access to undo a bit of work and thought needs to go into the best way to make Scintilla aware of the current full file path and to adopt the JOUrnal file concept of EDT I mentioned in another thread.
Thinking out loud without thinking through here.
We need a SET_JOURNAL_LOCATION( int code, sptr_t optionalPath)
0 = current file with .jou or -jou appended
1 = User $HOME/.journal-files (most every OS has the concept of $HOME now
2 = use optionalPath - must be valid and writeable
Options 1 & 2 require name mangling like I've done in RedDiamond
so main.cpp of project A doesn't walk on the main.cpp journal of project B
All existing undo/redo code would need to be jettisoned, except for the hot keys.
At least two tables would need to exist in the SQLite (or whatever) database. Some thumbnail sketches.
CREATE TABLE DONE_TABLE( DONE_TS TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
DONE_SEQ INTEGER DEFAULT 0,
TYPE_CD INTEGER,
UNDONE_TS TIMESTAMP DEFAULT 0,
UNDONE_SEQ INTEGER DEFAULT 0,
REPEAT INTEGER DEFAULT 0,
/* whatever other fields, probably begin/end sptr_t*/
DOC_CHUNK BLOB,
PRIMARY KEY(DONE_TS, DONE_SEQ) );
CREATE TABLE UNDONE_TABLE ( UNDONE_TS TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNDONE_SEQ INTEGER DEFAULT 0,
TYPE_CD INTEGER,
DONE_TS TIMESTAMP DEFAULT 0,
DONE_SEQ INTEGER DEFAULT 0,
REPEAT INTEGER DEFAULT 0,
/* whatever other fields, probably begin/end sptr_t */
DOC_CHUNK BLOB,
PRIMARY KEY(UNDONE_TS, UNDONE_SEQ) );
The SEQ is needed because the timestamp on the x86 is kind of sad. Assuming individual keystrokes are being recorded, someone with a hot repeat key could write quite a few records within the same timestamp resolution.
At application start and via timer at just after midnight, current date is checked against date of most recent record in each table. If different SEQ reset to 1 for next added record. Otherwise, 1 to the highest sequence and keep going.
Exact content of the tables is not really the issue here. I know this probably isn't enough or close to it. The framework is what is important.
All freshly done stuff is in the DONE_TABLE. It's UNDONE_TS and UNDONE_SEQ is zero.
All freshly undone stuff is in the UNDONE_TABLE. The REPEAT integer is zero
When they REDO an Undone it goes back into the DONE_TABLE but now has UNDONE_TS and UNDONE_SEQ with non-zero values and the REPEAT value from the UDONE_TABLE. It also has a new TS and SEQ.
When they undo a REDO the record goes back into the UNDONE_TABLE with new TS and SEQ and an incremented REPEAT.
This lets the highlighting ignore full text replacements caused by Astyle, etc. because they can have different TYPE_CD. A few simple selects can determine UNDONE needing one highlight, DONE needing another highlight, REDONE, etc.
The external file removes the need for providing any API to expose undo history.
Clearing the history is a matter of deleting the rows in the tables. Undo and redo operations could be further restricted by TYPE_CD if needed.
The only sticky wicket is communicating to Scintilla the where for the JOUrnal file and trapping the possibility that "same location as source" is write protected directory. Perhaps it should always write to $HOME/.journal-files? Perhaps it should always demand a writeable journal path at start?
Just my 0.0002 cents.