diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-12-03 02:25:05 +0100 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-12-03 03:53:59 +0100 |
commit | 0c07fd231d6de047cc0037b0de37c691561e34fa (patch) | |
tree | f9f0a734b569030259d11188a74d32233b5cb9ec | |
parent | 1d44c8f0f75acb979a98d94e4dae6ff44d1accbf (diff) | |
download | sciteco-0c07fd231d6de047cc0037b0de37c691561e34fa.tar.gz |
organize buffer ring as a tail-q (double-linked list with tail pointer)
* new buffers are added at the list tail
* when closing a buffer, the next one is selected or the previous one if it is the tail
* the ring may be traversed in reverse order
* undoing a buffer close (Ring::UndoTokenEdit) could be cleaned up to only use standard macros (is slightly less efficient though)
-rw-r--r-- | qbuffers.cpp | 55 | ||||
-rw-r--r-- | qbuffers.h | 32 |
2 files changed, 51 insertions, 36 deletions
diff --git a/qbuffers.cpp b/qbuffers.cpp index 1ee9139..7269699 100644 --- a/qbuffers.cpp +++ b/qbuffers.cpp @@ -364,6 +364,14 @@ QRegisters::hook(Hook type) globals["0"]->execute(); } +void +Buffer::UndoTokenClose::run(void) +{ + ring.close(buffer); + /* NOTE: the buffer is NOT deleted on Token destruction */ + delete buffer; +} + bool Buffer::load(const gchar *filename) { @@ -396,29 +404,16 @@ Buffer::load(const gchar *filename) } void -Buffer::close(void) -{ - LIST_REMOVE(this, buffers); - - if (filename) - interface.msg(Interface::MSG_INFO, - "Removed file \"%s\" from the ring", - filename); - else - interface.msg(Interface::MSG_INFO, - "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(); + TAILQ_INSERT_BEFORE(buffer->next(), buffer, buffers); + else + TAILQ_INSERT_TAIL(&ring->head, buffer, buffers); ring->current = buffer; buffer->edit(); @@ -431,7 +426,7 @@ Ring::find(const gchar *filename) gchar *resolved = get_absolute_path(filename); Buffer *cur; - LIST_FOREACH(cur, &head, buffers) + TAILQ_FOREACH(cur, &head, buffers) if (!g_strcmp0(cur->filename, resolved)) break; @@ -444,7 +439,7 @@ Ring::find(gint64 id) { Buffer *cur; - LIST_FOREACH(cur, &head, buffers) + TAILQ_FOREACH(cur, &head, buffers) if (!--id) break; @@ -468,7 +463,7 @@ Ring::is_any_dirty(void) { Buffer *cur; - LIST_FOREACH(cur, &head, buffers) + TAILQ_FOREACH(cur, &head, buffers) if (cur->dirty) return true; @@ -509,7 +504,7 @@ Ring::edit(const gchar *filename) QRegisters::hook(QRegisters::HOOK_EDIT); } else { buffer = new Buffer(); - LIST_INSERT_HEAD(&head, buffer, buffers); + TAILQ_INSERT_TAIL(&head, buffer, buffers); current = buffer; undo_close(); @@ -669,13 +664,27 @@ Ring::save(const gchar *filename) } void +Ring::close(Buffer *buffer) +{ + TAILQ_REMOVE(&head, buffer, buffers); + + if (buffer->filename) + interface.msg(Interface::MSG_INFO, + "Removed file \"%s\" from the ring", + buffer->filename); + else + interface.msg(Interface::MSG_INFO, + "Removed unnamed file from the ring."); +} + +void Ring::close(void) { Buffer *buffer = current; buffer->dot = interface.ssm(SCI_GETCURRENTPOS); - buffer->close(); - current = buffer->next() ? : first(); + close(buffer); + current = buffer->next() ? : buffer->prev(); /* transfer responsibility to UndoToken object */ undo.push(new UndoTokenEdit(this, buffer)); @@ -693,7 +702,7 @@ Ring::~Ring() { Buffer *buffer, *next; - LIST_FOREACH_SAFE(buffer, &head, buffers, next) + TAILQ_FOREACH_SAFE(buffer, &head, buffers, next) delete buffer; } @@ -263,17 +263,11 @@ class Buffer { UndoTokenClose(Buffer *_buffer) : UndoToken(), buffer(_buffer) {} - void - run(void) - { - buffer->close(); - /* NOTE: the buffer is NOT deleted on Token destruction */ - delete buffer; - } + void run(void); }; public: - LIST_ENTRY(Buffer) buffers; + TAILQ_ENTRY(Buffer) buffers; gchar *filename; gint dot; @@ -300,7 +294,14 @@ public: inline Buffer *& next(void) { - return LIST_NEXT(this, buffers); + return TAILQ_NEXT(this, buffers); + } + inline Buffer *& + prev(void) + { + TAILQ_HEAD(Head, Buffer); + + return TAILQ_PREV(this, Head, buffers); } inline void @@ -329,7 +330,6 @@ public: bool load(const gchar *filename); - void close(void); inline void undo_close(void) { @@ -376,21 +376,26 @@ extern class Ring { } }; - LIST_HEAD(Head, Buffer) head; + TAILQ_HEAD(Head, Buffer) head; public: Buffer *current; Ring() : current(NULL) { - LIST_INIT(&head); + TAILQ_INIT(&head); } ~Ring(); inline Buffer * first(void) { - return LIST_FIRST(&head); + return TAILQ_FIRST(&head); + } + inline Buffer * + last(void) + { + return TAILQ_LAST(&head, Head); } Buffer *find(const gchar *filename); @@ -411,6 +416,7 @@ public: bool save(const gchar *filename); + void close(Buffer *buffer); void close(void); inline void undo_close(void) |