From 07b8e9d8a293d63fd9c1059968b53ad396e9f013 Mon Sep 17 00:00:00 2001 From: Randy Palamar Date: Sat, 11 May 2024 10:38:28 -0600 Subject: [PATCH 1/8] cleanup vis event interface This removes the function pointer interface which was adding needless complexity and making it difficult to add new events. Now if new events are only meant for lua they only need to be added to the lua interface. This will also have a minor reduction in runtime memory usage and produce a smaller binary. The only runtime difference is that QUIT happens after all windows have been closed and their files freed. --- Makefile | 7 +- event-basic.c | 23 ++++++ main.c | 21 +---- view.c | 103 ++++++++++++++++++++++++- vis-core.h | 4 +- vis-lua.c | 208 +++++++++++++++++++++----------------------------- vis-lua.h | 21 +---- vis.c | 112 ++++----------------------- vis.h | 25 +----- 9 files changed, 236 insertions(+), 288 deletions(-) create mode 100644 event-basic.c diff --git a/Makefile b/Makefile index 7e77c7fd8..a2f1df35f 100644 --- a/Makefile +++ b/Makefile @@ -4,20 +4,20 @@ REGEX_SRC ?= text-regex.c SRC = array.c \ buffer.c \ + event-basic.c \ libutf.c \ main.c \ map.c \ sam.c \ - text.c \ text-common.c \ text-io.c \ text-iterator.c \ text-motions.c \ text-objects.c \ text-util.c \ + text.c \ ui-terminal.c \ view.c \ - vis.c \ vis-lua.c \ vis-marks.c \ vis-modes.c \ @@ -25,8 +25,9 @@ SRC = array.c \ vis-operators.c \ vis-prompt.c \ vis-registers.c \ - vis-text-objects.c \ vis-subprocess.c \ + vis-text-objects.c \ + vis.c \ $(REGEX_SRC) OBJ = $(SRC:%.c=obj/%.o) diff --git a/event-basic.c b/event-basic.c new file mode 100644 index 000000000..6d298b516 --- /dev/null +++ b/event-basic.c @@ -0,0 +1,23 @@ +#include + +#include "vis-core.h" + +#if !CONFIG_LUA +bool vis_event_emit(Vis *vis, enum VisEvents id, ...) { + if (!vis->initialized) { + vis->initialized = true; + vis->ui->init(vis->ui, vis); + } + + va_list ap; + va_start(ap, id); + + if (id == VIS_EVENT_WIN_STATUS) { + Win *win = va_arg(ap, Win*); + window_status_update(vis, win); + } + + va_end(ap); + return true; +} +#endif diff --git a/main.c b/main.c index 8aa31c6b8..41726df64 100644 --- a/main.c +++ b/main.c @@ -2213,26 +2213,7 @@ static void signal_handler(int signum, siginfo_t *siginfo, void *context) { } int main(int argc, char *argv[]) { - - VisEvent event = { - .init = vis_lua_init, - .start = vis_lua_start, - .quit = vis_lua_quit, - .mode_insert_input = vis_lua_mode_insert_input, - .mode_replace_input = vis_lua_mode_replace_input, - .file_open = vis_lua_file_open, - .file_save_pre = vis_lua_file_save_pre, - .file_save_post = vis_lua_file_save_post, - .file_close = vis_lua_file_close, - .win_open = vis_lua_win_open, - .win_close = vis_lua_win_close, - .win_highlight = vis_lua_win_highlight, - .win_status = vis_lua_win_status, - .term_csi = vis_lua_term_csi, - .ui_draw = vis_lua_ui_draw, - }; - - vis = vis_new(ui_term_new(), &event); + vis = vis_new(ui_term_new()); if (!vis) return EXIT_FAILURE; diff --git a/view.c b/view.c index df7906b54..f27760b9d 100644 --- a/view.c +++ b/view.c @@ -1,9 +1,12 @@ -#include -#include -#include #include #include #include +#include +#include +#include +#include + +#include "vis-core.h" #include "view.h" #include "text.h" #include "text-motions.h" @@ -119,6 +122,100 @@ static void selection_free(Selection*); /* set/move current cursor position to a given (line, column) pair */ static size_t cursor_set(Selection*, Line *line, int col); +void window_status_update(Vis *vis, Win *win) { + char left_parts[4][255] = { "", "", "", "" }; + char right_parts[4][32] = { "", "", "", "" }; + char left[sizeof(left_parts)+LENGTH(left_parts)*8]; + char right[sizeof(right_parts)+LENGTH(right_parts)*8]; + char status[sizeof(left)+sizeof(right)+1]; + size_t left_count = 0; + size_t right_count = 0; + + View *view = win->view; + File *file = win->file; + Text *txt = file->text; + int width = vis_window_width_get(win); + enum UiOption options = view_options_get(view); + bool focused = vis->win == win; + const char *filename = file_name_get(file); + const char *mode = vis->mode->status; + + if (focused && mode) + strcpy(left_parts[left_count++], mode); + + snprintf(left_parts[left_count++], sizeof(left_parts[0]), "%s%s%s", + filename ? filename : "[No Name]", + text_modified(txt) ? " [+]" : "", + vis_macro_recording(vis) ? " @": ""); + + int count = vis_count_get(vis); + const char *keys = buffer_content0(&vis->input_queue); + if (keys && keys[0]) + snprintf(right_parts[right_count++], sizeof(right_parts[0]), "%s", keys); + else if (count != VIS_COUNT_UNKNOWN) + snprintf(right_parts[right_count++], sizeof(right_parts[0]), "%d", count); + + int sel_count = view_selections_count(view); + if (sel_count > 1) { + Selection *s = view_selections_primary_get(view); + int sel_number = view_selections_number(s) + 1; + snprintf(right_parts[right_count++], sizeof(right_parts[0]), + "%d/%d", sel_number, sel_count); + } + + size_t size = text_size(txt); + size_t pos = view_cursor_get(view); + size_t percent = 0; + if (size > 0) { + double tmp = ((double)pos/(double)size)*100; + percent = (size_t)(tmp+1); + } + snprintf(right_parts[right_count++], sizeof(right_parts[0]), + "%zu%%", percent); + + if (!(options & UI_OPTION_LARGE_FILE)) { + Selection *sel = view_selections_primary_get(win->view); + size_t line = view_cursors_line(sel); + size_t col = view_cursors_col(sel); + if (col > UI_LARGE_FILE_LINE_SIZE) { + options |= UI_OPTION_LARGE_FILE; + view_options_set(win->view, options); + } + snprintf(right_parts[right_count++], sizeof(right_parts[0]), + "%zu, %zu", line, col); + } + + int left_len = snprintf(left, sizeof(left), " %s%s%s%s%s%s%s", + left_parts[0], + left_parts[1][0] ? " » " : "", + left_parts[1], + left_parts[2][0] ? " » " : "", + left_parts[2], + left_parts[3][0] ? " » " : "", + left_parts[3]); + + int right_len = snprintf(right, sizeof(right), "%s%s%s%s%s%s%s ", + right_parts[0], + right_parts[1][0] ? " « " : "", + right_parts[1], + right_parts[2][0] ? " « " : "", + right_parts[2], + right_parts[3][0] ? " « " : "", + right_parts[3]); + + if (left_len < 0 || right_len < 0) + return; + int left_width = text_string_width(left, left_len); + int right_width = text_string_width(right, right_len); + + int spaces = width - left_width - right_width; + if (spaces < 1) + spaces = 1; + + snprintf(status, sizeof(status), "%s%*s%s", left, spaces, " ", right); + vis_window_status(win, status); +} + void view_tabwidth_set(View *view, int tabwidth) { if (tabwidth < 1 || tabwidth > 8) return; diff --git a/vis-core.h b/vis-core.h index 4f81e4cbd..9746fc9d9 100644 --- a/vis-core.h +++ b/vis-core.h @@ -215,7 +215,6 @@ struct Vis { Array actions_user; /* dynamically allocated editor actions */ lua_State *lua; /* lua context used for syntax highlighting */ enum TextLoadMethod load_method; /* how existing files should be loaded */ - VisEvent *event; Array operators; Array motions; Array textobjects; @@ -268,8 +267,9 @@ Mode *mode_get(Vis*, enum VisMode); void mode_set(Vis *vis, Mode *new_mode); Macro *macro_get(Vis *vis, enum VisRegister); -void window_selection_save(Win *win); Win *window_new_file(Vis*, File*, enum UiOption); +void window_selection_save(Win *win); +void window_status_update(Vis *vis, Win *win); char *absolute_path(const char *path); diff --git a/vis-lua.c b/vis-lua.c index ca36d2d5e..22464034b 100644 --- a/vis-lua.c +++ b/vis-lua.c @@ -54,119 +54,13 @@ #define debug(...) do { } while (0) #endif -static void window_status_update(Vis *vis, Win *win) { - char left_parts[4][255] = { "", "", "", "" }; - char right_parts[4][32] = { "", "", "", "" }; - char left[sizeof(left_parts)+LENGTH(left_parts)*8]; - char right[sizeof(right_parts)+LENGTH(right_parts)*8]; - char status[sizeof(left)+sizeof(right)+1]; - size_t left_count = 0; - size_t right_count = 0; - - View *view = win->view; - File *file = win->file; - Text *txt = file->text; - int width = vis_window_width_get(win); - enum UiOption options = view_options_get(view); - bool focused = vis->win == win; - const char *filename = file_name_get(file); - const char *mode = vis->mode->status; - - if (focused && mode) - strcpy(left_parts[left_count++], mode); - - snprintf(left_parts[left_count++], sizeof(left_parts[0]), "%s%s%s", - filename ? filename : "[No Name]", - text_modified(txt) ? " [+]" : "", - vis_macro_recording(vis) ? " @": ""); - - int count = vis_count_get(vis); - const char *keys = buffer_content0(&vis->input_queue); - if (keys && keys[0]) - snprintf(right_parts[right_count++], sizeof(right_parts[0]), "%s", keys); - else if (count != VIS_COUNT_UNKNOWN) - snprintf(right_parts[right_count++], sizeof(right_parts[0]), "%d", count); - - int sel_count = view_selections_count(view); - if (sel_count > 1) { - Selection *s = view_selections_primary_get(view); - int sel_number = view_selections_number(s) + 1; - snprintf(right_parts[right_count++], sizeof(right_parts[0]), - "%d/%d", sel_number, sel_count); - } - - size_t size = text_size(txt); - size_t pos = view_cursor_get(view); - size_t percent = 0; - if (size > 0) { - double tmp = ((double)pos/(double)size)*100; - percent = (size_t)(tmp+1); - } - snprintf(right_parts[right_count++], sizeof(right_parts[0]), - "%zu%%", percent); - - if (!(options & UI_OPTION_LARGE_FILE)) { - Selection *sel = view_selections_primary_get(win->view); - size_t line = view_cursors_line(sel); - size_t col = view_cursors_col(sel); - if (col > UI_LARGE_FILE_LINE_SIZE) { - options |= UI_OPTION_LARGE_FILE; - view_options_set(win->view, options); - } - snprintf(right_parts[right_count++], sizeof(right_parts[0]), - "%zu, %zu", line, col); - } - - int left_len = snprintf(left, sizeof(left), " %s%s%s%s%s%s%s", - left_parts[0], - left_parts[1][0] ? " » " : "", - left_parts[1], - left_parts[2][0] ? " » " : "", - left_parts[2], - left_parts[3][0] ? " » " : "", - left_parts[3]); - - int right_len = snprintf(right, sizeof(right), "%s%s%s%s%s%s%s ", - right_parts[0], - right_parts[1][0] ? " « " : "", - right_parts[1], - right_parts[2][0] ? " « " : "", - right_parts[2], - right_parts[3][0] ? " « " : "", - right_parts[3]); - - if (left_len < 0 || right_len < 0) - return; - int left_width = text_string_width(left, left_len); - int right_width = text_string_width(right, right_len); - - int spaces = width - left_width - right_width; - if (spaces < 1) - spaces = 1; - - snprintf(status, sizeof(status), "%s%*s%s", left, spaces, " ", right); - vis_window_status(win, status); -} #if !CONFIG_LUA bool vis_lua_path_add(Vis *vis, const char *path) { return true; } bool vis_lua_paths_get(Vis *vis, char **lpath, char **cpath) { return false; } -void vis_lua_init(Vis *vis) { } -void vis_lua_start(Vis *vis) { } -void vis_lua_quit(Vis *vis) { } -void vis_lua_file_open(Vis *vis, File *file) { } -bool vis_lua_file_save_pre(Vis *vis, File *file, const char *path) { return true; } -void vis_lua_file_save_post(Vis *vis, File *file, const char *path) { } -void vis_lua_file_close(Vis *vis, File *file) { } -void vis_lua_win_open(Vis *vis, Win *win) { } -void vis_lua_win_close(Vis *vis, Win *win) { } -void vis_lua_win_highlight(Vis *vis, Win *win) { } -void vis_lua_win_status(Vis *vis, Win *win) { window_status_update(vis, win); } -void vis_lua_term_csi(Vis *vis, const long *csi) { } void vis_lua_process_response(Vis *vis, const char *name, char *buffer, size_t len, ResponseType rtype) { } -void vis_lua_ui_draw(Vis *vis) { } #else @@ -3213,7 +3107,7 @@ static void *alloc_lua(void *ud, void *ptr, size_t osize, size_t nsize) { * Can be used to set *global* configuration options. * @function init */ -void vis_lua_init(Vis *vis) { +static void vis_lua_init(Vis *vis) { lua_State *L = lua_newstate(alloc_lua, vis); if (!L) return; @@ -3432,7 +3326,7 @@ void vis_lua_init(Vis *vis) { * We are about to process interactive keyboard input. * @function start */ -void vis_lua_start(Vis *vis) { +static void vis_lua_start(Vis *vis) { vis_lua_event_call(vis, "start"); } @@ -3440,7 +3334,7 @@ void vis_lua_start(Vis *vis) { * Editor is about to terminate. * @function quit */ -void vis_lua_quit(Vis *vis) { +static void vis_lua_quit(Vis *vis) { if (!vis->lua) return; vis_lua_event_call(vis, "quit"); @@ -3471,12 +3365,12 @@ static bool vis_lua_input(Vis *vis, const char *key, size_t len) { return ret; } -void vis_lua_mode_insert_input(Vis *vis, const char *key, size_t len) { +void vis_event_mode_insert_input(Vis *vis, const char *key, size_t len) { if (!vis_lua_input(vis, key, len)) vis_insert_key(vis, key, len); } -void vis_lua_mode_replace_input(Vis *vis, const char *key, size_t len) { +void vis_event_mode_replace_input(Vis *vis, const char *key, size_t len) { if (!vis_lua_input(vis, key, len)) vis_replace_key(vis, key, len); } @@ -3486,7 +3380,7 @@ void vis_lua_mode_replace_input(Vis *vis, const char *key, size_t len) { * @function file_open * @tparam File file the file to be opened */ -void vis_lua_file_open(Vis *vis, File *file) { +static void vis_lua_file_open(Vis *vis, File *file) { debug("event: file-open: %s %p %p\n", file->name ? file->name : "unnamed", (void*)file, (void*)file->text); lua_State *L = vis->lua; if (!L) @@ -3507,7 +3401,7 @@ void vis_lua_file_open(Vis *vis, File *file) { * @tparam string path the absolute path to which the file will be written, `nil` if standard output * @treturn bool whether the write operation should be proceeded */ -bool vis_lua_file_save_pre(Vis *vis, File *file, const char *path) { +static bool vis_lua_file_save_pre(Vis *vis, File *file, const char *path) { lua_State *L = vis->lua; if (!L) return true; @@ -3530,7 +3424,7 @@ bool vis_lua_file_save_pre(Vis *vis, File *file, const char *path) { * @tparam File file the file which was written * @tparam string path the absolute path to which it was written, `nil` if standard output */ -void vis_lua_file_save_post(Vis *vis, File *file, const char *path) { +static void vis_lua_file_save_post(Vis *vis, File *file, const char *path) { lua_State *L = vis->lua; if (!L) return; @@ -3549,7 +3443,7 @@ void vis_lua_file_save_post(Vis *vis, File *file, const char *path) { * @function file_close * @tparam File file the file being closed */ -void vis_lua_file_close(Vis *vis, File *file) { +static void vis_lua_file_close(Vis *vis, File *file) { debug("event: file-close: %s %p %p\n", file->name ? file->name : "unnamed", (void*)file, (void*)file->text); lua_State *L = vis->lua; if (!L) @@ -3571,7 +3465,7 @@ void vis_lua_file_close(Vis *vis, File *file) { * @function win_open * @tparam Window win the window being opened */ -void vis_lua_win_open(Vis *vis, Win *win) { +static void vis_lua_win_open(Vis *vis, Win *win) { debug("event: win-open: %s %p %p\n", win->file->name ? win->file->name : "unnamed", (void*)win, (void*)win->view); lua_State *L = vis->lua; if (!L) @@ -3590,7 +3484,7 @@ void vis_lua_win_open(Vis *vis, Win *win) { * @function win_close * @tparam Window win the window being closed */ -void vis_lua_win_close(Vis *vis, Win *win) { +static void vis_lua_win_close(Vis *vis, Win *win) { debug("event: win-close: %s %p %p\n", win->file->name ? win->file->name : "unnamed", (void*)win, (void*)win->view); lua_State *L = vis->lua; if (!L) @@ -3612,7 +3506,7 @@ void vis_lua_win_close(Vis *vis, Win *win) { * @tparam Window win the window being redrawn * @see style */ -void vis_lua_win_highlight(Vis *vis, Win *win) { +static void vis_lua_win_highlight(Vis *vis, Win *win) { lua_State *L = vis->lua; if (!L) return; @@ -3630,7 +3524,7 @@ void vis_lua_win_highlight(Vis *vis, Win *win) { * @tparam Window win the affected window * @see status */ -void vis_lua_win_status(Vis *vis, Win *win) { +static void vis_lua_win_status(Vis *vis, Win *win) { lua_State *L = vis->lua; if (!L || win->file->internal) { window_status_update(vis, win); @@ -3651,7 +3545,7 @@ void vis_lua_win_status(Vis *vis, Win *win) { * @function term_csi * @param List of CSI parameters */ -void vis_lua_term_csi(Vis *vis, const long *csi) { +static void vis_lua_term_csi(Vis *vis, const long *csi) { lua_State *L = vis->lua; if (!L) return; @@ -3711,8 +3605,80 @@ void vis_lua_process_response(Vis *vis, const char *name, * Use sparingly and check for `nil` values! * @function ui_draw */ -void vis_lua_ui_draw(Vis *vis) { +static void vis_lua_ui_draw(Vis *vis) { vis_lua_event_call(vis, "ui_draw"); } +bool vis_event_emit(Vis *vis, enum VisEvents id, ...) { + if (!vis->initialized) { + vis->initialized = true; + vis->ui->init(vis->ui, vis); + vis_lua_init(vis); + } + + va_list ap; + va_start(ap, id); + bool ret = true; + + switch (id) { + case VIS_EVENT_INIT: + break; + case VIS_EVENT_START: + vis_lua_start(vis); + break; + case VIS_EVENT_FILE_OPEN: + case VIS_EVENT_FILE_SAVE_PRE: + case VIS_EVENT_FILE_SAVE_POST: + case VIS_EVENT_FILE_CLOSE: + { + File *file = va_arg(ap, File*); + if (file->internal) + break; + if (id == VIS_EVENT_FILE_OPEN) { + vis_lua_file_open(vis, file); + } else if (id == VIS_EVENT_FILE_SAVE_PRE) { + const char *path = va_arg(ap, const char*); + ret = vis_lua_file_save_pre(vis, file, path); + } else if (id == VIS_EVENT_FILE_SAVE_POST) { + const char *path = va_arg(ap, const char*); + vis_lua_file_save_post(vis, file, path); + } else if (id == VIS_EVENT_FILE_CLOSE) { + vis_lua_file_close(vis, file); + } + break; + } + case VIS_EVENT_WIN_OPEN: + case VIS_EVENT_WIN_CLOSE: + case VIS_EVENT_WIN_HIGHLIGHT: + case VIS_EVENT_WIN_STATUS: + { + Win *win = va_arg(ap, Win*); + if (win->file->internal && id != VIS_EVENT_WIN_STATUS) + break; + if (id == VIS_EVENT_WIN_OPEN) { + vis_lua_win_open(vis, win); + } else if (id == VIS_EVENT_WIN_CLOSE) { + vis_lua_win_close(vis, win); + } else if (id == VIS_EVENT_WIN_HIGHLIGHT) { + vis_lua_win_highlight(vis, win); + } else if (id == VIS_EVENT_WIN_STATUS) { + vis_lua_win_status(vis, win); + } + break; + } + case VIS_EVENT_QUIT: + vis_lua_quit(vis); + break; + case VIS_EVENT_TERM_CSI: + vis_lua_term_csi(vis, va_arg(ap, const long *)); + break; + case VIS_EVENT_UI_DRAW: + vis_lua_ui_draw(vis); + break; + } + + va_end(ap); + return ret; +} + #endif diff --git a/vis-lua.h b/vis-lua.h index b4f3f51bb..76e7029ff 100644 --- a/vis-lua.h +++ b/vis-lua.h @@ -22,26 +22,13 @@ bool vis_lua_path_add(Vis*, const char *path); bool vis_lua_paths_get(Vis*, char **lpath, char **cpath); /* various event handlers, triggered by the vis core */ -void vis_lua_init(Vis*); -void vis_lua_start(Vis*); -void vis_lua_quit(Vis*); #if !CONFIG_LUA -#define vis_lua_mode_insert_input vis_insert_key -#define vis_lua_mode_replace_input vis_replace_key +#define vis_event_mode_insert_input vis_insert_key +#define vis_event_mode_replace_input vis_replace_key #else -void vis_lua_mode_insert_input(Vis*, const char *key, size_t len); -void vis_lua_mode_replace_input(Vis*, const char *key, size_t len); +void vis_event_mode_insert_input(Vis*, const char *key, size_t len); +void vis_event_mode_replace_input(Vis*, const char *key, size_t len); #endif -void vis_lua_file_open(Vis*, File*); -bool vis_lua_file_save_pre(Vis*, File*, const char *path); -void vis_lua_file_save_post(Vis*, File*, const char *path); -void vis_lua_file_close(Vis*, File*); -void vis_lua_win_open(Vis*, Win*); -void vis_lua_win_close(Vis*, Win*); -void vis_lua_win_highlight(Vis*, Win*); -void vis_lua_win_status(Vis*, Win*); -void vis_lua_term_csi(Vis*, const long *); void vis_lua_process_response(Vis *, const char *, char *, size_t, ResponseType); -void vis_lua_ui_draw(Vis*); #endif diff --git a/vis.c b/vis.c index cabad6780..616b46393 100644 --- a/vis.c +++ b/vis.c @@ -35,86 +35,6 @@ static void macro_replay(Vis *vis, const Macro *macro); static void macro_replay_internal(Vis *vis, const Macro *macro); static void vis_keys_push(Vis *vis, const char *input, size_t pos, bool record); -bool vis_event_emit(Vis *vis, enum VisEvents id, ...) { - if (!vis->event) - return true; - - if (!vis->initialized) { - vis->initialized = true; - vis->ui->init(vis->ui, vis); - if (vis->event->init) - vis->event->init(vis); - } - - va_list ap; - va_start(ap, id); - bool ret = true; - - switch (id) { - case VIS_EVENT_INIT: - break; - case VIS_EVENT_START: - if (vis->event->start) - vis->event->start(vis); - break; - case VIS_EVENT_FILE_OPEN: - case VIS_EVENT_FILE_SAVE_PRE: - case VIS_EVENT_FILE_SAVE_POST: - case VIS_EVENT_FILE_CLOSE: - { - File *file = va_arg(ap, File*); - if (file->internal) - break; - if (id == VIS_EVENT_FILE_OPEN && vis->event->file_open) { - vis->event->file_open(vis, file); - } else if (id == VIS_EVENT_FILE_SAVE_PRE && vis->event->file_save_pre) { - const char *path = va_arg(ap, const char*); - ret = vis->event->file_save_pre(vis, file, path); - } else if (id == VIS_EVENT_FILE_SAVE_POST && vis->event->file_save_post) { - const char *path = va_arg(ap, const char*); - vis->event->file_save_post(vis, file, path); - } else if (id == VIS_EVENT_FILE_CLOSE && vis->event->file_close) { - vis->event->file_close(vis, file); - } - break; - } - case VIS_EVENT_WIN_OPEN: - case VIS_EVENT_WIN_CLOSE: - case VIS_EVENT_WIN_HIGHLIGHT: - case VIS_EVENT_WIN_STATUS: - { - Win *win = va_arg(ap, Win*); - if (win->file->internal && id != VIS_EVENT_WIN_STATUS) - break; - if (vis->event->win_open && id == VIS_EVENT_WIN_OPEN) { - vis->event->win_open(vis, win); - } else if (vis->event->win_close && id == VIS_EVENT_WIN_CLOSE) { - vis->event->win_close(vis, win); - } else if (vis->event->win_highlight && id == VIS_EVENT_WIN_HIGHLIGHT) { - vis->event->win_highlight(vis, win); - } else if (vis->event->win_status && id == VIS_EVENT_WIN_STATUS) { - vis->event->win_status(vis, win); - } - break; - } - case VIS_EVENT_QUIT: - if (vis->event->quit) - vis->event->quit(vis); - break; - case VIS_EVENT_TERM_CSI: - if (vis->event->term_csi) - vis->event->term_csi(vis, va_arg(ap, const long *)); - break; - case VIS_EVENT_UI_DRAW: - if (vis->event->ui_draw) - vis->event->ui_draw(vis); - break; - } - - va_end(ap); - return ret; -} - /** window / file handling */ static void file_free(Vis *vis, File *file) { @@ -182,7 +102,7 @@ char *absolute_path(const char *name) { return path_normalized[0] ? strdup(path_normalized) : NULL; } -static File *file_new(Vis *vis, const char *name) { +static File *file_new(Vis *vis, const char *name, bool internal) { char *name_absolute = NULL; bool cmp_names = 0; struct stat new; @@ -225,7 +145,9 @@ static File *file_new(Vis *vis, const char *name) { if (!(file = file_new_text(vis, text))) goto err; file->name = name_absolute; - vis_event_emit(vis, VIS_EVENT_FILE_OPEN, file); + file->internal = internal; + if (!internal) + vis_event_emit(vis, VIS_EVENT_FILE_OPEN, file); return file; err: free(name_absolute); @@ -235,11 +157,9 @@ static File *file_new(Vis *vis, const char *name) { } static File *file_new_internal(Vis *vis, const char *filename) { - File *file = file_new(vis, filename); - if (file) { + File *file = file_new(vis, filename, true); + if (file) file->refcount = 1; - file->internal = true; - } return file; } @@ -495,7 +415,7 @@ bool vis_window_reload(Win *win) { return false; /* can't reload unsaved file */ /* temporarily unset file name, otherwise file_new returns the same File */ win->file->name = NULL; - File *file = file_new(win->vis, name); + File *file = file_new(win->vis, name, false); win->file->name = name; if (!file) return false; @@ -507,7 +427,7 @@ bool vis_window_reload(Win *win) { } bool vis_window_change_file(Win *win, const char* filename) { - File *file = file_new(win->vis, filename); + File *file = file_new(win->vis, filename, false); if (!file) return false; file->refcount++; @@ -596,7 +516,7 @@ void vis_doupdates(Vis *vis, bool doupdate) { } bool vis_window_new(Vis *vis, const char *filename) { - File *file = file_new(vis, filename); + File *file = file_new(vis, filename, false); if (!file) return false; vis_doupdates(vis, false); @@ -676,7 +596,7 @@ void vis_window_close(Win *win) { vis_draw(vis); } -Vis *vis_new(Ui *ui, VisEvent *event) { +Vis *vis_new(Ui *ui) { if (!ui) return NULL; Vis *vis = calloc(1, sizeof(Vis)); @@ -719,13 +639,8 @@ Vis *vis_new(Ui *ui, VisEvent *event) { if (!(vis->shell = strdup(shell))) goto err; vis->mode_prev = vis->mode = &vis_modes[VIS_MODE_NORMAL]; - vis->event = event; - if (event) { - if (event->mode_insert_input) - vis_modes[VIS_MODE_INSERT].input = event->mode_insert_input; - if (event->mode_replace_input) - vis_modes[VIS_MODE_REPLACE].input = event->mode_replace_input; - } + vis_modes[VIS_MODE_INSERT].input = vis_event_mode_insert_input; + vis_modes[VIS_MODE_REPLACE].input = vis_event_mode_replace_input; return vis; err: vis_free(vis); @@ -735,10 +650,9 @@ Vis *vis_new(Ui *ui, VisEvent *event) { void vis_free(Vis *vis) { if (!vis) return; - vis_event_emit(vis, VIS_EVENT_QUIT); - vis->event = NULL; while (vis->windows) vis_window_close(vis->windows); + vis_event_emit(vis, VIS_EVENT_QUIT); file_free(vis, vis->command_file); file_free(vis, vis->search_file); file_free(vis, vis->error_file); diff --git a/vis.h b/vis.h index fcc1e055d..181083d22 100644 --- a/vis.h +++ b/vis.h @@ -40,27 +40,6 @@ typedef struct Win Win; /* maximum bytes needed for string representation of a (pseudo) key */ #define VIS_KEY_LENGTH_MAX 64 -/** - * Editor event handlers. - */ -typedef struct { - void (*init)(Vis*); - void (*start)(Vis*); - void (*quit)(Vis*); - void (*mode_insert_input)(Vis*, const char *key, size_t len); - void (*mode_replace_input)(Vis*, const char *key, size_t len); - void (*file_open)(Vis*, File*); - bool (*file_save_pre)(Vis*, File*, const char *path); - void (*file_save_post)(Vis*, File*, const char *path); - void (*file_close)(Vis*, File*); - void (*win_open)(Vis*, Win*); - void (*win_close)(Vis*, Win*); - void (*win_highlight)(Vis*, Win*); - void (*win_status)(Vis*, Win*); - void (*term_csi)(Vis*, const long *); - void (*ui_draw)(Vis*); -} VisEvent; - /** Union used to pass arguments to key action functions. */ typedef union { bool b; @@ -111,8 +90,8 @@ typedef struct { * @defgroup vis_lifecycle * @{ */ -/** Create a new editor instance using the given user interface and event handlers. */ -Vis *vis_new(Ui*, VisEvent*); +/** Create a new editor instance using the given user interface. */ +Vis *vis_new(Ui*); /** Free all resources associated with this editor instance, terminates UI. */ void vis_free(Vis*); /** From f4b26ee480b6c6af1bf27126ca7294847e9d3a79 Mon Sep 17 00:00:00 2001 From: Randy Palamar Date: Sat, 11 May 2024 11:46:54 -0600 Subject: [PATCH 2/8] cleanup some single line get/set functions --- main.c | 66 ++++++++++++++++++++++++------------------------- view.c | 4 +-- vis-lua.c | 10 ++++---- vis-motions.c | 18 +++++++------- vis-operators.c | 2 +- vis.c | 34 ++----------------------- vis.h | 20 ++------------- 7 files changed, 54 insertions(+), 100 deletions(-) diff --git a/main.c b/main.c index 41726df64..fdd39cc8e 100644 --- a/main.c +++ b/main.c @@ -1280,7 +1280,7 @@ static const char *selections_new(Vis *vis, const char *keys, const Arg *arg) { view_selections_anchor(sel_new, anchored); } } - vis_count_set(vis, VIS_COUNT_UNKNOWN); + vis->action.count = VIS_COUNT_UNKNOWN; return keys; } @@ -1439,7 +1439,7 @@ static const char *selections_remove(Vis *vis, const char *keys, const Arg *arg) static const char *selections_remove_column(Vis *vis, const char *keys, const Arg *arg) { View *view = vis_view(vis); int max = view_selections_column_count(view); - int column = vis_count_get_default(vis, arg->i) - 1; + int column = VIS_COUNT_DEFAULT(vis->action.count, arg->i) - 1; if (column >= max) column = max - 1; if (view_selections_count(view) == 1) { @@ -1452,14 +1452,14 @@ static const char *selections_remove_column(Vis *vis, const char *keys, const Ar view_selections_dispose(s); } - vis_count_set(vis, VIS_COUNT_UNKNOWN); + vis->action.count = VIS_COUNT_UNKNOWN; return keys; } static const char *selections_remove_column_except(Vis *vis, const char *keys, const Arg *arg) { View *view = vis_view(vis); int max = view_selections_column_count(view); - int column = vis_count_get_default(vis, arg->i) - 1; + int column = VIS_COUNT_DEFAULT(vis->action.count, arg->i) - 1; if (column >= max) column = max - 1; if (view_selections_count(view) == 1) { @@ -1477,7 +1477,7 @@ static const char *selections_remove_column_except(Vis *vis, const char *keys, c view_selections_dispose(sel); } - vis_count_set(vis, VIS_COUNT_UNKNOWN); + vis->action.count = VIS_COUNT_UNKNOWN; return keys; } @@ -1502,7 +1502,7 @@ static const char *selections_navigate(Vis *vis, const char *keys, const Arg *ar } } view_selections_primary_set(s); - vis_count_set(vis, VIS_COUNT_UNKNOWN); + vis->action.count = VIS_COUNT_UNKNOWN; return keys; } @@ -1519,7 +1519,7 @@ static const char *selections_rotate(Vis *vis, const char *keys, const Arg *arg) View *view = vis_view(vis); int columns = view_selections_column_count(view); int selections = columns == 1 ? view_selections_count(view) : columns; - int count = vis_count_get_default(vis, 1); + int count = VIS_COUNT_DEFAULT(vis->action.count, 1); array_init_sized(&arr, sizeof(Rotate)); if (!array_reserve(&arr, selections)) return keys; @@ -1569,7 +1569,7 @@ static const char *selections_rotate(Vis *vis, const char *keys, const Arg *arg) } array_release(&arr); - vis_count_set(vis, VIS_COUNT_UNKNOWN); + vis->action.count = VIS_COUNT_UNKNOWN; return keys; } @@ -1595,7 +1595,7 @@ static const char *selections_trim(Vis *vis, const char *keys, const Arg *arg) { } static void selections_set(Vis *vis, View *view, Array *sel) { - enum VisMode mode = vis_mode_get(vis); + enum VisMode mode = vis->mode->id; bool anchored = mode == VIS_MODE_VISUAL || mode == VIS_MODE_VISUAL_LINE; view_selections_set_all(view, sel, anchored); if (!anchored) @@ -1603,7 +1603,7 @@ static void selections_set(Vis *vis, View *view, Array *sel) { } static const char *selections_save(Vis *vis, const char *keys, const Arg *arg) { - Win *win = vis_window(vis); + Win *win = vis->win; View *view = vis_view(vis); enum VisMark mark = vis_mark_used(vis); Array sel = view_selections_get_all(view); @@ -1614,7 +1614,7 @@ static const char *selections_save(Vis *vis, const char *keys, const Arg *arg) { } static const char *selections_restore(Vis *vis, const char *keys, const Arg *arg) { - Win *win = vis_window(vis); + Win *win = vis->win; View *view = vis_view(vis); enum VisMark mark = vis_mark_used(vis); Array sel = vis_mark_get(win, mark); @@ -1625,7 +1625,7 @@ static const char *selections_restore(Vis *vis, const char *keys, const Arg *arg } static const char *selections_union(Vis *vis, const char *keys, const Arg *arg) { - Win *win = vis_window(vis); + Win *win = vis->win; View *view = vis_view(vis); enum VisMark mark = vis_mark_used(vis); Array a = vis_mark_get(win, mark); @@ -1692,7 +1692,7 @@ static void intersect(Array *ret, Array *a, Array *b) { } static const char *selections_intersect(Vis *vis, const char *keys, const Arg *arg) { - Win *win = vis_window(vis); + Win *win = vis->win; View *view = vis_view(vis); enum VisMark mark = vis_mark_used(vis); Array a = vis_mark_get(win, mark); @@ -1745,7 +1745,7 @@ static const char *selections_complement(Vis *vis, const char *keys, const Arg * static const char *selections_minus(Vis *vis, const char *keys, const Arg *arg) { Text *txt = vis_text(vis); - Win *win = vis_window(vis); + Win *win = vis->win; View *view = vis_view(vis); enum VisMark mark = vis_mark_used(vis); Array a = view_selections_get_all(view); @@ -1788,25 +1788,25 @@ static const char *replace(Vis *vis, const char *keys, const Arg *arg) { return next; vis_operator(vis, VIS_OP_REPLACE, replacement); - if (vis_mode_get(vis) == VIS_MODE_OPERATOR_PENDING) + if (vis->mode->id == VIS_MODE_OPERATOR_PENDING) vis_motion(vis, VIS_MOVE_CHAR_NEXT); return next; } static const char *count(Vis *vis, const char *keys, const Arg *arg) { int digit = keys[-1] - '0'; - int count = vis_count_get_default(vis, 0); + int count = VIS_COUNT_DEFAULT(vis->action.count, 0); if (0 <= digit && digit <= 9) { if (digit == 0 && count == 0) vis_motion(vis, VIS_MOVE_LINE_BEGIN); else - vis_count_set(vis, count * 10 + digit); + vis->action.count = VIS_COUNT_NORMALIZE(count * 10 + digit); } return keys; } static const char *gotoline(Vis *vis, const char *keys, const Arg *arg) { - if (vis_count_get(vis) != VIS_COUNT_UNKNOWN) + if (vis->action.count != VIS_COUNT_UNKNOWN) vis_motion(vis, VIS_MOVE_LINE); else if (arg->i < 0) vis_motion(vis, VIS_MOVE_FILE_BEGIN); @@ -2032,7 +2032,7 @@ static const char *insert_verbatim(Vis *vis, const char *keys, const Arg *arg) { static const char *wscroll(Vis *vis, const char *keys, const Arg *arg) { View *view = vis_view(vis); - int count = vis_count_get(vis); + int count = vis->action.count; switch (arg->i) { case -PAGE: view_scroll_page_up(view); @@ -2055,20 +2055,20 @@ static const char *wscroll(Vis *vis, const char *keys, const Arg *arg) { view_scroll_down(view, count); break; } - vis_count_set(vis, VIS_COUNT_UNKNOWN); + vis->action.count = VIS_COUNT_UNKNOWN; return keys; } static const char *wslide(Vis *vis, const char *keys, const Arg *arg) { View *view = vis_view(vis); - int count = vis_count_get(vis); + int count = vis->action.count; if (count == VIS_COUNT_UNKNOWN) count = arg->i < 0 ? -arg->i : arg->i; if (arg->i >= 0) view_slide_down(view, count); else view_slide_up(view, count); - vis_count_set(vis, VIS_COUNT_UNKNOWN); + vis->action.count = VIS_COUNT_UNKNOWN; return keys; } @@ -2088,7 +2088,7 @@ static const char *openline(Vis *vis, const char *keys, const Arg *arg) { vis_motion(vis, VIS_MOVE_LINE_END); vis_keys_feed(vis, ""); } else { - if (vis_get_autoindent(vis)) { + if (vis->autoindent) { vis_motion(vis, VIS_MOVE_LINE_START); vis_keys_feed(vis, ""); } else { @@ -2101,30 +2101,30 @@ static const char *openline(Vis *vis, const char *keys, const Arg *arg) { } static const char *join(Vis *vis, const char *keys, const Arg *arg) { - bool normal = (vis_mode_get(vis) == VIS_MODE_NORMAL); + bool normal = (vis->mode->id == VIS_MODE_NORMAL); vis_operator(vis, VIS_OP_JOIN, arg->s); if (normal) { - int count = vis_count_get_default(vis, 0); - if (count) - vis_count_set(vis, count-1); + vis->action.count = VIS_COUNT_DEFAULT(vis->action.count, 0); + if (vis->action.count > 0) + vis->action.count -= 1; vis_motion(vis, VIS_MOVE_LINE_NEXT); } return keys; } static const char *normalmode_escape(Vis *vis, const char *keys, const Arg *arg) { - if (vis_count_get(vis) == VIS_COUNT_UNKNOWN) + if (vis->action.count == VIS_COUNT_UNKNOWN) selections_clear(vis, keys, arg); else - vis_count_set(vis, VIS_COUNT_UNKNOWN); + vis->action.count = VIS_COUNT_UNKNOWN; return keys; } static const char *visualmode_escape(Vis *vis, const char *keys, const Arg *arg) { - if (vis_count_get(vis) == VIS_COUNT_UNKNOWN) + if (vis->action.count == VIS_COUNT_UNKNOWN) vis_mode_switch(vis, VIS_MODE_NORMAL); else - vis_count_set(vis, VIS_COUNT_UNKNOWN); + vis->action.count = VIS_COUNT_UNKNOWN; return keys; } @@ -2189,7 +2189,7 @@ static const char *unicode_info(Vis *vis, const char *keys, const Arg *arg) { } static const char *percent(Vis *vis, const char *keys, const Arg *arg) { - if (vis_count_get(vis) == VIS_COUNT_UNKNOWN) + if (vis->action.count == VIS_COUNT_UNKNOWN) vis_motion(vis, VIS_MOVE_BRACKET_MATCH); else vis_motion(vis, VIS_MOVE_PERCENT); @@ -2323,7 +2323,7 @@ int main(int argc, char *argv[]) { } } - if (!vis_window(vis) && !win_created) { + if (!vis->win && !win_created) { if (!vis_window_new(vis, NULL)) vis_die(vis, "Can not create empty buffer\n"); if (cmd) diff --git a/view.c b/view.c index f27760b9d..6f3138fec 100644 --- a/view.c +++ b/view.c @@ -134,7 +134,7 @@ void window_status_update(Vis *vis, Win *win) { View *view = win->view; File *file = win->file; Text *txt = file->text; - int width = vis_window_width_get(win); + int width = win->ui->window_width(win->ui); enum UiOption options = view_options_get(view); bool focused = vis->win == win; const char *filename = file_name_get(file); @@ -148,7 +148,7 @@ void window_status_update(Vis *vis, Win *win) { text_modified(txt) ? " [+]" : "", vis_macro_recording(vis) ? " @": ""); - int count = vis_count_get(vis); + int count = vis->action.count; const char *keys = buffer_content0(&vis->input_queue); if (keys && keys[0]) snprintf(right_parts[right_count++], sizeof(right_parts[0]), "%s", keys); diff --git a/vis-lua.c b/vis-lua.c index 22464034b..c2b9581c9 100644 --- a/vis-lua.c +++ b/vis-lua.c @@ -1384,7 +1384,7 @@ static int vis_index(lua_State *L) { } if (strcmp(key, "count") == 0) { - int count = vis_count_get(vis); + int count = vis->action.count; if (count == VIS_COUNT_UNKNOWN) lua_pushnil(L); else @@ -1467,7 +1467,7 @@ static int vis_newindex(lua_State *L) { count = VIS_COUNT_UNKNOWN; else count = luaL_checkunsigned(L, 3); - vis_count_set(vis, count); + vis->action.count = count; return 0; } @@ -1788,12 +1788,12 @@ static int window_index(lua_State *L) { } if (strcmp(key, "width") == 0) { - lua_pushunsigned(L, vis_window_width_get(win)); + lua_pushunsigned(L, win->ui->window_width(win->ui)); return 1; } if (strcmp(key, "height") == 0) { - lua_pushunsigned(L, vis_window_height_get(win)); + lua_pushunsigned(L, win->ui->window_height(win->ui)); return 1; } @@ -2050,7 +2050,7 @@ static int window_style_pos(lua_State *L) { static int window_status(lua_State *L) { Win *win = obj_ref_check(L, 1, VIS_LUA_TYPE_WINDOW); char status[1024] = ""; - int width = vis_window_width_get(win); + int width = win->ui->window_width(win->ui); const char *left = luaL_checkstring(L, 2); const char *right = luaL_optstring(L, 3, ""); int left_width = text_string_width(left, strlen(left)); diff --git a/vis-motions.c b/vis-motions.c index 6178f5a3e..430b51ff4 100644 --- a/vis-motions.c +++ b/vis-motions.c @@ -69,7 +69,7 @@ static size_t common_word_next(Vis *vis, Text *txt, size_t pos, if (!text_iterator_byte_get(&it, &c)) return pos; const Movement *motion = NULL; - int count = vis_count_get_default(vis, 1); + int count = VIS_COUNT_DEFAULT(vis->action.count, 1); if (isspace((unsigned char)c)) { motion = &vis_motions[start_next]; } else if (!isboundary((unsigned char)c) && text_iterator_char_next(&it, &c) && isboundary((unsigned char)c)) { @@ -175,7 +175,7 @@ static size_t firstline(Text *txt, size_t pos) { } static size_t line(Vis *vis, Text *txt, size_t pos) { - int count = vis_count_get_default(vis, 1); + int count = VIS_COUNT_DEFAULT(vis->action.count, 1); return text_line_start(txt, text_pos_by_lineno(txt, count)); } @@ -185,11 +185,11 @@ static size_t lastline(Text *txt, size_t pos) { } static size_t column(Vis *vis, Text *txt, size_t pos) { - return text_line_offset(txt, pos, vis_count_get_default(vis, 0)); + return text_line_offset(txt, pos, VIS_COUNT_DEFAULT(vis->action.count, 0)); } static size_t view_lines_top(Vis *vis, View *view) { - return view_screenline_goto(view, vis_count_get_default(vis, 1)); + return view_screenline_goto(view, VIS_COUNT_DEFAULT(vis->action.count, 1)); } static size_t view_lines_middle(Vis *vis, View *view) { @@ -199,7 +199,7 @@ static size_t view_lines_middle(Vis *vis, View *view) { static size_t view_lines_bottom(Vis *vis, View *view) { int h = view_height_get(vis->win->view); - return view_screenline_goto(vis->win->view, h - vis_count_get_default(vis, 0)); + return view_screenline_goto(vis->win->view, h - VIS_COUNT_DEFAULT(vis->action.count, 0)); } static size_t window_nop(Vis *vis, Win *win, size_t pos) { @@ -233,25 +233,25 @@ static size_t bracket_match(Text *txt, size_t pos) { } static size_t percent(Vis *vis, Text *txt, size_t pos) { - int ratio = vis_count_get_default(vis, 0); + int ratio = VIS_COUNT_DEFAULT(vis->action.count, 0); if (ratio > 100) ratio = 100; return text_size(txt) * ratio / 100; } static size_t byte(Vis *vis, Text *txt, size_t pos) { - pos = vis_count_get_default(vis, 0); + pos = VIS_COUNT_DEFAULT(vis->action.count, 0); size_t max = text_size(txt); return pos <= max ? pos : max; } static size_t byte_left(Vis *vis, Text *txt, size_t pos) { - size_t off = vis_count_get_default(vis, 1); + size_t off = VIS_COUNT_DEFAULT(vis->action.count, 1); return off <= pos ? pos-off : 0; } static size_t byte_right(Vis *vis, Text *txt, size_t pos) { - size_t off = vis_count_get_default(vis, 1); + size_t off = VIS_COUNT_DEFAULT(vis->action.count, 1); size_t new = pos + off; size_t max = text_size(txt); return new <= max && new > pos ? new : max; diff --git a/vis-operators.c b/vis-operators.c index 0e4f8b4d1..817480db1 100644 --- a/vis-operators.c +++ b/vis-operators.c @@ -272,7 +272,7 @@ bool vis_operator(Vis *vis, enum VisOperator id, ...) { } case VIS_OP_DELETE: { - enum VisMode mode = vis_mode_get(vis); + enum VisMode mode = vis->mode->id; enum VisRegister reg = vis_register_used(vis); if (reg == VIS_REG_DEFAULT && (mode == VIS_MODE_INSERT || mode == VIS_MODE_REPLACE)) vis_register(vis, VIS_REG_BLACKHOLE); diff --git a/vis.c b/vis.c index 616b46393..b4f3ff9ab 100644 --- a/vis.c +++ b/vis.c @@ -481,14 +481,6 @@ void vis_window_prev(Vis *vis) { vis_window_focus(sel); } -int vis_window_width_get(const Win *win) { - return win->ui->window_width(win->ui); -} - -int vis_window_height_get(const Win *win) { - return win->ui->window_height(win->ui); -} - void vis_draw(Vis *vis) { for (Win *win = vis->windows; win; win = win->next) view_draw(win->view); @@ -1461,7 +1453,7 @@ bool vis_macro_replay(Vis *vis, enum VisRegister id) { Macro *macro = macro_get(vis, id); if (!macro || macro == vis->recording) return false; - int count = vis_count_get_default(vis, 1); + int count = VIS_COUNT_DEFAULT(vis->action.count, 1); vis_cancel(vis); for (int i = 0; i < count; i++) macro_replay(vis, macro); @@ -1502,25 +1494,11 @@ void vis_repeat(Vis *vis) { vis_file_snapshot(vis, win->file); } -int vis_count_get(Vis *vis) { - return vis->action.count; -} - -int vis_count_get_default(Vis *vis, int def) { - if (vis->action.count == VIS_COUNT_UNKNOWN) - return def; - return vis->action.count; -} - -void vis_count_set(Vis *vis, int count) { - vis->action.count = (count >= 0 ? count : VIS_COUNT_UNKNOWN); -} - VisCountIterator vis_count_iterator_get(Vis *vis, int def) { return (VisCountIterator) { .vis = vis, .iteration = 0, - .count = vis_count_get_default(vis, def), + .count = VIS_COUNT_DEFAULT(vis->action.count, def), }; } @@ -1928,11 +1906,3 @@ View *vis_view(Vis *vis) { Win *win = vis->win; return win ? win->view : NULL; } - -Win *vis_window(Vis *vis) { - return vis->win; -} - -bool vis_get_autoindent(const Vis *vis) { - return vis->autoindent; -} diff --git a/vis.h b/vis.h index 181083d22..a915c0ed7 100644 --- a/vis.h +++ b/vis.h @@ -208,10 +208,6 @@ void vis_window_prev(Vis*); void vis_window_focus(Win*); /** Swap location of two windows. */ void vis_window_swap(Win*, Win*); -/** Query window width. */ -int vis_window_width_get(const Win*); -/** Query window height. */ -int vis_window_height_get(const Win*); /** * @} * @defgroup vis_info @@ -294,8 +290,6 @@ enum VisMode { * @endrst */ void vis_mode_switch(Vis*, enum VisMode); -/** Get currently active mode. */ -enum VisMode vis_mode_get(Vis*); /** Translate human readable mode name to constant. */ enum VisMode vis_mode_from(Vis*, const char *name); @@ -560,14 +554,8 @@ int vis_motion_register(Vis*, void *context, VisMotionFunction*); */ /** No count was specified. */ #define VIS_COUNT_UNKNOWN (-1) -/** Get count, might return `VIS_COUNT_UNKNOWN`. */ -int vis_count_get(Vis*); -/** Get count, if none was specified, return ``def``. */ -int vis_count_get_default(Vis*, int def); -/** Set a count. */ -void vis_count_set(Vis*, int count); -/** Set the tabwidth */ -void vis_tabwidth_set(Vis*, int tw); +#define VIS_COUNT_DEFAULT(count, def) ((count) == VIS_COUNT_UNKNOWN ? (def) : (count)) +#define VIS_COUNT_NORMALIZE(count) ((count) < 0 ? VIS_COUNT_UNKNOWN : (count)) /** Set the shell */ void vis_shell_set(Vis*, const char *new_shell); @@ -974,9 +962,5 @@ void vis_file_snapshot(Vis*, File*); /* TODO: expose proper API to iterate through files etc */ Text *vis_text(Vis*); View *vis_view(Vis*); -Win *vis_window(Vis*); - -/* Get value of autoindent */ -bool vis_get_autoindent(const Vis*); #endif From 4c2b2d8a100a67212134c1bb89fad39311fa441e Mon Sep 17 00:00:00 2001 From: Randy Palamar Date: Sat, 11 May 2024 16:27:29 -0600 Subject: [PATCH 3/8] make View unopaque --- main.c | 18 ++++---- sam.c | 4 +- ui-terminal.c | 14 +++--- view.c | 112 +----------------------------------------------- view.h | 79 +++++++++++++++++++++------------- vis-cmds.c | 6 ++- vis-lua.c | 26 +++++------ vis-motions.c | 6 +-- vis-operators.c | 4 +- vis-prompt.c | 2 +- vis-registers.c | 2 +- vis.c | 28 ++++++------ 12 files changed, 108 insertions(+), 193 deletions(-) diff --git a/main.c b/main.c index fdd39cc8e..7a45dff00 100644 --- a/main.c +++ b/main.c @@ -1348,7 +1348,7 @@ static const char *selections_align_indent(Vis *vis, const char *keys, const Arg static const char *selections_clear(Vis *vis, const char *keys, const Arg *arg) { View *view = vis_view(vis); - if (view_selections_count(view) > 1) + if (view->selection_count > 1) view_selections_dispose_all(view); else view_selection_clear(view_selections_primary_get(view)); @@ -1356,7 +1356,7 @@ static const char *selections_clear(Vis *vis, const char *keys, const Arg *arg) } static Selection *selection_new(View *view, Filerange *r, bool isprimary) { - Text *txt = view_text(view); + Text *txt = view->text; size_t pos = text_char_prev(txt, r->end); Selection *s = view_selections_new(view, pos); if (!s) @@ -1378,7 +1378,7 @@ static const char *selections_match_next(Vis *vis, const char *keys, const Arg * static bool match_word; - if (view_selections_count(view) == 1) { + if (view->selection_count == 1) { Filerange word = text_object_word(txt, view_cursors_pos(s)); match_word = text_range_equal(&sel, &word); } @@ -1442,7 +1442,7 @@ static const char *selections_remove_column(Vis *vis, const char *keys, const Ar int column = VIS_COUNT_DEFAULT(vis->action.count, arg->i) - 1; if (column >= max) column = max - 1; - if (view_selections_count(view) == 1) { + if (view->selection_count == 1) { vis_keys_feed(vis, ""); return keys; } @@ -1462,7 +1462,7 @@ static const char *selections_remove_column_except(Vis *vis, const char *keys, c int column = VIS_COUNT_DEFAULT(vis->action.count, arg->i) - 1; if (column >= max) column = max - 1; - if (view_selections_count(view) == 1) { + if (view->selection_count == 1) { vis_redraw(vis); return keys; } @@ -1483,7 +1483,7 @@ static const char *selections_remove_column_except(Vis *vis, const char *keys, c static const char *selections_navigate(Vis *vis, const char *keys, const Arg *arg) { View *view = vis_view(vis); - if (view_selections_count(view) == 1) + if (view->selection_count == 1) return wscroll(vis, keys, arg); Selection *s = view_selections_primary_get(view); VisCountIterator it = vis_count_iterator_get(vis, 1); @@ -1518,7 +1518,7 @@ static const char *selections_rotate(Vis *vis, const char *keys, const Arg *arg) Text *txt = vis_text(vis); View *view = vis_view(vis); int columns = view_selections_column_count(view); - int selections = columns == 1 ? view_selections_count(view) : columns; + int selections = columns == 1 ? view->selection_count : columns; int count = VIS_COUNT_DEFAULT(vis->action.count, 1); array_init_sized(&arr, sizeof(Rotate)); if (!array_reserve(&arr, selections)) @@ -1877,7 +1877,7 @@ static const char *undo(Vis *vis, const char *keys, const Arg *arg) { size_t pos = text_undo(vis_text(vis)); if (pos != EPOS) { View *view = vis_view(vis); - if (view_selections_count(view) == 1) + if (view->selection_count == 1) view_cursor_to(view, pos); /* redraw all windows in case some display the same file */ vis_draw(vis); @@ -1889,7 +1889,7 @@ static const char *redo(Vis *vis, const char *keys, const Arg *arg) { size_t pos = text_redo(vis_text(vis)); if (pos != EPOS) { View *view = vis_view(vis); - if (view_selections_count(view) == 1) + if (view->selection_count == 1) view_cursor_to(view, pos); /* redraw all windows in case some display the same file */ vis_draw(vis); diff --git a/sam.c b/sam.c index 223bbe268..ef39ff670 100644 --- a/sam.c +++ b/sam.c @@ -1509,11 +1509,11 @@ static bool cmd_select(Vis *vis, Win *win, Command *cmd, const char *argv[], Sel bool ret = true; View *view = win->view; Text *txt = win->file->text; - bool multiple_cursors = view_selections_count(view) > 1; + bool multiple_cursors = view->selection_count > 1; Selection *primary = view_selections_primary_get(view); if (vis->mode->visual) - count_init(cmd->cmd, view_selections_count(view)+1); + count_init(cmd->cmd, view->selection_count + 1); for (Selection *s = view_selections(view), *next; s && ret; s = next) { next = view_selections_next(s); diff --git a/ui-terminal.c b/ui-terminal.c index 09e618ea8..c26cdb044 100644 --- a/ui-terminal.c +++ b/ui-terminal.c @@ -243,7 +243,7 @@ static void ui_window_draw(UiWin *w) { UiTerm *ui = win->ui; View *view = win->win->view; int width = win->width, height = win->height; - const Line *line = view_lines_first(view); + const Line *line = view->topline; bool status = win->options & UI_OPTION_STATUSBAR; bool nu = win->options & UI_OPTION_LINE_NUMBERS_ABSOLUTE; bool rnu = win->options & UI_OPTION_LINE_NUMBERS_RELATIVE; @@ -254,14 +254,14 @@ static void ui_window_draw(UiWin *w) { win->sidebar_width = sidebar_width; } vis_window_draw(win->win); - line = view_lines_first(view); + line = view->topline; size_t prev_lineno = 0; Selection *sel = view_selections_primary_get(view); const Line *cursor_line = view_cursors_line_get(sel); size_t cursor_lineno = cursor_line->lineno; char buf[(sizeof(size_t) * CHAR_BIT + 2) / 3 + 1 + 1]; int x = win->x, y = win->y; - int view_width = view_width_get(view); + int view_width = view->width; Cell *cells = ui->cells + y * ui->width; if (x + sidebar_width + view_width > ui->width) view_width = ui->width - x - sidebar_width; @@ -400,7 +400,7 @@ static void ui_redraw(Ui *ui) { UiTerm *tui = (UiTerm*)ui; ui_term_backend_clear(tui); for (UiTermWin *win = tui->windows; win; win = win->next) - view_invalidate(win->win->view); + win->win->view->need_update = true; } static void ui_resize(Ui *ui) { @@ -457,8 +457,8 @@ static void ui_window_focus(UiWin *w) { if (new->options & UI_OPTION_STATUSBAR) new->ui->selwin = new; if (old) - view_invalidate(old->win->view); - view_invalidate(new->win->view); + old->win->view->need_update = true; + new->win->view->need_update = true; } static void ui_window_options_set(UiWin *w, enum UiOption options) { @@ -579,7 +579,7 @@ static UiWin *ui_window_new(Ui *ui, Win *w, enum UiOption options) { styles[UI_STYLE_STATUS].attr |= CELL_ATTR_REVERSE; styles[UI_STYLE_STATUS_FOCUSED].attr |= CELL_ATTR_REVERSE|CELL_ATTR_BOLD; styles[UI_STYLE_INFO].attr |= CELL_ATTR_BOLD; - view_ui(w->view, &win->uiwin); + w->view->ui = &win->uiwin; if (tui->windows) tui->windows->prev = win; diff --git a/view.c b/view.c index 6f3138fec..046fdffed 100644 --- a/view.c +++ b/view.c @@ -13,19 +13,6 @@ #include "text-util.h" #include "util.h" -typedef struct { - char *symbol; -} SyntaxSymbol; - -enum { - SYNTAX_SYMBOL_SPACE, - SYNTAX_SYMBOL_TAB, - SYNTAX_SYMBOL_TAB_FILL, - SYNTAX_SYMBOL_EOL, - SYNTAX_SYMBOL_EOF, - SYNTAX_SYMBOL_LAST, -}; - /* A selection is made up of two marks named cursor and anchor. * While the anchor remains fixed the cursor mark follows cursor motions. * For a selection (indicated by []), the marks (^) are placed as follows: @@ -56,39 +43,6 @@ struct Selection { Selection *prev, *next; /* previous/next cursors ordered by location at creation time */ }; -struct View { - Text *text; /* underlying text management */ - char *textbuf; /* scratch buffer used for drawing */ - UiWin *ui; /* corresponding ui window */ - Cell cell_blank; /* used for empty/blank cells */ - int width, height; /* size of display area */ - size_t start, end; /* currently displayed area [start, end] in bytes from the start of the file */ - size_t start_last; /* previously used start of visible area, used to update the mark */ - Mark start_mark; /* mark to keep track of the start of the visible area */ - size_t lines_size; /* number of allocated bytes for lines (grows only) */ - Line *lines; /* view->height number of lines representing view content */ - Line *topline; /* top of the view, first line currently shown */ - Line *lastline; /* last currently used line, always <= bottomline */ - Line *bottomline; /* bottom of view, might be unused if lastline < bottomline */ - Selection *selection; /* primary selection, always placed within the visible viewport */ - Selection *selection_latest; /* most recently created cursor */ - Selection *selection_dead; /* primary cursor which was disposed, will be removed when another cursor is created */ - int selection_count; /* how many cursors do currently exist */ - Line *line; /* used while drawing view content, line where next char will be drawn */ - int col; /* used while drawing view content, column where next char will be drawn */ - const SyntaxSymbol *symbols[SYNTAX_SYMBOL_LAST]; /* symbols to use for white spaces etc */ - int tabwidth; /* how many spaces should be used to display a tab character */ - Selection *selections; /* all cursors currently active */ - int selection_generation; /* used to filter out newly created cursors during iteration */ - bool need_update; /* whether view has been redrawn */ - bool large_file; /* optimize for displaying large files */ - int colorcolumn; - char *breakat; /* characters which might cause a word wrap */ - int wrapcolumn; /* wrap lines at minimum of window width and wrapcolumn (if != 0) */ - int wrapcol; /* used while drawing view content, column where word wrap might happen */ - bool prevch_breakat; /* used while drawing view content, previous char is part of breakat */ -}; - static const SyntaxSymbol symbols_none[] = { [SYNTAX_SYMBOL_SPACE] = { " " }, [SYNTAX_SYMBOL_TAB] = { " " }, @@ -155,7 +109,7 @@ void window_status_update(Vis *vis, Win *win) { else if (count != VIS_COUNT_UNKNOWN) snprintf(right_parts[right_count++], sizeof(right_parts[0]), "%d", count); - int sel_count = view_selections_count(view); + int sel_count = view->selection_count; if (sel_count > 1) { Selection *s = view_selections_primary_get(view); int sel_number = view_selections_number(s) + 1; @@ -223,10 +177,6 @@ void view_tabwidth_set(View *view, int tabwidth) { view_draw(view); } -int view_tabwidth_get(View *view) { - return view->tabwidth; -} - /* reset internal view data structures (cell matrix, line offsets etc.) */ static void view_clear(View *view) { memset(view->lines, 0, view->lines_size); @@ -270,10 +220,6 @@ static void view_clear(View *view) { view->ui->style_set(view->ui, &view->cell_blank, UI_STYLE_DEFAULT); } -Filerange view_viewport_get(View *view) { - return (Filerange){ .start = view->start, .end = view->end }; -} - static int view_max_text_width(const View *view) { if (view->wrapcolumn > 0) return MIN(view->wrapcolumn, view->width); @@ -575,10 +521,6 @@ void view_draw(View *view) { view->need_update = true; } -void view_invalidate(View *view) { - view->need_update = true; -} - bool view_update(View *view) { if (!view->need_update) return false; @@ -621,14 +563,6 @@ bool view_resize(View *view, int width, int height) { return true; } -int view_height_get(View *view) { - return view->height; -} - -int view_width_get(View *view) { - return view->width; -} - void view_free(View *view) { if (!view) return; @@ -676,10 +610,6 @@ View *view_new(Text *text) { return view; } -void view_ui(View *view, UiWin* ui) { - view->ui = ui; -} - static size_t cursor_set(Selection *sel, Line *line, int col) { int row = 0; View *view = sel->view; @@ -955,14 +885,6 @@ size_t view_cursor_get(View *view) { return view_cursors_pos(view->selection); } -Line *view_lines_first(View *view) { - return view->topline; -} - -Line *view_lines_last(View *view) { - return view->lastline; -} - Line *view_cursors_line_get(Selection *sel) { return sel->line; } @@ -998,24 +920,6 @@ enum UiOption view_options_get(View *view) { return view->ui ? view->ui->options_get(view->ui) : 0; } -void view_colorcolumn_set(View *view, int col) { - if (col >= 0) - view->colorcolumn = col; -} - -int view_colorcolumn_get(View *view) { - return view->colorcolumn; -} - -void view_wrapcolumn_set(View *view, int col) { - if (col >= 0) - view->wrapcolumn = col; -} - -int view_wrapcolumn_get(View *view) { - return view->wrapcolumn; -} - bool view_breakat_set(View *view, const char *breakat) { char *copy = strdup(breakat); if (!copy) @@ -1025,10 +929,6 @@ bool view_breakat_set(View *view, const char *breakat) { return true; } -const char *view_breakat_get(View *view) { - return view->breakat; -} - size_t view_screenline_goto(View *view, int n) { size_t pos = view->start; for (Line *line = view->topline; --n > 0 && line != view->lastline; line = line->next) @@ -1108,10 +1008,6 @@ Selection *view_selections_new_force(View *view, size_t pos) { return selections_new(view, pos, true); } -int view_selections_count(View *view) { - return view->selection_count; -} - int view_selections_number(Selection *sel) { return sel->number; } @@ -1458,7 +1354,7 @@ void view_selections_set_all(View *view, Array *arr, bool anchored) { Array view_selections_get_all(View *view) { Array arr; array_init_sized(&arr, sizeof(Filerange)); - if (!array_reserve(&arr, view_selections_count(view))) + if (!array_reserve(&arr, view->selection_count)) return arr; for (Selection *s = view->selections; s; s = s->next) { Filerange r = view_selections_get(s); @@ -1490,10 +1386,6 @@ void view_selections_normalize(View *view) { view_selections_set(prev, &range_prev); } -Text *view_text(View *view) { - return view->text; -} - char *view_symbol_eof_get(View *view) { return view->symbols[SYNTAX_SYMBOL_EOF]->symbol; } diff --git a/view.h b/view.h index 68eeb4b9f..003e83e7f 100644 --- a/view.h +++ b/view.h @@ -4,20 +4,31 @@ #include #include -typedef struct View View; typedef struct Selection Selection; -typedef struct Cell Cell; #include "text.h" #include "ui.h" #include "array.h" +typedef struct { + char *symbol; +} SyntaxSymbol; + +enum { + SYNTAX_SYMBOL_SPACE, + SYNTAX_SYMBOL_TAB, + SYNTAX_SYMBOL_TAB_FILL, + SYNTAX_SYMBOL_EOL, + SYNTAX_SYMBOL_EOF, + SYNTAX_SYMBOL_LAST, +}; + typedef struct { Mark anchor; Mark cursor; } SelectionRegion; -struct Cell { +typedef struct { char data[16]; /* utf8 encoded character displayed in this cell (might be more than one Unicode codepoint. might also not be the same as in the underlying text, for example tabs get expanded */ @@ -27,7 +38,7 @@ struct Cell { occupied by the same character have a length of 0. */ int width; /* display width i.e. number of columns occupied by this character */ CellStyle style; /* colors and attributes used to display this cell */ -}; +} Cell; typedef struct Line Line; struct Line { /* a line on the screen, *not* in the file */ @@ -38,14 +49,45 @@ struct Line { /* a line on the screen, *not* in the file */ Cell cells[]; /* win->width cells storing information about the displayed characters */ }; +typedef struct { + Text *text; /* underlying text management */ + char *textbuf; /* scratch buffer used for drawing */ + UiWin *ui; /* corresponding ui window */ + Cell cell_blank; /* used for empty/blank cells */ + int width, height; /* size of display area */ + size_t start, end; /* currently displayed area [start, end] in bytes from the start of the file */ + size_t start_last; /* previously used start of visible area, used to update the mark */ + Mark start_mark; /* mark to keep track of the start of the visible area */ + size_t lines_size; /* number of allocated bytes for lines (grows only) */ + Line *lines; /* view->height number of lines representing view content */ + Line *topline; /* top of the view, first line currently shown */ + Line *lastline; /* last currently used line, always <= bottomline */ + Line *bottomline; /* bottom of view, might be unused if lastline < bottomline */ + Selection *selection; /* primary selection, always placed within the visible viewport */ + Selection *selection_latest; /* most recently created cursor */ + Selection *selection_dead; /* primary cursor which was disposed, will be removed when another cursor is created */ + int selection_count; /* how many cursors do currently exist */ + Line *line; /* used while drawing view content, line where next char will be drawn */ + int col; /* used while drawing view content, column where next char will be drawn */ + const SyntaxSymbol *symbols[SYNTAX_SYMBOL_LAST]; /* symbols to use for white spaces etc */ + int tabwidth; /* how many spaces should be used to display a tab character */ + Selection *selections; /* all cursors currently active */ + int selection_generation; /* used to filter out newly created cursors during iteration */ + bool need_update; /* whether view has been redrawn */ + bool large_file; /* optimize for displaying large files */ + int colorcolumn; + char *breakat; /* characters which might cause a word wrap */ + int wrapcolumn; /* wrap lines at minimum of window width and wrapcolumn (if != 0) */ + int wrapcol; /* used while drawing view content, column where word wrap might happen */ + bool prevch_breakat; /* used while drawing view content, previous char is part of breakat */ +} View; + /** * @defgroup view_life * @{ */ View *view_new(Text*); void view_free(View*); -void view_ui(View*, UiWin*); -Text *view_text(View*); void view_reload(View*, Text*); /** * @} @@ -53,7 +95,7 @@ void view_reload(View*, Text*); * @{ */ /** Get the currently displayed text range. */ -Filerange view_viewport_get(View*); +#define VIEW_VIEWPORT_GET(v) (Filerange){ .start = v->start, .end = v->end } /** * Get window coordinate of text position. * @param pos The position to query. @@ -65,10 +107,6 @@ Filerange view_viewport_get(View*); bool view_coord_get(View*, size_t pos, Line **line, int *row, int *col); /** Get position at the start of the ``n``-th window line, counting from 1. */ size_t view_screenline_goto(View*, int n); -/** Get first screen line. */ -Line *view_lines_first(View*); -/** Get last non-empty screen line. */ -Line *view_lines_last(View*); size_t view_slide_up(View*, int lines); size_t view_slide_down(View*, int lines); size_t view_scroll_up(View*, int lines); @@ -87,14 +125,11 @@ void view_scroll_to(View*, size_t pos); * @{ */ bool view_resize(View*, int width, int height); -int view_height_get(View*); -int view_width_get(View*); /** * @} * @defgroup view_draw * @{ */ -void view_invalidate(View*); void view_draw(View*); bool view_update(View*); @@ -113,7 +148,7 @@ bool view_update(View*); Selection *view_selections_new(View*, size_t pos); /** * Create a new selection even if position is already covered by an - * existing selection. + * existing selection. * @rst * .. note:: This should only be used if the old selection is eventually * disposed. @@ -167,13 +202,6 @@ Selection *view_selections(View*); Selection *view_selections_prev(Selection*); /** Get immediate successor of selection. */ Selection *view_selections_next(Selection*); -/** - * Get number of existing selections. - * @rst - * .. note:: Is always at least 1. - * @endrst - */ -int view_selections_count(View*); /** * Get selection index. * @rst @@ -357,17 +385,10 @@ bool view_regions_save(View*, Filerange*, SelectionRegion*); */ void view_options_set(View*, enum UiOption options); enum UiOption view_options_get(View*); -void view_colorcolumn_set(View*, int col); -int view_colorcolumn_get(View*); -void view_wrapcolumn_set(View*, int col); -int view_wrapcolumn_get(View*); bool view_breakat_set(View*, const char *breakat); -const char *view_breakat_get(View*); /** Set how many spaces are used to display a tab `\t` character. */ void view_tabwidth_set(View*, int tabwidth); -/** Get how many spaces are used to display a tab `\t` character. */ -int view_tabwidth_get(View*); /** Define a display style. */ bool view_style_define(View*, enum UiStyle, const char *style); /** Apply a style to a text range. */ diff --git a/vis-cmds.c b/vis-cmds.c index 2b6428ab6..2874169db 100644 --- a/vis-cmds.c +++ b/vis-cmds.c @@ -316,7 +316,8 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Select break; } case OPTION_COLOR_COLUMN: - view_colorcolumn_set(win->view, arg.i); + if (arg.i >= 0) + win->view->colorcolumn = arg.i; break; case OPTION_SAVE_METHOD: if (strcmp("auto", arg.s) == 0) { @@ -370,7 +371,8 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Select } break; case OPTION_WRAP_COLUMN: - view_wrapcolumn_set(win->view, arg.i); + if (arg.i >= 0) + win->view->wrapcolumn = arg.i; break; default: if (!opt->func) diff --git a/vis-lua.c b/vis-lua.c index c2b9581c9..c51a924f0 100644 --- a/vis-lua.c +++ b/vis-lua.c @@ -1766,10 +1766,10 @@ static int window_index(lua_State *L) { const char *key = lua_tostring(L, 2); if (strcmp(key, "viewport") == 0) { - Filerange b = view_viewport_get(win->view); + Filerange b = VIEW_VIEWPORT_GET(win->view); Filerange l; - l.start = view_lines_first(win->view)->lineno; - l.end = view_lines_last(win->view)->lineno; + l.start = win->view->topline->lineno; + l.end = win->view->lastline->lineno; lua_createtable(L, 0, 4); lua_pushstring(L, "bytes"); @@ -1779,10 +1779,10 @@ static int window_index(lua_State *L) { pushrange(L, &l); lua_settable(L, -3); lua_pushstring(L, "width"); - lua_pushunsigned(L, view_width_get(win->view)); + lua_pushunsigned(L, win->view->width); lua_settable(L, -3); lua_pushstring(L, "height"); - lua_pushunsigned(L, view_height_get(win->view)); + lua_pushunsigned(L, win->view->height); lua_settable(L, -3); return 1; } @@ -1832,7 +1832,7 @@ static int window_options_assign(Win *win, lua_State *L, const char *key, int ne if (lua_isstring(L, next)) view_breakat_set(win->view, lua_tostring(L, next)); } else if (strcmp(key, "colorcolumn") == 0 || strcmp(key, "cc") == 0) { - view_colorcolumn_set(win->view, luaL_checkint(L, next)); + win->view->colorcolumn = luaL_checkunsigned(L, next); } else if (strcmp(key, "cursorline") == 0 || strcmp(key, "cul") == 0) { if (lua_toboolean(L, next)) flags |= UI_OPTION_CURSOR_LINE; @@ -1882,7 +1882,7 @@ static int window_options_assign(Win *win, lua_State *L, const char *key, int ne flags &= ~UI_OPTION_STATUSBAR; view_options_set(win->view, flags); } else if (strcmp(key, "wrapcolumn") == 0 || strcmp(key, "wc") == 0) { - view_wrapcolumn_set(win->view, luaL_checkint(L, next)); + win->view->wrapcolumn = luaL_checkunsigned(L, next); } else if (strcmp(key, "tabwidth") == 0 || strcmp(key, "tw") == 0) { view_tabwidth_set(win->view, luaL_checkint(L, next)); } else if (strcmp(key, "expandtab") == 0 || strcmp(key, "et") == 0) { @@ -2142,10 +2142,10 @@ static int window_options_index(lua_State *L) { if (lua_isstring(L, 2)) { const char *key = lua_tostring(L, 2); if (strcmp(key, "breakat") == 0 || strcmp(key, "brk") == 0) { - lua_pushstring(L, view_breakat_get(win->view)); + lua_pushstring(L, win->view->breakat); return 1; } else if (strcmp(key, "colorcolumn") == 0 || strcmp(key, "cc") == 0) { - lua_pushunsigned(L, view_colorcolumn_get(win->view)); + lua_pushunsigned(L, win->view->colorcolumn); return 1; } else if (strcmp(key, "cursorline") == 0 || strcmp(key, "cul") == 0) { lua_pushboolean(L, view_options_get(win->view) & UI_OPTION_CURSOR_LINE); @@ -2175,10 +2175,10 @@ static int window_options_index(lua_State *L) { lua_pushboolean(L, view_options_get(win->view) & UI_OPTION_STATUSBAR); return 1; } else if (strcmp(key, "tabwidth") == 0 || strcmp(key, "tw") == 0) { - lua_pushinteger(L, view_tabwidth_get(win->view)); + lua_pushinteger(L, win->view->tabwidth); return 1; } else if (strcmp(key, "wrapcolumn") == 0 || strcmp(key, "wc") == 0) { - lua_pushunsigned(L, view_wrapcolumn_get(win->view)); + lua_pushunsigned(L, win->view->wrapcolumn); return 1; } } @@ -2203,7 +2203,7 @@ static const struct luaL_Reg window_option_funcs[] = { static int window_selections_index(lua_State *L) { View *view = obj_ref_check(L, 1, VIS_LUA_TYPE_SELECTIONS); size_t index = luaL_checkunsigned(L, 2); - size_t count = view_selections_count(view); + size_t count = view->selection_count; if (index == 0 || index > count) goto err; for (Selection *s = view_selections(view); s; s = view_selections_next(s)) { @@ -2219,7 +2219,7 @@ static int window_selections_index(lua_State *L) { static int window_selections_len(lua_State *L) { View *view = obj_ref_check(L, 1, VIS_LUA_TYPE_SELECTIONS); - lua_pushunsigned(L, view_selections_count(view)); + lua_pushunsigned(L, view->selection_count); return 1; } diff --git a/vis-motions.c b/vis-motions.c index 430b51ff4..1d3f49a23 100644 --- a/vis-motions.c +++ b/vis-motions.c @@ -193,13 +193,13 @@ static size_t view_lines_top(Vis *vis, View *view) { } static size_t view_lines_middle(Vis *vis, View *view) { - int h = view_height_get(view); + int h = view->height; return view_screenline_goto(view, h/2); } static size_t view_lines_bottom(Vis *vis, View *view) { - int h = view_height_get(vis->win->view); - return view_screenline_goto(vis->win->view, h - VIS_COUNT_DEFAULT(vis->action.count, 0)); + int h = view->height; + return view_screenline_goto(view, h - VIS_COUNT_DEFAULT(vis->action.count, 0)); } static size_t window_nop(Vis *vis, Win *win, size_t pos) { diff --git a/vis-operators.c b/vis-operators.c index 817480db1..5ce64c490 100644 --- a/vis-operators.c +++ b/vis-operators.c @@ -102,7 +102,7 @@ static size_t op_put(Vis *vis, Text *txt, OperatorContext *c) { static size_t op_shift_right(Vis *vis, Text *txt, OperatorContext *c) { char spaces[9] = " "; - spaces[MIN(view_tabwidth_get(vis->win->view), LENGTH(spaces) - 1)] = '\0'; + spaces[MIN(vis->win->view->tabwidth, LENGTH(spaces) - 1)] = '\0'; const char *tab = vis->win->expandtab ? spaces : "\t"; size_t tablen = strlen(tab); size_t pos = text_line_begin(txt, c->range.end), prev_pos; @@ -127,7 +127,7 @@ static size_t op_shift_right(Vis *vis, Text *txt, OperatorContext *c) { static size_t op_shift_left(Vis *vis, Text *txt, OperatorContext *c) { size_t pos = text_line_begin(txt, c->range.end), prev_pos; - size_t tabwidth = view_tabwidth_get(vis->win->view), tablen; + size_t tabwidth = vis->win->view->tabwidth, tablen; size_t newpos = c->pos; /* if range ends at the begin of a line, skip line break */ diff --git a/vis-prompt.c b/vis-prompt.c index 1add11afe..f265b1012 100644 --- a/vis-prompt.c +++ b/vis-prompt.c @@ -114,7 +114,7 @@ static const char *prompt_enter(Vis *vis, const char *keys, const Arg *arg) { static const char *prompt_esc(Vis *vis, const char *keys, const Arg *arg) { Win *prompt = vis->win; - if (view_selections_count(prompt->view) > 1) { + if (prompt->view->selection_count > 1) { view_selections_dispose_all(prompt->view); } else { prompt_restore(prompt); diff --git a/vis-registers.c b/vis-registers.c index 1875da95d..485284c45 100644 --- a/vis-registers.c +++ b/vis-registers.c @@ -188,7 +188,7 @@ bool register_put_range(Vis *vis, Register *reg, Text *txt, Filerange *range) { size_t vis_register_count(Vis *vis, Register *reg) { if (reg->type == REGISTER_NUMBER) - return vis->win ? view_selections_count(vis->win->view) : 0; + return vis->win ? vis->win->view->selection_count : 0; return array_length(®->values); } diff --git a/vis.c b/vis.c index b4f3ff9ab..a5606e3db 100644 --- a/vis.c +++ b/vis.c @@ -218,15 +218,15 @@ static void window_free(Win *win) { static void window_draw_colorcolumn(Win *win) { View *view = win->view; - int cc = view_colorcolumn_get(view); + int cc = view->colorcolumn; if (cc <= 0) return; size_t lineno = 0; int line_cols = 0; /* Track the number of columns we've passed on each line */ bool line_cc_set = false; /* Has the colorcolumn attribute been set for this line yet */ - int width = view_width_get(view); + int width = view->width; - for (Line *l = view_lines_first(view); l; l = l->next) { + for (Line *l = view->topline; l; l = l->next) { if (l->lineno != lineno) { line_cols = 0; line_cc_set = false; @@ -254,13 +254,13 @@ static void window_draw_cursorline(Win *win) { return; if (vis->mode->visual || vis->win != win) return; - if (view_selections_count(view) > 1) + if (view->selection_count > 1) return; - int width = view_width_get(view); + int width = view->width; Selection *sel = view_selections_primary_get(view); size_t lineno = view_cursors_line_get(sel)->lineno; - for (Line *l = view_lines_first(view); l; l = l->next) { + for (Line *l = view->topline; l; l = l->next) { if (l->lineno == lineno) { for (int x = 0; x < width; x++) win->ui->style_set(win->ui, &l->cells[x], UI_STYLE_CURSOR_LINE); @@ -282,11 +282,11 @@ static void window_draw_selection(Win *win, Selection *cur) { if (!start_line && !end_line) return; if (!start_line) { - start_line = view_lines_first(view); + start_line = view->topline; start_col = 0; } if (!end_line) { - end_line = view_lines_last(view); + end_line = view->lastline; end_col = end_line->width; } for (Line *l = start_line; l != end_line->next; l = l->next) { @@ -302,7 +302,7 @@ static void window_draw_cursor_matching(Win *win, Selection *cur) { return; Line *line_match; int col_match; size_t pos = view_cursors_pos(cur); - Filerange limits = view_viewport_get(win->view); + Filerange limits = VIEW_VIEWPORT_GET(win->view); size_t pos_match = text_bracket_match_symbol(win->file->text, pos, "(){}[]\"'`", &limits); if (pos == pos_match) return; @@ -326,7 +326,7 @@ static void window_draw_cursor(Win *win, Selection *cur) { static void window_draw_selections(Win *win) { View *view = win->view; - Filerange viewport = view_viewport_get(view); + Filerange viewport = VIEW_VIEWPORT_GET(view); Selection *sel = view_selections_primary_get(view); for (Selection *s = view_selections_prev(sel); s; s = view_selections_prev(s)) { window_draw_selection(win, s); @@ -348,9 +348,9 @@ static void window_draw_selections(Win *win) { static void window_draw_eof(Win *win) { View *view = win->view; - if (view_width_get(view) == 0) + if (view->width == 0) return; - for (Line *l = view_lines_last(view)->next; l; l = l->next) { + for (Line *l = view->lastline->next; l; l = l->next) { strncpy(l->cells[0].data, view_symbol_eof_get(view), sizeof(l->cells[0].data)-1); win->ui->style_set(win->ui, &l->cells[0], UI_STYLE_EOF); } @@ -765,7 +765,7 @@ void vis_do(Vis *vis) { if (a->op == &vis_operators[VIS_OP_MODESWITCH]) count = 1; /* count should apply to inserted text not motion */ bool repeatable = a->op && !vis->macro_operator && !vis->win->parent; - bool multiple_cursors = view_selections_count(view) > 1; + bool multiple_cursors = view->selection_count > 1; bool linewise = !(a->type & CHARWISE) && ( a->type & LINEWISE || (a->movement && a->movement->type & LINEWISE) || @@ -1530,7 +1530,7 @@ void vis_insert_tab(Vis *vis) { return; } char spaces[9]; - int tabwidth = MIN(view_tabwidth_get(vis->win->view), LENGTH(spaces) - 1); + int tabwidth = MIN(vis->win->view->tabwidth, LENGTH(spaces) - 1); for (Selection *s = view_selections(win->view); s; s = view_selections_next(s)) { size_t pos = view_cursors_pos(s); int width = text_line_width_get(win->file->text, pos); From 06d7681cfffbc3e982fe192db4190f124b2b0848 Mon Sep 17 00:00:00 2001 From: Randy Palamar Date: Sat, 11 May 2024 17:52:28 -0600 Subject: [PATCH 4/8] make Selection unopaque --- main.c | 23 +++++++++-------- sam.c | 10 ++++---- ui-terminal.c | 3 +-- view.c | 69 +++++++++++-------------------------------------- view.h | 71 ++++++++++++++++----------------------------------- vis-cmds.c | 2 +- vis-lua.c | 6 ++--- vis-marks.c | 4 +-- vis-modes.c | 6 ++--- vis-prompt.c | 4 +-- vis.c | 13 +++++----- 11 files changed, 72 insertions(+), 139 deletions(-) diff --git a/main.c b/main.c index 7a45dff00..e40abb9cb 100644 --- a/main.c +++ b/main.c @@ -1240,7 +1240,7 @@ static const char *repeat(Vis *vis, const char *keys, const Arg *arg) { static const char *selections_new(Vis *vis, const char *keys, const Arg *arg) { View *view = vis_view(vis); - bool anchored = view_selections_anchored(view_selections_primary_get(view)); + bool anchored = view_selections_primary_get(view)->anchored; VisCountIterator it = vis_count_iterator_get(vis, 1); while (vis_count_iterator_next(&it)) { Selection *sel = NULL; @@ -1277,7 +1277,7 @@ static const char *selections_new(Vis *vis, const char *keys, const Arg *arg) { } if (sel_new) { view_selections_primary_set(sel_new); - view_selections_anchor(sel_new, anchored); + sel_new->anchored = anchored; } } vis->action.count = VIS_COUNT_UNKNOWN; @@ -1289,9 +1289,10 @@ static const char *selections_align(Vis *vis, const char *keys, const Arg *arg) Text *txt = vis_text(vis); int mincol = INT_MAX; for (Selection *s = view_selections(view); s; s = view_selections_next(s)) { - int col = view_cursors_cell_get(s); - if (col >= 0 && col < mincol) - mincol = col; + if (!s->line) + continue; + if (s->col >= 0 && s->col < mincol) + mincol = s->col; } for (Selection *s = view_selections(view); s; s = view_selections_next(s)) { if (view_cursors_cell_set(s, mincol) == -1) { @@ -1362,7 +1363,7 @@ static Selection *selection_new(View *view, Filerange *r, bool isprimary) { if (!s) return NULL; view_selections_set(s, r); - view_selections_anchor(s, true); + s->anchored = true; if (isprimary) view_selections_primary_set(s); return s; @@ -1432,7 +1433,7 @@ static const char *selections_match_skip(Vis *vis, const char *keys, const Arg * static const char *selections_remove(Vis *vis, const char *keys, const Arg *arg) { View *view = vis_view(vis); view_selections_dispose(view_selections_primary_get(view)); - view_cursor_to(view, view_cursor_get(view)); + view_cursors_to(view->selection, view_cursor_get(view)); return keys; } @@ -1878,7 +1879,7 @@ static const char *undo(Vis *vis, const char *keys, const Arg *arg) { if (pos != EPOS) { View *view = vis_view(vis); if (view->selection_count == 1) - view_cursor_to(view, pos); + view_cursors_to(view->selection, pos); /* redraw all windows in case some display the same file */ vis_draw(vis); } @@ -1890,7 +1891,7 @@ static const char *redo(Vis *vis, const char *keys, const Arg *arg) { if (pos != EPOS) { View *view = vis_view(vis); if (view->selection_count == 1) - view_cursor_to(view, pos); + view_cursors_to(view->selection, pos); /* redraw all windows in case some display the same file */ vis_draw(vis); } @@ -1903,7 +1904,7 @@ static const char *earlier(Vis *vis, const char *keys, const Arg *arg) { while (vis_count_iterator_next(&it)) pos = text_earlier(vis_text(vis)); if (pos != EPOS) { - view_cursor_to(vis_view(vis), pos); + view_cursors_to(vis_view(vis)->selection, pos); /* redraw all windows in case some display the same file */ vis_draw(vis); } @@ -1916,7 +1917,7 @@ static const char *later(Vis *vis, const char *keys, const Arg *arg) { while (vis_count_iterator_next(&it)) pos = text_later(vis_text(vis)); if (pos != EPOS) { - view_cursor_to(vis_view(vis), pos); + view_cursors_to(vis_view(vis)->selection, pos); /* redraw all windows in case some display the same file */ vis_draw(vis); } diff --git a/sam.c b/sam.c index ef39ff670..8b322407f 100644 --- a/sam.c +++ b/sam.c @@ -1270,7 +1270,7 @@ enum SamError sam_cmd(Vis *vis, const char *s) { if (c->sel) { if (visual) { view_selections_set(c->sel, &r); - view_selections_anchor(c->sel, true); + c->sel->anchored = true; } else { if (memchr(c->data, '\n', c->len)) view_cursors_to(c->sel, r.start); @@ -1281,7 +1281,7 @@ enum SamError sam_cmd(Vis *vis, const char *s) { Selection *sel = view_selections_new(c->win->view, r.start); if (sel) { view_selections_set(sel, &r); - view_selections_anchor(sel, true); + sel->anchored = true; } } } @@ -1295,12 +1295,12 @@ enum SamError sam_cmd(Vis *vis, const char *s) { if (vis->win) { if (primary_pos != EPOS && view_selection_disposed(vis->win->view)) - view_cursor_to(vis->win->view, primary_pos); + view_cursors_to(vis->win->view->selection, primary_pos); view_selections_primary_set(view_selections(vis->win->view)); vis_jumplist_save(vis); bool completed = true; for (Selection *s = view_selections(vis->win->view); s; s = view_selections_next(s)) { - if (view_selections_anchored(s)) { + if (s->anchored) { completed = false; break; } @@ -1572,7 +1572,7 @@ static bool cmd_print(Vis *vis, Win *win, Command *cmd, const char *argv[], Sele return false; if (range->start != range->end) { view_selections_set(sel, range); - view_selections_anchor(sel, true); + sel->anchored = true; } else { view_cursors_to(sel, range->start); view_selection_clear(sel); diff --git a/ui-terminal.c b/ui-terminal.c index c26cdb044..8c27416ca 100644 --- a/ui-terminal.c +++ b/ui-terminal.c @@ -257,8 +257,7 @@ static void ui_window_draw(UiWin *w) { line = view->topline; size_t prev_lineno = 0; Selection *sel = view_selections_primary_get(view); - const Line *cursor_line = view_cursors_line_get(sel); - size_t cursor_lineno = cursor_line->lineno; + size_t cursor_lineno = sel->line->lineno; char buf[(sizeof(size_t) * CHAR_BIT + 2) / 3 + 1 + 1]; int x = win->x, y = win->y; int view_width = view->width; diff --git a/view.c b/view.c index 046fdffed..29b8c3278 100644 --- a/view.c +++ b/view.c @@ -29,20 +29,6 @@ * the necessary offset for the last character. */ -struct Selection { - Mark cursor; /* other selection endpoint where it changes */ - Mark anchor; /* position where the selection was created */ - bool anchored; /* whether anchor remains fixed */ - size_t pos; /* in bytes from the start of the file */ - int row, col; /* in terms of zero based screen coordinates */ - int lastcol; /* remembered column used when moving across lines */ - Line *line; /* screen line on which cursor currently resides */ - int generation; /* used to filter out newly created cursors during iteration */ - int number; /* how many cursors are located before this one */ - View *view; /* associated view to which this cursor belongs */ - Selection *prev, *next; /* previous/next cursors ordered by location at creation time */ -}; - static const SyntaxSymbol symbols_none[] = { [SYNTAX_SYMBOL_SPACE] = { " " }, [SYNTAX_SYMBOL_TAB] = { " " }, @@ -64,7 +50,7 @@ static Cell cell_unused; /* move visible viewport n-lines up/down, redraws the view but does not change * cursor position which becomes invalid and should be corrected by calling - * view_cursor_to. the return value indicates whether the visible area changed. + * view_cursors_to. the return value indicates whether the visible area changed. */ static bool view_viewport_up(View *view, int n); static bool view_viewport_down(View *view, int n); @@ -406,12 +392,6 @@ bool view_coord_get(View *view, size_t pos, Line **retline, int *retrow, int *re return true; } -/* move the cursor to the character at pos bytes from the beginning of the file. - * if pos is not in the current viewport, redraw the view to make it visible */ -void view_cursor_to(View *view, size_t pos) { - view_cursors_to(view->selection, pos); -} - /* redraw the complete with data starting from view->start bytes into the file. * stop once the screen is full, update view->end, view->lastline */ void view_draw(View *view) { @@ -577,7 +557,7 @@ void view_free(View *view) { void view_reload(View *view, Text *text) { view->text = text; view_selections_clear_all(view); - view_cursor_to(view, 0); + view_cursors_to(view->selection, 0); } View *view_new(Text *text) { @@ -606,7 +586,7 @@ View *view_new(Text *text) { return NULL; } - view_cursor_to(view, 0); + view_cursors_to(view->selection, 0); return view; } @@ -683,7 +663,8 @@ void view_redraw_top(View *view) { for (Line *cur = view->topline; cur && cur != line; cur = cur->next) view->start += cur->len; view_draw(view); - view_cursor_to(view, view->selection->pos); + /* FIXME: does this logic make sense */ + view_cursors_to(view->selection, view->selection->pos); } void view_redraw_center(View *view) { @@ -705,7 +686,7 @@ void view_redraw_center(View *view) { break; } view_draw(view); - view_cursor_to(view, pos); + view_cursors_to(view->selection, pos); } void view_redraw_bottom(View *view) { @@ -721,7 +702,7 @@ size_t view_slide_up(View *view, int lines) { if (sel->line == view->topline) cursor_set(sel, view->topline, sel->col); else - view_cursor_to(view, sel->pos); + view_cursors_to(view->selection, sel->pos); } else { view_screenline_down(sel); } @@ -736,7 +717,7 @@ size_t view_slide_down(View *view, int lines) { if (lastline) cursor_set(sel, view->lastline, col); else - view_cursor_to(view, sel->pos); + view_cursors_to(view->selection, sel->pos); } else { view_screenline_up(sel); } @@ -749,7 +730,7 @@ size_t view_scroll_up(View *view, int lines) { Line *line = sel->line < view->lastline ? sel->line : view->lastline; cursor_set(sel, line, view->selection->col); } else { - view_cursor_to(view, 0); + view_cursors_to(view->selection, 0); } return sel->pos; } @@ -757,9 +738,9 @@ size_t view_scroll_up(View *view, int lines) { size_t view_scroll_page_up(View *view) { Selection *sel = view->selection; if (view->start == 0) { - view_cursor_to(view, 0); + view_cursors_to(view->selection, 0); } else { - view_cursor_to(view, view->start-1); + view_cursors_to(view->selection, view->start-1); view_redraw_bottom(view); view_screenline_begin(sel); } @@ -774,9 +755,9 @@ size_t view_scroll_page_down(View *view) { size_t view_scroll_halfpage_up(View *view) { Selection *sel = view->selection; if (view->start == 0) { - view_cursor_to(view, 0); + view_cursors_to(view->selection, 0); } else { - view_cursor_to(view, view->start-1); + view_cursors_to(view->selection, view->start-1); view_redraw_center(view); view_screenline_begin(sel); } @@ -787,7 +768,7 @@ size_t view_scroll_halfpage_down(View *view) { size_t end = view->end; size_t pos = view_scroll_down(view, view->height/2); if (pos < text_size(view->text)) - view_cursor_to(view, end); + view_cursors_to(view->selection, end); return view->selection->pos; } @@ -797,7 +778,7 @@ size_t view_scroll_down(View *view, int lines) { Line *line = sel->line > view->topline ? sel->line : view->topline; cursor_set(sel, line, sel->col); } else { - view_cursor_to(view, text_size(view->text)); + view_cursors_to(view->selection, text_size(view->text)); } return sel->pos; } @@ -885,10 +866,6 @@ size_t view_cursor_get(View *view) { return view_cursors_pos(view->selection); } -Line *view_cursors_line_get(Selection *sel) { - return sel->line; -} - void view_scroll_to(View *view, size_t pos) { view_cursors_scroll_to(view->selection, pos); } @@ -1167,10 +1144,6 @@ size_t view_cursors_col(Selection *s) { return text_line_char_get(s->view->text, pos) + 1; } -int view_cursors_cell_get(Selection *s) { - return s->line ? s->col : -1; -} - int view_cursors_cell_set(Selection *s, int cell) { if (!s->line || cell < 0) return -1; @@ -1231,10 +1204,6 @@ void view_cursors_place(Selection *s, size_t line, size_t col) { view_cursors_to(s, pos); } -void view_selections_anchor(Selection *s, bool anchored) { - s->anchored = anchored; -} - void view_selection_clear(Selection *s) { s->anchored = false; s->anchor = s->cursor; @@ -1248,10 +1217,6 @@ void view_selections_flip(Selection *s) { view_cursors_to(s, text_mark_get(s->view->text, s->cursor)); } -bool view_selections_anchored(Selection *s) { - return s->anchored; -} - void view_selections_clear_all(View *view) { for (Selection *s = view->selections; s; s = s->next) view_selection_clear(s); @@ -1270,10 +1235,6 @@ void view_selections_dispose_all(View *view) { view_draw(view); } -Filerange view_selection_get(View *view) { - return view_selections_get(view->selection); -} - Filerange view_selections_get(Selection *s) { if (!s) return text_range_empty(); diff --git a/view.h b/view.h index 003e83e7f..fff6cfc52 100644 --- a/view.h +++ b/view.h @@ -4,10 +4,8 @@ #include #include -typedef struct Selection Selection; - -#include "text.h" #include "ui.h" +#include "text.h" #include "array.h" typedef struct { @@ -49,7 +47,22 @@ struct Line { /* a line on the screen, *not* in the file */ Cell cells[]; /* win->width cells storing information about the displayed characters */ }; -typedef struct { +struct View; +typedef struct Selection { + Mark cursor; /* other selection endpoint where it changes */ + Mark anchor; /* position where the selection was created */ + bool anchored; /* whether anchor remains fixed */ + size_t pos; /* in bytes from the start of the file */ + int row, col; /* in terms of zero based screen coordinates */ + int lastcol; /* remembered column used when moving across lines */ + Line *line; /* screen line on which cursor currently resides */ + int generation; /* used to filter out newly created cursors during iteration */ + int number; /* how many cursors are located before this one */ + struct View *view; /* associated view to which this cursor belongs */ + struct Selection *prev, *next; /* previous/next cursors ordered by location at creation time */ +} Selection; + +typedef struct View { Text *text; /* underlying text management */ char *textbuf; /* scratch buffer used for drawing */ UiWin *ui; /* corresponding ui window */ @@ -248,19 +261,6 @@ void view_selections_clear_all(View*); * @endrst */ void view_selections_flip(Selection*); -/** - * @} - * @defgroup view_anchor - * @{ - */ -/** - * Anchor selection. - * Further updates will only update the cursor, the anchor will remain fixed. - */ -void view_selections_anchor(Selection*, bool anchored); -/** Check whether selection is anchored. */ -bool view_selections_anchored(Selection*); -/** Get position of selection cursor. */ /** * @} * @defgroup view_props @@ -278,20 +278,6 @@ size_t view_cursors_line(Selection*); * @endrst */ size_t view_cursors_col(Selection*); -/** - * Get screen line of selection cursor. - * @rst - * .. warning: Is `NULL` for non-visible selections. - * @endrst - */ -Line *view_cursors_line_get(Selection*); -/** - * Get zero based index of screen cell on which selection cursor currently resides. - * @rst - * .. warning:: Returns ``-1`` if the selection cursor is currently not visible. - * @endrst - */ -int view_cursors_cell_get(Selection*); /** * @} * @defgroup view_place @@ -304,6 +290,11 @@ int view_cursors_cell_get(Selection*); * will be adjusted to form a singleton selection covering one * character starting at `pos`. Otherwise only the selection * cursor will be changed while the anchor remains fixed. + * + * If primary position was not visible before, we attempt to show + * the surrounding context. The viewport will be adjusted such + * that the line holding the primary cursor is shown in the middle + * of the window. * @endrst */ void view_cursors_to(Selection*, size_t pos); @@ -351,26 +342,8 @@ size_t view_screenline_end(Selection*); * @defgroup view_primary * @{ */ -/** - * Move primary selection cursor to the given position. - * Makes sure that position is visible. - * @rst - * .. note:: If position was not visible before, we attempt to show - * surrounding context. The viewport will be adjusted such - * that the line holding the cursor is shown in the middle - * of the window. - * @endrst - */ -void view_cursor_to(View*, size_t pos); /** Get cursor position of primary selection. */ size_t view_cursor_get(View*); -/** - * Get primary selection. - * @rst - * .. note:: Is always a non-empty range. - * @endrst - */ -Filerange view_selection_get(View*); /** * @} * @defgroup view_save diff --git a/vis-cmds.c b/vis-cmds.c index 2874169db..6cfc932e6 100644 --- a/vis-cmds.c +++ b/vis-cmds.c @@ -876,7 +876,7 @@ static bool cmd_help(Vis *vis, Win *win, Command *cmd, const char *argv[], Selec text_appendf(txt, " %-32s\t%s\n", configs[i].name, configs[i].enabled ? "yes" : "no"); text_save(txt, NULL); - view_cursor_to(vis->win->view, 0); + view_cursors_to(vis->win->view->selection, 0); if (argv[1]) vis_motion(vis, VIS_MOVE_SEARCH_FORWARD, argv[1]); diff --git a/vis-lua.c b/vis-lua.c index c51a924f0..e8911f187 100644 --- a/vis-lua.c +++ b/vis-lua.c @@ -2363,7 +2363,7 @@ static int window_selection_index(lua_State *L) { } if (strcmp(key, "anchored") == 0) { - lua_pushboolean(L, view_selections_anchored(sel)); + lua_pushboolean(L, sel->anchored); return 1; } @@ -2388,7 +2388,7 @@ static int window_selection_newindex(lua_State *L) { Filerange range = getrange(L, 3); if (text_range_valid(&range)) { view_selections_set(sel, &range); - view_selections_anchor(sel, true); + sel->anchored = true; } else { view_selection_clear(sel); } @@ -2396,7 +2396,7 @@ static int window_selection_newindex(lua_State *L) { } if (strcmp(key, "anchored") == 0) { - view_selections_anchor(sel, lua_toboolean(L, 3)); + sel->anchored = lua_toboolean(L, 3); return 0; } } diff --git a/vis-marks.c b/vis-marks.c index 8ae97ac2f..aea654d71 100644 --- a/vis-marks.c +++ b/vis-marks.c @@ -161,7 +161,7 @@ static bool marklist_prev(Win *win, MarkList *list) { View *view = win->view; bool restore = false; Array cur = view_selections_get_all(view); - bool anchored = view_selections_anchored(view_selections_primary_get(view)); + bool anchored = view_selections_primary_get(view)->anchored; Array *top = array_peek(&list->prev); if (!top) goto out; @@ -192,7 +192,7 @@ static bool marklist_prev(Win *win, MarkList *list) { static bool marklist_next(Win *win, MarkList *list) { View *view = win->view; - bool anchored = view_selections_anchored(view_selections_primary_get(view)); + bool anchored = view_selections_primary_get(view)->anchored; for (;;) { Array *next = array_pop(&list->next); if (!next) diff --git a/vis-modes.c b/vis-modes.c index 2e120aab3..41121a863 100644 --- a/vis-modes.c +++ b/vis-modes.c @@ -190,7 +190,7 @@ static void vis_mode_visual_enter(Vis *vis, Mode *old) { Win *win = vis->win; if (!old->visual && win) { for (Selection *s = view_selections(win->view); s; s = view_selections_next(s)) - view_selections_anchor(s, true); + s->anchored = true; } } @@ -198,7 +198,7 @@ static void vis_mode_visual_line_enter(Vis *vis, Mode *old) { Win *win = vis->win; if (!old->visual && win) { for (Selection *s = view_selections(win->view); s; s = view_selections_next(s)) - view_selections_anchor(s, true); + s->anchored = true; } if (!vis->action.op) vis_motion(vis, VIS_MOVE_NOP); @@ -213,7 +213,7 @@ static void vis_mode_visual_line_leave(Vis *vis, Mode *new) { window_selection_save(win); view_selections_clear_all(win->view); } else { - view_cursor_to(win->view, view_cursor_get(win->view)); + view_cursors_to(win->view->selection, view_cursor_get(win->view)); } } diff --git a/vis-prompt.c b/vis-prompt.c index f265b1012..6dbe69c97 100644 --- a/vis-prompt.c +++ b/vis-prompt.c @@ -54,7 +54,7 @@ static const char *prompt_enter(Vis *vis, const char *keys, const Arg *arg) { Win *win = prompt->parent; char *cmd = NULL; - Filerange range = view_selection_get(view); + Filerange range = view_selections_get(view->selection); if (!vis->mode->visual) { const char *pattern = NULL; Regex *regex = text_regex_new(); @@ -202,6 +202,6 @@ void vis_message_show(Vis *vis, const char *msg) { size_t pos = text_size(txt); text_appendf(txt, "%s\n", msg); text_save(txt, NULL); - view_cursor_to(win->view, pos); + view_cursors_to(win->view->selection, pos); vis_window_focus(win); } diff --git a/vis.c b/vis.c index a5606e3db..c1b9ae079 100644 --- a/vis.c +++ b/vis.c @@ -259,7 +259,7 @@ static void window_draw_cursorline(Win *win) { int width = view->width; Selection *sel = view_selections_primary_get(view); - size_t lineno = view_cursors_line_get(sel)->lineno; + size_t lineno = sel->line->lineno; for (Line *l = view->topline; l; l = l->next) { if (l->lineno == lineno) { for (int x = 0; x < width; x++) @@ -314,12 +314,11 @@ static void window_draw_cursor_matching(Win *win, Selection *cur) { static void window_draw_cursor(Win *win, Selection *cur) { if (win->vis->win != win) return; - Line *line = view_cursors_line_get(cur); - int col = view_cursors_cell_get(cur); - if (!line || col == -1) + Line *line = cur->line; + if (!line) return; Selection *primary = view_selections_primary_get(win->view); - win->ui->style_set(win->ui, &line->cells[col], primary == cur ? UI_STYLE_CURSOR_PRIMARY : UI_STYLE_CURSOR); + win->ui->style_set(win->ui, &line->cells[cur->col], primary == cur ? UI_STYLE_CURSOR_PRIMARY : UI_STYLE_CURSOR); window_draw_cursor_matching(win, cur); return; } @@ -451,7 +450,7 @@ bool vis_window_split(Win *original) { } win->file = original->file; view_options_set(win->view, view_options_get(original->view)); - view_cursor_to(win->view, view_cursor_get(original->view)); + view_cursors_to(win->view->selection, view_cursor_get(original->view)); vis_doupdates(win->vis, true); return true; } @@ -910,7 +909,7 @@ void vis_do(Vis *vis) { c.range = text_range_linewise(txt, &c.range); if (vis->mode->visual) { view_selections_set(sel, &c.range); - view_selections_anchor(sel, true); + sel->anchored = true; } if (a->op) { From 54b3babf49ac75fce78815ae1d7a19f3def69660 Mon Sep 17 00:00:00 2001 From: Randy Palamar Date: Sun, 12 May 2024 11:28:56 -0600 Subject: [PATCH 5/8] replace UiTermWin with UiWin & remove function pointers --- ui-terminal.c | 104 ++++++++++++++------------------------------------ ui.h | 25 ++++++++---- view.c | 20 +++------- view.h | 3 -- vis-cmds.c | 12 +++--- vis-lua.c | 30 +++++++-------- vis.c | 22 +++++------ vis.h | 2 - 8 files changed, 82 insertions(+), 136 deletions(-) diff --git a/ui-terminal.c b/ui-terminal.c index 8c27416ca..9aaac7dfd 100644 --- a/ui-terminal.c +++ b/ui-terminal.c @@ -32,13 +32,12 @@ #define MAX_WIDTH 1024 #define MAX_HEIGHT 1024 -typedef struct UiTermWin UiTermWin; -typedef struct { +struct UiTerm { Ui ui; /* generic ui interface, has to be the first struct member */ Vis *vis; /* editor instance to which this ui belongs */ - UiTermWin *windows; /* all windows managed by this ui */ - UiTermWin *selwin; /* the currently selected layout */ + UiWin *windows; /* all windows managed by this ui */ + UiWin *selwin; /* the currently selected layout */ char info[MAX_WIDTH]; /* info message displayed at the bottom of the screen */ int width, height; /* terminal dimensions available for all windows */ enum UiLayout layout; /* whether windows are displayed horizontally or vertically */ @@ -49,18 +48,6 @@ typedef struct { size_t cells_size; /* #bytes allocated for 2D grid (grows only) */ Cell *cells; /* 2D grid of cells, at least as large as current terminal size */ bool doupdate; /* Whether to update the screen after refreshing contents */ -} UiTerm; - -struct UiTermWin { - UiWin uiwin; /* generic interface, has to be the first struct member */ - UiTerm *ui; /* ui which manages this window */ - Win *win; /* editor window being displayed */ - int id; /* unique identifier for this window */ - int width, height; /* window dimension including status bar */ - int x, y; /* window position */ - int sidebar_width; /* width of the sidebar showing line numbers etc. */ - UiTermWin *next, *prev; /* pointers to neighbouring windows */ - enum UiOption options; /* display settings for this window */ }; #if CONFIG_CURSES @@ -88,7 +75,7 @@ __attribute__((noreturn)) static void ui_die_msg(Ui *ui, const char *msg, ...) { va_end(ap); } -static void ui_window_resize(UiTermWin *win, int width, int height) { +static void ui_window_resize(UiWin *win, int width, int height) { debug("ui-win-resize[%s]: %dx%d\n", win->win->file->name ? win->win->file->name : "noname", width, height); bool status = win->options & UI_OPTION_STATUSBAR; win->width = width; @@ -96,7 +83,7 @@ static void ui_window_resize(UiTermWin *win, int width, int height) { view_resize(win->win->view, width - win->sidebar_width, status ? height - 1 : height); } -static void ui_window_move(UiTermWin *win, int x, int y) { +static void ui_window_move(UiWin *win, int x, int y) { debug("ui-win-move[%s]: (%d, %d)\n", win->win->file->name ? win->win->file->name : "noname", x, y); win->x = x; win->y = y; @@ -150,8 +137,7 @@ static bool color_fromstring(UiTerm *ui, CellColor *color, const char *s) return false; } -static bool ui_style_define(UiWin *w, int id, const char *style) { - UiTermWin *win = (UiTermWin*)w; +bool ui_style_define(UiWin *win, int id, const char *style) { UiTerm *tui = win->ui; if (id >= UI_STYLE_MAX) return false; @@ -217,7 +203,7 @@ static void ui_draw_line(UiTerm *tui, int x, int y, char c, enum UiStyle style_i } } -static void ui_draw_string(UiTerm *tui, int x, int y, const char *str, UiTermWin *win, enum UiStyle style_id) { +static void ui_draw_string(UiTerm *tui, int x, int y, const char *str, UiWin *win, enum UiStyle style_id) { debug("draw-string: [%d][%d]\n", y, x); if (x < 0 || x >= tui->width || y < 0 || y >= tui->height) return; @@ -238,8 +224,7 @@ static void ui_draw_string(UiTerm *tui, int x, int y, const char *str, UiTermWin } } -static void ui_window_draw(UiWin *w) { - UiTermWin *win = (UiTermWin*)w; +static void ui_window_draw(UiWin *win) { UiTerm *ui = win->ui; View *view = win->win->view; int width = win->width, height = win->height; @@ -290,8 +275,7 @@ static void ui_window_draw(UiWin *w) { } } -static void ui_window_style_set(UiWin *w, Cell *cell, enum UiStyle id) { - UiTermWin *win = (UiTermWin*)w; +void ui_window_style_set(UiWin *win, Cell *cell, enum UiStyle id) { UiTerm *tui = win->ui; CellStyle set, style = tui->styles[win->id * UI_STYLE_MAX + id]; @@ -307,19 +291,17 @@ static void ui_window_style_set(UiWin *w, Cell *cell, enum UiStyle id) { memcpy(&cell->style, &set, sizeof(CellStyle)); } -static bool ui_window_style_set_pos(UiWin *w, int x, int y, enum UiStyle id) { - UiTermWin *win = (UiTermWin*)w; +bool ui_window_style_set_pos(UiWin *win, int x, int y, enum UiStyle id) { UiTerm *tui = win->ui; if (x < 0 || y < 0 || y >= win->height || x >= win->width) { return false; } Cell *cell = CELL_AT_POS(tui, win->x + x, win->y + y) - ui_window_style_set(w, cell, id); + ui_window_style_set(win, cell, id); return true; } -static void ui_window_status(UiWin *w, const char *status) { - UiTermWin *win = (UiTermWin*)w; +void ui_window_status(UiWin *win, const char *status) { if (!(win->options & UI_OPTION_STATUSBAR)) return; UiTerm *ui = win->ui; @@ -332,7 +314,7 @@ static void ui_arrange(Ui *ui, enum UiLayout layout) { UiTerm *tui = (UiTerm*)ui; tui->layout = layout; int n = 0, m = !!tui->info[0], x = 0, y = 0; - for (UiTermWin *win = tui->windows; win; win = win->next) { + for (UiWin *win = tui->windows; win; win = win->next) { if (win->options & UI_OPTION_ONELINE) m++; else @@ -341,7 +323,7 @@ static void ui_arrange(Ui *ui, enum UiLayout layout) { int max_height = tui->height - m; int width = (tui->width / MAX(1, n)) - 1; int height = max_height / MAX(1, n); - for (UiTermWin *win = tui->windows; win; win = win->next) { + for (UiWin *win = tui->windows; win; win = win->next) { if (win->options & UI_OPTION_ONELINE) continue; n--; @@ -370,7 +352,7 @@ static void ui_arrange(Ui *ui, enum UiLayout layout) { if (layout == UI_LAYOUT_VERTICAL) y = max_height; - for (UiTermWin *win = tui->windows; win; win = win->next) { + for (UiWin *win = tui->windows; win; win = win->next) { if (!(win->options & UI_OPTION_ONELINE)) continue; ui_window_resize(win, tui->width, 1); @@ -387,7 +369,7 @@ static void ui_draw(Ui *ui) { debug("ui-draw\n"); UiTerm *tui = (UiTerm*)ui; ui_arrange(ui, tui->layout); - for (UiTermWin *win = tui->windows; win; win = win->next) + for (UiWin *win = tui->windows; win; win = win->next) ui_window_draw((UiWin*)win); if (tui->info[0]) ui_draw_string(tui, 0, tui->height-1, tui->info, NULL, UI_STYLE_INFO); @@ -398,7 +380,7 @@ static void ui_draw(Ui *ui) { static void ui_redraw(Ui *ui) { UiTerm *tui = (UiTerm*)ui; ui_term_backend_clear(tui); - for (UiTermWin *win = tui->windows; win; win = win->next) + for (UiWin *win = tui->windows; win; win = win->next) win->win->view->need_update = true; } @@ -432,8 +414,7 @@ static void ui_resize(Ui *ui) { tui->height = height; } -static void ui_window_free(UiWin *w) { - UiTermWin *win = (UiTermWin*)w; +static void ui_window_free(UiWin *win) { if (!win) return; UiTerm *tui = win->ui; @@ -450,9 +431,8 @@ static void ui_window_free(UiWin *w) { free(win); } -static void ui_window_focus(UiWin *w) { - UiTermWin *new = (UiTermWin*)w; - UiTermWin *old = new->ui->selwin; +static void ui_window_focus(UiWin *new) { + UiWin *old = new->ui->selwin; if (new->options & UI_OPTION_STATUSBAR) new->ui->selwin = new; if (old) @@ -460,13 +440,12 @@ static void ui_window_focus(UiWin *w) { new->win->view->need_update = true; } -static void ui_window_options_set(UiWin *w, enum UiOption options) { - UiTermWin *win = (UiTermWin*)w; +void ui_window_options_set(UiWin *win, enum UiOption options) { win->options = options; if (options & UI_OPTION_ONELINE) { /* move the new window to the end of the list */ UiTerm *tui = win->ui; - UiTermWin *last = tui->windows; + UiWin *last = tui->windows; while (last->next) last = last->next; if (last != win) { @@ -484,25 +463,11 @@ static void ui_window_options_set(UiWin *w, enum UiOption options) { ui_draw((Ui*)win->ui); } -static enum UiOption ui_window_options_get(UiWin *win) { - return ((UiTermWin*)win)->options; -} - -static int ui_window_width(UiWin *win) { - return ((UiTermWin*)win)->width; -} - -static int ui_window_height(UiWin *win) { - return ((UiTermWin*)win)->height; -} - -static void ui_window_swap(UiWin *aw, UiWin *bw) { - UiTermWin *a = (UiTermWin*)aw; - UiTermWin *b = (UiTermWin*)bw; +static void ui_window_swap(UiWin *a, UiWin *b) { if (a == b || !a || !b) return; UiTerm *tui = a->ui; - UiTermWin *tmp = a->next; + UiWin *tmp = a->next; a->next = b->next; b->next = tmp; if (a->next) @@ -521,9 +486,9 @@ static void ui_window_swap(UiWin *aw, UiWin *bw) { else if (tui->windows == b) tui->windows = a; if (tui->selwin == a) - ui_window_focus(bw); + ui_window_focus(b); else if (tui->selwin == b) - ui_window_focus(aw); + ui_window_focus(a); } static UiWin *ui_window_new(Ui *ui, Win *w, enum UiOption options) { @@ -542,21 +507,10 @@ static UiWin *ui_window_new(Ui *ui, Win *w, enum UiOption options) { tui->styles = styles; tui->styles_size = styles_size; } - UiTermWin *win = calloc(1, sizeof(UiTermWin)); + UiWin *win = calloc(1, sizeof(UiWin)); if (!win) return NULL; - win->uiwin = (UiWin) { - .style_set = ui_window_style_set, - .style_set_pos = ui_window_style_set_pos, - .status = ui_window_status, - .options_set = ui_window_options_set, - .options_get = ui_window_options_get, - .style_define = ui_style_define, - .window_width = ui_window_width, - .window_height = ui_window_height, - }; - tui->ids |= bit; win->id = id; win->ui = tui; @@ -578,7 +532,7 @@ static UiWin *ui_window_new(Ui *ui, Win *w, enum UiOption options) { styles[UI_STYLE_STATUS].attr |= CELL_ATTR_REVERSE; styles[UI_STYLE_STATUS_FOCUSED].attr |= CELL_ATTR_REVERSE|CELL_ATTR_BOLD; styles[UI_STYLE_INFO].attr |= CELL_ATTR_BOLD; - w->view->ui = &win->uiwin; + w->view->ui = win; if (tui->windows) tui->windows->prev = win; @@ -592,7 +546,7 @@ static UiWin *ui_window_new(Ui *ui, Win *w, enum UiOption options) { ui_window_options_set((UiWin*)win, options); - return &win->uiwin; + return win; } static void ui_info(Ui *ui, const char *msg, va_list ap) { diff --git a/ui.h b/ui.h index 45b6065eb..3a4bb8bce 100644 --- a/ui.h +++ b/ui.h @@ -12,6 +12,7 @@ typedef struct Ui Ui; typedef struct UiWin UiWin; +typedef struct UiTerm UiTerm; enum UiLayout { UI_LAYOUT_HORIZONTAL, @@ -96,16 +97,24 @@ struct Ui { }; struct UiWin { - void (*style_set)(UiWin*, Cell*, enum UiStyle); - bool (*style_set_pos)(UiWin*, int x, int y, enum UiStyle); - void (*status)(UiWin*, const char *txt); - void (*options_set)(UiWin*, enum UiOption); - enum UiOption (*options_get)(UiWin*); - bool (*style_define)(UiWin*, int id, const char *style); - int (*window_width)(UiWin*); - int (*window_height)(UiWin*); + UiTerm *ui; /* ui which manages this window */ + Win *win; /* editor window being displayed */ + int id; /* unique identifier for this window */ + int width, height; /* window dimension including status bar */ + int x, y; /* window position */ + int sidebar_width; /* width of the sidebar showing line numbers etc. */ + UiWin *next, *prev; /* pointers to neighbouring windows */ + enum UiOption options; /* display settings for this window */ }; +#define UI_OPTIONS_GET(ui) ((ui) ? (ui)->options : 0) + +bool ui_style_define(UiWin *win, int id, const char *style); +bool ui_window_style_set_pos(UiWin *win, int x, int y, enum UiStyle id); +void ui_window_style_set(UiWin *win, Cell *cell, enum UiStyle id); + enum UiLayout ui_layout_get(Ui *ui); +void ui_window_options_set(UiWin *win, enum UiOption options); +void ui_window_status(UiWin *win, const char *status); #endif diff --git a/view.c b/view.c index 29b8c3278..afc72da66 100644 --- a/view.c +++ b/view.c @@ -74,8 +74,8 @@ void window_status_update(Vis *vis, Win *win) { View *view = win->view; File *file = win->file; Text *txt = file->text; - int width = win->ui->window_width(win->ui); - enum UiOption options = view_options_get(view); + int width = win->ui->width; + enum UiOption options = UI_OPTIONS_GET(view->ui); bool focused = vis->win == win; const char *filename = file_name_get(file); const char *mode = vis->mode->status; @@ -153,7 +153,7 @@ void window_status_update(Vis *vis, Win *win) { spaces = 1; snprintf(status, sizeof(status), "%s%*s%s", left, spaces, " ", right); - vis_window_status(win, status); + ui_window_status(win->ui, status); } void view_tabwidth_set(View *view, int tabwidth) { @@ -203,7 +203,7 @@ static void view_clear(View *view) { view->wrapcol = 0; view->prevch_breakat = false; if (view->ui) - view->ui->style_set(view->ui, &view->cell_blank, UI_STYLE_DEFAULT); + ui_window_style_set(view->ui, &view->cell_blank, UI_STYLE_DEFAULT); } static int view_max_text_width(const View *view) { @@ -890,11 +890,7 @@ void view_options_set(View *view, enum UiOption options) { view->large_file = (options & UI_OPTION_LARGE_FILE); if (view->ui) - view->ui->options_set(view->ui, options); -} - -enum UiOption view_options_get(View *view) { - return view->ui ? view->ui->options_get(view->ui) : 0; + ui_window_options_set(view->ui, options); } bool view_breakat_set(View *view, const char *breakat) { @@ -1351,10 +1347,6 @@ char *view_symbol_eof_get(View *view) { return view->symbols[SYNTAX_SYMBOL_EOF]->symbol; } -bool view_style_define(View *view, enum UiStyle id, const char *style) { - return view->ui->style_define(view->ui, id, style); -} - void view_style(View *view, enum UiStyle style, size_t start, size_t end) { if (end < view->start || start > view->end) return; @@ -1384,7 +1376,7 @@ void view_style(View *view, enum UiStyle style, size_t start, size_t end) { do { while (pos <= end && col < width) { pos += line->cells[col].len; - view->ui->style_set(view->ui, &line->cells[col++], style); + ui_window_style_set(view->ui, &line->cells[col++], style); } col = 0; } while (pos <= end && (line = line->next)); diff --git a/view.h b/view.h index fff6cfc52..a9ebbc5c8 100644 --- a/view.h +++ b/view.h @@ -357,13 +357,10 @@ bool view_regions_save(View*, Filerange*, SelectionRegion*); * @{ */ void view_options_set(View*, enum UiOption options); -enum UiOption view_options_get(View*); bool view_breakat_set(View*, const char *breakat); /** Set how many spaces are used to display a tab `\t` character. */ void view_tabwidth_set(View*, int tabwidth); -/** Define a display style. */ -bool view_style_define(View*, enum UiStyle, const char *style); /** Apply a style to a text range. */ void view_style(View*, enum UiStyle, size_t start, size_t end); diff --git a/vis-cmds.c b/vis-cmds.c index 6cfc932e6..2b3398d0c 100644 --- a/vis-cmds.c +++ b/vis-cmds.c @@ -276,7 +276,7 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Select [OPTION_SHOW_EOF] = UI_OPTION_SYMBOL_EOF, [OPTION_STATUSBAR] = UI_OPTION_STATUSBAR, }; - int flags = view_options_get(win->view); + int flags = UI_OPTIONS_GET(win->view->ui); if (arg.b || (toggle && !(flags & values[opt_index]))) flags |= values[opt_index]; else @@ -285,7 +285,7 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Select break; } case OPTION_NUMBER: { - enum UiOption opt = view_options_get(win->view); + enum UiOption opt = UI_OPTIONS_GET(win->view->ui); if (arg.b || (toggle && !(opt & UI_OPTION_LINE_NUMBERS_ABSOLUTE))) { opt &= ~UI_OPTION_LINE_NUMBERS_RELATIVE; opt |= UI_OPTION_LINE_NUMBERS_ABSOLUTE; @@ -296,7 +296,7 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Select break; } case OPTION_NUMBER_RELATIVE: { - enum UiOption opt = view_options_get(win->view); + enum UiOption opt = UI_OPTIONS_GET(win->view->ui); if (arg.b || (toggle && !(opt & UI_OPTION_LINE_NUMBERS_RELATIVE))) { opt &= ~UI_OPTION_LINE_NUMBERS_ABSOLUTE; opt |= UI_OPTION_LINE_NUMBERS_RELATIVE; @@ -307,7 +307,7 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Select break; } case OPTION_CURSOR_LINE: { - enum UiOption opt = view_options_get(win->view); + enum UiOption opt = UI_OPTIONS_GET(win->view->ui); if (arg.b || (toggle && !(opt & UI_OPTION_CURSOR_LINE))) opt |= UI_OPTION_CURSOR_LINE; else @@ -545,7 +545,7 @@ static bool cmd_qall(Vis *vis, Win *win, Command *cmd, const char *argv[], Selec static bool cmd_split(Vis *vis, Win *win, Command *cmd, const char *argv[], Selection *sel, Filerange *range) { if (!win) return false; - enum UiOption options = view_options_get(win->view); + enum UiOption options = UI_OPTIONS_GET(win->view->ui); windows_arrange(vis, UI_LAYOUT_HORIZONTAL); if (!argv[1]) return vis_window_split(win); @@ -558,7 +558,7 @@ static bool cmd_split(Vis *vis, Win *win, Command *cmd, const char *argv[], Sele static bool cmd_vsplit(Vis *vis, Win *win, Command *cmd, const char *argv[], Selection *sel, Filerange *range) { if (!win) return false; - enum UiOption options = view_options_get(win->view); + enum UiOption options = UI_OPTIONS_GET(win->view->ui); windows_arrange(vis, UI_LAYOUT_VERTICAL); if (!argv[1]) return vis_window_split(win); diff --git a/vis-lua.c b/vis-lua.c index e8911f187..4bf582a36 100644 --- a/vis-lua.c +++ b/vis-lua.c @@ -1788,12 +1788,12 @@ static int window_index(lua_State *L) { } if (strcmp(key, "width") == 0) { - lua_pushunsigned(L, win->ui->window_width(win->ui)); + lua_pushunsigned(L, win->ui->width); return 1; } if (strcmp(key, "height") == 0) { - lua_pushunsigned(L, win->ui->window_height(win->ui)); + lua_pushunsigned(L, win->ui->height); return 1; } @@ -1827,7 +1827,7 @@ static int window_index(lua_State *L) { } static int window_options_assign(Win *win, lua_State *L, const char *key, int next) { - enum UiOption flags = view_options_get(win->view); + enum UiOption flags = UI_OPTIONS_GET(win->view->ui); if (strcmp(key, "breakat") == 0 || strcmp(key, "brk") == 0) { if (lua_isstring(L, next)) view_breakat_set(win->view, lua_tostring(L, next)); @@ -1988,7 +1988,7 @@ static int window_style_define(lua_State *L) { Win *win = obj_ref_check(L, 1, VIS_LUA_TYPE_WINDOW); enum UiStyle id = luaL_checkunsigned(L, 2); const char *style = luaL_checkstring(L, 3); - bool ret = view_style_define(win->view, id, style); + bool ret = ui_style_define(win->view->ui, id, style); lua_pushboolean(L, ret); return 1; } @@ -2035,7 +2035,7 @@ static int window_style_pos(lua_State *L) { enum UiStyle style = luaL_checkunsigned(L, 2); size_t x = checkpos(L, 3); size_t y = checkpos(L, 4); - bool ret = win->ui->style_set_pos(win->ui, (int)x, (int)y, style); + bool ret = ui_window_style_set_pos(win->ui, (int)x, (int)y, style); lua_pushboolean(L, ret); return 1; } @@ -2050,7 +2050,7 @@ static int window_style_pos(lua_State *L) { static int window_status(lua_State *L) { Win *win = obj_ref_check(L, 1, VIS_LUA_TYPE_WINDOW); char status[1024] = ""; - int width = win->ui->window_width(win->ui); + int width = win->ui->width; const char *left = luaL_checkstring(L, 2); const char *right = luaL_optstring(L, 3, ""); int left_width = text_string_width(left, strlen(left)); @@ -2059,7 +2059,7 @@ static int window_status(lua_State *L) { if (spaces < 1) spaces = 1; snprintf(status, sizeof(status)-1, "%s%*s%s", left, spaces, " ", right); - vis_window_status(win, status); + ui_window_status(win->ui, status); return 0; } @@ -2148,31 +2148,31 @@ static int window_options_index(lua_State *L) { lua_pushunsigned(L, win->view->colorcolumn); return 1; } else if (strcmp(key, "cursorline") == 0 || strcmp(key, "cul") == 0) { - lua_pushboolean(L, view_options_get(win->view) & UI_OPTION_CURSOR_LINE); + lua_pushboolean(L, UI_OPTIONS_GET(win->view->ui) & UI_OPTION_CURSOR_LINE); return 1; } else if (strcmp(key, "expandtab") == 0 || strcmp(key, "et") == 0) { lua_pushboolean(L, win->expandtab); return 1; } else if (strcmp(key, "numbers") == 0 || strcmp(key, "nu") == 0) { - lua_pushboolean(L, view_options_get(win->view) & UI_OPTION_LINE_NUMBERS_ABSOLUTE); + lua_pushboolean(L, UI_OPTIONS_GET(win->view->ui) & UI_OPTION_LINE_NUMBERS_ABSOLUTE); return 1; } else if (strcmp(key, "relativenumbers") == 0 || strcmp(key, "rnu") == 0) { - lua_pushboolean(L, view_options_get(win->view) & UI_OPTION_LINE_NUMBERS_RELATIVE); + lua_pushboolean(L, UI_OPTIONS_GET(win->view->ui) & UI_OPTION_LINE_NUMBERS_RELATIVE); return 1; } else if (strcmp(key, "showeof") == 0) { - lua_pushboolean(L, view_options_get(win->view) & UI_OPTION_SYMBOL_EOF); + lua_pushboolean(L, UI_OPTIONS_GET(win->view->ui) & UI_OPTION_SYMBOL_EOF); return 1; } else if (strcmp(key, "shownewlines") == 0) { - lua_pushboolean(L, view_options_get(win->view) & UI_OPTION_SYMBOL_EOL); + lua_pushboolean(L, UI_OPTIONS_GET(win->view->ui) & UI_OPTION_SYMBOL_EOL); return 1; } else if (strcmp(key, "showspaces") == 0) { - lua_pushboolean(L, view_options_get(win->view) & UI_OPTION_SYMBOL_SPACE); + lua_pushboolean(L, UI_OPTIONS_GET(win->view->ui) & UI_OPTION_SYMBOL_SPACE); return 1; } else if (strcmp(key, "showtabs") == 0) { - lua_pushboolean(L, view_options_get(win->view) & UI_OPTION_SYMBOL_TAB); + lua_pushboolean(L, UI_OPTIONS_GET(win->view->ui) & UI_OPTION_SYMBOL_TAB); return 1; } else if (strcmp(key, "statusbar") == 0) { - lua_pushboolean(L, view_options_get(win->view) & UI_OPTION_STATUSBAR); + lua_pushboolean(L, UI_OPTIONS_GET(win->view->ui) & UI_OPTION_STATUSBAR); return 1; } else if (strcmp(key, "tabwidth") == 0 || strcmp(key, "tw") == 0) { lua_pushinteger(L, win->view->tabwidth); diff --git a/vis.c b/vis.c index c1b9ae079..d03bde8cb 100644 --- a/vis.c +++ b/vis.c @@ -184,10 +184,6 @@ const char *file_name_get(File *file) { return file->name[cwdlen] == '/' ? file->name+cwdlen+1 : file->name; } -void vis_window_status(Win *win, const char *status) { - win->ui->status(win->ui, status); -} - void window_selection_save(Win *win) { Vis *vis = win->vis; View *view = win->view; @@ -238,7 +234,7 @@ static void window_draw_colorcolumn(Win *win) { /* This screen line contains the cell we want to highlight */ if (cc <= line_cols + width) { - win->ui->style_set(win->ui, &l->cells[cc - 1 - line_cols], UI_STYLE_COLOR_COLUMN); + ui_window_style_set(win->ui, &l->cells[cc - 1 - line_cols], UI_STYLE_COLOR_COLUMN); line_cc_set = true; } else { line_cols += width; @@ -249,7 +245,7 @@ static void window_draw_colorcolumn(Win *win) { static void window_draw_cursorline(Win *win) { Vis *vis = win->vis; View *view = win->view; - enum UiOption options = view_options_get(view); + enum UiOption options = UI_OPTIONS_GET(view->ui); if (!(options & UI_OPTION_CURSOR_LINE)) return; if (vis->mode->visual || vis->win != win) @@ -263,7 +259,7 @@ static void window_draw_cursorline(Win *win) { for (Line *l = view->topline; l; l = l->next) { if (l->lineno == lineno) { for (int x = 0; x < width; x++) - win->ui->style_set(win->ui, &l->cells[x], UI_STYLE_CURSOR_LINE); + ui_window_style_set(win->ui, &l->cells[x], UI_STYLE_CURSOR_LINE); } else if (l->lineno > lineno) { break; } @@ -293,7 +289,7 @@ static void window_draw_selection(Win *win, Selection *cur) { int col = (l == start_line) ? start_col : 0; int end = (l == end_line) ? end_col : l->width; while (col < end) - win->ui->style_set(win->ui, &l->cells[col++], UI_STYLE_SELECTION); + ui_window_style_set(win->ui, &l->cells[col++], UI_STYLE_SELECTION); } } @@ -308,7 +304,7 @@ static void window_draw_cursor_matching(Win *win, Selection *cur) { return; if (!view_coord_get(win->view, pos_match, &line_match, NULL, &col_match)) return; - win->ui->style_set(win->ui, &line_match->cells[col_match], UI_STYLE_SELECTION); + ui_window_style_set(win->ui, &line_match->cells[col_match], UI_STYLE_SELECTION); } static void window_draw_cursor(Win *win, Selection *cur) { @@ -318,7 +314,7 @@ static void window_draw_cursor(Win *win, Selection *cur) { if (!line) return; Selection *primary = view_selections_primary_get(win->view); - win->ui->style_set(win->ui, &line->cells[cur->col], primary == cur ? UI_STYLE_CURSOR_PRIMARY : UI_STYLE_CURSOR); + ui_window_style_set(win->ui, &line->cells[cur->col], primary == cur ? UI_STYLE_CURSOR_PRIMARY : UI_STYLE_CURSOR); window_draw_cursor_matching(win, cur); return; } @@ -351,7 +347,7 @@ static void window_draw_eof(Win *win) { return; for (Line *l = view->lastline->next; l; l = l->next) { strncpy(l->cells[0].data, view_symbol_eof_get(view), sizeof(l->cells[0].data)-1); - win->ui->style_set(win->ui, &l->cells[0], UI_STYLE_EOF); + ui_window_style_set(win->ui, &l->cells[0], UI_STYLE_EOF); } } @@ -394,7 +390,7 @@ Win *window_new_file(Vis *vis, File *file, enum UiOption options) { marklist_init(&win->jumplist, 32); mark_init(&win->saved_selections); file->refcount++; - view_options_set(win->view, view_options_get(win->view)); + view_options_set(win->view, UI_OPTIONS_GET(win->view->ui)); if (vis->windows) vis->windows->prev = win; @@ -449,7 +445,7 @@ bool vis_window_split(Win *original) { map_copy(win->modes[i].bindings, original->modes[i].bindings); } win->file = original->file; - view_options_set(win->view, view_options_get(original->view)); + view_options_set(win->view, UI_OPTIONS_GET(original->view->ui)); view_cursors_to(win->view->selection, view_cursor_get(original->view)); vis_doupdates(win->vis, true); return true; diff --git a/vis.h b/vis.h index a915c0ed7..057e66bbc 100644 --- a/vis.h +++ b/vis.h @@ -196,8 +196,6 @@ bool vis_window_closable(Win*); void vis_window_close(Win*); /** Split the window, shares the underlying file object. */ bool vis_window_split(Win*); -/** Change status message of this window. */ -void vis_window_status(Win*, const char *status); void vis_window_draw(Win*); void vis_window_invalidate(Win*); /** Focus next window. */ From 486e8631ce9269d34c00c07038e04013640f8825 Mon Sep 17 00:00:00 2001 From: Randy Palamar Date: Sun, 12 May 2024 12:35:48 -0600 Subject: [PATCH 6/8] replace UiTerm with Ui & delete function pointers --- event-basic.c | 2 +- main.c | 6 +- ui-terminal-curses.c | 42 ++++------- ui-terminal-vt100.c | 46 +++++------- ui-terminal.c | 170 ++++++++++++------------------------------- ui-terminal.h | 9 --- ui.h | 107 +++++++++++++++++---------- view.h | 12 --- vis-cmds.c | 18 ++--- vis-lua.c | 12 +-- vis-prompt.c | 6 +- vis.c | 66 +++++++---------- vis.h | 25 ------- 13 files changed, 188 insertions(+), 333 deletions(-) delete mode 100644 ui-terminal.h diff --git a/event-basic.c b/event-basic.c index 6d298b516..cb2d2c191 100644 --- a/event-basic.c +++ b/event-basic.c @@ -6,7 +6,7 @@ bool vis_event_emit(Vis *vis, enum VisEvents id, ...) { if (!vis->initialized) { vis->initialized = true; - vis->ui->init(vis->ui, vis); + ui_init(vis->ui, vis); } va_list ap; diff --git a/main.c b/main.c index e40abb9cb..d19b6f470 100644 --- a/main.c +++ b/main.c @@ -10,7 +10,7 @@ #include #include -#include "ui-terminal.h" +#include "ui.h" #include "vis.h" #include "vis-lua.h" #include "text-util.h" @@ -1229,7 +1229,7 @@ static const char *macro_replay(Vis *vis, const char *keys, const Arg *arg) { } static const char *suspend(Vis *vis, const char *keys, const Arg *arg) { - vis_suspend(vis); + ui_terminal_suspend(vis->ui); return keys; } @@ -2214,7 +2214,7 @@ static void signal_handler(int signum, siginfo_t *siginfo, void *context) { } int main(int argc, char *argv[]) { - vis = vis_new(ui_term_new()); + vis = vis_new(ui_terminal_new()); if (!vis) return EXIT_FAILURE; diff --git a/ui-terminal-curses.c b/ui-terminal-curses.c index b89d9b58f..2b4a6fd6c 100644 --- a/ui-terminal-curses.c +++ b/ui-terminal-curses.c @@ -4,18 +4,6 @@ #define UI_TERMKEY_FLAGS (TERMKEY_FLAG_UTF8|TERMKEY_FLAG_NOTERMIOS) -#define ui_term_backend_init ui_curses_init -#define ui_term_backend_blit ui_curses_blit -#define ui_term_backend_clear ui_curses_clear -#define ui_term_backend_colors ui_curses_colors -#define ui_term_backend_resize ui_curses_resize -#define ui_term_backend_restore ui_curses_restore -#define ui_term_backend_save ui_curses_save -#define ui_term_backend_new ui_curses_new -#define ui_term_backend_resume ui_curses_resume -#define ui_term_backend_suspend ui_curses_suspend -#define ui_term_backend_free ui_curses_free - #define CELL_COLOR_BLACK COLOR_BLACK #define CELL_COLOR_RED COLOR_RED #define CELL_COLOR_GREEN COLOR_GREEN @@ -85,7 +73,7 @@ static void undo_palette(void) } /* Work out the nearest color from the 256 color set, or perhaps exactly. */ -static CellColor color_rgb(UiTerm *ui, uint8_t r, uint8_t g, uint8_t b) +static CellColor color_rgb(Ui *ui, uint8_t r, uint8_t g, uint8_t b) { static short color_clobber_idx = 0; static uint32_t clobbering_colors[MAX_COLOR_CLOBBER]; @@ -163,7 +151,7 @@ static CellColor color_rgb(UiTerm *ui, uint8_t r, uint8_t g, uint8_t b) return i; } -static CellColor color_terminal(UiTerm *ui, uint8_t index) { +static CellColor color_terminal(Ui *ui, uint8_t index) { return index; } @@ -227,7 +215,7 @@ static inline attr_t style_to_attr(CellStyle *style) { return style->attr | COLOR_PAIR(color_pair_get(style->fg, style->bg)); } -static void ui_curses_blit(UiTerm *tui) { +static void ui_term_backend_blit(Ui *tui) { int w = tui->width, h = tui->height; Cell *cell = tui->cells; for (int y = 0; y < h; y++) { @@ -242,16 +230,16 @@ static void ui_curses_blit(UiTerm *tui) { doupdate(); } -static void ui_curses_clear(UiTerm *tui) { +static void ui_term_backend_clear(Ui *tui) { clear(); } -static bool ui_curses_resize(UiTerm *tui, int width, int height) { +static bool ui_term_backend_resize(Ui *tui, int width, int height) { return resizeterm(height, width) == OK && wresize(stdscr, height, width) == OK; } -static void ui_curses_save(UiTerm *tui, bool fscr) { +static void ui_term_backend_save(Ui *tui, bool fscr) { curs_set(1); if (fscr) { def_prog_mode(); @@ -261,17 +249,17 @@ static void ui_curses_save(UiTerm *tui, bool fscr) { } } -static void ui_curses_restore(UiTerm *tui) { +static void ui_term_backend_restore(Ui *tui) { reset_prog_mode(); wclear(stdscr); curs_set(0); } -static int ui_curses_colors(Ui *ui) { +int ui_terminal_colors(void) { return COLORS; } -static bool ui_curses_init(UiTerm *tui, char *term) { +static bool ui_term_backend_init(Ui *tui, char *term) { if (!newterm(term, stderr, stdin)) { snprintf(tui->info, sizeof(tui->info), "Warning: unknown term `%s'", term); if (!newterm(strstr(term, "-256color") ? "xterm-256color" : "xterm", stderr, stdin)) @@ -288,19 +276,19 @@ static bool ui_curses_init(UiTerm *tui, char *term) { return true; } -static UiTerm *ui_curses_new(void) { - return calloc(1, sizeof(UiTerm)); +static Ui *ui_term_backend_new(void) { + return calloc(1, sizeof(Ui)); } -static void ui_curses_resume(UiTerm *term) { } +void ui_terminal_resume(Ui *term) { } -static void ui_curses_suspend(UiTerm *term) { +static void ui_term_backend_suspend(Ui *term) { if (change_colors == 1) undo_palette(); } -static void ui_curses_free(UiTerm *term) { - ui_curses_suspend(term); +static void ui_term_backend_free(Ui *term) { + ui_term_backend_suspend(term); endwin(); } diff --git a/ui-terminal-vt100.c b/ui-terminal-vt100.c index 565313f9e..dffc23526 100644 --- a/ui-terminal-vt100.c +++ b/ui-terminal-vt100.c @@ -41,18 +41,6 @@ #define UI_TERMKEY_FLAGS TERMKEY_FLAG_UTF8 -#define ui_term_backend_init ui_vt100_init -#define ui_term_backend_blit ui_vt100_blit -#define ui_term_backend_clear ui_vt100_clear -#define ui_term_backend_colors ui_vt100_colors -#define ui_term_backend_resize ui_vt100_resize -#define ui_term_backend_save ui_vt100_save -#define ui_term_backend_restore ui_vt100_restore -#define ui_term_backend_suspend ui_vt100_suspend -#define ui_term_backend_resume ui_vt100_resume -#define ui_term_backend_new ui_vt100_new -#define ui_term_backend_free ui_vt100_free - #define CELL_COLOR_BLACK { .index = 0 } #define CELL_COLOR_RED { .index = 1 } #define CELL_COLOR_GREEN { .index = 2 } @@ -72,7 +60,7 @@ #define CELL_ATTR_DIM (1 << 5) typedef struct { - UiTerm uiterm; + Ui uiterm; Buffer buf; } UiVt100; @@ -82,11 +70,11 @@ static inline bool cell_color_equal(CellColor c1, CellColor c2) { return c1.r == c2.r && c1.g == c2.g && c1.b == c2.b; } -static CellColor color_rgb(UiTerm *ui, uint8_t r, uint8_t g, uint8_t b) { +static CellColor color_rgb(Ui *ui, uint8_t r, uint8_t g, uint8_t b) { return (CellColor){ .r = r, .g = g, .b = b, .index = (uint8_t)-1 }; } -static CellColor color_terminal(UiTerm *ui, uint8_t index) { +static CellColor color_terminal(Ui *ui, uint8_t index) { return (CellColor){ .r = 0, .g = 0, .b = 0, .index = index }; } @@ -108,7 +96,7 @@ static void cursor_visible(bool visible) { output_literal(visible ? "\x1b[?25h" : "\x1b[?25l"); } -static void ui_vt100_blit(UiTerm *tui) { +static void ui_term_backend_blit(Ui *tui) { Buffer *buf = &((UiVt100*)tui)->buf; buffer_clear(buf); CellAttr attr = CELL_ATTR_NORMAL; @@ -174,54 +162,54 @@ static void ui_vt100_blit(UiTerm *tui) { output(buffer_content(buf), buffer_length0(buf)); } -static void ui_vt100_clear(UiTerm *tui) { } +static void ui_term_backend_clear(Ui *tui) { } -static bool ui_vt100_resize(UiTerm *tui, int width, int height) { +static bool ui_term_backend_resize(Ui *tui, int width, int height) { return true; } -static void ui_vt100_save(UiTerm *tui, bool fscr) { +static void ui_term_backend_save(Ui *tui, bool fscr) { cursor_visible(true); } -static void ui_vt100_restore(UiTerm *tui) { +static void ui_term_backend_restore(Ui *tui) { cursor_visible(false); } -static int ui_vt100_colors(Ui *ui) { +int ui_terminal_colors(void) { char *term = getenv("TERM"); return (term && strstr(term, "-256color")) ? 256 : 16; } -static void ui_vt100_suspend(UiTerm *tui) { +static void ui_term_backend_suspend(Ui *tui) { if (!tui->termkey) return; termkey_stop(tui->termkey); cursor_visible(true); screen_alternate(false); } -static void ui_vt100_resume(UiTerm *tui) { +void ui_terminal_resume(Ui *tui) { screen_alternate(true); cursor_visible(false); termkey_start(tui->termkey); } -static bool ui_vt100_init(UiTerm *tui, char *term) { - ui_vt100_resume(tui); +static bool ui_term_backend_init(Ui *tui, char *term) { + ui_terminal_resume(tui); return true; } -static UiTerm *ui_vt100_new(void) { +static Ui *ui_term_backend_new(void) { UiVt100 *vtui = calloc(1, sizeof *vtui); if (!vtui) return NULL; buffer_init(&vtui->buf); - return (UiTerm*)vtui; + return (Ui*)vtui; } -static void ui_vt100_free(UiTerm *tui) { +static void ui_term_backend_free(Ui *tui) { UiVt100 *vtui = (UiVt100*)tui; - ui_vt100_suspend(tui); + ui_term_backend_suspend(tui); buffer_release(&vtui->buf); } diff --git a/ui-terminal.c b/ui-terminal.c index 9aaac7dfd..048ba7fa6 100644 --- a/ui-terminal.c +++ b/ui-terminal.c @@ -13,7 +13,6 @@ #include #include -#include "ui-terminal.h" #include "vis.h" #include "vis-core.h" #include "text.h" @@ -30,26 +29,6 @@ #define debug(...) do { } while (0) #endif -#define MAX_WIDTH 1024 -#define MAX_HEIGHT 1024 - -struct UiTerm { - Ui ui; /* generic ui interface, has to be the first struct member */ - Vis *vis; /* editor instance to which this ui belongs */ - UiWin *windows; /* all windows managed by this ui */ - UiWin *selwin; /* the currently selected layout */ - char info[MAX_WIDTH]; /* info message displayed at the bottom of the screen */ - int width, height; /* terminal dimensions available for all windows */ - enum UiLayout layout; /* whether windows are displayed horizontally or vertically */ - TermKey *termkey; /* libtermkey instance to handle keyboard input (stdin or /dev/tty) */ - size_t ids; /* bit mask of in use window ids */ - size_t styles_size; /* #bytes allocated for styles array */ - CellStyle *styles; /* each window has UI_STYLE_MAX different style definitions */ - size_t cells_size; /* #bytes allocated for 2D grid (grows only) */ - Cell *cells; /* 2D grid of cells, at least as large as current terminal size */ - bool doupdate; /* Whether to update the screen after refreshing contents */ -}; - #if CONFIG_CURSES #include "ui-terminal-curses.c" #else @@ -59,16 +38,15 @@ struct UiTerm { /* helper macro for handling UiTerm.cells */ #define CELL_AT_POS(UI, X, Y) (((UI)->cells) + (X) + ((Y) * (UI)->width)); -__attribute__((noreturn)) static void ui_die(Ui *ui, const char *msg, va_list ap) { - UiTerm *tui = (UiTerm*)ui; - ui_term_backend_free(tui); +void ui_die(Ui *tui, const char *msg, va_list ap) { + ui_terminal_free(tui); if (tui->termkey) termkey_stop(tui->termkey); vfprintf(stderr, msg, ap); exit(EXIT_FAILURE); } -__attribute__((noreturn)) static void ui_die_msg(Ui *ui, const char *msg, ...) { +static void ui_die_msg(Ui *ui, const char *msg, ...) { va_list ap; va_start(ap, msg); ui_die(ui, msg, ap); @@ -89,7 +67,7 @@ static void ui_window_move(UiWin *win, int x, int y) { win->y = y; } -static bool color_fromstring(UiTerm *ui, CellColor *color, const char *s) +static bool color_fromstring(Ui *ui, CellColor *color, const char *s) { if (!s) return false; @@ -138,7 +116,7 @@ static bool color_fromstring(UiTerm *ui, CellColor *color, const char *s) } bool ui_style_define(UiWin *win, int id, const char *style) { - UiTerm *tui = win->ui; + Ui *tui = win->ui; if (id >= UI_STYLE_MAX) return false; if (!style) @@ -190,7 +168,7 @@ bool ui_style_define(UiWin *win, int id, const char *style) { return true; } -static void ui_draw_line(UiTerm *tui, int x, int y, char c, enum UiStyle style_id) { +static void ui_draw_line(Ui *tui, int x, int y, char c, enum UiStyle style_id) { if (x < 0 || x >= tui->width || y < 0 || y >= tui->height) return; CellStyle style = tui->styles[style_id]; @@ -203,7 +181,7 @@ static void ui_draw_line(UiTerm *tui, int x, int y, char c, enum UiStyle style_i } } -static void ui_draw_string(UiTerm *tui, int x, int y, const char *str, UiWin *win, enum UiStyle style_id) { +static void ui_draw_string(Ui *tui, int x, int y, const char *str, UiWin *win, enum UiStyle style_id) { debug("draw-string: [%d][%d]\n", y, x); if (x < 0 || x >= tui->width || y < 0 || y >= tui->height) return; @@ -225,7 +203,7 @@ static void ui_draw_string(UiTerm *tui, int x, int y, const char *str, UiWin *wi } static void ui_window_draw(UiWin *win) { - UiTerm *ui = win->ui; + Ui *ui = win->ui; View *view = win->win->view; int width = win->width, height = win->height; const Line *line = view->topline; @@ -276,7 +254,7 @@ static void ui_window_draw(UiWin *win) { } void ui_window_style_set(UiWin *win, Cell *cell, enum UiStyle id) { - UiTerm *tui = win->ui; + Ui *tui = win->ui; CellStyle set, style = tui->styles[win->id * UI_STYLE_MAX + id]; if (id == UI_STYLE_DEFAULT) { @@ -292,7 +270,7 @@ void ui_window_style_set(UiWin *win, Cell *cell, enum UiStyle id) { } bool ui_window_style_set_pos(UiWin *win, int x, int y, enum UiStyle id) { - UiTerm *tui = win->ui; + Ui *tui = win->ui; if (x < 0 || y < 0 || y >= win->height || x >= win->width) { return false; } @@ -304,14 +282,13 @@ bool ui_window_style_set_pos(UiWin *win, int x, int y, enum UiStyle id) { void ui_window_status(UiWin *win, const char *status) { if (!(win->options & UI_OPTION_STATUSBAR)) return; - UiTerm *ui = win->ui; + Ui *ui = win->ui; enum UiStyle style = ui->selwin == win ? UI_STYLE_STATUS_FOCUSED : UI_STYLE_STATUS; ui_draw_string(ui, win->x, win->y + win->height - 1, status, win, style); } -static void ui_arrange(Ui *ui, enum UiLayout layout) { +void ui_arrange(Ui *tui, enum UiLayout layout) { debug("ui-arrange\n"); - UiTerm *tui = (UiTerm*)ui; tui->layout = layout; int n = 0, m = !!tui->info[0], x = 0, y = 0; for (UiWin *win = tui->windows; win; win = win->next) { @@ -360,32 +337,24 @@ static void ui_arrange(Ui *ui, enum UiLayout layout) { } } -static void ui_doupdates(Ui *ui, bool doupdate) { - UiTerm *tui = (UiTerm*)ui; - tui->doupdate = doupdate; -} - -static void ui_draw(Ui *ui) { +void ui_draw(Ui *tui) { debug("ui-draw\n"); - UiTerm *tui = (UiTerm*)ui; - ui_arrange(ui, tui->layout); + ui_arrange(tui, tui->layout); for (UiWin *win = tui->windows; win; win = win->next) - ui_window_draw((UiWin*)win); + ui_window_draw(win); if (tui->info[0]) ui_draw_string(tui, 0, tui->height-1, tui->info, NULL, UI_STYLE_INFO); vis_event_emit(tui->vis, VIS_EVENT_UI_DRAW); ui_term_backend_blit(tui); } -static void ui_redraw(Ui *ui) { - UiTerm *tui = (UiTerm*)ui; +void ui_redraw(Ui *tui) { ui_term_backend_clear(tui); for (UiWin *win = tui->windows; win; win = win->next) win->win->view->need_update = true; } -static void ui_resize(Ui *ui) { - UiTerm *tui = (UiTerm*)ui; +void ui_resize(Ui *tui) { struct winsize ws; int width = 80, height = 24; @@ -396,8 +365,8 @@ static void ui_resize(Ui *ui) { height = ws.ws_row; } - width = MIN(width, MAX_WIDTH); - height = MIN(height, MAX_HEIGHT); + width = MIN(width, UI_MAX_WIDTH); + height = MIN(height, UI_MAX_HEIGHT); if (!ui_term_backend_resize(tui, width, height)) return; @@ -414,10 +383,10 @@ static void ui_resize(Ui *ui) { tui->height = height; } -static void ui_window_free(UiWin *win) { +void ui_window_free(UiWin *win) { if (!win) return; - UiTerm *tui = win->ui; + Ui *tui = win->ui; if (win->prev) win->prev->next = win->next; if (win->next) @@ -431,7 +400,7 @@ static void ui_window_free(UiWin *win) { free(win); } -static void ui_window_focus(UiWin *new) { +void ui_window_focus(UiWin *new) { UiWin *old = new->ui->selwin; if (new->options & UI_OPTION_STATUSBAR) new->ui->selwin = new; @@ -444,7 +413,7 @@ void ui_window_options_set(UiWin *win, enum UiOption options) { win->options = options; if (options & UI_OPTION_ONELINE) { /* move the new window to the end of the list */ - UiTerm *tui = win->ui; + Ui *tui = win->ui; UiWin *last = tui->windows; while (last->next) last = last->next; @@ -460,13 +429,13 @@ void ui_window_options_set(UiWin *win, enum UiOption options) { win->next = NULL; } } - ui_draw((Ui*)win->ui); + ui_draw(win->ui); } -static void ui_window_swap(UiWin *a, UiWin *b) { +void ui_window_swap(UiWin *a, UiWin *b) { if (a == b || !a || !b) return; - UiTerm *tui = a->ui; + Ui *tui = a->ui; UiWin *tmp = a->next; a->next = b->next; b->next = tmp; @@ -491,8 +460,7 @@ static void ui_window_swap(UiWin *a, UiWin *b) { ui_window_focus(a); } -static UiWin *ui_window_new(Ui *ui, Win *w, enum UiOption options) { - UiTerm *tui = (UiTerm*)ui; +UiWin *ui_window_new(Ui *tui, Win *w, enum UiOption options) { /* get rightmost zero bit, i.e. highest available id */ size_t bit = ~tui->ids & (tui->ids + 1); size_t id = 0; @@ -544,19 +512,17 @@ static UiWin *ui_window_new(Ui *ui, Win *w, enum UiOption options) { options &= ~UI_OPTION_LINE_NUMBERS_ABSOLUTE; } - ui_window_options_set((UiWin*)win, options); + ui_window_options_set(win, options); return win; } -static void ui_info(Ui *ui, const char *msg, va_list ap) { - UiTerm *tui = (UiTerm*)ui; +void ui_info_show(Ui *tui, const char *msg, va_list ap) { ui_draw_line(tui, 0, tui->height-1, ' ', UI_STYLE_INFO); vsnprintf(tui->info, sizeof(tui->info), msg, ap); } -static void ui_info_hide(Ui *ui) { - UiTerm *tui = (UiTerm*)ui; +void ui_info_hide(Ui *tui) { if (tui->info[0]) tui->info[0] = '\0'; } @@ -580,31 +546,19 @@ static TermKey *ui_termkey_reopen(Ui *ui, int fd) { return ui_termkey_new(fd); } -static TermKey *ui_termkey_get(Ui *ui) { - UiTerm *tui = (UiTerm*)ui; - return tui->termkey; -} - -static void ui_suspend(Ui *ui) { - UiTerm *tui = (UiTerm*)ui; +void ui_terminal_suspend(Ui *tui) { ui_term_backend_suspend(tui); kill(0, SIGTSTP); } -static void ui_resume(Ui *ui) { - UiTerm *tui = (UiTerm*)ui; - ui_term_backend_resume(tui); -} - -static bool ui_getkey(Ui *ui, TermKeyKey *key) { - UiTerm *tui = (UiTerm*)ui; +bool ui_getkey(Ui *tui, TermKeyKey *key) { TermKeyResult ret = termkey_getkey(tui->termkey, key); if (ret == TERMKEY_RES_EOF) { termkey_destroy(tui->termkey); errno = 0; - if (!(tui->termkey = ui_termkey_reopen(ui, STDIN_FILENO))) - ui_die_msg(ui, "Failed to re-open stdin as /dev/tty: %s\n", errno != 0 ? strerror(errno) : ""); + if (!(tui->termkey = ui_termkey_reopen(tui, STDIN_FILENO))) + ui_die_msg(tui, "Failed to re-open stdin as /dev/tty: %s\n", errno != 0 ? strerror(errno) : ""); return false; } @@ -619,20 +573,17 @@ static bool ui_getkey(Ui *ui, TermKeyKey *key) { return ret == TERMKEY_RES_KEY; } -static void ui_terminal_save(Ui *ui, bool fscr) { - UiTerm *tui = (UiTerm*)ui; +void ui_terminal_save(Ui *tui, bool fscr) { ui_term_backend_save(tui, fscr); termkey_stop(tui->termkey); } -static void ui_terminal_restore(Ui *ui) { - UiTerm *tui = (UiTerm*)ui; +void ui_terminal_restore(Ui *tui) { termkey_start(tui->termkey); ui_term_backend_restore(tui); } -static bool ui_init(Ui *ui, Vis *vis) { - UiTerm *tui = (UiTerm*)ui; +bool ui_init(Ui *tui, Vis *vis) { tui->vis = vis; setlocale(LC_CTYPE, ""); @@ -648,7 +599,7 @@ static bool ui_init(Ui *ui, Vis *vis) { /* work around libtermkey bug which fails if stdin is /dev/null */ if (errno == EBADF) { errno = 0; - if (!(tui->termkey = ui_termkey_reopen(ui, STDIN_FILENO)) && errno == ENXIO) + if (!(tui->termkey = ui_termkey_reopen(tui, STDIN_FILENO)) && errno == ENXIO) tui->termkey = termkey_new_abstract(term, UI_TERMKEY_FLAGS); } if (!tui->termkey) @@ -657,24 +608,19 @@ static bool ui_init(Ui *ui, Vis *vis) { if (!ui_term_backend_init(tui, term)) goto err; - ui_resize(ui); + ui_resize(tui); return true; err: - ui_die_msg(ui, "Failed to start curses interface: %s\n", errno != 0 ? strerror(errno) : ""); + ui_die_msg(tui, "Failed to start curses interface: %s\n", errno != 0 ? strerror(errno) : ""); return false; } -enum UiLayout ui_layout_get(Ui *ui) { - UiTerm *tui = (UiTerm *)ui; - return tui->layout; -} - -Ui *ui_term_new(void) { +Ui *ui_terminal_new(void) { size_t styles_size = UI_STYLE_MAX * sizeof(CellStyle); CellStyle *styles = calloc(1, styles_size); if (!styles) return NULL; - UiTerm *tui = ui_term_backend_new(); + Ui *tui = ui_term_backend_new(); if (!tui) { free(styles); return NULL; @@ -682,40 +628,14 @@ Ui *ui_term_new(void) { tui->styles_size = styles_size; tui->styles = styles; tui->doupdate = true; - Ui *ui = (Ui*)tui; - *ui = (Ui) { - .init = ui_init, - .free = ui_term_free, - .termkey_get = ui_termkey_get, - .suspend = ui_suspend, - .resume = ui_resume, - .resize = ui_resize, - .window_new = ui_window_new, - .window_free = ui_window_free, - .window_focus = ui_window_focus, - .window_swap = ui_window_swap, - .draw = ui_draw, - .redraw = ui_redraw, - .arrange = ui_arrange, - .doupdates = ui_doupdates, - .die = ui_die, - .info = ui_info, - .info_hide = ui_info_hide, - .getkey = ui_getkey, - .terminal_save = ui_terminal_save, - .terminal_restore = ui_terminal_restore, - .colors = ui_term_backend_colors, - }; - - return ui; + return tui; } -void ui_term_free(Ui *ui) { - UiTerm *tui = (UiTerm*)ui; +void ui_terminal_free(Ui *tui) { if (!tui) return; while (tui->windows) - ui_window_free((UiWin*)tui->windows); + ui_window_free(tui->windows); ui_term_backend_free(tui); if (tui->termkey) termkey_destroy(tui->termkey); diff --git a/ui-terminal.h b/ui-terminal.h deleted file mode 100644 index 45286abff..000000000 --- a/ui-terminal.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef UI_TERMINAL_H -#define UI_TERMINAL_H - -#include "ui.h" - -Ui *ui_term_new(void); -void ui_term_free(Ui*); - -#endif diff --git a/ui.h b/ui.h index 3a4bb8bce..806b9ce03 100644 --- a/ui.h +++ b/ui.h @@ -10,9 +10,8 @@ /* enable large file optimization for files containing lines longer than: */ #define UI_LARGE_FILE_LINE_SIZE (1 << 16) -typedef struct Ui Ui; -typedef struct UiWin UiWin; -typedef struct UiTerm UiTerm; +#define UI_MAX_WIDTH 1024 +#define UI_MAX_HEIGHT 1024 enum UiLayout { UI_LAYOUT_HORIZONTAL, @@ -68,52 +67,82 @@ typedef struct { CellColor fg, bg; } CellStyle; +typedef struct { + char data[16]; /* utf8 encoded character displayed in this cell (might be more than + one Unicode codepoint. might also not be the same as in the + underlying text, for example tabs get expanded */ + size_t len; /* number of bytes the character displayed in this cell uses, for + characters which use more than 1 column to display, their length + is stored in the leftmost cell whereas all following cells + occupied by the same character have a length of 0. */ + int width; /* display width i.e. number of columns occupied by this character */ + CellStyle style; /* colors and attributes used to display this cell */ +} Cell; + +struct Ui; +struct Win; +typedef struct UiWin { + struct Ui *ui; /* ui which manages this window */ + struct Win *win; /* editor window being displayed */ + int id; /* unique identifier for this window */ + int width, height; /* window dimension including status bar */ + int x, y; /* window position */ + int sidebar_width; /* width of the sidebar showing line numbers etc. */ + struct UiWin *next, *prev; /* pointers to neighbouring windows */ + enum UiOption options; /* display settings for this window */ +} UiWin; + +struct Vis; +typedef struct Ui { + struct Vis *vis; /* editor instance to which this ui belongs */ + UiWin *windows; /* all windows managed by this ui */ + UiWin *selwin; /* the currently selected layout */ + char info[UI_MAX_WIDTH]; /* info message displayed at the bottom of the screen */ + int width, height; /* terminal dimensions available for all windows */ + enum UiLayout layout; /* whether windows are displayed horizontally or vertically */ + TermKey *termkey; /* libtermkey instance to handle keyboard input (stdin or /dev/tty) */ + size_t ids; /* bit mask of in use window ids */ + size_t styles_size; /* #bytes allocated for styles array */ + CellStyle *styles; /* each window has UI_STYLE_MAX different style definitions */ + size_t cells_size; /* #bytes allocated for 2D grid (grows only) */ + Cell *cells; /* 2D grid of cells, at least as large as current terminal size */ + bool doupdate; /* Whether to update the screen after refreshing contents */ +} Ui; + +#include "view.h" #include "vis.h" #include "text.h" -#include "view.h" -struct Ui { - bool (*init)(Ui*, Vis*); - void (*free)(Ui*); - void (*resize)(Ui*); - UiWin* (*window_new)(Ui*, Win*, enum UiOption); - void (*window_free)(UiWin*); - void (*window_focus)(UiWin*); - void (*window_swap)(UiWin*, UiWin*); - void (*die)(Ui*, const char *msg, va_list ap) __attribute__((noreturn)); - void (*info)(Ui*, const char *msg, va_list ap); - void (*info_hide)(Ui*); - void (*arrange)(Ui*, enum UiLayout); - void (*draw)(Ui*); - void (*redraw)(Ui*); - void (*suspend)(Ui*); - void (*resume)(Ui*); - void (*doupdates)(Ui*, bool); - bool (*getkey)(Ui*, TermKeyKey*); - void (*terminal_save)(Ui*, bool fscr); - void (*terminal_restore)(Ui*); - TermKey* (*termkey_get)(Ui*); - int (*colors)(Ui*); -}; +#define UI_OPTIONS_GET(ui) ((ui) ? (ui)->options : 0) -struct UiWin { - UiTerm *ui; /* ui which manages this window */ - Win *win; /* editor window being displayed */ - int id; /* unique identifier for this window */ - int width, height; /* window dimension including status bar */ - int x, y; /* window position */ - int sidebar_width; /* width of the sidebar showing line numbers etc. */ - UiWin *next, *prev; /* pointers to neighbouring windows */ - enum UiOption options; /* display settings for this window */ -}; +Ui *ui_terminal_new(void); +int ui_terminal_colors(void); +void ui_terminal_free(Ui*); +void ui_terminal_restore(Ui*); +void ui_terminal_resume(Ui*); +void ui_terminal_save(Ui*, bool fscr); +void ui_terminal_suspend(Ui*); -#define UI_OPTIONS_GET(ui) ((ui) ? (ui)->options : 0) +__attribute__((noreturn)) void ui_die(Ui *, const char *, va_list); +bool ui_init(Ui *, Vis *); +void ui_arrange(Ui*, enum UiLayout); +void ui_draw(Ui*); +void ui_info_hide(Ui *); +void ui_info_show(Ui *, const char *, va_list); +void ui_redraw(Ui*); +void ui_resize(Ui*); + +UiWin *ui_window_new(Ui *, Win *, enum UiOption); +void ui_window_focus(UiWin *); +void ui_window_free(UiWin *); +void ui_window_swap(UiWin *, UiWin *); + +bool ui_getkey(Ui *, TermKeyKey *); bool ui_style_define(UiWin *win, int id, const char *style); bool ui_window_style_set_pos(UiWin *win, int x, int y, enum UiStyle id); void ui_window_style_set(UiWin *win, Cell *cell, enum UiStyle id); -enum UiLayout ui_layout_get(Ui *ui); void ui_window_options_set(UiWin *win, enum UiOption options); void ui_window_status(UiWin *win, const char *status); diff --git a/view.h b/view.h index a9ebbc5c8..79275c800 100644 --- a/view.h +++ b/view.h @@ -26,18 +26,6 @@ typedef struct { Mark cursor; } SelectionRegion; -typedef struct { - char data[16]; /* utf8 encoded character displayed in this cell (might be more than - one Unicode codepoint. might also not be the same as in the - underlying text, for example tabs get expanded */ - size_t len; /* number of bytes the character displayed in this cell uses, for - characters which use more than 1 column to display, their length - is stored in the leftmost cell whereas all following cells - occupied by the same character have a length of 0. */ - int width; /* display width i.e. number of columns occupied by this character */ - CellStyle style; /* colors and attributes used to display this cell */ -} Cell; - typedef struct Line Line; struct Line { /* a line on the screen, *not* in the file */ Line *prev, *next; /* pointer to neighbouring screen lines */ diff --git a/vis-cmds.c b/vis-cmds.c index 2b3398d0c..1515bc849 100644 --- a/vis-cmds.c +++ b/vis-cmds.c @@ -125,10 +125,6 @@ static bool cmd_user(Vis *vis, Win *win, Command *cmd, const char *argv[], Selec return user && user->func(vis, win, user->data, cmd->flags == '!', argv, sel, range); } -static void windows_arrange(Vis *vis, enum UiLayout layout) { - vis->ui->arrange(vis->ui, layout); -} - void vis_shell_set(Vis *vis, const char *new_shell) { char *shell = strdup(new_shell); if (!shell) { @@ -250,7 +246,7 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Select break; case OPTION_ESCDELAY: { - TermKey *termkey = vis->ui->termkey_get(vis->ui); + TermKey *termkey = vis->ui->termkey; termkey_set_waittime(termkey, arg.i); break; } @@ -358,7 +354,7 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Select vis_info_show(vis, "Invalid layout `%s', expected 'h' or 'v'", arg.s); return false; } - windows_arrange(vis, layout); + ui_arrange(vis->ui, layout); break; } case OPTION_IGNORECASE: @@ -546,7 +542,7 @@ static bool cmd_split(Vis *vis, Win *win, Command *cmd, const char *argv[], Sele if (!win) return false; enum UiOption options = UI_OPTIONS_GET(win->view->ui); - windows_arrange(vis, UI_LAYOUT_HORIZONTAL); + ui_arrange(vis->ui, UI_LAYOUT_HORIZONTAL); if (!argv[1]) return vis_window_split(win); bool ret = openfiles(vis, &argv[1]); @@ -559,7 +555,7 @@ static bool cmd_vsplit(Vis *vis, Win *win, Command *cmd, const char *argv[], Sel if (!win) return false; enum UiOption options = UI_OPTIONS_GET(win->view->ui); - windows_arrange(vis, UI_LAYOUT_VERTICAL); + ui_arrange(vis->ui, UI_LAYOUT_VERTICAL); if (!argv[1]) return vis_window_split(win); bool ret = openfiles(vis, &argv[1]); @@ -569,12 +565,12 @@ static bool cmd_vsplit(Vis *vis, Win *win, Command *cmd, const char *argv[], Sel } static bool cmd_new(Vis *vis, Win *win, Command *cmd, const char *argv[], Selection *sel, Filerange *range) { - windows_arrange(vis, UI_LAYOUT_HORIZONTAL); + ui_arrange(vis->ui, UI_LAYOUT_HORIZONTAL); return vis_window_new(vis, NULL); } static bool cmd_vnew(Vis *vis, Win *win, Command *cmd, const char *argv[], Selection *sel, Filerange *range) { - windows_arrange(vis, UI_LAYOUT_VERTICAL); + ui_arrange(vis->ui, UI_LAYOUT_VERTICAL); return vis_window_new(vis, NULL); } @@ -779,7 +775,7 @@ static void print_symbolic_keys(Vis *vis, Text *txt) { TERMKEY_SYM_KPEQUALS, }; - TermKey *termkey = vis->ui->termkey_get(vis->ui); + TermKey *termkey = vis->ui->termkey; text_appendf(txt, " ␣ (a literal \" \" space symbol must be used to refer to )\n"); for (size_t i = 0; i < LENGTH(keys); i++) { text_appendf(txt, " <%s>\n", termkey_get_keyname(termkey, keys[i])); diff --git a/vis-lua.c b/vis-lua.c index 4bf582a36..3b5f7840d 100644 --- a/vis-lua.c +++ b/vis-lua.c @@ -1429,7 +1429,7 @@ static int vis_options_assign(Vis *vis, lua_State *L, const char *key, int next) } else if (strcmp(key, "changecolors") == 0) { vis->change_colors = lua_toboolean(L, next); } else if (strcmp(key, "escdelay") == 0) { - TermKey *tk = vis->ui->termkey_get(vis->ui); + TermKey *tk = vis->ui->termkey; termkey_set_waittime(tk, luaL_checkint(L, next)); } else if (strcmp(key, "ignorecase") == 0 || strcmp(key, "ic") == 0) { vis->ignorecase = lua_toboolean(L, next); @@ -1570,7 +1570,7 @@ static int vis_options_index(lua_State *L) { lua_pushboolean(L, vis->change_colors); return 1; } else if (strcmp(key, "escdelay") == 0) { - TermKey *tk = vis->ui->termkey_get(vis->ui); + TermKey *tk = vis->ui->termkey; lua_pushunsigned(L, termkey_get_waittime(tk)); return 1; } else if (strcmp(key, "ignorecase") == 0 || strcmp(key, "ic") == 0) { @@ -1633,7 +1633,7 @@ static int ui_index(lua_State *L) { const char *key = lua_tostring(L, 2); if (strcmp(key, "layout") == 0) { - lua_pushunsigned(L, ui_layout_get(ui)); + lua_pushunsigned(L, ui->layout); return 1; } } @@ -1648,7 +1648,7 @@ static int ui_newindex(lua_State *L) { const char *key = lua_tostring(L, 2); if (strcmp(key, "layout") == 0) { - ui->arrange(ui, luaL_checkint(L, 3)); + ui_arrange(ui, luaL_checkint(L, 3)); return 0; } } @@ -3260,7 +3260,7 @@ static void vis_lua_init(Vis *vis) { obj_type_new(L, VIS_LUA_TYPE_UI); luaL_setfuncs(L, ui_funcs, 0); - lua_pushunsigned(L, vis->ui->colors(vis->ui)); + lua_pushunsigned(L, ui_terminal_colors()); lua_setfield(L, -2, "colors"); lua_newtable(L); static const struct { @@ -3612,7 +3612,7 @@ static void vis_lua_ui_draw(Vis *vis) { bool vis_event_emit(Vis *vis, enum VisEvents id, ...) { if (!vis->initialized) { vis->initialized = true; - vis->ui->init(vis->ui, vis); + ui_init(vis->ui, vis); vis_lua_init(vis); } diff --git a/vis-prompt.c b/vis-prompt.c index 6dbe69c97..474a32c98 100644 --- a/vis-prompt.c +++ b/vis-prompt.c @@ -182,14 +182,10 @@ void vis_prompt_show(Vis *vis, const char *title) { void vis_info_show(Vis *vis, const char *msg, ...) { va_list ap; va_start(ap, msg); - vis->ui->info(vis->ui, msg, ap); + ui_info_show(vis->ui, msg, ap); va_end(ap); } -void vis_info_hide(Vis *vis) { - vis->ui->info_hide(vis->ui); -} - void vis_message_show(Vis *vis, const char *msg) { if (!msg) return; diff --git a/vis.c b/vis.c index d03bde8cb..be4a66a64 100644 --- a/vis.c +++ b/vis.c @@ -203,7 +203,7 @@ static void window_free(Win *win) { other->parent = NULL; } if (vis->ui) - vis->ui->window_free(win->ui); + ui_window_free(win->ui); view_free(win->view); for (size_t i = 0; i < LENGTH(win->modes); i++) map_free(win->modes[i].bindings); @@ -382,7 +382,7 @@ Win *window_new_file(Vis *vis, File *file, enum UiOption options) { win->file = file; win->view = view_new(file->text); win->expandtab = false; - win->ui = vis->ui->window_new(vis->ui, win, options); + win->ui = ui_window_new(vis->ui, win, options); if (!win->view || !win->ui) { window_free(win); return NULL; @@ -397,7 +397,7 @@ Win *window_new_file(Vis *vis, File *file, enum UiOption options) { win->next = vis->windows; vis->windows = win; vis->win = win; - vis->ui->window_focus(win->ui); + ui_window_focus(win->ui); for (size_t i = 0; i < LENGTH(win->modes); i++) win->modes[i].parent = &vis_modes[i]; vis_event_emit(vis, VIS_EVENT_WIN_OPEN, win); @@ -434,7 +434,7 @@ bool vis_window_change_file(Win *win, const char* filename) { } bool vis_window_split(Win *original) { - vis_doupdates(original->vis, false); + original->vis->ui->doupdate = false; Win *win = window_new_file(original->vis, original->file, UI_OPTION_STATUSBAR); if (!win) return false; @@ -447,7 +447,7 @@ bool vis_window_split(Win *original) { win->file = original->file; view_options_set(win->view, UI_OPTIONS_GET(original->view->ui)); view_cursors_to(win->view->selection, view_cursor_get(original->view)); - vis_doupdates(win->vis, true); + win->vis->ui->doupdate = true; return true; } @@ -456,7 +456,7 @@ void vis_window_focus(Win *win) { return; Vis *vis = win->vis; vis->win = win; - vis->ui->window_focus(win->ui); + ui_window_focus(win->ui); } void vis_window_next(Vis *vis) { @@ -482,37 +482,21 @@ void vis_draw(Vis *vis) { } void vis_redraw(Vis *vis) { - vis->ui->redraw(vis->ui); - vis_update(vis); -} - -void vis_update(Vis *vis) { - vis->ui->draw(vis->ui); -} - -void vis_suspend(Vis *vis) { - vis->ui->suspend(vis->ui); -} - -void vis_resume(Vis *vis) { - vis->ui->resume(vis->ui); -} - -void vis_doupdates(Vis *vis, bool doupdate) { - vis->ui->doupdates(vis->ui, doupdate); + ui_redraw(vis->ui); + ui_draw(vis->ui); } bool vis_window_new(Vis *vis, const char *filename) { File *file = file_new(vis, filename, false); if (!file) return false; - vis_doupdates(vis, false); + vis->ui->doupdate = false; Win *win = window_new_file(vis, file, UI_OPTION_STATUSBAR|UI_OPTION_SYMBOL_EOF); if (!win) { file_free(vis, file); return false; } - vis_doupdates(vis, true); + vis->ui->doupdate = true; return true; } @@ -554,7 +538,7 @@ void vis_window_swap(Win *a, Win *b) { vis->windows = b; else if (vis->windows == b) vis->windows = a; - vis->ui->window_swap(a->ui, b->ui); + ui_window_swap(a->ui, b->ui); if (vis->win == a) vis_window_focus(b); else if (vis->win == b) @@ -579,7 +563,7 @@ void vis_window_close(Win *win) { vis->message_window = NULL; window_free(win); if (vis->win) - vis->ui->window_focus(vis->win->ui); + ui_window_focus(vis->win->ui); vis_draw(vis); } @@ -645,7 +629,7 @@ void vis_free(Vis *vis) { file_free(vis, vis->error_file); for (int i = 0; i < LENGTH(vis->registers); i++) register_release(&vis->registers[i]); - vis->ui->free(vis->ui); + ui_terminal_free(vis->ui); if (vis->usercmds) { const char *name; while (map_first(vis->usercmds, &name) && vis_cmd_unregister(vis, name)); @@ -976,7 +960,7 @@ void vis_cancel(Vis *vis) { void vis_die(Vis *vis, const char *msg, ...) { va_list ap; va_start(ap, msg); - vis->ui->die(vis->ui, msg, ap); + ui_die(vis->ui, msg, ap); va_end(ap); } @@ -984,7 +968,7 @@ const char *vis_keys_next(Vis *vis, const char *keys) { if (!keys || !*keys) return NULL; TermKeyKey key; - TermKey *termkey = vis->ui->termkey_get(vis->ui); + TermKey *termkey = vis->ui->termkey; const char *next = NULL; /* first try to parse a special key of the form */ if (*keys == '<' && keys[1] && (next = termkey_strpkey(termkey, keys+1, &key, TERMKEY_FORMAT_VIM)) && *next == '>') @@ -1012,7 +996,7 @@ long vis_keys_codepoint(Vis *vis, const char *keys) { long codepoint = -1; const char *next; TermKeyKey key; - TermKey *termkey = vis->ui->termkey_get(vis->ui); + TermKey *termkey = vis->ui->termkey; if (!keys[0]) return -1; @@ -1205,9 +1189,9 @@ static void vis_keys_push(Vis *vis, const char *input, size_t pos, bool record) static const char *getkey(Vis *vis) { TermKeyKey key = { 0 }; - if (!vis->ui->getkey(vis->ui, &key)) + if (!ui_getkey(vis->ui, &key)) return NULL; - vis_info_hide(vis); + ui_info_hide(vis->ui); bool use_keymap = vis->mode->id != VIS_MODE_INSERT && vis->mode->id != VIS_MODE_REPLACE && !vis->keymap_disabled; @@ -1221,7 +1205,7 @@ static const char *getkey(Vis *vis) { } } - TermKey *termkey = vis->ui->termkey_get(vis->ui); + TermKey *termkey = vis->ui->termkey; if (key.type == TERMKEY_TYPE_UNKNOWN_CSI) { long args[18]; size_t nargs; @@ -1315,16 +1299,16 @@ int vis_run(Vis *vis) { } if (vis->resume) { - vis_resume(vis); + ui_terminal_resume(vis->ui); vis->resume = false; } if (vis->need_resize) { - vis->ui->resize(vis->ui); + ui_resize(vis->ui); vis->need_resize = false; } - vis_update(vis); + ui_draw(vis->ui); idle.tv_sec = vis->mode->idle_timeout; int r = pselect(vis_process_before_tick(&fds) + 1, &fds, NULL, NULL, timeout, &emptyset); @@ -1344,7 +1328,7 @@ int vis_run(Vis *vis) { continue; } - TermKey *termkey = vis->ui->termkey_get(vis->ui); + TermKey *termkey = vis->ui->termkey; termkey_advisereadable(termkey); const char *key; @@ -1640,7 +1624,7 @@ int vis_pipe(Vis *vis, File *file, Filerange *range, const char *argv[], return -1; } - vis->ui->terminal_save(vis->ui, fullscreen); + ui_terminal_save(vis->ui, fullscreen); pid_t pid = fork(); if (pid == -1) { @@ -1834,7 +1818,7 @@ int vis_pipe(Vis *vis, File *file, Filerange *range, const char *argv[], sigaction(SIGTERM, &sigterm_old, NULL); vis->interrupted = false; - vis->ui->terminal_restore(vis->ui); + ui_terminal_restore(vis->ui); if (WIFEXITED(status)) return WEXITSTATUS(status); diff --git a/vis.h b/vis.h index 057e66bbc..032b00bd0 100644 --- a/vis.h +++ b/vis.h @@ -109,27 +109,6 @@ void vis_exit(Vis*, int status); */ void vis_die(Vis*, const char *msg, ...) __attribute__((noreturn,format(printf, 2, 3))); -/** - * Temporarily suspend the editor process. - * @rst - * .. note:: This function will generate a ``SIGTSTP`` signal. - * @endrst - **/ -void vis_suspend(Vis*); -/** - * Resume editor process. - * @rst - * .. note:: This function is usually called in response to a ``SIGCONT`` signal. - * @endrst - */ -void vis_resume(Vis*); -/** - * Set doupdate flag. - * @rst - * .. note:: Prevent flickering in curses by delaying window updates. - * @endrst - */ -void vis_doupdates(Vis*, bool); /** * Inform the editor core that a signal occurred. * @return Whether the signal was handled. @@ -162,8 +141,6 @@ bool vis_interrupt_requested(Vis*); void vis_draw(Vis*); /** Completely redraw user interface. */ void vis_redraw(Vis*); -/** Blit user interface state to output device. */ -void vis_update(Vis*); /** * @} * @defgroup vis_windows @@ -226,8 +203,6 @@ void vis_prompt_show(Vis*, const char *title); * @endrst */ void vis_info_show(Vis*, const char *msg, ...) __attribute__((format(printf, 2, 3))); -/** Hide informational message. */ -void vis_info_hide(Vis*); /** Display arbitrary long message in a dedicated window. */ void vis_message_show(Vis*, const char *msg); From 7e85064ac77ea43e84d88eb910b0adb6f07d5d12 Mon Sep 17 00:00:00 2001 From: Randy Palamar Date: Tue, 21 May 2024 10:23:25 -0600 Subject: [PATCH 7/8] remove some ui pointer chasing There only exists a single Ui so there is no need to force a pointer redirection for accessing it. The Ui member was moved down in vis-core.h to punt around an issue with the way lua checks for existing objects. It may show up again as I flatten more structs. --- event-basic.c | 2 +- main.c | 4 ++-- ui-terminal-curses.c | 4 ++-- ui-terminal-vt100.c | 25 +++++++++------------ ui-terminal.c | 12 +++++----- ui.h | 3 ++- vis-cmds.c | 15 ++++++------- vis-core.h | 2 +- vis-lua.c | 12 +++++----- vis-prompt.c | 2 +- vis.c | 53 ++++++++++++++++++++++---------------------- vis.h | 4 ++-- 12 files changed, 65 insertions(+), 73 deletions(-) diff --git a/event-basic.c b/event-basic.c index cb2d2c191..d59ef8aa8 100644 --- a/event-basic.c +++ b/event-basic.c @@ -6,7 +6,7 @@ bool vis_event_emit(Vis *vis, enum VisEvents id, ...) { if (!vis->initialized) { vis->initialized = true; - ui_init(vis->ui, vis); + ui_init(&vis->ui, vis); } va_list ap; diff --git a/main.c b/main.c index d19b6f470..85330cbc5 100644 --- a/main.c +++ b/main.c @@ -1229,7 +1229,7 @@ static const char *macro_replay(Vis *vis, const char *keys, const Arg *arg) { } static const char *suspend(Vis *vis, const char *keys, const Arg *arg) { - ui_terminal_suspend(vis->ui); + ui_terminal_suspend(&vis->ui); return keys; } @@ -2214,7 +2214,7 @@ static void signal_handler(int signum, siginfo_t *siginfo, void *context) { } int main(int argc, char *argv[]) { - vis = vis_new(ui_terminal_new()); + vis = vis_new(); if (!vis) return EXIT_FAILURE; diff --git a/ui-terminal-curses.c b/ui-terminal-curses.c index 2b4a6fd6c..c3ae06488 100644 --- a/ui-terminal-curses.c +++ b/ui-terminal-curses.c @@ -276,8 +276,8 @@ static bool ui_term_backend_init(Ui *tui, char *term) { return true; } -static Ui *ui_term_backend_new(void) { - return calloc(1, sizeof(Ui)); +static bool ui_backend_init(Ui *ui) { + return true; } void ui_terminal_resume(Ui *term) { } diff --git a/ui-terminal-vt100.c b/ui-terminal-vt100.c index dffc23526..a1c92f35b 100644 --- a/ui-terminal-vt100.c +++ b/ui-terminal-vt100.c @@ -59,11 +59,6 @@ #define CELL_ATTR_ITALIC (1 << 4) #define CELL_ATTR_DIM (1 << 5) -typedef struct { - Ui uiterm; - Buffer buf; -} UiVt100; - static inline bool cell_color_equal(CellColor c1, CellColor c2) { if (c1.index != (uint8_t)-1 || c2.index != (uint8_t)-1) return c1.index == c2.index; @@ -97,7 +92,7 @@ static void cursor_visible(bool visible) { } static void ui_term_backend_blit(Ui *tui) { - Buffer *buf = &((UiVt100*)tui)->buf; + Buffer *buf = tui->ctx; buffer_clear(buf); CellAttr attr = CELL_ATTR_NORMAL; CellColor fg = CELL_COLOR_DEFAULT, bg = CELL_COLOR_DEFAULT; @@ -199,18 +194,20 @@ static bool ui_term_backend_init(Ui *tui, char *term) { return true; } -static Ui *ui_term_backend_new(void) { - UiVt100 *vtui = calloc(1, sizeof *vtui); - if (!vtui) - return NULL; - buffer_init(&vtui->buf); - return (Ui*)vtui; +static bool ui_backend_init(Ui *ui) { + Buffer *buf = calloc(1, sizeof(Buffer)); + if (!buf) + return false; + buffer_init(buf); + ui->ctx = buf; + return true; } static void ui_term_backend_free(Ui *tui) { - UiVt100 *vtui = (UiVt100*)tui; + Buffer *buf = tui->ctx; ui_term_backend_suspend(tui); - buffer_release(&vtui->buf); + buffer_release(buf); + free(buf); } static bool is_default_color(CellColor c) { diff --git a/ui-terminal.c b/ui-terminal.c index 048ba7fa6..d19724ab1 100644 --- a/ui-terminal.c +++ b/ui-terminal.c @@ -615,20 +615,19 @@ bool ui_init(Ui *tui, Vis *vis) { return false; } -Ui *ui_terminal_new(void) { +bool ui_terminal_init(Ui *tui) { size_t styles_size = UI_STYLE_MAX * sizeof(CellStyle); CellStyle *styles = calloc(1, styles_size); if (!styles) - return NULL; - Ui *tui = ui_term_backend_new(); - if (!tui) { + return false; + if (!ui_backend_init(tui)) { free(styles); - return NULL; + return false; } tui->styles_size = styles_size; tui->styles = styles; tui->doupdate = true; - return tui; + return true; } void ui_terminal_free(Ui *tui) { @@ -641,5 +640,4 @@ void ui_terminal_free(Ui *tui) { termkey_destroy(tui->termkey); free(tui->cells); free(tui->styles); - free(tui); } diff --git a/ui.h b/ui.h index 806b9ce03..c03a7096f 100644 --- a/ui.h +++ b/ui.h @@ -107,6 +107,7 @@ typedef struct Ui { size_t cells_size; /* #bytes allocated for 2D grid (grows only) */ Cell *cells; /* 2D grid of cells, at least as large as current terminal size */ bool doupdate; /* Whether to update the screen after refreshing contents */ + void *ctx; /* Any additional data needed by the backend */ } Ui; #include "view.h" @@ -115,7 +116,7 @@ typedef struct Ui { #define UI_OPTIONS_GET(ui) ((ui) ? (ui)->options : 0) -Ui *ui_terminal_new(void); +bool ui_terminal_init(Ui*); int ui_terminal_colors(void); void ui_terminal_free(Ui*); void ui_terminal_restore(Ui*); diff --git a/vis-cmds.c b/vis-cmds.c index 1515bc849..ae9ba4906 100644 --- a/vis-cmds.c +++ b/vis-cmds.c @@ -246,8 +246,7 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Select break; case OPTION_ESCDELAY: { - TermKey *termkey = vis->ui->termkey; - termkey_set_waittime(termkey, arg.i); + termkey_set_waittime(vis->ui.termkey, arg.i); break; } case OPTION_EXPANDTAB: @@ -354,7 +353,7 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Select vis_info_show(vis, "Invalid layout `%s', expected 'h' or 'v'", arg.s); return false; } - ui_arrange(vis->ui, layout); + ui_arrange(&vis->ui, layout); break; } case OPTION_IGNORECASE: @@ -542,7 +541,7 @@ static bool cmd_split(Vis *vis, Win *win, Command *cmd, const char *argv[], Sele if (!win) return false; enum UiOption options = UI_OPTIONS_GET(win->view->ui); - ui_arrange(vis->ui, UI_LAYOUT_HORIZONTAL); + ui_arrange(&vis->ui, UI_LAYOUT_HORIZONTAL); if (!argv[1]) return vis_window_split(win); bool ret = openfiles(vis, &argv[1]); @@ -555,7 +554,7 @@ static bool cmd_vsplit(Vis *vis, Win *win, Command *cmd, const char *argv[], Sel if (!win) return false; enum UiOption options = UI_OPTIONS_GET(win->view->ui); - ui_arrange(vis->ui, UI_LAYOUT_VERTICAL); + ui_arrange(&vis->ui, UI_LAYOUT_VERTICAL); if (!argv[1]) return vis_window_split(win); bool ret = openfiles(vis, &argv[1]); @@ -565,12 +564,12 @@ static bool cmd_vsplit(Vis *vis, Win *win, Command *cmd, const char *argv[], Sel } static bool cmd_new(Vis *vis, Win *win, Command *cmd, const char *argv[], Selection *sel, Filerange *range) { - ui_arrange(vis->ui, UI_LAYOUT_HORIZONTAL); + ui_arrange(&vis->ui, UI_LAYOUT_HORIZONTAL); return vis_window_new(vis, NULL); } static bool cmd_vnew(Vis *vis, Win *win, Command *cmd, const char *argv[], Selection *sel, Filerange *range) { - ui_arrange(vis->ui, UI_LAYOUT_VERTICAL); + ui_arrange(&vis->ui, UI_LAYOUT_VERTICAL); return vis_window_new(vis, NULL); } @@ -775,7 +774,7 @@ static void print_symbolic_keys(Vis *vis, Text *txt) { TERMKEY_SYM_KPEQUALS, }; - TermKey *termkey = vis->ui->termkey; + TermKey *termkey = vis->ui.termkey; text_appendf(txt, " ␣ (a literal \" \" space symbol must be used to refer to )\n"); for (size_t i = 0; i < LENGTH(keys); i++) { text_appendf(txt, " <%s>\n", termkey_get_keyname(termkey, keys[i])); diff --git a/vis-core.h b/vis-core.h index 9746fc9d9..7d729f78f 100644 --- a/vis-core.h +++ b/vis-core.h @@ -168,7 +168,6 @@ struct Win { }; struct Vis { - Ui *ui; /* user interface responsible for visual appearance */ File *files; /* all files currently managed by this editor instance */ File *command_file; /* special internal file used to store :-command prompt */ File *search_file; /* special internal file used to store /,? search prompt */ @@ -176,6 +175,7 @@ struct Vis { Win *windows; /* all windows currently managed by this editor instance */ Win *win; /* currently active/focused window */ Win *message_window; /* special window to display multi line messages */ + Ui ui; /* user interface responsible for visual appearance */ Register registers[VIS_REG_INVALID]; /* registers used for text manipulations yank/put etc. and macros */ Macro *recording, *last_recording; /* currently (if non NULL) and least recently recorded macro */ const Macro *replaying; /* macro currently being replayed */ diff --git a/vis-lua.c b/vis-lua.c index 3b5f7840d..6bd8a080e 100644 --- a/vis-lua.c +++ b/vis-lua.c @@ -1399,7 +1399,7 @@ static int vis_index(lua_State *L) { } if (strcmp(key, "registers") == 0) { - obj_ref_new(L, vis->ui, VIS_LUA_TYPE_REGISTERS); + obj_ref_new(L, &vis->ui, VIS_LUA_TYPE_REGISTERS); return 1; } @@ -1415,7 +1415,7 @@ static int vis_index(lua_State *L) { } if (strcmp(key, "ui") == 0) { - obj_ref_new(L, vis->ui, VIS_LUA_TYPE_UI); + obj_ref_new(L, &vis->ui, VIS_LUA_TYPE_UI); return 1; } } @@ -1429,8 +1429,7 @@ static int vis_options_assign(Vis *vis, lua_State *L, const char *key, int next) } else if (strcmp(key, "changecolors") == 0) { vis->change_colors = lua_toboolean(L, next); } else if (strcmp(key, "escdelay") == 0) { - TermKey *tk = vis->ui->termkey; - termkey_set_waittime(tk, luaL_checkint(L, next)); + termkey_set_waittime(vis->ui.termkey, luaL_checkint(L, next)); } else if (strcmp(key, "ignorecase") == 0 || strcmp(key, "ic") == 0) { vis->ignorecase = lua_toboolean(L, next); } else if (strcmp(key, "loadmethod") == 0) { @@ -1570,8 +1569,7 @@ static int vis_options_index(lua_State *L) { lua_pushboolean(L, vis->change_colors); return 1; } else if (strcmp(key, "escdelay") == 0) { - TermKey *tk = vis->ui->termkey; - lua_pushunsigned(L, termkey_get_waittime(tk)); + lua_pushunsigned(L, termkey_get_waittime(vis->ui.termkey)); return 1; } else if (strcmp(key, "ignorecase") == 0 || strcmp(key, "ic") == 0) { lua_pushboolean(L, vis->ignorecase); @@ -3612,7 +3610,7 @@ static void vis_lua_ui_draw(Vis *vis) { bool vis_event_emit(Vis *vis, enum VisEvents id, ...) { if (!vis->initialized) { vis->initialized = true; - ui_init(vis->ui, vis); + ui_init(&vis->ui, vis); vis_lua_init(vis); } diff --git a/vis-prompt.c b/vis-prompt.c index 474a32c98..dd6716136 100644 --- a/vis-prompt.c +++ b/vis-prompt.c @@ -182,7 +182,7 @@ void vis_prompt_show(Vis *vis, const char *title) { void vis_info_show(Vis *vis, const char *msg, ...) { va_list ap; va_start(ap, msg); - ui_info_show(vis->ui, msg, ap); + ui_info_show(&vis->ui, msg, ap); va_end(ap); } diff --git a/vis.c b/vis.c index be4a66a64..9bac2a8ca 100644 --- a/vis.c +++ b/vis.c @@ -202,8 +202,7 @@ static void window_free(Win *win) { if (other->parent == win) other->parent = NULL; } - if (vis->ui) - ui_window_free(win->ui); + ui_window_free(win->ui); view_free(win->view); for (size_t i = 0; i < LENGTH(win->modes); i++) map_free(win->modes[i].bindings); @@ -382,7 +381,7 @@ Win *window_new_file(Vis *vis, File *file, enum UiOption options) { win->file = file; win->view = view_new(file->text); win->expandtab = false; - win->ui = ui_window_new(vis->ui, win, options); + win->ui = ui_window_new(&vis->ui, win, options); if (!win->view || !win->ui) { window_free(win); return NULL; @@ -434,7 +433,7 @@ bool vis_window_change_file(Win *win, const char* filename) { } bool vis_window_split(Win *original) { - original->vis->ui->doupdate = false; + original->vis->ui.doupdate = false; Win *win = window_new_file(original->vis, original->file, UI_OPTION_STATUSBAR); if (!win) return false; @@ -447,7 +446,7 @@ bool vis_window_split(Win *original) { win->file = original->file; view_options_set(win->view, UI_OPTIONS_GET(original->view->ui)); view_cursors_to(win->view->selection, view_cursor_get(original->view)); - win->vis->ui->doupdate = true; + win->vis->ui.doupdate = true; return true; } @@ -482,21 +481,21 @@ void vis_draw(Vis *vis) { } void vis_redraw(Vis *vis) { - ui_redraw(vis->ui); - ui_draw(vis->ui); + ui_redraw(&vis->ui); + ui_draw(&vis->ui); } bool vis_window_new(Vis *vis, const char *filename) { File *file = file_new(vis, filename, false); if (!file) return false; - vis->ui->doupdate = false; + vis->ui.doupdate = false; Win *win = window_new_file(vis, file, UI_OPTION_STATUSBAR|UI_OPTION_SYMBOL_EOF); if (!win) { file_free(vis, file); return false; } - vis->ui->doupdate = true; + vis->ui.doupdate = true; return true; } @@ -567,14 +566,15 @@ void vis_window_close(Win *win) { vis_draw(vis); } -Vis *vis_new(Ui *ui) { - if (!ui) - return NULL; +Vis *vis_new(void) { Vis *vis = calloc(1, sizeof(Vis)); if (!vis) return NULL; vis->exit_status = -1; - vis->ui = ui; + if (!ui_terminal_init(&vis->ui)) { + free(vis); + return NULL; + } vis->change_colors = true; for (size_t i = 0; i < LENGTH(vis->registers); i++) register_init(&vis->registers[i]); @@ -629,7 +629,7 @@ void vis_free(Vis *vis) { file_free(vis, vis->error_file); for (int i = 0; i < LENGTH(vis->registers); i++) register_release(&vis->registers[i]); - ui_terminal_free(vis->ui); + ui_terminal_free(&vis->ui); if (vis->usercmds) { const char *name; while (map_first(vis->usercmds, &name) && vis_cmd_unregister(vis, name)); @@ -960,7 +960,7 @@ void vis_cancel(Vis *vis) { void vis_die(Vis *vis, const char *msg, ...) { va_list ap; va_start(ap, msg); - ui_die(vis->ui, msg, ap); + ui_die(&vis->ui, msg, ap); va_end(ap); } @@ -968,7 +968,7 @@ const char *vis_keys_next(Vis *vis, const char *keys) { if (!keys || !*keys) return NULL; TermKeyKey key; - TermKey *termkey = vis->ui->termkey; + TermKey *termkey = vis->ui.termkey; const char *next = NULL; /* first try to parse a special key of the form */ if (*keys == '<' && keys[1] && (next = termkey_strpkey(termkey, keys+1, &key, TERMKEY_FORMAT_VIM)) && *next == '>') @@ -996,7 +996,7 @@ long vis_keys_codepoint(Vis *vis, const char *keys) { long codepoint = -1; const char *next; TermKeyKey key; - TermKey *termkey = vis->ui->termkey; + TermKey *termkey = vis->ui.termkey; if (!keys[0]) return -1; @@ -1189,9 +1189,9 @@ static void vis_keys_push(Vis *vis, const char *input, size_t pos, bool record) static const char *getkey(Vis *vis) { TermKeyKey key = { 0 }; - if (!ui_getkey(vis->ui, &key)) + if (!ui_getkey(&vis->ui, &key)) return NULL; - ui_info_hide(vis->ui); + ui_info_hide(&vis->ui); bool use_keymap = vis->mode->id != VIS_MODE_INSERT && vis->mode->id != VIS_MODE_REPLACE && !vis->keymap_disabled; @@ -1205,7 +1205,7 @@ static const char *getkey(Vis *vis) { } } - TermKey *termkey = vis->ui->termkey; + TermKey *termkey = vis->ui.termkey; if (key.type == TERMKEY_TYPE_UNKNOWN_CSI) { long args[18]; size_t nargs; @@ -1299,16 +1299,16 @@ int vis_run(Vis *vis) { } if (vis->resume) { - ui_terminal_resume(vis->ui); + ui_terminal_resume(&vis->ui); vis->resume = false; } if (vis->need_resize) { - ui_resize(vis->ui); + ui_resize(&vis->ui); vis->need_resize = false; } - ui_draw(vis->ui); + ui_draw(&vis->ui); idle.tv_sec = vis->mode->idle_timeout; int r = pselect(vis_process_before_tick(&fds) + 1, &fds, NULL, NULL, timeout, &emptyset); @@ -1328,8 +1328,7 @@ int vis_run(Vis *vis) { continue; } - TermKey *termkey = vis->ui->termkey; - termkey_advisereadable(termkey); + termkey_advisereadable(vis->ui.termkey); const char *key; while ((key = getkey(vis))) @@ -1624,7 +1623,7 @@ int vis_pipe(Vis *vis, File *file, Filerange *range, const char *argv[], return -1; } - ui_terminal_save(vis->ui, fullscreen); + ui_terminal_save(&vis->ui, fullscreen); pid_t pid = fork(); if (pid == -1) { @@ -1818,7 +1817,7 @@ int vis_pipe(Vis *vis, File *file, Filerange *range, const char *argv[], sigaction(SIGTERM, &sigterm_old, NULL); vis->interrupted = false; - ui_terminal_restore(vis->ui); + ui_terminal_restore(&vis->ui); if (WIFEXITED(status)) return WEXITSTATUS(status); diff --git a/vis.h b/vis.h index 032b00bd0..eb8ec92d1 100644 --- a/vis.h +++ b/vis.h @@ -90,8 +90,8 @@ typedef struct { * @defgroup vis_lifecycle * @{ */ -/** Create a new editor instance using the given user interface. */ -Vis *vis_new(Ui*); +/** Create a new editor instance. */ +Vis *vis_new(void); /** Free all resources associated with this editor instance, terminates UI. */ void vis_free(Vis*); /** From 7554ecd77efc29601b7b44deca602724917ce019 Mon Sep 17 00:00:00 2001 From: Randy Palamar Date: Tue, 21 May 2024 11:27:08 -0600 Subject: [PATCH 8/8] remove some view pointer chasing Same as previous commit each window only has a single View. No need for it to be stored elsewhere in memory. --- sam.c | 25 ++++++++--------- ui-terminal.c | 12 ++++---- view.c | 19 +++++-------- view.h | 4 +-- vis-cmds.c | 34 +++++++++++------------ vis-core.h | 2 +- vis-lua.c | 74 ++++++++++++++++++++++++------------------------- vis-marks.c | 13 ++++----- vis-modes.c | 12 ++++---- vis-operators.c | 7 ++--- vis-prompt.c | 12 ++++---- vis-registers.c | 2 +- vis.c | 74 ++++++++++++++++++++++++------------------------- 13 files changed, 139 insertions(+), 151 deletions(-) diff --git a/sam.c b/sam.c index 8b322407f..90d19c297 100644 --- a/sam.c +++ b/sam.c @@ -1232,7 +1232,7 @@ enum SamError sam_cmd(Vis *vis, const char *s) { } bool visual = vis->mode->visual; - size_t primary_pos = vis->win ? view_cursor_get(vis->win->view) : EPOS; + size_t primary_pos = vis->win ? view_cursor_get(&vis->win->view) : EPOS; Filerange range = text_range_empty(); sam_execute(vis, vis->win, cmd, NULL, &range); @@ -1278,7 +1278,7 @@ enum SamError sam_cmd(Vis *vis, const char *s) { view_cursors_to(c->sel, r.end); } } else if (visual) { - Selection *sel = view_selections_new(c->win->view, r.start); + Selection *sel = view_selections_new(&c->win->view, r.start); if (sel) { view_selections_set(sel, &r); sel->anchored = true; @@ -1291,15 +1291,15 @@ enum SamError sam_cmd(Vis *vis, const char *s) { } for (Win *win = vis->windows; win; win = win->next) - view_selections_normalize(win->view); + view_selections_normalize(&win->view); if (vis->win) { - if (primary_pos != EPOS && view_selection_disposed(vis->win->view)) - view_cursors_to(vis->win->view->selection, primary_pos); - view_selections_primary_set(view_selections(vis->win->view)); + if (primary_pos != EPOS && view_selection_disposed(&vis->win->view)) + view_cursors_to(vis->win->view.selection, primary_pos); + view_selections_primary_set(view_selections(&vis->win->view)); vis_jumplist_save(vis); bool completed = true; - for (Selection *s = view_selections(vis->win->view); s; s = view_selections_next(s)) { + for (Selection *s = view_selections(&vis->win->view); s; s = view_selections_next(s)) { if (s->anchored) { completed = false; break; @@ -1507,7 +1507,7 @@ static bool cmd_select(Vis *vis, Win *win, Command *cmd, const char *argv[], Sel if (!win) return sam_execute(vis, NULL, cmd->cmd, NULL, &r); bool ret = true; - View *view = win->view; + View *view = &win->view; Text *txt = win->file->text; bool multiple_cursors = view->selection_count > 1; Selection *primary = view_selections_primary_get(view); @@ -1557,7 +1557,7 @@ static bool cmd_select(Vis *vis, Win *win, Command *cmd, const char *argv[], Sel break; } - if (vis->win && vis->win->view == view && primary != view_selections_primary_get(view)) + if (vis->win && &vis->win->view == view && primary != view_selections_primary_get(view)) view_selections_primary_set(view_selections(view)); return ret; } @@ -1565,9 +1565,8 @@ static bool cmd_select(Vis *vis, Win *win, Command *cmd, const char *argv[], Sel static bool cmd_print(Vis *vis, Win *win, Command *cmd, const char *argv[], Selection *sel, Filerange *range) { if (!win || !text_range_valid(range)) return false; - View *view = win->view; if (!sel) - sel = view_selections_new_force(view, range->start); + sel = view_selections_new_force(&win->view, range->start); if (!sel) return false; if (range->start != range->end) { @@ -1641,7 +1640,7 @@ static bool cmd_write(Vis *vis, Win *win, Command *cmd, const char *argv[], Sele bool visual = vis->mode->visual; - for (Selection *s = view_selections(win->view); s; s = view_selections_next(s)) { + for (Selection *s = view_selections(&win->view); s; s = view_selections_next(s)) { Filerange range = visual ? view_selections_get(s) : *r; ssize_t written = text_write_range(text, &range, file->fd); if (written == -1 || (size_t)written != text_range_size(&range)) { @@ -1709,7 +1708,7 @@ static bool cmd_write(Vis *vis, Win *win, Command *cmd, const char *argv[], Sele bool failure = false; bool visual = vis->mode->visual; - for (Selection *s = view_selections(win->view); s; s = view_selections_next(s)) { + for (Selection *s = view_selections(&win->view); s; s = view_selections_next(s)) { Filerange range = visual ? view_selections_get(s) : *r; ssize_t written = text_save_write_range(ctx, &range); failure = (written == -1 || (size_t)written != text_range_size(&range)); diff --git a/ui-terminal.c b/ui-terminal.c index d19724ab1..d540308eb 100644 --- a/ui-terminal.c +++ b/ui-terminal.c @@ -58,7 +58,7 @@ static void ui_window_resize(UiWin *win, int width, int height) { bool status = win->options & UI_OPTION_STATUSBAR; win->width = width; win->height = height; - view_resize(win->win->view, width - win->sidebar_width, status ? height - 1 : height); + view_resize(&win->win->view, width - win->sidebar_width, status ? height - 1 : height); } static void ui_window_move(UiWin *win, int x, int y) { @@ -204,7 +204,7 @@ static void ui_draw_string(Ui *tui, int x, int y, const char *str, UiWin *win, e static void ui_window_draw(UiWin *win) { Ui *ui = win->ui; - View *view = win->win->view; + View *view = &win->win->view; int width = win->width, height = win->height; const Line *line = view->topline; bool status = win->options & UI_OPTION_STATUSBAR; @@ -351,7 +351,7 @@ void ui_draw(Ui *tui) { void ui_redraw(Ui *tui) { ui_term_backend_clear(tui); for (UiWin *win = tui->windows; win; win = win->next) - win->win->view->need_update = true; + win->win->view.need_update = true; } void ui_resize(Ui *tui) { @@ -405,8 +405,8 @@ void ui_window_focus(UiWin *new) { if (new->options & UI_OPTION_STATUSBAR) new->ui->selwin = new; if (old) - old->win->view->need_update = true; - new->win->view->need_update = true; + old->win->view.need_update = true; + new->win->view.need_update = true; } void ui_window_options_set(UiWin *win, enum UiOption options) { @@ -500,7 +500,7 @@ UiWin *ui_window_new(Ui *tui, Win *w, enum UiOption options) { styles[UI_STYLE_STATUS].attr |= CELL_ATTR_REVERSE; styles[UI_STYLE_STATUS_FOCUSED].attr |= CELL_ATTR_REVERSE|CELL_ATTR_BOLD; styles[UI_STYLE_INFO].attr |= CELL_ATTR_BOLD; - w->view->ui = win; + w->view.ui = win; if (tui->windows) tui->windows->prev = win; diff --git a/view.c b/view.c index afc72da66..6e67088e9 100644 --- a/view.c +++ b/view.c @@ -71,7 +71,7 @@ void window_status_update(Vis *vis, Win *win) { size_t left_count = 0; size_t right_count = 0; - View *view = win->view; + View *view = &win->view; File *file = win->file; Text *txt = file->text; int width = win->ui->width; @@ -114,12 +114,12 @@ void window_status_update(Vis *vis, Win *win) { "%zu%%", percent); if (!(options & UI_OPTION_LARGE_FILE)) { - Selection *sel = view_selections_primary_get(win->view); + Selection *sel = view_selections_primary_get(&win->view); size_t line = view_cursors_line(sel); size_t col = view_cursors_col(sel); if (col > UI_LARGE_FILE_LINE_SIZE) { options |= UI_OPTION_LARGE_FILE; - view_options_set(win->view, options); + view_options_set(&win->view, options); } snprintf(right_parts[right_count++], sizeof(right_parts[0]), "%zu, %zu", line, col); @@ -551,7 +551,6 @@ void view_free(View *view) { free(view->textbuf); free(view->lines); free(view->breakat); - free(view); } void view_reload(View *view, Text *text) { @@ -560,12 +559,9 @@ void view_reload(View *view, Text *text) { view_cursors_to(view->selection, 0); } -View *view_new(Text *text) { +bool view_init(View *view, Text *text) { if (!text) - return NULL; - View *view = calloc(1, sizeof(View)); - if (!view) - return NULL; + return false; view->text = text; view->tabwidth = 8; @@ -582,12 +578,11 @@ View *view_new(Text *text) { !view_selections_new(view, 0) || !view_resize(view, 1, 1)) { - view_free(view); - return NULL; + return false; } view_cursors_to(view->selection, 0); - return view; + return true; } static size_t cursor_set(Selection *sel, Line *line, int col) { diff --git a/view.h b/view.h index 79275c800..b159267e0 100644 --- a/view.h +++ b/view.h @@ -87,7 +87,7 @@ typedef struct View { * @defgroup view_life * @{ */ -View *view_new(Text*); +bool view_init(View*, Text*); void view_free(View*); void view_reload(View*, Text*); /** @@ -96,7 +96,7 @@ void view_reload(View*, Text*); * @{ */ /** Get the currently displayed text range. */ -#define VIEW_VIEWPORT_GET(v) (Filerange){ .start = v->start, .end = v->end } +#define VIEW_VIEWPORT_GET(v) (Filerange){ .start = v.start, .end = v.end } /** * Get window coordinate of text position. * @param pos The position to query. diff --git a/vis-cmds.c b/vis-cmds.c index ae9ba4906..382a7d795 100644 --- a/vis-cmds.c +++ b/vis-cmds.c @@ -256,7 +256,7 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Select vis->autoindent = toggle ? !vis->autoindent : arg.b; break; case OPTION_TABWIDTH: - view_tabwidth_set(vis->win->view, arg.i); + view_tabwidth_set(&vis->win->view, arg.i); break; case OPTION_SHOW_SPACES: case OPTION_SHOW_TABS: @@ -271,48 +271,48 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Select [OPTION_SHOW_EOF] = UI_OPTION_SYMBOL_EOF, [OPTION_STATUSBAR] = UI_OPTION_STATUSBAR, }; - int flags = UI_OPTIONS_GET(win->view->ui); + int flags = UI_OPTIONS_GET(win->view.ui); if (arg.b || (toggle && !(flags & values[opt_index]))) flags |= values[opt_index]; else flags &= ~values[opt_index]; - view_options_set(win->view, flags); + view_options_set(&win->view, flags); break; } case OPTION_NUMBER: { - enum UiOption opt = UI_OPTIONS_GET(win->view->ui); + enum UiOption opt = UI_OPTIONS_GET(win->view.ui); if (arg.b || (toggle && !(opt & UI_OPTION_LINE_NUMBERS_ABSOLUTE))) { opt &= ~UI_OPTION_LINE_NUMBERS_RELATIVE; opt |= UI_OPTION_LINE_NUMBERS_ABSOLUTE; } else { opt &= ~UI_OPTION_LINE_NUMBERS_ABSOLUTE; } - view_options_set(win->view, opt); + view_options_set(&win->view, opt); break; } case OPTION_NUMBER_RELATIVE: { - enum UiOption opt = UI_OPTIONS_GET(win->view->ui); + enum UiOption opt = UI_OPTIONS_GET(win->view.ui); if (arg.b || (toggle && !(opt & UI_OPTION_LINE_NUMBERS_RELATIVE))) { opt &= ~UI_OPTION_LINE_NUMBERS_ABSOLUTE; opt |= UI_OPTION_LINE_NUMBERS_RELATIVE; } else { opt &= ~UI_OPTION_LINE_NUMBERS_RELATIVE; } - view_options_set(win->view, opt); + view_options_set(&win->view, opt); break; } case OPTION_CURSOR_LINE: { - enum UiOption opt = UI_OPTIONS_GET(win->view->ui); + enum UiOption opt = UI_OPTIONS_GET(win->view.ui); if (arg.b || (toggle && !(opt & UI_OPTION_CURSOR_LINE))) opt |= UI_OPTION_CURSOR_LINE; else opt &= ~UI_OPTION_CURSOR_LINE; - view_options_set(win->view, opt); + view_options_set(&win->view, opt); break; } case OPTION_COLOR_COLUMN: if (arg.i >= 0) - win->view->colorcolumn = arg.i; + win->view.colorcolumn = arg.i; break; case OPTION_SAVE_METHOD: if (strcmp("auto", arg.s) == 0) { @@ -360,14 +360,14 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Select vis->ignorecase = toggle ? !vis->ignorecase : arg.b; break; case OPTION_BREAKAT: - if (!view_breakat_set(win->view, arg.s)) { + if (!view_breakat_set(&win->view, arg.s)) { vis_info_show(vis, "Failed to set breakat"); return false; } break; case OPTION_WRAP_COLUMN: if (arg.i >= 0) - win->view->wrapcolumn = arg.i; + win->view.wrapcolumn = arg.i; break; default: if (!opt->func) @@ -540,26 +540,26 @@ static bool cmd_qall(Vis *vis, Win *win, Command *cmd, const char *argv[], Selec static bool cmd_split(Vis *vis, Win *win, Command *cmd, const char *argv[], Selection *sel, Filerange *range) { if (!win) return false; - enum UiOption options = UI_OPTIONS_GET(win->view->ui); + enum UiOption options = UI_OPTIONS_GET(win->view.ui); ui_arrange(&vis->ui, UI_LAYOUT_HORIZONTAL); if (!argv[1]) return vis_window_split(win); bool ret = openfiles(vis, &argv[1]); if (ret) - view_options_set(vis->win->view, options); + view_options_set(&vis->win->view, options); return ret; } static bool cmd_vsplit(Vis *vis, Win *win, Command *cmd, const char *argv[], Selection *sel, Filerange *range) { if (!win) return false; - enum UiOption options = UI_OPTIONS_GET(win->view->ui); + enum UiOption options = UI_OPTIONS_GET(win->view.ui); ui_arrange(&vis->ui, UI_LAYOUT_VERTICAL); if (!argv[1]) return vis_window_split(win); bool ret = openfiles(vis, &argv[1]); if (ret) - view_options_set(vis->win->view, options); + view_options_set(&vis->win->view, options); return ret; } @@ -871,7 +871,7 @@ static bool cmd_help(Vis *vis, Win *win, Command *cmd, const char *argv[], Selec text_appendf(txt, " %-32s\t%s\n", configs[i].name, configs[i].enabled ? "yes" : "no"); text_save(txt, NULL); - view_cursors_to(vis->win->view->selection, 0); + view_cursors_to(vis->win->view.selection, 0); if (argv[1]) vis_motion(vis, VIS_MOVE_SEARCH_FORWARD, argv[1]); diff --git a/vis-core.h b/vis-core.h index 7d729f78f..c66924e9b 100644 --- a/vis-core.h +++ b/vis-core.h @@ -157,7 +157,7 @@ struct Win { Vis *vis; /* editor instance to which this window belongs */ UiWin *ui; /* ui object handling visual appearance of this window */ File *file; /* file being displayed in this window */ - View *view; /* currently displayed part of underlying text */ + View view; /* currently displayed part of underlying text */ bool expandtab; /* whether typed tabs should be converted to spaces in this window*/ MarkList jumplist; /* LRU jump management */ Array saved_selections; /* register used to store selections */ diff --git a/vis-lua.c b/vis-lua.c index 6bd8a080e..75e2e24c7 100644 --- a/vis-lua.c +++ b/vis-lua.c @@ -1107,7 +1107,7 @@ static bool command_lua(Vis *vis, Win *win, void *data, bool force, const char * if (!obj_ref_new(L, win, VIS_LUA_TYPE_WINDOW)) return false; if (!sel) - sel = view_selections_primary_get(win->view); + sel = view_selections_primary_get(&win->view); if (!obj_lightref_new(L, sel, VIS_LUA_TYPE_SELECTION)) return false; pushrange(L, range); @@ -1766,8 +1766,8 @@ static int window_index(lua_State *L) { if (strcmp(key, "viewport") == 0) { Filerange b = VIEW_VIEWPORT_GET(win->view); Filerange l; - l.start = win->view->topline->lineno; - l.end = win->view->lastline->lineno; + l.start = win->view.topline->lineno; + l.end = win->view.lastline->lineno; lua_createtable(L, 0, 4); lua_pushstring(L, "bytes"); @@ -1777,10 +1777,10 @@ static int window_index(lua_State *L) { pushrange(L, &l); lua_settable(L, -3); lua_pushstring(L, "width"); - lua_pushunsigned(L, win->view->width); + lua_pushunsigned(L, win->view.width); lua_settable(L, -3); lua_pushstring(L, "height"); - lua_pushunsigned(L, win->view->height); + lua_pushunsigned(L, win->view.height); lua_settable(L, -3); return 1; } @@ -1801,13 +1801,13 @@ static int window_index(lua_State *L) { } if (strcmp(key, "selection") == 0) { - Selection *sel = view_selections_primary_get(win->view); + Selection *sel = view_selections_primary_get(&win->view); obj_lightref_new(L, sel, VIS_LUA_TYPE_SELECTION); return 1; } if (strcmp(key, "selections") == 0) { - obj_ref_new(L, win->view, VIS_LUA_TYPE_SELECTIONS); + obj_ref_new(L, &win->view, VIS_LUA_TYPE_SELECTIONS); return 1; } @@ -1825,64 +1825,64 @@ static int window_index(lua_State *L) { } static int window_options_assign(Win *win, lua_State *L, const char *key, int next) { - enum UiOption flags = UI_OPTIONS_GET(win->view->ui); + enum UiOption flags = UI_OPTIONS_GET(win->view.ui); if (strcmp(key, "breakat") == 0 || strcmp(key, "brk") == 0) { if (lua_isstring(L, next)) - view_breakat_set(win->view, lua_tostring(L, next)); + view_breakat_set(&win->view, lua_tostring(L, next)); } else if (strcmp(key, "colorcolumn") == 0 || strcmp(key, "cc") == 0) { - win->view->colorcolumn = luaL_checkunsigned(L, next); + win->view.colorcolumn = luaL_checkunsigned(L, next); } else if (strcmp(key, "cursorline") == 0 || strcmp(key, "cul") == 0) { if (lua_toboolean(L, next)) flags |= UI_OPTION_CURSOR_LINE; else flags &= ~UI_OPTION_CURSOR_LINE; - view_options_set(win->view, flags); + view_options_set(&win->view, flags); } else if (strcmp(key, "numbers") == 0 || strcmp(key, "nu") == 0) { if (lua_toboolean(L, next)) flags |= UI_OPTION_LINE_NUMBERS_ABSOLUTE; else flags &= ~UI_OPTION_LINE_NUMBERS_ABSOLUTE; - view_options_set(win->view, flags); + view_options_set(&win->view, flags); } else if (strcmp(key, "relativenumbers") == 0 || strcmp(key, "rnu") == 0) { if (lua_toboolean(L, next)) flags |= UI_OPTION_LINE_NUMBERS_RELATIVE; else flags &= ~UI_OPTION_LINE_NUMBERS_RELATIVE; - view_options_set(win->view, flags); + view_options_set(&win->view, flags); } else if (strcmp(key, "showeof") == 0) { if (lua_toboolean(L, next)) flags |= UI_OPTION_SYMBOL_EOF; else flags &= ~UI_OPTION_SYMBOL_EOF; - view_options_set(win->view, flags); + view_options_set(&win->view, flags); } else if (strcmp(key, "shownewlines") == 0) { if (lua_toboolean(L, next)) flags |= UI_OPTION_SYMBOL_EOL; else flags &= ~UI_OPTION_SYMBOL_EOL; - view_options_set(win->view, flags); + view_options_set(&win->view, flags); } else if (strcmp(key, "showspaces") == 0) { if (lua_toboolean(L, next)) flags |= UI_OPTION_SYMBOL_SPACE; else flags &= ~UI_OPTION_SYMBOL_SPACE; - view_options_set(win->view, flags); + view_options_set(&win->view, flags); } else if (strcmp(key, "showtabs") == 0) { if (lua_toboolean(L, next)) flags |= UI_OPTION_SYMBOL_TAB; else flags &= ~UI_OPTION_SYMBOL_TAB; - view_options_set(win->view, flags); + view_options_set(&win->view, flags); } else if (strcmp(key, "statusbar") == 0) { if (lua_toboolean(L, next)) flags |= UI_OPTION_STATUSBAR; else flags &= ~UI_OPTION_STATUSBAR; - view_options_set(win->view, flags); + view_options_set(&win->view, flags); } else if (strcmp(key, "wrapcolumn") == 0 || strcmp(key, "wc") == 0) { - win->view->wrapcolumn = luaL_checkunsigned(L, next); + win->view.wrapcolumn = luaL_checkunsigned(L, next); } else if (strcmp(key, "tabwidth") == 0 || strcmp(key, "tw") == 0) { - view_tabwidth_set(win->view, luaL_checkint(L, next)); + view_tabwidth_set(&win->view, luaL_checkint(L, next)); } else if (strcmp(key, "expandtab") == 0 || strcmp(key, "et") == 0) { win->expandtab = lua_toboolean(L, next); } @@ -1942,7 +1942,7 @@ static int window_selections_iterator_next(lua_State *L) { static int window_selections_iterator(lua_State *L) { Win *win = obj_ref_check(L, 1, VIS_LUA_TYPE_WINDOW); Selection **handle = lua_newuserdata(L, sizeof *handle); - *handle = view_selections(win->view); + *handle = view_selections(&win->view); lua_pushcclosure(L, window_selections_iterator_next, 1); return 1; } @@ -1986,7 +1986,7 @@ static int window_style_define(lua_State *L) { Win *win = obj_ref_check(L, 1, VIS_LUA_TYPE_WINDOW); enum UiStyle id = luaL_checkunsigned(L, 2); const char *style = luaL_checkstring(L, 3); - bool ret = ui_style_define(win->view->ui, id, style); + bool ret = ui_style_define(win->view.ui, id, style); lua_pushboolean(L, ret); return 1; } @@ -2008,7 +2008,7 @@ static int window_style(lua_State *L) { enum UiStyle style = luaL_checkunsigned(L, 2); size_t start = checkpos(L, 3); size_t end = checkpos(L, 4); - view_style(win->view, style, start, end); + view_style(&win->view, style, start, end); return 0; } @@ -2068,7 +2068,7 @@ static int window_status(lua_State *L) { */ static int window_draw(lua_State *L) { Win *win = obj_ref_check(L, 1, VIS_LUA_TYPE_WINDOW); - view_draw(win->view); + view_draw(&win->view); return 0; } @@ -2140,43 +2140,43 @@ static int window_options_index(lua_State *L) { if (lua_isstring(L, 2)) { const char *key = lua_tostring(L, 2); if (strcmp(key, "breakat") == 0 || strcmp(key, "brk") == 0) { - lua_pushstring(L, win->view->breakat); + lua_pushstring(L, win->view.breakat); return 1; } else if (strcmp(key, "colorcolumn") == 0 || strcmp(key, "cc") == 0) { - lua_pushunsigned(L, win->view->colorcolumn); + lua_pushunsigned(L, win->view.colorcolumn); return 1; } else if (strcmp(key, "cursorline") == 0 || strcmp(key, "cul") == 0) { - lua_pushboolean(L, UI_OPTIONS_GET(win->view->ui) & UI_OPTION_CURSOR_LINE); + lua_pushboolean(L, UI_OPTIONS_GET(win->view.ui) & UI_OPTION_CURSOR_LINE); return 1; } else if (strcmp(key, "expandtab") == 0 || strcmp(key, "et") == 0) { lua_pushboolean(L, win->expandtab); return 1; } else if (strcmp(key, "numbers") == 0 || strcmp(key, "nu") == 0) { - lua_pushboolean(L, UI_OPTIONS_GET(win->view->ui) & UI_OPTION_LINE_NUMBERS_ABSOLUTE); + lua_pushboolean(L, UI_OPTIONS_GET(win->view.ui) & UI_OPTION_LINE_NUMBERS_ABSOLUTE); return 1; } else if (strcmp(key, "relativenumbers") == 0 || strcmp(key, "rnu") == 0) { - lua_pushboolean(L, UI_OPTIONS_GET(win->view->ui) & UI_OPTION_LINE_NUMBERS_RELATIVE); + lua_pushboolean(L, UI_OPTIONS_GET(win->view.ui) & UI_OPTION_LINE_NUMBERS_RELATIVE); return 1; } else if (strcmp(key, "showeof") == 0) { - lua_pushboolean(L, UI_OPTIONS_GET(win->view->ui) & UI_OPTION_SYMBOL_EOF); + lua_pushboolean(L, UI_OPTIONS_GET(win->view.ui) & UI_OPTION_SYMBOL_EOF); return 1; } else if (strcmp(key, "shownewlines") == 0) { - lua_pushboolean(L, UI_OPTIONS_GET(win->view->ui) & UI_OPTION_SYMBOL_EOL); + lua_pushboolean(L, UI_OPTIONS_GET(win->view.ui) & UI_OPTION_SYMBOL_EOL); return 1; } else if (strcmp(key, "showspaces") == 0) { - lua_pushboolean(L, UI_OPTIONS_GET(win->view->ui) & UI_OPTION_SYMBOL_SPACE); + lua_pushboolean(L, UI_OPTIONS_GET(win->view.ui) & UI_OPTION_SYMBOL_SPACE); return 1; } else if (strcmp(key, "showtabs") == 0) { - lua_pushboolean(L, UI_OPTIONS_GET(win->view->ui) & UI_OPTION_SYMBOL_TAB); + lua_pushboolean(L, UI_OPTIONS_GET(win->view.ui) & UI_OPTION_SYMBOL_TAB); return 1; } else if (strcmp(key, "statusbar") == 0) { - lua_pushboolean(L, UI_OPTIONS_GET(win->view->ui) & UI_OPTION_STATUSBAR); + lua_pushboolean(L, UI_OPTIONS_GET(win->view.ui) & UI_OPTION_STATUSBAR); return 1; } else if (strcmp(key, "tabwidth") == 0 || strcmp(key, "tw") == 0) { - lua_pushinteger(L, win->view->tabwidth); + lua_pushinteger(L, win->view.tabwidth); return 1; } else if (strcmp(key, "wrapcolumn") == 0 || strcmp(key, "wc") == 0) { - lua_pushunsigned(L, win->view->wrapcolumn); + lua_pushunsigned(L, win->view.wrapcolumn); return 1; } } @@ -3492,7 +3492,7 @@ static void vis_lua_win_close(Vis *vis, Win *win) { obj_ref_new(L, win, VIS_LUA_TYPE_WINDOW); pcall(vis, L, 1, 0); } - obj_ref_free(L, win->view); + obj_ref_free(L, &win->view); obj_ref_free(L, win); lua_pop(L, 1); } diff --git a/vis-marks.c b/vis-marks.c index aea654d71..48c065cdb 100644 --- a/vis-marks.c +++ b/vis-marks.c @@ -72,12 +72,11 @@ static Array mark_get(Win *win, Array *mark) { array_init_sized(&sel, sizeof(Filerange)); if (!mark) return sel; - View *view = win->view; size_t len = array_length(mark); array_reserve(&sel, len); for (size_t i = 0; i < len; i++) { SelectionRegion *sr = array_get(mark, i); - Filerange r = view_regions_restore(view, sr); + Filerange r = view_regions_restore(&win->view, sr); if (text_range_valid(&r)) array_add(&sel, &r); } @@ -93,11 +92,10 @@ static void mark_set(Win *win, Array *mark, Array *sel) { if (!mark) return; array_clear(mark); - View *view = win->view; for (size_t i = 0, len = array_length(sel); i < len; i++) { SelectionRegion ss; Filerange *r = array_get(sel, i); - if (view_regions_save(view, r, &ss)) + if (view_regions_save(&win->view, r, &ss)) array_add(mark, &ss); } } @@ -150,15 +148,14 @@ static bool marklist_push(Win *win, MarkList *list, Array *sel) { } bool vis_jumplist_save(Vis *vis) { - View *view = vis->win->view; - Array sel = view_selections_get_all(view); + Array sel = view_selections_get_all(&vis->win->view); bool ret = marklist_push(vis->win, &vis->win->jumplist, &sel); array_release(&sel); return ret; } static bool marklist_prev(Win *win, MarkList *list) { - View *view = win->view; + View *view = &win->view; bool restore = false; Array cur = view_selections_get_all(view); bool anchored = view_selections_primary_get(view)->anchored; @@ -191,7 +188,7 @@ static bool marklist_prev(Win *win, MarkList *list) { } static bool marklist_next(Win *win, MarkList *list) { - View *view = win->view; + View *view = &win->view; bool anchored = view_selections_primary_get(view)->anchored; for (;;) { Array *next = array_pop(&list->next); diff --git a/vis-modes.c b/vis-modes.c index 41121a863..f6d2b267a 100644 --- a/vis-modes.c +++ b/vis-modes.c @@ -148,7 +148,7 @@ static void vis_mode_normal_enter(Vis *vis, Mode *old) { return; if (vis->autoindent && strcmp(vis->key_prev, "") == 0) { Text *txt = win->file->text; - for (Selection *s = view_selections(win->view); s; s = view_selections_next(s)) { + for (Selection *s = view_selections(&win->view); s; s = view_selections_next(s)) { size_t pos = view_cursors_pos(s); size_t start = text_line_start(txt, pos); size_t end = text_line_end(txt, pos); @@ -189,7 +189,7 @@ static void vis_mode_operator_input(Vis *vis, const char *str, size_t len) { static void vis_mode_visual_enter(Vis *vis, Mode *old) { Win *win = vis->win; if (!old->visual && win) { - for (Selection *s = view_selections(win->view); s; s = view_selections_next(s)) + for (Selection *s = view_selections(&win->view); s; s = view_selections_next(s)) s->anchored = true; } } @@ -197,7 +197,7 @@ static void vis_mode_visual_enter(Vis *vis, Mode *old) { static void vis_mode_visual_line_enter(Vis *vis, Mode *old) { Win *win = vis->win; if (!old->visual && win) { - for (Selection *s = view_selections(win->view); s; s = view_selections_next(s)) + for (Selection *s = view_selections(&win->view); s; s = view_selections_next(s)) s->anchored = true; } if (!vis->action.op) @@ -211,9 +211,9 @@ static void vis_mode_visual_line_leave(Vis *vis, Mode *new) { if (!new->visual) { if (!vis->action.op) window_selection_save(win); - view_selections_clear_all(win->view); + view_selections_clear_all(&win->view); } else { - view_cursors_to(win->view->selection, view_cursor_get(win->view)); + view_cursors_to(win->view.selection, view_cursor_get(&win->view)); } } @@ -222,7 +222,7 @@ static void vis_mode_visual_leave(Vis *vis, Mode *new) { if (!new->visual && win) { if (!vis->action.op) window_selection_save(win); - view_selections_clear_all(win->view); + view_selections_clear_all(&win->view); } } diff --git a/vis-operators.c b/vis-operators.c index 5ce64c490..59abcf6bb 100644 --- a/vis-operators.c +++ b/vis-operators.c @@ -102,7 +102,7 @@ static size_t op_put(Vis *vis, Text *txt, OperatorContext *c) { static size_t op_shift_right(Vis *vis, Text *txt, OperatorContext *c) { char spaces[9] = " "; - spaces[MIN(vis->win->view->tabwidth, LENGTH(spaces) - 1)] = '\0'; + spaces[MIN(vis->win->view.tabwidth, LENGTH(spaces) - 1)] = '\0'; const char *tab = vis->win->expandtab ? spaces : "\t"; size_t tablen = strlen(tab); size_t pos = text_line_begin(txt, c->range.end), prev_pos; @@ -127,7 +127,7 @@ static size_t op_shift_right(Vis *vis, Text *txt, OperatorContext *c) { static size_t op_shift_left(Vis *vis, Text *txt, OperatorContext *c) { size_t pos = text_line_begin(txt, c->range.end), prev_pos; - size_t tabwidth = vis->win->view->tabwidth, tablen; + size_t tabwidth = vis->win->view.tabwidth, tablen; size_t newpos = c->pos; /* if range ends at the begin of a line, skip line break */ @@ -161,7 +161,6 @@ static size_t op_shift_left(Vis *vis, Text *txt, OperatorContext *c) { } static size_t op_cursor(Vis *vis, Text *txt, OperatorContext *c) { - View *view = vis->win->view; Filerange r = text_range_linewise(txt, &c->range); for (size_t line = text_range_line_first(txt, &r); line != EPOS; line = text_range_line_next(txt, &r, line)) { size_t pos; @@ -169,7 +168,7 @@ static size_t op_cursor(Vis *vis, Text *txt, OperatorContext *c) { pos = text_line_finish(txt, line); else pos = text_line_start(txt, line); - view_selections_new_force(view, pos); + view_selections_new_force(&vis->win->view, pos); } return EPOS; } diff --git a/vis-prompt.c b/vis-prompt.c index dd6716136..86699f22a 100644 --- a/vis-prompt.c +++ b/vis-prompt.c @@ -49,7 +49,7 @@ static void prompt_restore(Win *win) { static const char *prompt_enter(Vis *vis, const char *keys, const Arg *arg) { Win *prompt = vis->win; - View *view = prompt->view; + View *view = &prompt->view; Text *txt = prompt->file->text; Win *win = prompt->parent; char *cmd = NULL; @@ -114,8 +114,8 @@ static const char *prompt_enter(Vis *vis, const char *keys, const Arg *arg) { static const char *prompt_esc(Vis *vis, const char *keys, const Arg *arg) { Win *prompt = vis->win; - if (prompt->view->selection_count > 1) { - view_selections_dispose_all(prompt->view); + if (prompt->view.selection_count > 1) { + view_selections_dispose_all(&prompt->view); } else { prompt_restore(prompt); prompt_hide(prompt); @@ -126,7 +126,7 @@ static const char *prompt_esc(Vis *vis, const char *keys, const Arg *arg) { static const char *prompt_up(Vis *vis, const char *keys, const Arg *arg) { vis_motion(vis, VIS_MOVE_LINE_UP); vis_window_mode_unmap(vis->win, VIS_MODE_INSERT, ""); - view_options_set(vis->win->view, UI_OPTION_SYMBOL_EOF); + view_options_set(&vis->win->view, UI_OPTION_SYMBOL_EOF); return keys; } @@ -164,7 +164,7 @@ void vis_prompt_show(Vis *vis, const char *title) { return; Text *txt = prompt->file->text; text_appendf(txt, "%s\n", title); - Selection *sel = view_selections_primary_get(prompt->view); + Selection *sel = view_selections_primary_get(&prompt->view); view_cursors_scroll_to(sel, text_size(txt)-1); prompt->parent = active; prompt->parent_mode = vis->mode; @@ -198,6 +198,6 @@ void vis_message_show(Vis *vis, const char *msg) { size_t pos = text_size(txt); text_appendf(txt, "%s\n", msg); text_save(txt, NULL); - view_cursors_to(win->view->selection, pos); + view_cursors_to(win->view.selection, pos); vis_window_focus(win); } diff --git a/vis-registers.c b/vis-registers.c index 485284c45..6e21a5840 100644 --- a/vis-registers.c +++ b/vis-registers.c @@ -188,7 +188,7 @@ bool register_put_range(Vis *vis, Register *reg, Text *txt, Filerange *range) { size_t vis_register_count(Vis *vis, Register *reg) { if (reg->type == REGISTER_NUMBER) - return vis->win ? vis->win->view->selection_count : 0; + return vis->win ? vis->win->view.selection_count : 0; return array_length(®->values); } diff --git a/vis.c b/vis.c index 9bac2a8ca..4a025f9a2 100644 --- a/vis.c +++ b/vis.c @@ -186,8 +186,7 @@ const char *file_name_get(File *file) { void window_selection_save(Win *win) { Vis *vis = win->vis; - View *view = win->view; - Array sel = view_selections_get_all(view); + Array sel = view_selections_get_all(&win->view); vis_mark_set(win, VIS_MARK_SELECTION, &sel); array_release(&sel); vis_jumplist_save(vis); @@ -203,7 +202,7 @@ static void window_free(Win *win) { other->parent = NULL; } ui_window_free(win->ui); - view_free(win->view); + view_free(&win->view); for (size_t i = 0; i < LENGTH(win->modes); i++) map_free(win->modes[i].bindings); marklist_release(&win->jumplist); @@ -212,16 +211,15 @@ static void window_free(Win *win) { } static void window_draw_colorcolumn(Win *win) { - View *view = win->view; - int cc = view->colorcolumn; + int cc = win->view.colorcolumn; if (cc <= 0) return; size_t lineno = 0; int line_cols = 0; /* Track the number of columns we've passed on each line */ bool line_cc_set = false; /* Has the colorcolumn attribute been set for this line yet */ - int width = view->width; + int width = win->view.width; - for (Line *l = view->topline; l; l = l->next) { + for (Line *l = win->view.topline; l; l = l->next) { if (l->lineno != lineno) { line_cols = 0; line_cc_set = false; @@ -243,19 +241,18 @@ static void window_draw_colorcolumn(Win *win) { static void window_draw_cursorline(Win *win) { Vis *vis = win->vis; - View *view = win->view; - enum UiOption options = UI_OPTIONS_GET(view->ui); + enum UiOption options = UI_OPTIONS_GET(win->view.ui); if (!(options & UI_OPTION_CURSOR_LINE)) return; if (vis->mode->visual || vis->win != win) return; - if (view->selection_count > 1) + if (win->view.selection_count > 1) return; - int width = view->width; - Selection *sel = view_selections_primary_get(view); + int width = win->view.width; + Selection *sel = view_selections_primary_get(&win->view); size_t lineno = sel->line->lineno; - for (Line *l = view->topline; l; l = l->next) { + for (Line *l = win->view.topline; l; l = l->next) { if (l->lineno == lineno) { for (int x = 0; x < width; x++) ui_window_style_set(win->ui, &l->cells[x], UI_STYLE_CURSOR_LINE); @@ -266,7 +263,7 @@ static void window_draw_cursorline(Win *win) { } static void window_draw_selection(Win *win, Selection *cur) { - View *view = win->view; + View *view = &win->view; Filerange sel = view_selections_get(cur); if (!text_range_valid(&sel)) return; @@ -301,7 +298,7 @@ static void window_draw_cursor_matching(Win *win, Selection *cur) { size_t pos_match = text_bracket_match_symbol(win->file->text, pos, "(){}[]\"'`", &limits); if (pos == pos_match) return; - if (!view_coord_get(win->view, pos_match, &line_match, NULL, &col_match)) + if (!view_coord_get(&win->view, pos_match, &line_match, NULL, &col_match)) return; ui_window_style_set(win->ui, &line_match->cells[col_match], UI_STYLE_SELECTION); } @@ -312,16 +309,15 @@ static void window_draw_cursor(Win *win, Selection *cur) { Line *line = cur->line; if (!line) return; - Selection *primary = view_selections_primary_get(win->view); + Selection *primary = view_selections_primary_get(&win->view); ui_window_style_set(win->ui, &line->cells[cur->col], primary == cur ? UI_STYLE_CURSOR_PRIMARY : UI_STYLE_CURSOR); window_draw_cursor_matching(win, cur); return; } static void window_draw_selections(Win *win) { - View *view = win->view; - Filerange viewport = VIEW_VIEWPORT_GET(view); - Selection *sel = view_selections_primary_get(view); + Filerange viewport = VIEW_VIEWPORT_GET(win->view); + Selection *sel = view_selections_primary_get(&win->view); for (Selection *s = view_selections_prev(sel); s; s = view_selections_prev(s)) { window_draw_selection(win, s); size_t pos = view_cursors_pos(s); @@ -341,7 +337,7 @@ static void window_draw_selections(Win *win) { } static void window_draw_eof(Win *win) { - View *view = win->view; + View *view = &win->view; if (view->width == 0) return; for (Line *l = view->lastline->next; l; l = l->next) { @@ -351,7 +347,7 @@ static void window_draw_eof(Win *win) { } void vis_window_draw(Win *win) { - if (!win->ui || !view_update(win->view)) + if (!win->ui || !view_update(&win->view)) return; Vis *vis = win->vis; vis_event_emit(vis, VIS_EVENT_WIN_HIGHLIGHT, win); @@ -369,7 +365,7 @@ void vis_window_draw(Win *win) { void vis_window_invalidate(Win *win) { for (Win *w = win->vis->windows; w; w = w->next) { if (w->file == win->file) - view_draw(w->view); + view_draw(&w->view); } } @@ -379,17 +375,20 @@ Win *window_new_file(Vis *vis, File *file, enum UiOption options) { return NULL; win->vis = vis; win->file = file; - win->view = view_new(file->text); + if (!view_init(&win->view, file->text)) { + free(win); + return NULL; + } win->expandtab = false; win->ui = ui_window_new(&vis->ui, win, options); - if (!win->view || !win->ui) { + if (!win->ui) { window_free(win); return NULL; } marklist_init(&win->jumplist, 32); mark_init(&win->saved_selections); file->refcount++; - view_options_set(win->view, UI_OPTIONS_GET(win->view->ui)); + view_options_set(&win->view, UI_OPTIONS_GET(win->view.ui)); if (vis->windows) vis->windows->prev = win; @@ -416,7 +415,7 @@ bool vis_window_reload(Win *win) { file_free(win->vis, win->file); file->refcount = 1; win->file = file; - view_reload(win->view, file->text); + view_reload(&win->view, file->text); return true; } @@ -428,7 +427,7 @@ bool vis_window_change_file(Win *win, const char* filename) { if (win->file) file_free(win->vis, win->file); win->file = file; - view_reload(win->view, file->text); + view_reload(&win->view, file->text); return true; } @@ -444,8 +443,8 @@ bool vis_window_split(Win *original) { map_copy(win->modes[i].bindings, original->modes[i].bindings); } win->file = original->file; - view_options_set(win->view, UI_OPTIONS_GET(original->view->ui)); - view_cursors_to(win->view->selection, view_cursor_get(original->view)); + view_options_set(&win->view, UI_OPTIONS_GET(original->view.ui)); + view_cursors_to(win->view.selection, view_cursor_get(&original->view)); win->vis->ui.doupdate = true; return true; } @@ -477,7 +476,7 @@ void vis_window_prev(Vis *vis) { void vis_draw(Vis *vis) { for (Win *win = vis->windows; win; win = win->next) - view_draw(win->view); + view_draw(&win->view); } void vis_redraw(Vis *vis) { @@ -671,7 +670,7 @@ void vis_insert_key(Vis *vis, const char *data, size_t len) { Win *win = vis->win; if (!win) return; - for (Selection *s = view_selections(win->view); s; s = view_selections_next(s)) { + for (Selection *s = view_selections(&win->view); s; s = view_selections_next(s)) { size_t pos = view_cursors_pos(s); vis_insert(vis, pos, data, len); view_cursors_scroll_to(s, pos + len); @@ -696,7 +695,7 @@ void vis_replace_key(Vis *vis, const char *data, size_t len) { Win *win = vis->win; if (!win) return; - for (Selection *s = view_selections(win->view); s; s = view_selections_next(s)) { + for (Selection *s = view_selections(&win->view); s; s = view_selections_next(s)) { size_t pos = view_cursors_pos(s); vis_replace(vis, pos, data, len); view_cursors_scroll_to(s, pos + len); @@ -737,7 +736,7 @@ void vis_do(Vis *vis) { return; File *file = win->file; Text *txt = file->text; - View *view = win->view; + View *view = &win->view; Action *a = &vis->action; int count = MAX(a->count, 1); @@ -1508,8 +1507,8 @@ void vis_insert_tab(Vis *vis) { return; } char spaces[9]; - int tabwidth = MIN(vis->win->view->tabwidth, LENGTH(spaces) - 1); - for (Selection *s = view_selections(win->view); s; s = view_selections_next(s)) { + int tabwidth = MIN(vis->win->view.tabwidth, LENGTH(spaces) - 1); + for (Selection *s = view_selections(&win->view); s; s = view_selections_next(s)) { size_t pos = view_cursors_pos(s); int width = text_line_width_get(win->file->text, pos); int count = tabwidth - (width % tabwidth); @@ -1564,9 +1563,8 @@ void vis_insert_nl(Vis *vis) { Win *win = vis->win; if (!win) return; - View *view = win->view; Text *txt = win->file->text; - for (Selection *s = view_selections(view); s; s = view_selections_next(s)) { + for (Selection *s = view_selections(&win->view); s; s = view_selections_next(s)) { size_t pos = view_cursors_pos(s); size_t newpos = vis_text_insert_nl(vis, txt, pos); /* This is a bit of a hack to fix cursor positioning when @@ -1882,5 +1880,5 @@ Text *vis_text(Vis *vis) { View *vis_view(Vis *vis) { Win *win = vis->win; - return win ? win->view : NULL; + return win ? &win->view : NULL; }