summaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c143
1 files changed, 114 insertions, 29 deletions
diff --git a/src/main.c b/src/main.c
index 92e84d1..a1d26e5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,4 +1,3 @@
-#include <assert.h>
#include <locale.h>
#include <signal.h>
#include <stdbool.h>
@@ -52,15 +51,20 @@ void _abort(struct command_ctx ctx, int argc, const char *argv[]) {
}
void unimplemented_command(struct command_ctx ctx, int argc,
- const char *argv[]) {}
+ const char *argv[]) {
+ minibuffer_echo("TODO: %s is not implemented", (const char *)ctx.userdata);
+}
void exit_editor(struct command_ctx ctx, int argc, const char *argv[]) {
terminate();
}
-static struct command GLOBAL_COMMANDS[] = {
- {.name = "find-file", .fn = unimplemented_command},
- {.name = "abort", .fn = _abort},
- {.name = "exit", .fn = exit_editor}};
+static struct command GLOBAL_COMMANDS[] = {{
+ .name = "find-file",
+ .fn = unimplemented_command,
+ .userdata = (void *)"find-file",
+ },
+ {.name = "abort", .fn = _abort},
+ {.name = "exit", .fn = exit_editor}};
uint64_t calc_frame_time_ns(struct timespec *timers, uint32_t num_timer_pairs) {
uint64_t total = 0;
@@ -76,6 +80,41 @@ uint64_t calc_frame_time_ns(struct timespec *timers, uint32_t num_timer_pairs) {
return total;
}
+struct buffers {
+ // TODO: more buffers
+ struct buffer buffers[32];
+ uint32_t nbuffers;
+};
+
+struct window {
+ uint32_t x;
+ uint32_t y;
+ uint32_t width;
+ uint32_t height;
+ struct buffer *buffer;
+};
+
+struct buffer_update window_update_buffer(struct window *window,
+ uint64_t frame_time) {
+ return buffer_update(window->buffer, window->width, window->height,
+ frame_alloc, frame_time);
+}
+
+void buffers_init(struct buffers *buffers) { buffers->nbuffers = 0; }
+
+void buffers_add(struct buffers *buffers, struct buffer buffer) {
+ buffers->buffers[buffers->nbuffers] = buffer;
+ ++buffers->nbuffers;
+}
+
+void buffers_destroy(struct buffers *buffers) {
+ for (uint32_t bufi = 0; bufi < buffers->nbuffers; ++bufi) {
+ buffer_destroy(&buffers->buffers[bufi]);
+ }
+
+ buffers->nbuffers = 0;
+}
+
int main(int argc, char *argv[]) {
const char *filename = NULL;
if (argc >= 1) {
@@ -111,18 +150,21 @@ int main(int argc, char *argv[]) {
struct keymap ctrlx_map = keymap_create("c-x", 32);
struct binding global_binds[] = {
PREFIX(Ctrl, 'X', &ctrlx_map),
+ BINDING(Ctrl, 'G', "abort"),
};
struct binding ctrlx_bindings[] = {
BINDING(Ctrl, 'C', "exit"),
- BINDING(Ctrl, 'G', "abort"),
BINDING(Ctrl, 'S', "buffer-write-to-file"),
+ BINDING(Ctrl, 'F', "find-file"),
};
keymap_bind_keys(&global_keymap, global_binds,
sizeof(global_binds) / sizeof(global_binds[0]));
keymap_bind_keys(&ctrlx_map, ctrlx_bindings,
sizeof(ctrlx_bindings) / sizeof(ctrlx_bindings[0]));
- struct buffer curbuf = buffer_create("welcome");
+ struct buffers buflist = {0};
+ buffers_init(&buflist);
+ struct buffer curbuf = buffer_create("welcome", true);
if (filename != NULL) {
curbuf = buffer_from_file(filename, &reactor);
} else {
@@ -130,41 +172,68 @@ int main(int argc, char *argv[]) {
buffer_add_text(&curbuf, (uint8_t *)welcome_txt, strlen(welcome_txt));
}
- minibuffer_init(display.height - 1);
+ buffers_add(&buflist, curbuf);
+
+ // one main window
+ struct window main_window = (struct window){
+ .buffer = &curbuf,
+ .height = display.height - 1,
+ .width = display.width,
+ .x = 0,
+ .y = 0,
+ };
+
+ // and one for the minibuffer
+ struct buffer minibuffer = buffer_create("minibuffer", false);
+ buffers_add(&buflist, minibuffer);
+
+ minibuffer_init(&minibuffer);
+ struct window minibuffer_window = (struct window){
+ .buffer = &minibuffer,
+ .x = 0,
+ .y = display.height - 1,
+ .height = 1,
+ .width = display.width,
+ };
struct timespec buffer_begin, buffer_end, display_begin, display_end,
keyboard_begin, keyboard_end;
uint64_t frame_time = 0;
- struct render_cmd_buf render_bufs[2] = {
- {.source = "minibuffer"},
- {.source = "buffer"},
+ struct render_cmd_buf render_bufs[2] = {0};
+
+ struct window *windows[2] = {
+ &minibuffer_window,
+ &main_window,
};
+ // TODO: not always
+ struct window *active_window = &main_window;
+
while (running) {
clock_gettime(CLOCK_MONOTONIC, &buffer_begin);
- // update minibuffer
- struct minibuffer_update minibuf_upd = minibuffer_update(frame_alloc);
- render_bufs[0].cmds = minibuf_upd.cmds;
- render_bufs[0].ncmds = minibuf_upd.ncmds;
-
- // update current buffer
- struct buffer_update buf_upd =
- buffer_update(&curbuf, display.width, display.height - 1, frame_alloc,
- &reactor, frame_time);
- render_bufs[1].cmds = buf_upd.cmds;
- render_bufs[1].ncmds = buf_upd.ncmds;
+ // update windows
+ uint32_t dot_line = 0, dot_col = 0;
+ for (uint32_t windowi = 0; windowi < 2; ++windowi) {
+ struct window *win = windows[windowi];
+ struct buffer_update buf_upd = window_update_buffer(win, frame_time);
+ render_bufs[windowi].cmds = buf_upd.cmds;
+ render_bufs[windowi].ncmds = buf_upd.ncmds;
+ render_bufs[windowi].xoffset = win->x;
+ render_bufs[windowi].yoffset = win->y;
+ }
clock_gettime(CLOCK_MONOTONIC, &buffer_end);
// update screen
clock_gettime(CLOCK_MONOTONIC, &display_begin);
+ uint32_t relline, relcol;
+ buffer_relative_dot_pos(active_window->buffer, &relline, &relcol);
if (render_bufs[0].ncmds > 0 || render_bufs[1].ncmds > 0) {
- display_update(&display, render_bufs, 2, buf_upd.dot_line,
- buf_upd.dot_col);
+ display_update(&display, render_bufs, 2, relline, relcol);
}
clock_gettime(CLOCK_MONOTONIC, &display_end);
@@ -175,6 +244,10 @@ int main(int argc, char *argv[]) {
struct keymap *local_keymaps = NULL;
uint32_t nbuffer_keymaps = buffer_keymaps(&curbuf, &local_keymaps);
struct keyboard_update kbd_upd = keyboard_update(&kbd, &reactor);
+
+ // buffer up chars to handle utf-8 "correctly"
+ uint8_t chars[kbd_upd.nkeys];
+ uint8_t nchars;
for (uint32_t ki = 0; ki < kbd_upd.nkeys; ++ki) {
struct key *k = &kbd_upd.keys[ki];
@@ -190,11 +263,13 @@ int main(int argc, char *argv[]) {
}
if (res.found) {
+ if (nchars > 0) {
+ buffer_add_text(active_window->buffer, chars, nchars);
+ nchars = 0;
+ }
switch (res.type) {
case BindingType_Command: {
- const char *argv[] = {};
- res.command->fn((struct command_ctx){.current_buffer = &curbuf}, 0,
- argv);
+ execute_command(res.command, active_window->buffer, 0, NULL);
current_keymap = NULL;
break;
}
@@ -207,12 +282,21 @@ int main(int argc, char *argv[]) {
}
}
} else if (current_keymap != NULL) {
+ if (nchars > 0) {
+ buffer_add_text(active_window->buffer, chars, nchars);
+ nchars = 0;
+ }
minibuffer_echo_timeout(4, "key is not bound!");
current_keymap = NULL;
} else {
- buffer_add_text(&curbuf, &k->c, 1);
+ chars[nchars] = k->c;
+ ++nchars;
}
}
+ if (nchars > 0) {
+ buffer_add_text(active_window->buffer, chars, nchars);
+ nchars = 0;
+ }
clock_gettime(CLOCK_MONOTONIC, &keyboard_end);
// calculate frame time
@@ -223,6 +307,7 @@ int main(int argc, char *argv[]) {
frame_allocator_clear(&frame_allocator);
}
+ buffers_destroy(&buflist);
display_clear(&display);
display_destroy(&display);
keymap_destroy(&global_keymap);