summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Cervin <albert@acervin.com>2023-01-09 23:50:48 +0100
committerAlbert Cervin <albert@acervin.com>2023-01-09 23:50:48 +0100
commitfd8ecb6d0f9af3245e8b1a662987b8cf4e89dec9 (patch)
tree4d7236e75292153b917671251767218b979bdeb2
parent690786504fce73edea78c7ec13b34771771e4caf (diff)
downloaddged-fd8ecb6d0f9af3245e8b1a662987b8cf4e89dec9.tar.gz
dged-fd8ecb6d0f9af3245e8b1a662987b8cf4e89dec9.tar.xz
dged-fd8ecb6d0f9af3245e8b1a662987b8cf4e89dec9.zip
More stuff
Render things and line numbers.
-rw-r--r--src/buffer.c190
-rw-r--r--src/buffer.h31
-rw-r--r--src/display.c142
-rw-r--r--src/display.h26
-rw-r--r--src/keyboard.c11
-rw-r--r--src/main.c42
-rw-r--r--src/minibuffer.c9
7 files changed, 303 insertions, 148 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 9d9fb68..5e05a73 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -12,6 +12,18 @@
#include <time.h>
#include <unistd.h>
+struct update_hook_result buffer_linenum_hook(struct buffer *buffer,
+ struct command_list *commands,
+ uint32_t width, uint32_t height,
+ uint64_t frame_time,
+ void *userdata);
+
+struct update_hook_result buffer_modeline_hook(struct buffer *buffer,
+ struct command_list *commands,
+ uint32_t width, uint32_t height,
+ uint64_t frame_time,
+ void *userdata);
+
struct buffer buffer_create(const char *name, bool modeline) {
struct buffer b =
(struct buffer){.filename = NULL,
@@ -56,6 +68,10 @@ struct buffer buffer_create(const char *name, bool modeline) {
buffer_add_update_hook(&b, buffer_modeline_hook, modeline);
}
+ if (modeline) {
+ buffer_add_update_hook(&b, buffer_linenum_hook, NULL);
+ }
+
return b;
}
@@ -187,6 +203,11 @@ void write_line(struct text_chunk *chunk, void *userdata) {
}
void buffer_to_file(struct buffer *buffer) {
+ if (!buffer->filename) {
+ minibuffer_echo("TODO: buffer \"%s\" is not associated with a file",
+ buffer->name);
+ return;
+ }
// TODO: handle errors
FILE *file = fopen(buffer->filename, "w");
@@ -228,18 +249,28 @@ uint32_t buffer_add_update_hook(struct buffer *buffer, update_hook_cb hook,
++buffer->update_hooks.nhooks;
- // TODO: cant really have this if someone wants to remove a hook
+ // TODO: cant really have this if we actually want to remove a hook
return buffer->update_hooks.nhooks - 1;
}
struct cmdbuf {
struct command_list *cmds;
- uint32_t first_line;
+ uint32_t scroll_line;
+ uint32_t line_offset;
+ uint32_t col_offset;
+ struct line_render_hook *line_render_hooks;
+ uint32_t nlinerender_hooks;
};
void render_line(struct text_chunk *line, void *userdata) {
struct cmdbuf *cmdbuf = (struct cmdbuf *)userdata;
- command_list_draw_text(cmdbuf->cmds, 0, line->line - cmdbuf->first_line,
+ uint32_t visual_line = line->line - cmdbuf->scroll_line + cmdbuf->line_offset;
+ for (uint32_t hooki = 0; hooki < cmdbuf->nlinerender_hooks; ++hooki) {
+ struct line_render_hook *hook = &cmdbuf->line_render_hooks[hooki];
+ hook->callback(line, visual_line, cmdbuf->cmds, hook->userdata);
+ }
+
+ command_list_draw_text(cmdbuf->cmds, cmdbuf->col_offset, visual_line,
line->text, line->nbytes);
}
@@ -278,20 +309,11 @@ uint32_t visual_dot_col(struct buffer *buffer, uint32_t dot_col) {
return visual_dot_col;
}
-void buffer_relative_dot_pos(struct buffer *buffer, uint32_t *relline,
- uint32_t *relcol) {
- int64_t rel_col, rel_line;
- uint32_t visual_col = visual_dot_col(buffer, buffer->dot_col);
- to_relative(buffer, buffer->dot_line, visual_col, &rel_line, &rel_col);
-
- *relline = rel_line < 0 ? 0 : (uint32_t)rel_line;
- *relcol = rel_col < 0 ? 0 : (uint32_t)rel_col;
-}
-
-struct margin buffer_modeline_hook(struct buffer *buffer,
- struct command_list *commands,
- uint32_t width, uint32_t height,
- uint64_t frame_time, void *userdata) {
+struct update_hook_result buffer_modeline_hook(struct buffer *buffer,
+ struct command_list *commands,
+ uint32_t width, uint32_t height,
+ uint64_t frame_time,
+ void *userdata) {
char buf[width * 4];
static uint64_t samples[10] = {0};
@@ -308,10 +330,8 @@ struct margin buffer_modeline_hook(struct buffer *buffer,
struct tm *lt = localtime(&now);
char left[128], right[128];
- uint32_t relcol, relline;
- buffer_relative_dot_pos(buffer, &relline, &relcol);
-
- snprintf(left, 128, " %-16s (%d, %d)", buffer->name, relline + 1, relcol);
+ snprintf(left, 128, " %-16s (%d, %d)", buffer->name, buffer->dot_line + 1,
+ visual_dot_col(buffer, buffer->dot_col));
snprintf(right, 128, "(%.2f ms) %02d:%02d", frame_time / 1e6, lt->tm_hour,
lt->tm_min);
@@ -329,69 +349,137 @@ struct margin buffer_modeline_hook(struct buffer *buffer,
command_list_reset_color(commands);
}
- struct margin m = {0};
- m.bottom = 1;
- return m;
+ struct update_hook_result res = {0};
+ res.margins.bottom = 1;
+ return res;
+}
+
+struct linenumdata {
+ uint32_t longest_nchars;
+} linenum_data;
+
+void linenum_render_hook(struct text_chunk *line_data, uint32_t line,
+ struct command_list *commands, void *userdata) {
+
+ struct linenumdata *data = (struct linenumdata *)userdata;
+ static char buf[16];
+ command_list_set_index_color_bg(commands, 236);
+ command_list_set_index_color_fg(commands, 244);
+ uint32_t chars =
+ snprintf(buf, 16, "%*d", data->longest_nchars, line_data->line + 1);
+ command_list_draw_text_copy(commands, 0, line, (uint8_t *)buf, chars);
+ command_list_reset_color(commands);
+ command_list_draw_text(commands, data->longest_nchars + 1, line,
+ (uint8_t *)" ", 1);
+}
+
+struct update_hook_result buffer_linenum_hook(struct buffer *buffer,
+ struct command_list *commands,
+ uint32_t width, uint32_t height,
+ uint64_t frame_time,
+ void *userdata) {
+ uint32_t total_lines = text_num_lines(buffer->text);
+ uint32_t longest_nchars = 10;
+ if (total_lines < 10) {
+ longest_nchars = 1;
+ } else if (total_lines < 100) {
+ longest_nchars = 2;
+ } else if (total_lines < 1000) {
+ longest_nchars = 3;
+ } else if (total_lines < 10000) {
+ longest_nchars = 4;
+ } else if (total_lines < 100000) {
+ longest_nchars = 5;
+ } else if (total_lines < 1000000) {
+ longest_nchars = 6;
+ } else if (total_lines < 10000000) {
+ longest_nchars = 7;
+ } else if (total_lines < 100000000) {
+ longest_nchars = 8;
+ } else if (total_lines < 1000000000) {
+ longest_nchars = 9;
+ }
+
+ linenum_data.longest_nchars = longest_nchars;
+ struct update_hook_result res = {0};
+ res.margins.left = longest_nchars + 2;
+ res.line_render_hook.callback = linenum_render_hook;
+ res.line_render_hook.userdata = &linenum_data;
+ return res;
}
void buffer_update(struct buffer *buffer, uint32_t width, uint32_t height,
- struct command_list *commands, uint64_t frame_time) {
+ struct command_list *commands, uint64_t frame_time,
+ uint32_t *relline, uint32_t *relcol) {
if (width == 0 || height == 0) {
return;
}
struct margin total_margins = {0};
+ struct line_render_hook line_hooks[16];
+ uint32_t nlinehooks = 0;
for (uint32_t hooki = 0; hooki < buffer->update_hooks.nhooks; ++hooki) {
struct update_hook *h = &buffer->update_hooks.hooks[hooki];
- struct margin margins =
+ struct update_hook_result res =
h->callback(buffer, commands, width, height, frame_time, h->userdata);
- if (margins.left > total_margins.left) {
- total_margins.left = margins.left;
- }
- if (margins.right > total_margins.right) {
- total_margins.right = margins.right;
- }
- if (margins.top > total_margins.top) {
- total_margins.top = margins.top;
- }
- if (margins.bottom > total_margins.bottom) {
- total_margins.bottom = margins.bottom;
+ struct margin margins = res.margins;
+
+ if (res.line_render_hook.callback != NULL) {
+ line_hooks[nlinehooks] = res.line_render_hook;
+ ++nlinehooks;
}
- }
- // reserve space for modeline
- uint32_t bufheight = height - (total_margins.top + total_margins.bottom);
- uint32_t bufwidth = width - (total_margins.left + total_margins.right);
+ total_margins.left += margins.left;
+ total_margins.right += margins.right;
+ total_margins.top += margins.top;
+ total_margins.bottom += margins.bottom;
+
+ height -= margins.top + margins.bottom;
+ width -= margins.left + margins.right;
+ }
int64_t rel_line, rel_col;
to_relative(buffer, buffer->dot_line, buffer->dot_col, &rel_line, &rel_col);
int line_delta = 0, col_delta = 0;
if (rel_line < 0) {
- line_delta = -(int)bufheight / 2;
- } else if (rel_line >= bufheight) {
- line_delta = bufheight / 2;
+ line_delta = -(int)height / 2;
+ } else if (rel_line >= height) {
+ line_delta = height / 2;
}
if (rel_col < 0) {
col_delta = rel_col;
- } else if (rel_col > bufwidth) {
- col_delta = rel_col - bufwidth;
+ } else if (rel_col > width) {
+ col_delta = rel_col - width;
}
scroll(buffer, line_delta, col_delta);
struct cmdbuf cmdbuf = (struct cmdbuf){
.cmds = commands,
- .first_line = buffer->scroll_line,
+ .scroll_line = buffer->scroll_line,
+ .col_offset = total_margins.left,
+ .line_offset = total_margins.top,
+ .line_render_hooks = line_hooks,
+ .nlinerender_hooks = nlinehooks,
};
- text_for_each_line(buffer->text, buffer->scroll_line, bufheight, render_line,
+ text_for_each_line(buffer->text, buffer->scroll_line, height, render_line,
&cmdbuf);
+ // draw empty lines
uint32_t nlines = text_num_lines(buffer->text);
- for (uint32_t linei = nlines - buffer->scroll_line; linei < bufheight;
- ++linei) {
- command_list_draw_text(commands, 0, linei, NULL, 0);
+ for (uint32_t linei = nlines - buffer->scroll_line + total_margins.top;
+ linei < height; ++linei) {
+ command_list_draw_text(commands, total_margins.left, linei, NULL, 0);
}
+
+ // update the visual cursor position
+ to_relative(buffer, buffer->dot_line, buffer->dot_col, &rel_line, &rel_col);
+ uint32_t visual_col = visual_dot_col(buffer, buffer->dot_col);
+ to_relative(buffer, buffer->dot_line, visual_col, &rel_line, &rel_col);
+
+ *relline = rel_line < 0 ? 0 : (uint32_t)rel_line + total_margins.top;
+ *relcol = rel_col < 0 ? 0 : (uint32_t)rel_col + total_margins.left;
}
diff --git a/src/buffer.h b/src/buffer.h
index 141c1ea..e8ab62b 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -16,10 +16,22 @@ struct margin {
uint32_t bottom;
};
-typedef struct margin (*update_hook_cb)(struct buffer *buffer,
- struct command_list *commands,
- uint32_t width, uint32_t height,
- uint64_t frame_time, void *userdata);
+typedef void (*line_render_cb)(struct text_chunk *line_data, uint32_t line,
+ struct command_list *commands, void *userdata);
+
+struct line_render_hook {
+ line_render_cb callback;
+ void *userdata;
+};
+
+struct update_hook_result {
+ struct margin margins;
+ struct line_render_hook line_render_hook;
+};
+
+typedef struct update_hook_result (*update_hook_cb)(
+ struct buffer *buffer, struct command_list *commands, uint32_t width,
+ uint32_t height, uint64_t frame_time, void *userdata);
struct update_hook {
update_hook_cb callback;
@@ -76,9 +88,6 @@ void buffer_end_of_line(struct buffer *buffer);
void buffer_beginning_of_line(struct buffer *buffer);
void buffer_newline(struct buffer *buffer);
-void buffer_relative_dot_pos(struct buffer *buffer, uint32_t *relline,
- uint32_t *relcol);
-
uint32_t buffer_add_update_hook(struct buffer *buffer, update_hook_cb hook,
void *userdata);
@@ -86,12 +95,8 @@ struct buffer buffer_from_file(const char *filename, struct reactor *reactor);
void buffer_to_file(struct buffer *buffer);
void buffer_update(struct buffer *buffer, uint32_t width, uint32_t height,
- struct command_list *commands, uint64_t frame_time);
-
-struct margin buffer_modeline_hook(struct buffer *buffer,
- struct command_list *commands,
- uint32_t width, uint32_t height,
- uint64_t frame_time, void *userdata);
+ struct command_list *commands, uint64_t frame_time,
+ uint32_t *relline, uint32_t *relcol);
// commands
#define BUFFER_WRAPCMD(fn) \
diff --git a/src/display.c b/src/display.c
index 94b1c36..146d31e 100644
--- a/src/display.c
+++ b/src/display.c
@@ -5,21 +5,48 @@
#include <stdarg.h>
#include <stdio.h>
+#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#define ESC 0x1b
-struct display display_create() {
+struct render_command {
+ uint32_t col;
+ uint32_t row;
+
+ uint8_t *data;
+ uint32_t len;
+
+ uint8_t *fmt;
+ uint32_t fmt_len;
+};
+
+struct command_list {
+ struct render_command *cmds;
+ uint64_t ncmds;
+ uint64_t capacity;
+
+ uint32_t xoffset;
+ uint32_t yoffset;
+
+ uint8_t format[64];
+ uint32_t format_len;
+ alloc_fn allocator;
+
+ char name[16];
+};
+
+struct winsize getsize() {
struct winsize ws;
- if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0) {
- // TODO: if it fails to fetch, do something?
- return (struct display){
- .height = 0,
- .width = 0,
- };
- }
+ ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
+ return ws;
+}
+
+struct display display_create() {
+
+ struct winsize ws = getsize();
// save old settings
struct termios orig_term;
@@ -28,9 +55,6 @@ struct display display_create() {
// set terminal to raw mode
struct termios term;
cfmakeraw(&term);
- // TODO: move to kbd?
- term.c_cc[VMIN] = 0;
- term.c_cc[VTIME] = 0;
tcsetattr(0, TCSADRAIN, &term);
@@ -42,6 +66,12 @@ struct display display_create() {
};
}
+void display_resize(struct display *display) {
+ struct winsize sz = getsize();
+ display->width = sz.ws_col;
+ display->height = sz.ws_row;
+}
+
void display_destroy(struct display *display) {
// reset old terminal mode
tcsetattr(0, TCSADRAIN, &display->orig_term);
@@ -73,6 +103,19 @@ void put_ansiparm(int n) {
putbyte((n % 10) + '0');
}
+void put_format(uint8_t *bytes, uint32_t nbytes) {
+ putbyte(ESC);
+ putbyte('[');
+ putbyte('0');
+
+ if (nbytes > 0) {
+ putbyte(';');
+ putbytes(bytes, nbytes);
+ }
+
+ putbyte('m');
+}
+
void display_move_cursor(struct display *display, uint32_t row, uint32_t col) {
putbyte(ESC);
putbyte('[');
@@ -94,7 +137,8 @@ void delete_to_eol() {
}
struct command_list *command_list_create(uint32_t capacity, alloc_fn allocator,
- uint32_t xoffset, uint32_t yoffset) {
+ uint32_t xoffset, uint32_t yoffset,
+ const char *name) {
struct command_list *command_list = allocator(sizeof(struct command_list));
command_list->capacity = capacity;
@@ -102,8 +146,10 @@ struct command_list *command_list_create(uint32_t capacity, alloc_fn allocator,
command_list->xoffset = xoffset;
command_list->yoffset = yoffset;
command_list->format_len = 0;
+ strncpy(command_list->name, name, 15);
command_list->cmds = allocator(sizeof(struct render_command) * capacity);
+ command_list->allocator = allocator;
return command_list;
}
@@ -111,78 +157,71 @@ struct command_list *command_list_create(uint32_t capacity, alloc_fn allocator,
void push_format(struct command_list *list, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
- if (list->format_len == 0) {
- list->format[0] = ESC;
- list->format[1] = '[';
-
- list->format_len = 2;
- }
- if (list->format_len > 2) {
+ if (list->format_len > 0) {
list->format[list->format_len] = ';';
++list->format_len;
}
- uint32_t format_space_left = sizeof(list->format) - 1 - list->format_len;
+ uint32_t format_space_left = sizeof(list->format) - list->format_len;
list->format_len += vsnprintf((char *)(list->format + list->format_len),
format_space_left, fmt, args);
va_end(args);
}
-void flush_format(struct command_list *list, uint32_t col, uint32_t row) {
- list->format[list->format_len] = 'm';
- ++list->format_len;
-
- struct render_command *cmd = &list->cmds[list->ncmds];
- cmd->data = list->format;
- cmd->col = col + list->xoffset;
- cmd->row = row + list->yoffset;
- cmd->len = list->format_len;
-
- list->format_len = 0;
-
- ++list->ncmds;
+void set_cmd_format(struct command_list *list, struct render_command *cmd) {
+ if (list->format_len > 0) {
+ cmd->fmt = list->allocator(list->format_len);
+ memcpy(cmd->fmt, list->format, list->format_len);
+ cmd->fmt_len = list->format_len;
+ } else {
+ cmd->fmt = NULL;
+ cmd->fmt_len = 0;
+ }
}
+void reset_format(struct command_list *list) { list->format_len = 0; }
+
void command_list_draw_text(struct command_list *list, uint32_t col,
uint32_t row, uint8_t *data, uint32_t len) {
- uint32_t needed_capacity = list->ncmds + 1;
- if (list->format_len > 0) {
- ++needed_capacity;
- }
-
- if (needed_capacity > list->capacity) {
+ if (list->ncmds == list->capacity) {
// TODO: better
return;
}
- if (list->format_len > 0) {
- flush_format(list, col, row);
- }
-
struct render_command *cmd = &list->cmds[list->ncmds];
cmd->data = data;
cmd->col = col + list->xoffset;
cmd->row = row + list->yoffset;
cmd->len = len;
+ set_cmd_format(list, cmd);
+
++list->ncmds;
}
+void command_list_draw_text_copy(struct command_list *list, uint32_t col,
+ uint32_t row, uint8_t *data, uint32_t len) {
+ uint8_t *bytes = (uint8_t *)list->allocator(len);
+ memcpy(bytes, data, len);
+
+ command_list_draw_text(list, col, row, bytes, len);
+}
+
void command_list_set_index_color_fg(struct command_list *list,
uint8_t color_idx) {
if (color_idx < 8) {
push_format(list, "%d", 30 + color_idx);
} else if (color_idx < 16) {
- push_format(list, "%d", 90 + color_idx);
+ push_format(list, "%d", 90 + color_idx - 8);
} else {
- push_format(list, "30;5;%d", color_idx);
+ push_format(list, "38;5;%d", color_idx);
}
}
void command_list_set_color_fg(struct command_list *list, uint8_t red,
uint8_t green, uint8_t blue) {
- push_format(list, "30;2;%d;%d;%d", red, green, blue);
+ push_format(list, "38;2;%d;%d;%d", red, green, blue);
}
void command_list_set_index_color_bg(struct command_list *list,
@@ -190,20 +229,18 @@ void command_list_set_index_color_bg(struct command_list *list,
if (color_idx < 8) {
push_format(list, "%d", 40 + color_idx);
} else if (color_idx < 16) {
- push_format(list, "%d", 100 + color_idx);
+ push_format(list, "%d", 100 + color_idx - 8);
} else {
- push_format(list, "40;5;%d", color_idx);
+ push_format(list, "48;5;%d", color_idx);
}
}
void command_list_set_color_bg(struct command_list *list, uint8_t red,
uint8_t green, uint8_t blue) {
- push_format(list, "40;2;%d;%d;%d", red, green, blue);
+ push_format(list, "48;2;%d;%d;%d", red, green, blue);
}
-void command_list_reset_color(struct command_list *list) {
- push_format(list, "0");
-}
+void command_list_reset_color(struct command_list *list) { reset_format(list); }
void display_render(struct display *display,
struct command_list *command_list) {
@@ -213,6 +250,7 @@ void display_render(struct display *display,
for (uint64_t cmdi = 0; cmdi < cl->ncmds; ++cmdi) {
struct render_command *cmd = &cl->cmds[cmdi];
display_move_cursor(display, cmd->row, cmd->col);
+ put_format(cmd->fmt, cmd->fmt_len);
putbytes(cmd->data, cmd->len);
delete_to_eol();
}
diff --git a/src/display.h b/src/display.h
index c1c3667..e518b34 100644
--- a/src/display.h
+++ b/src/display.h
@@ -10,26 +10,11 @@ struct display {
uint32_t height;
};
-struct render_command {
- uint32_t col;
- uint32_t row;
-
- uint8_t *data;
- uint32_t len;
-};
-
-struct command_list {
- struct render_command *cmds;
- uint64_t ncmds;
- uint64_t capacity;
- uint32_t xoffset;
- uint32_t yoffset;
-
- uint8_t format[64];
- uint32_t format_len;
-};
+struct render_command;
+struct command_list;
struct display display_create();
+void display_resize(struct display *display);
void display_destroy(struct display *display);
void display_clear(struct display *display);
@@ -41,7 +26,8 @@ void display_end_render(struct display *display);
typedef void *(*alloc_fn)(size_t);
struct command_list *command_list_create(uint32_t capacity, alloc_fn allocator,
- uint32_t xoffset, uint32_t yoffset);
+ uint32_t xoffset, uint32_t yoffset,
+ const char *name);
void command_list_set_index_color_bg(struct command_list *list,
uint8_t color_idx);
@@ -54,3 +40,5 @@ void command_list_set_color_fg(struct command_list *list, uint8_t red,
void command_list_reset_color(struct command_list *list);
void command_list_draw_text(struct command_list *list, uint32_t col,
uint32_t row, uint8_t *data, uint32_t len);
+void command_list_draw_text_copy(struct command_list *list, uint32_t col,
+ uint32_t row, uint8_t *data, uint32_t len);
diff --git a/src/keyboard.c b/src/keyboard.c
index ae74e8e..e2cdc34 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1,3 +1,4 @@
+#define _DEFAULT_SOURCE
#include "keyboard.h"
#include "reactor.h"
#include "stdio.h"
@@ -6,10 +7,18 @@
#include <ctype.h>
#include <errno.h>
#include <string.h>
+#include <termios.h>
#include <unistd.h>
struct keyboard keyboard_create(struct reactor *reactor) {
- // TODO: should input term stuff be set here?
+ struct termios term;
+ tcgetattr(0, &term);
+
+ // set input to non-blocking
+ term.c_cc[VMIN] = 0;
+ term.c_cc[VTIME] = 0;
+ tcsetattr(0, TCSADRAIN, &term);
+
return (struct keyboard){
.reactor_event_id =
reactor_register_interest(reactor, STDIN_FILENO, ReadInterest),
diff --git a/src/main.c b/src/main.c
index ed5417a..f93140d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -46,6 +46,15 @@ bool running = true;
void terminate() { running = false; }
+static struct display display;
+static bool display_resized = false;
+void resized() {
+ display_resize(&display);
+ display_resized = true;
+
+ signal(SIGWINCH, resized);
+}
+
int32_t _abort(struct command_ctx ctx, int argc, const char *argv[]) {
minibuffer_echo_timeout(4, "💣 aborted");
return 0;
@@ -105,9 +114,10 @@ struct window {
};
void window_update_buffer(struct window *window, struct command_list *commands,
- uint64_t frame_time) {
+ uint64_t frame_time, uint32_t *relline,
+ uint32_t *relcol) {
buffer_update(window->buffer, window->width, window->height, commands,
- frame_time);
+ frame_time, relline, relcol);
}
void buffers_init(struct buffers *buffers) { buffers->nbuffers = 0; }
@@ -141,8 +151,9 @@ int main(int argc, char *argv[]) {
struct reactor reactor = reactor_create();
// initialize display
- struct display display = display_create();
+ display = display_create();
display_clear(&display);
+ signal(SIGWINCH, resized);
// init keyboard
struct keyboard kbd = keyboard_create(&reactor);
@@ -227,6 +238,13 @@ int main(int argc, char *argv[]) {
clock_gettime(CLOCK_MONOTONIC, &buffer_begin);
+ if (display_resized) {
+ minibuffer_window.width = display.width;
+ main_window.height = display.height - 1;
+ main_window.width = display.width;
+ display_resized = false;
+ }
+
// update windows
uint32_t dot_line = 0, dot_col = 0;
for (uint32_t windowi = 0; windowi < sizeof(windows) / sizeof(windows[0]);
@@ -234,8 +252,17 @@ int main(int argc, char *argv[]) {
struct window *win = windows[windowi];
// TODO: better capacity
command_lists[windowi] =
- command_list_create(win->height * 2, frame_alloc, win->x, win->y);
- window_update_buffer(win, command_lists[windowi], frame_time);
+ command_list_create(win->height * win->width, frame_alloc, win->x,
+ win->y, win->buffer->name);
+
+ uint32_t relline, relcol;
+ window_update_buffer(win, command_lists[windowi], frame_time, &relline,
+ &relcol);
+
+ if (win == active_window) {
+ dot_line = relline;
+ dot_col = relcol;
+ }
}
clock_gettime(CLOCK_MONOTONIC, &buffer_end);
@@ -243,15 +270,14 @@ int main(int argc, char *argv[]) {
// update screen
clock_gettime(CLOCK_MONOTONIC, &display_begin);
uint32_t relline, relcol;
- buffer_relative_dot_pos(active_window->buffer, &relline, &relcol);
display_begin_render(&display);
for (uint32_t windowi = 0; windowi < sizeof(windows) / sizeof(windows[0]);
++windowi) {
display_render(&display, command_lists[windowi]);
}
- display_move_cursor(&display, relline + active_window->y,
- relcol + active_window->x);
+ display_move_cursor(&display, dot_line + active_window->y,
+ dot_col + active_window->x);
display_end_render(&display);
clock_gettime(CLOCK_MONOTONIC, &display_end);
diff --git a/src/minibuffer.c b/src/minibuffer.c
index 762bbe7..b622ab0 100644
--- a/src/minibuffer.c
+++ b/src/minibuffer.c
@@ -11,9 +11,10 @@ static struct minibuffer {
struct timespec expires;
} g_minibuffer = {0};
-struct margin update(struct buffer *buffer, struct command_list *commands,
- uint32_t width, uint32_t height, uint64_t frame_time,
- void *userdata) {
+struct update_hook_result update(struct buffer *buffer,
+ struct command_list *commands, uint32_t width,
+ uint32_t height, uint64_t frame_time,
+ void *userdata) {
struct timespec current;
struct minibuffer *mb = (struct minibuffer *)userdata;
clock_gettime(CLOCK_MONOTONIC, &current);
@@ -21,7 +22,7 @@ struct margin update(struct buffer *buffer, struct command_list *commands,
buffer_clear(buffer);
}
- return (struct margin){0};
+ return (struct update_hook_result){0};
}
void minibuffer_init(struct buffer *buffer) {