diff options
-rw-r--r-- | parser.cpp | 7 | ||||
-rw-r--r-- | qbuffers.cpp | 28 | ||||
-rw-r--r-- | qbuffers.h | 23 |
3 files changed, 54 insertions, 4 deletions
@@ -957,6 +957,13 @@ State * StateECommand::custom(gchar chr) { switch (g_ascii_toupper(chr)) { + case 'F': + BEGIN_EXEC(&States::start); + if (!ring.current) + return NULL; /* FIXME */ + ring.close(); + break; + case 'X': BEGIN_EXEC(&States::start); undo.push_var<bool>(quit_requested); diff --git a/qbuffers.cpp b/qbuffers.cpp index e72c730..f4212d7 100644 --- a/qbuffers.cpp +++ b/qbuffers.cpp @@ -190,6 +190,22 @@ Buffer::close(void) "Removed unnamed file from the ring."); } +void +Ring::UndoTokenEdit::run(void) +{ + /* + * assumes that buffer still has correct prev/next + * pointers + */ + *buffer->buffers.le_prev = buffer; + if (buffer->next()) + buffer->next()->buffers.le_prev = &buffer->next(); + + ring->current = buffer; + buffer->edit(); + buffer = NULL; +} + Buffer * Ring::find(const gchar *filename) { @@ -283,12 +299,18 @@ Ring::close(void) { Buffer *buffer = current; + buffer->dot = editor_msg(SCI_GETCURRENTPOS); buffer->close(); current = buffer->next() ? : first(); - if (!current) - edit(NULL); + /* transfer responsibility to UndoToken object */ + undo.push(new UndoTokenEdit(this, buffer)); - delete buffer; + if (current) { + current->edit(); + } else { + edit(NULL); + undo_close(); + } } Ring::~Ring() @@ -143,6 +143,7 @@ class Buffer { run(void) { buffer->close(); + /* NOTE: the buffer is NOT deleted on Token destruction */ delete buffer; } }; @@ -168,7 +169,7 @@ public: g_free(filename); } - inline Buffer * + inline Buffer *& next(void) { return LIST_NEXT(this, buffers); @@ -206,6 +207,26 @@ public: }; extern class Ring { + /* + * Emitted after a buffer close + * The pointer is the only remaining reference to the buffer! + */ + class UndoTokenEdit : public UndoToken { + Ring *ring; + Buffer *buffer; + + public: + UndoTokenEdit(Ring *_ring, Buffer *_buffer) + : UndoToken(), ring(_ring), buffer(_buffer) {} + ~UndoTokenEdit() + { + if (buffer) + delete buffer; + } + + void run(void); + }; + LIST_HEAD(Head, Buffer) head; public: |