summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlbert Cervin <albert@acervin.com>2023-05-09 22:51:57 +0200
committerAlbert Cervin <albert@acervin.com>2023-05-09 22:51:57 +0200
commit5a5ec57d8521a5aa7317d2658ead95b8e2fde5b9 (patch)
tree4097ded91a3e9f708903ddd066464bb0779513e0 /src
parent1d8b5da24db92f9598cd6aeb59d283ae39024349 (diff)
downloaddged-5a5ec57d8521a5aa7317d2658ead95b8e2fde5b9.tar.gz
dged-5a5ec57d8521a5aa7317d2658ead95b8e2fde5b9.tar.xz
dged-5a5ec57d8521a5aa7317d2658ead95b8e2fde5b9.zip
Finish buflist implementation
Also fix tests and man page install.
Diffstat (limited to 'src')
-rw-r--r--src/dged/buffer.c3
-rw-r--r--src/dged/buffers.c1
-rw-r--r--src/dged/window.c14
-rw-r--r--src/dged/window.h1
-rw-r--r--src/main/cmds.c101
-rw-r--r--src/main/main.c2
6 files changed, 110 insertions, 12 deletions
diff --git a/src/dged/buffer.c b/src/dged/buffer.c
index 201a75e..f2e7eb9 100644
--- a/src/dged/buffer.c
+++ b/src/dged/buffer.c
@@ -522,6 +522,9 @@ void buffer_read_from_file(struct buffer *b) {
struct buffer buffer_from_file(char *filename) {
char *full_filename = realpath(filename, NULL);
+ if (full_filename == NULL) {
+ full_filename = strdup(filename);
+ }
struct buffer b = create_internal(basename((char *)filename), full_filename);
buffer_read_from_file(&b);
diff --git a/src/dged/buffers.c b/src/dged/buffers.c
index 265a248..99dad9a 100644
--- a/src/dged/buffers.c
+++ b/src/dged/buffers.c
@@ -61,4 +61,5 @@ void buffers_destroy(struct buffers *buffers) {
VEC_FOR_EACH(&buffers->buffers, struct buffer * b) { buffer_destroy(b); }
VEC_DESTROY(&buffers->buffers);
+ VEC_DESTROY(&buffers->add_hooks);
}
diff --git a/src/dged/window.c b/src/dged/window.c
index efdcd29..33659a7 100644
--- a/src/dged/window.c
+++ b/src/dged/window.c
@@ -202,6 +202,20 @@ void windows_set_active(struct window *window) {
}
}
+struct window *window_find_by_buffer(struct buffer *b) {
+ struct window_node *n = BINTREE_ROOT(&g_windows.windows);
+ BINTREE_FIRST(n);
+ while (n != NULL) {
+ struct window *w = &BINTREE_VALUE(n);
+ if (window_buffer(w) == b) {
+ return w;
+ }
+ BINTREE_NEXT(n);
+ }
+
+ return NULL;
+}
+
struct window *windows_get_active() {
return &BINTREE_VALUE(g_windows.active);
}
diff --git a/src/dged/window.h b/src/dged/window.h
index b3284e9..be9b952 100644
--- a/src/dged/window.h
+++ b/src/dged/window.h
@@ -27,6 +27,7 @@ void windows_set_active(struct window *window);
struct window *windows_focus(uint32_t id);
struct window *windows_get_active();
struct window *windows_focus_next();
+struct window *window_find_by_buffer(struct buffer *b);
void window_set_buffer(struct window *window, struct buffer *buffer);
struct buffer *window_buffer(struct window *window);
diff --git a/src/main/cmds.c b/src/main/cmds.c
index 63a7e01..3b18869 100644
--- a/src/main/cmds.c
+++ b/src/main/cmds.c
@@ -14,6 +14,7 @@
int32_t _abort(struct command_ctx ctx, int argc, const char *argv[]) {
minibuffer_abort_prompt();
+ buffer_clear_mark(window_buffer_view(ctx.active_window));
minibuffer_echo_timeout(4, "💣 aborted");
return 0;
}
@@ -48,8 +49,15 @@ int32_t find_file(struct command_ctx ctx, int argc, const char *argv[]) {
}
const char *filename = realpath(pth, NULL);
+ if (filename == NULL) {
+ filename = pth;
+ }
struct buffer *b = buffers_find_by_filename(ctx.buffers, filename);
- free((char *)filename);
+
+ if (filename != pth) {
+ free((char *)filename);
+ }
+
if (b == NULL) {
b = buffers_add(ctx.buffers, buffer_from_file((char *)pth));
} else {
@@ -272,32 +280,101 @@ int32_t timers(struct command_ctx ctx, int argc, const char *argv[]) {
void buffer_to_list_line(struct buffer *buffer, void *userdata) {
struct buffer_view *listbuf = (struct buffer_view *)userdata;
char buf[1024];
- size_t written = snprintf(buf, 1024, "%-16s %s\n", buffer->name,
- buffer->filename != NULL ? buffer->filename : "<no-file>");
+ size_t written =
+ snprintf(buf, 1024, "%-16s %s\n", buffer->name,
+ buffer->filename != NULL ? buffer->filename : "<no-file>");
if (written > 0) {
buffer_add_text(listbuf, (uint8_t *)buf, written);
}
}
+int32_t buflist_visit_cmd(struct command_ctx ctx, int argc,
+ const char *argv[]) {
+ struct window *w = ctx.active_window;
+
+ struct buffer_view *bv = window_buffer_view(w);
+ struct text_chunk text = buffer_get_line(bv->buffer, bv->dot.line);
+
+ char *end = (char *)memchr(text.text, ' ', text.nbytes);
+
+ if (end != NULL) {
+ uint32_t len = end - (char *)text.text;
+ char *bufname = (char *)malloc(len + 1);
+ memcpy(bufname, text.text, len);
+ bufname[len] = '\0';
+
+ struct buffer *target = buffers_find(ctx.buffers, bufname);
+ if (target != NULL) {
+ struct window *tgt_window = window_find_by_buffer(target);
+ if (tgt_window != NULL) {
+ windows_set_active(tgt_window);
+ } else {
+ window_set_buffer(w, target);
+ }
+ }
+ }
+ return 0;
+}
+
+int32_t buflist_close_cmd(struct command_ctx ctx, int argc,
+ const char *argv[]) {
+ window_close(ctx.active_window);
+ return 0;
+}
+
+void buflist_refresh(struct buffers *buffers, struct buffer_view *target) {
+ buffer_set_readonly(target->buffer, false);
+ buffer_clear(target);
+ buffers_for_each(buffers, buffer_to_list_line, target);
+ buffer_goto_beginning(target);
+ buffer_set_readonly(target->buffer, true);
+}
+
+int32_t buflist_refresh_cmd(struct command_ctx ctx, int argc,
+ const char *argv[]) {
+ buflist_refresh(ctx.buffers, window_buffer_view(ctx.active_window));
+ return 0;
+}
+
int32_t buffer_list(struct command_ctx ctx, int argc, const char *argv[]) {
struct buffer *b = buffers_find(ctx.buffers, "buffers");
if (b == NULL) {
b = buffers_add(ctx.buffers, buffer_create("buffers"));
}
- struct window *new_window_a, *new_window_b;
- window_split(ctx.active_window, &new_window_a, &new_window_b);
+ struct window *w = window_find_by_buffer(b);
+ if (w == NULL) {
+ struct window *new_window_a;
+ window_split(ctx.active_window, &new_window_a, &w);
- window_set_buffer(new_window_b, b);
+ window_set_buffer(w, b);
+ }
- struct buffer_view *bv = window_buffer_view(new_window_b);
- buffer_set_readonly(b, false);
- buffer_clear(bv);
- buffers_for_each(ctx.buffers, buffer_to_list_line, bv);
+ buflist_refresh(ctx.buffers, window_buffer_view(w));
- buffer_goto_beginning(bv);
- buffer_set_readonly(b, true);
+ static struct command buflist_visit = {
+ .name = "buflist-visit",
+ .fn = buflist_visit_cmd,
+ };
+
+ static struct command buflist_close = {
+ .name = "buflist-close",
+ .fn = buflist_close_cmd,
+ };
+
+ static struct command buflist_refresh = {
+ .name = "buflist-refresh",
+ .fn = buflist_refresh_cmd,
+ };
+
+ struct binding bindings[] = {
+ ANONYMOUS_BINDING(Ctrl, 'M', &buflist_visit),
+ ANONYMOUS_BINDING(None, 'q', &buflist_close),
+ ANONYMOUS_BINDING(None, 'g', &buflist_refresh),
+ };
+ buffer_bind_keys(b, bindings, sizeof(bindings) / sizeof(bindings[0]));
+ windows_set_active(w);
return 0;
}
diff --git a/src/main/main.c b/src/main/main.c
index cd36733..3858682 100644
--- a/src/main/main.c
+++ b/src/main/main.c
@@ -348,5 +348,7 @@ int main(int argc, char *argv[]) {
buffer_static_teardown();
settings_destroy();
+ VEC_DESTROY(&g_watched_files);
+
return 0;
}