summaryrefslogtreecommitdiff
path: root/src/dged/buffers.c
diff options
context:
space:
mode:
authorAlbert Cervin <albert@acervin.com>2024-03-26 10:59:06 +0100
committerAlbert Cervin <albert@acervin.com>2024-03-26 10:59:06 +0100
commit1b888cc723792ec0e49c7e5aaa78c3c5486a95b9 (patch)
treeda0b4f6fcdf394b155938472a0ca0d100effb2ef /src/dged/buffers.c
parent5b3234f34fd081a3fe81c95bd55f4bfc853568a5 (diff)
downloaddged-1b888cc723792ec0e49c7e5aaa78c3c5486a95b9.tar.gz
dged-1b888cc723792ec0e49c7e5aaa78c3c5486a95b9.tar.xz
dged-1b888cc723792ec0e49c7e5aaa78c3c5486a95b9.zip
Implement kill-buffer command
Can be killed with the command `kill-buffer`, the shortcut `C-x k` or from the buffer menu.
Diffstat (limited to 'src/dged/buffers.c')
-rw-r--r--src/dged/buffers.c96
1 files changed, 83 insertions, 13 deletions
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 <stdbool.h>
#include <stdlib.h>
-
#include <string.h>
+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);
}