diff options
Diffstat (limited to 'src/main')
| -rw-r--r-- | src/main/bindings.c | 5 | ||||
| -rw-r--r-- | src/main/cmds.c | 25 | ||||
| -rw-r--r-- | src/main/main.c | 58 |
3 files changed, 86 insertions, 2 deletions
diff --git a/src/main/bindings.c b/src/main/bindings.c index 10436d6..7ea75eb 100644 --- a/src/main/bindings.c +++ b/src/main/bindings.c @@ -35,11 +35,14 @@ void set_default_buffer_bindings(struct keymap *keymap) { BINDING(Ctrl, 'S', "find-next"), BINDING(Ctrl, 'R', "find-prev"), + BINDING(Meta, 'g', "goto-line"), BINDING(Meta, '<', "goto-beginning"), BINDING(Meta, '>', "goto-end"), BINDING(Ctrl, 'V', "scroll-down"), BINDING(Meta, 'v', "scroll-up"), + BINDING(Spec, '6', "scroll-down"), + BINDING(Spec, '5', "scroll-up"), BINDING(ENTER, "newline"), BINDING(TAB, "indent"), @@ -204,4 +207,6 @@ void destroy_keymaps() { km->active = false; } } + + VEC_DESTROY(&g_buffer_keymaps); } diff --git a/src/main/cmds.c b/src/main/cmds.c index 27b2a77..4cbb00f 100644 --- a/src/main/cmds.c +++ b/src/main/cmds.c @@ -47,8 +47,16 @@ int32_t find_file(struct command_ctx ctx, int argc, const char *argv[]) { return 1; } - window_set_buffer(ctx.active_window, - buffers_add(ctx.buffers, buffer_from_file((char *)pth))); + const char *filename = realpath(pth, NULL); + struct buffer *b = buffers_find_by_filename(ctx.buffers, filename); + free((char *)filename); + if (b == NULL) { + b = buffers_add(ctx.buffers, buffer_from_file((char *)pth)); + } else { + buffer_reload(b); + } + + window_set_buffer(ctx.active_window, b); minibuffer_echo_timeout(4, "buffer \"%s\" loaded", window_buffer(ctx.active_window)->name); @@ -317,12 +325,14 @@ BUFFER_WRAPCMD_POS(buffer_paste_older); BUFFER_WRAPCMD_POS(buffer_goto_beginning); BUFFER_WRAPCMD_POS(buffer_goto_end); BUFFER_WRAPCMD_POS(buffer_undo); + static int32_t buffer_view_scroll_up_cmd(struct command_ctx ctx, int argc, const char *argv[]) { buffer_view_scroll_up(window_buffer_view(ctx.active_window), window_height(ctx.active_window)); return 0; }; + static int32_t buffer_view_scroll_down_cmd(struct command_ctx ctx, int argc, const char *argv[]) { buffer_view_scroll_down(window_buffer_view(ctx.active_window), @@ -330,6 +340,16 @@ static int32_t buffer_view_scroll_down_cmd(struct command_ctx ctx, int argc, return 0; }; +static int32_t buffer_goto_line(struct command_ctx ctx, int argc, + const char *argv[]) { + if (argc == 0) { + return minibuffer_prompt(ctx, "line: "); + } + + uint32_t line = atoi(argv[0]); + buffer_goto(window_buffer_view(ctx.active_window), line - 1, 0); +} + void register_buffer_commands(struct commands *commands) { static struct command buffer_commands[] = { @@ -359,6 +379,7 @@ void register_buffer_commands(struct commands *commands) { {.name = "scroll-down", .fn = buffer_view_scroll_down_cmd}, {.name = "scroll-up", .fn = buffer_view_scroll_up_cmd}, {.name = "reload", .fn = buffer_reload_cmd}, + {.name = "goto-line", .fn = buffer_goto_line}, }; register_commands(commands, buffer_commands, diff --git a/src/main/main.c b/src/main/main.c index f13e77e..cd36733 100644 --- a/src/main/main.c +++ b/src/main/main.c @@ -59,6 +59,59 @@ uint64_t calc_frame_time_ns(struct timespec *timers, uint32_t num_timer_pairs) { #define TIMED_SCOPE_BEGIN(timer) clock_gettime(CLOCK_MONOTONIC, &timer##_begin) #define TIMED_SCOPE_END(timer) clock_gettime(CLOCK_MONOTONIC, &timer##_end) +struct watched_file { + uint32_t watch_id; + struct buffer *buffer; +}; + +VEC(struct watched_file) g_watched_files; + +void watch_file(struct buffer *buffer, void *userdata) { + if (buffer_is_backed(buffer)) { + struct reactor *reactor = (struct reactor *)userdata; + VEC_APPEND(&g_watched_files, struct watched_file * w); + w->buffer = buffer; + w->watch_id = reactor_watch_file(reactor, buffer->filename, FileWritten); + } +} + +void reload_buffer(struct buffer *buffer) { + if (!buffer_is_modified(buffer)) { + buffer_reload(buffer); + } else { + minibuffer_echo("not updating buffer %s because it contains changes", + buffer->name); + } +} + +void update_file_watches(struct reactor *reactor) { + // first, find invalid file watches and try to update them + VEC_FOR_EACH(&g_watched_files, struct watched_file * w) { + if (w->watch_id == -1) { + w->watch_id = + reactor_watch_file(reactor, w->buffer->filename, FileWritten); + reload_buffer(w->buffer); + } + } + + // then pick up any events we might have + struct file_event ev; + while (reactor_next_file_event(reactor, &ev)) { + // find the buffer we need to reload + VEC_FOR_EACH(&g_watched_files, struct watched_file * w) { + if (w->watch_id == ev.id) { + if (ev.mask & LastEvent != 0) { + w->watch_id = -1; + continue; + } + + reload_buffer(w->buffer); + break; + } + } + } +} + void usage() { printf("TODO: print usage\n"); } int main(int argc, char *argv[]) { @@ -127,8 +180,11 @@ int main(int argc, char *argv[]) { struct keymap *current_keymap = NULL; struct keymap *global_keymap = register_bindings(); + VEC_INIT(&g_watched_files, 32); + struct buffers buflist = {0}; buffers_init(&buflist, 32); + buffers_add_add_hook(&buflist, watch_file, (void *)reactor); struct buffer initial_buffer = buffer_create("welcome"); if (filename != NULL) { buffer_destroy(&initial_buffer); @@ -270,6 +326,8 @@ int main(int argc, char *argv[]) { } TIMED_SCOPE_END(keyboard); + update_file_watches(reactor); + // calculate frame time struct timespec timers[] = {buffer_begin, buffer_end, display_begin, display_end, keyboard_begin, keyboard_end}; |
