From 5a5ec57d8521a5aa7317d2658ead95b8e2fde5b9 Mon Sep 17 00:00:00 2001 From: Albert Cervin Date: Tue, 9 May 2023 22:51:57 +0200 Subject: Finish buflist implementation Also fix tests and man page install. --- Makefile | 11 +++--- linux.mk | 2 +- src/dged/buffer.c | 3 ++ src/dged/buffers.c | 1 + src/dged/window.c | 14 ++++++++ src/dged/window.h | 1 + src/main/cmds.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++------- src/main/main.c | 2 ++ 8 files changed, 117 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index 9c8a987..7c58ea5 100644 --- a/Makefile +++ b/Makefile @@ -31,10 +31,11 @@ UNAME_S != uname -s | tr '[:upper:]' '[:lower:]' DEPS = $(DGED_SOURCES:.c=.d) $(TEST_SOURCES:.c=.d) OBJS = $(SOURCES:.c=.o) +PLATFORM_OBJS = $(PLATFORM_SOURCES:.c=.o) MAIN_OBJS = $(MAIN_SOURCES:.c=.o) TEST_OBJS = $(TEST_SOURCES:.c=.o) -FILES = $(DEPS) $(MAIN_OBJS) $(OBJS) dged libdged.a $(TEST_OBJS) +FILES = $(DEPS) $(MAIN_OBJS) $(OBJS) dged libdged.a $(TEST_OBJS) $(PLATFORM_OBJS) # dependency generation .c.d: @@ -49,11 +50,11 @@ FILES = $(DEPS) $(MAIN_OBJS) $(OBJS) dged libdged.a $(TEST_OBJS) dged: $(MAIN_OBJS) libdged.a $(CC) $(LDFLAGS) $(MAIN_OBJS) libdged.a -o dged -lm -libdged.a: $(OBJS) - $(AR) -rc libdged.a $(OBJS) +libdged.a: $(OBJS) $(PLATFORM_OBJS) + $(AR) -rc libdged.a $(OBJS) $(PLATFORM_OBJS) run-tests: $(TEST_OBJS) $(OBJS) - $(CC) $(LDFLAGS) $(TEST_OBJS) $(OBJS) -o run-tests + $(CC) $(LDFLAGS) $(TEST_OBJS) $(OBJS) -lm -o run-tests check: run-tests clang-format --dry-run --Werror $(SOURCES:%.c=../%.c) $(MAIN_SOURCES:%.c=../%.c) $(TEST_SOURCES:%c=../%c) @@ -80,7 +81,7 @@ install: dged install -m 755 $(.OBJDIR)/dged $(prefix)/bin/dged install -d $(prefix)/share/man/man1 - install -m 644 dged.1 $(prefix)/share/man/man1/dged.1 + install -m 644 $(.CURDIR)/dged.1 $(prefix)/share/man/man1/dged.1 docs: doxygen $(.CURDIR)/Doxyfile diff --git a/linux.mk b/linux.mk index 9486fb4..c30ff9b 100644 --- a/linux.mk +++ b/linux.mk @@ -1,3 +1,3 @@ CFLAGS += -DLINUX -D_XOPEN_SOURCE=700 -SOURCES += src/dged/reactor-epoll.c +PLATFORM_SOURCES += src/dged/reactor-epoll.c 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 : ""); + size_t written = + snprintf(buf, 1024, "%-16s %s\n", buffer->name, + buffer->filename != NULL ? buffer->filename : ""); 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; } -- cgit v1.2.3