From 1b888cc723792ec0e49c7e5aaa78c3c5486a95b9 Mon Sep 17 00:00:00 2001 From: Albert Cervin Date: Tue, 26 Mar 2024 10:59:06 +0100 Subject: Implement kill-buffer command Can be killed with the command `kill-buffer`, the shortcut `C-x k` or from the buffer menu. --- src/dged/buffers.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 83 insertions(+), 13 deletions(-) (limited to 'src/dged/buffers.c') diff --git a/src/dged/buffers.c b/src/dged/buffers.c index 99dad9a..f591385 100644 --- a/src/dged/buffers.c +++ b/src/dged/buffers.c @@ -1,24 +1,42 @@ #include "buffers.h" #include "buffer.h" +#include #include - #include +struct buffer_entry { + struct buffer buffer; + bool empty; +}; + void buffers_init(struct buffers *buffers, uint32_t initial_capacity) { VEC_INIT(&buffers->buffers, initial_capacity); VEC_INIT(&buffers->add_hooks, 32); + VEC_INIT(&buffers->remove_hooks, 32); } struct buffer *buffers_add(struct buffers *buffers, struct buffer buffer) { - VEC_PUSH(&buffers->buffers, buffer); + struct buffer_entry *slot = NULL; + VEC_FOR_EACH(&buffers->buffers, struct buffer_entry * e) { + if (e->empty) { + slot = e; + } + } + + if (slot == NULL) { + VEC_APPEND(&buffers->buffers, struct buffer_entry * new); + slot = new; + } + + slot->buffer = buffer; + slot->empty = false; - struct buffer *slot = VEC_BACK(&buffers->buffers); VEC_FOR_EACH(&buffers->add_hooks, struct buffers_hook * hook) { - hook->callback(slot, hook->userdata); + hook->callback(&slot->buffer, hook->userdata); } - return slot; + return &slot->buffer; } uint32_t buffers_add_add_hook(struct buffers *buffers, buffers_hook_cb callback, @@ -31,10 +49,20 @@ uint32_t buffers_add_add_hook(struct buffers *buffers, buffers_hook_cb callback, return VEC_SIZE(&buffers->add_hooks) - 1; } +uint32_t buffers_add_remove_hook(struct buffers *buffers, + buffers_hook_cb callback, void *userdata) { + VEC_PUSH(&buffers->remove_hooks, ((struct buffers_hook){ + .callback = callback, + .userdata = userdata, + })); + + return VEC_SIZE(&buffers->remove_hooks) - 1; +} + struct buffer *buffers_find(struct buffers *buffers, const char *name) { - VEC_FOR_EACH(&buffers->buffers, struct buffer * b) { - if (strcmp(name, b->name) == 0) { - return b; + VEC_FOR_EACH(&buffers->buffers, struct buffer_entry * e) { + if (!e->empty && strcmp(name, e->buffer.name) == 0) { + return &e->buffer; } } @@ -43,23 +71,65 @@ struct buffer *buffers_find(struct buffers *buffers, const char *name) { struct buffer *buffers_find_by_filename(struct buffers *buffers, const char *path) { - VEC_FOR_EACH(&buffers->buffers, struct buffer * b) { - if (b->filename != NULL && strcmp(path, b->filename) == 0) { - return b; + VEC_FOR_EACH(&buffers->buffers, struct buffer_entry * e) { + if (!e->empty && e->buffer.filename != NULL && + strcmp(path, e->buffer.filename) == 0) { + return &e->buffer; } } return NULL; } +bool buffers_remove(struct buffers *buffers, const char *name) { + struct buffer_entry *buf_entry = NULL; + VEC_FOR_EACH(&buffers->buffers, struct buffer_entry * e) { + if (!e->empty && strcmp(name, e->buffer.name) == 0) { + buf_entry = e; + } + } + + if (buf_entry == NULL) { + return false; + } + + VEC_FOR_EACH(&buffers->remove_hooks, struct buffers_hook * hook) { + hook->callback(&buf_entry->buffer, hook->userdata); + } + + buf_entry->empty = true; + buffer_destroy(&buf_entry->buffer); + return true; +} + void buffers_for_each(struct buffers *buffers, buffers_hook_cb callback, void *userdata) { - VEC_FOR_EACH(&buffers->buffers, struct buffer * b) { callback(b, userdata); } + VEC_FOR_EACH(&buffers->buffers, struct buffer_entry * e) { + if (!e->empty) { + callback(&e->buffer, userdata); + } + } +} + +uint32_t buffers_num_buffers(struct buffers *buffers) { + return VEC_SIZE(&buffers->buffers); +} + +struct buffer *buffers_first(struct buffers *buffers) { + return buffers_num_buffers(buffers) > 0 + ? &VEC_ENTRIES(&buffers->buffers)[0].buffer + : NULL; } void buffers_destroy(struct buffers *buffers) { - VEC_FOR_EACH(&buffers->buffers, struct buffer * b) { buffer_destroy(b); } + VEC_FOR_EACH(&buffers->buffers, struct buffer_entry * e) { + if (!e->empty) { + buffer_destroy(&e->buffer); + e->empty = true; + } + } VEC_DESTROY(&buffers->buffers); VEC_DESTROY(&buffers->add_hooks); + VEC_DESTROY(&buffers->remove_hooks); } -- cgit v1.2.3