#include "undostack.h"
#include <string.h>
+// undo can be incremental or direct, from key to current
+//#define UNDO_INCREMENTAL
+
UndoStack::UndoStack() : List<UndoStackItem>()
{
current = 0;
UndoStackItem* UndoStack::push()
{
-// current is only 0 if before first undo
- if( current )
- current = insert_after(current);
- else
- current = insert_before(first);
-
-// delete future undos if necessary
- if( current && current->next ) {
- while( current->next ) remove(last);
- }
-
// delete oldest 2 undos if necessary
if( total() > UNDOLEVELS ) {
- for( int i=0; i<2; ++i ) {
- UndoStackItem *second = first->next;
- char *temp_data = 0;
-
-
- if( !second->is_key() ) {
- temp_data = second->get_data();
- }
- remove(first);
-
-// Convert new first to key buffer.
- if( !second->is_key() ) {
- second->set_data(temp_data);
- }
- delete [] temp_data;
+ UndoStackItem *item = first, *key = item;
+#ifdef UNDO_INCREMENTAL
+ for( int i=2; --i>=0; item=item->next );
+#else
+ for( int i=2; --i>=0; item=item->next )
+ if( item->is_key() ) key = item;
+#endif
+ char *data = !item->is_key() ? key->get_data() : 0;
+ while( first != item ) {
+ if( current == first ) current = first->next;
+ delete first;
+ }
+ if( data ) {
+ item->set_data(data);
+ delete [] data;
}
}
+// current is only 0 if before first undo
+ current = current ? insert_after(current) : insert_before(first);
+// delete future undos if necessary
+ while( current->next ) remove(last);
return current;
}
}
}
-// undo can be incremental or direct, from key to current
-//#define UNDO_INCREMENTAL
-
class undo_record {
public:
int32_t new_ofs;
return hp;
}
-UndoLine::UndoLine(UndoHash *hash)
+UndoLine::UndoLine(UndoHash *hash, char *tp)
{
- this->txt = 0; this->len = 0;
+ this->txt = tp; this->len = 0;
this->hash = hash;
hash->occurs[va] = hash->occurs[vb] = 1;
}
void UndoVersion::scan_lines(UndoHashTable *hash, char *sp, char *ep)
{
- append(new UndoLine(hash->bof));
for( int line=1; sp<ep; ++line ) {
char *txt = sp;
while( sp<ep && *sp++ != '\n' );
++ln->hash->occurs[ver];
append(ln);
}
- append(new UndoLine(hash->eof));
}
UndoVersion alines(va), blines(vb);
char *asp = data, *aep = asp + data_size-1;
char *bsp = prev, *bep = bsp + prev_size-1;
+ alines.append(new UndoLine(hash.bof, asp));
+ blines.append(new UndoLine(hash.bof, bsp));
alines.scan_lines(&hash, asp, aep);
blines.scan_lines(&hash, bsp, bep);
-// trim suffix
int asz = alines.size(), bsz = blines.size();
+// trim matching suffix
while( asz > 0 && bsz > 0 && alines[asz-1]->eq(blines[bsz-1]) ) {
- --asz; --bsz;
+ aep = alines[--asz]->txt; alines.remove_object();
+ bep = blines[--bsz]->txt; blines.remove_object();
}
+// include for matching last item
+ alines.append(new UndoLine(hash.eof, aep));
+ blines.append(new UndoLine(hash.eof, bep));
+ hash.eof->line[va] = asz++;
+ hash.eof->line[vb] = bsz++;
int ai = 0, bi = 0;
while( ai < asz || bi < bsz ) {