From 9658e4b3886fda4c481641c9e191deebf36aa40d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Mon, 26 Oct 2015 22:43:57 +0100 Subject: vis: make Vis an opaque type, hide implementaton details --- main.c | 68 +++++++++++++++++----------------- ui-curses.c | 10 ++--- vis.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------ vis.h | 91 ++-------------------------------------------- 4 files changed, 151 insertions(+), 137 deletions(-) diff --git a/main.c b/main.c index 6e86494..1745db9 100644 --- a/main.c +++ b/main.c @@ -1073,8 +1073,8 @@ static const char *repeat(Vis *vis, const char *keys, const Arg *arg) { } static const char *cursors_new(Vis *vis, const char *keys, const Arg *arg) { - View *view = vis->win->view; - Text *txt = vis->win->file->text; + View *view = vis_view(vis); + Text *txt = vis_text(vis); size_t pos = view_cursor_get(view); if (arg->i > 0) pos = text_line_down(txt, pos); @@ -1087,8 +1087,8 @@ static const char *cursors_new(Vis *vis, const char *keys, const Arg *arg) { } static const char *cursors_align(Vis *vis, const char *keys, const Arg *arg) { - View *view = vis->win->view; - Text *txt = vis->win->file->text; + View *view = vis_view(vis); + Text *txt = vis_text(vis); int mincol = INT_MAX; for (Cursor *c = view_cursors(view); c; c = view_cursors_next(c)) { size_t pos = view_cursors_pos(c); @@ -1105,7 +1105,7 @@ static const char *cursors_align(Vis *vis, const char *keys, const Arg *arg) { } static const char *cursors_clear(Vis *vis, const char *keys, const Arg *arg) { - View *view = vis->win->view; + View *view = vis_view(vis); if (view_cursors_count(view) > 1) view_cursors_clear(view); else @@ -1114,8 +1114,8 @@ static const char *cursors_clear(Vis *vis, const char *keys, const Arg *arg) { } static const char *cursors_select(Vis *vis, const char *keys, const Arg *arg) { - Text *txt = vis->win->file->text; - View *view = vis->win->view; + Text *txt = vis_text(vis); + View *view = vis_view(vis); for (Cursor *cursor = view_cursors(view); cursor; cursor = view_cursors_next(cursor)) { Filerange sel = view_cursors_selection_get(cursor); Filerange word = text_object_word(txt, view_cursors_pos(cursor)); @@ -1129,8 +1129,8 @@ static const char *cursors_select(Vis *vis, const char *keys, const Arg *arg) { } static const char *cursors_select_next(Vis *vis, const char *keys, const Arg *arg) { - Text *txt = vis->win->file->text; - View *view = vis->win->view; + Text *txt = vis_text(vis); + View *view = vis_view(vis); Cursor *cursor = view_cursor(view); Filerange sel = view_cursors_selection_get(cursor); if (!text_range_valid(&sel)) @@ -1156,7 +1156,7 @@ static const char *cursors_select_next(Vis *vis, const char *keys, const Arg *ar } static const char *cursors_select_skip(Vis *vis, const char *keys, const Arg *arg) { - View *view = vis->win->view; + View *view = vis_view(vis); Cursor *cursor = view_cursor(view); keys = cursors_select_next(vis, keys, arg); if (cursor != view_cursor(view)) @@ -1165,7 +1165,7 @@ static const char *cursors_select_skip(Vis *vis, const char *keys, const Arg *ar } static const char *cursors_remove(Vis *vis, const char *keys, const Arg *arg) { - View *view = vis->win->view; + View *view = vis_view(vis); view_cursors_dispose(view_cursor(view)); return keys; } @@ -1181,7 +1181,7 @@ static const char *replace(Vis *vis, const char *keys, const Arg *arg) { buffer_put(&vis->buffer_repeat, keys, len); */ vis_replace_key(vis, keys, len); - text_snapshot(vis->win->file->text); + text_snapshot(vis_text(vis)); return next; } @@ -1238,13 +1238,13 @@ static const char *textobj(Vis *vis, const char *keys, const Arg *arg) { } static const char *selection_end(Vis *vis, const char *keys, const Arg *arg) { - for (Cursor *c = view_cursors(vis->win->view); c; c = view_cursors_next(c)) + for (Cursor *c = view_cursors(vis_view(vis)); c; c = view_cursors_next(c)) view_cursors_selection_swap(c); return keys; } static const char *selection_restore(Vis *vis, const char *keys, const Arg *arg) { - for (Cursor *c = view_cursors(vis->win->view); c; c = view_cursors_next(c)) + for (Cursor *c = view_cursors(vis_view(vis)); c; c = view_cursors_next(c)) view_cursors_selection_restore(c); vis_mode_switch(vis, VIS_MODE_VISUAL); return keys; @@ -1282,7 +1282,7 @@ static const char *key2mark(Vis *vis, const char *keys, int *mark) { static const char *mark_set(Vis *vis, const char *keys, const Arg *arg) { int mark; keys = key2mark(vis, keys, &mark); - vis_mark_set(vis, mark, view_cursor_get(vis->win->view)); + vis_mark_set(vis, mark, view_cursor_get(vis_view(vis))); return keys; } @@ -1294,9 +1294,9 @@ static const char *mark_motion(Vis *vis, const char *keys, const Arg *arg) { } static const char *undo(Vis *vis, const char *keys, const Arg *arg) { - size_t pos = text_undo(vis->win->file->text); + size_t pos = text_undo(vis_text(vis)); if (pos != EPOS) { - View *view = vis->win->view; + View *view = vis_view(vis); if (view_cursors_count(view) == 1) view_cursor_to(view, pos); /* redraw all windows in case some display the same file */ @@ -1306,9 +1306,9 @@ static const char *undo(Vis *vis, const char *keys, const Arg *arg) { } static const char *redo(Vis *vis, const char *keys, const Arg *arg) { - size_t pos = text_redo(vis->win->file->text); + size_t pos = text_redo(vis_text(vis)); if (pos != EPOS) { - View *view = vis->win->view; + View *view = vis_view(vis); if (view_cursors_count(view) == 1) view_cursor_to(view, pos); /* redraw all windows in case some display the same file */ @@ -1318,9 +1318,9 @@ static const char *redo(Vis *vis, const char *keys, const Arg *arg) { } static const char *earlier(Vis *vis, const char *keys, const Arg *arg) { - size_t pos = text_earlier(vis->win->file->text, MAX(vis_count_get(vis), 1)); + size_t pos = text_earlier(vis_text(vis), MAX(vis_count_get(vis), 1)); if (pos != EPOS) { - view_cursor_to(vis->win->view, pos); + view_cursor_to(vis_view(vis), pos); /* redraw all windows in case some display the same file */ vis_draw(vis); } @@ -1328,9 +1328,9 @@ static const char *earlier(Vis *vis, const char *keys, const Arg *arg) { } static const char *later(Vis *vis, const char *keys, const Arg *arg) { - size_t pos = text_later(vis->win->file->text, MAX(vis_count_get(vis), 1)); + size_t pos = text_later(vis_text(vis), MAX(vis_count_get(vis), 1)); if (pos != EPOS) { - view_cursor_to(vis->win->view, pos); + view_cursor_to(vis_view(vis), pos); /* redraw all windows in case some display the same file */ vis_draw(vis); } @@ -1348,9 +1348,9 @@ static const char *insert_register(Vis *vis, const char *keys, const Arg *arg) { keys = key2register(vis, keys, ®id); Register *reg = vis_register_get(vis, regid); if (reg) { - int pos = view_cursor_get(vis->win->view); + int pos = view_cursor_get(vis_view(vis)); vis_insert(vis, pos, reg->data, reg->len); - view_cursor_to(vis->win->view, pos + reg->len); + view_cursor_to(vis_view(vis), pos + reg->len); } return keys; } @@ -1438,9 +1438,9 @@ static const char *insert_verbatim(Vis *vis, const char *keys, const Arg *arg) { } if (len > 0) { - size_t pos = view_cursor_get(vis->win->view); + size_t pos = view_cursor_get(vis_view(vis)); vis_insert(vis, pos, buf, len); - view_cursor_to(vis->win->view, pos + len); + view_cursor_to(vis_view(vis), pos + len); } return keys; } @@ -1454,10 +1454,10 @@ static int argi2lines(Vis *vis, const Arg *arg) { switch (arg->i) { case -PAGE: case +PAGE: - return view_height_get(vis->win->view); + return view_height_get(vis_view(vis)); case -PAGE_HALF: case +PAGE_HALF: - return view_height_get(vis->win->view)/2; + return view_height_get(vis_view(vis))/2; default: if (vis_count_get(vis) > 0) return vis_count_get(vis); @@ -1467,17 +1467,17 @@ static int argi2lines(Vis *vis, const Arg *arg) { static const char *wscroll(Vis *vis, const char *keys, const Arg *arg) { if (arg->i >= 0) - view_scroll_down(vis->win->view, argi2lines(vis, arg)); + view_scroll_down(vis_view(vis), argi2lines(vis, arg)); else - view_scroll_up(vis->win->view, argi2lines(vis, arg)); + view_scroll_up(vis_view(vis), argi2lines(vis, arg)); return keys; } static const char *wslide(Vis *vis, const char *keys, const Arg *arg) { if (arg->i >= 0) - view_slide_down(vis->win->view, argi2lines(vis, arg)); + view_slide_down(vis_view(vis), argi2lines(vis, arg)); else - view_slide_up(vis->win->view, argi2lines(vis, arg)); + view_slide_up(vis_view(vis), argi2lines(vis, arg)); return keys; } @@ -1487,7 +1487,7 @@ static const char *call(Vis *vis, const char *keys, const Arg *arg) { } static const char *window(Vis *vis, const char *keys, const Arg *arg) { - arg->w(vis->win->view); + arg->w(vis_view(vis)); return keys; } diff --git a/ui-curses.c b/ui-curses.c index 2871e66..3bc7c2b 100644 --- a/ui-curses.c +++ b/ui-curses.c @@ -608,7 +608,7 @@ static void ui_window_draw_status(UiWin *w) { UiCurses *uic = win->ui; Vis *vis = uic->vis; bool focused = uic->selwin == win; - const char *filename = win->file->name; + const char *filename = vis_file_name(win->file); const char *status = vis_mode_status(vis); CursorPos pos = view_cursor_getpos(win->view); wattrset(win->winstatus, focused ? A_REVERSE|A_BOLD : A_REVERSE); @@ -616,7 +616,7 @@ static void ui_window_draw_status(UiWin *w) { mvwprintw(win->winstatus, 0, 0, "%s %s %s %s", focused && status ? status : "", filename ? filename : "[No Name]", - text_modified(win->file->text) ? "[+]" : "", + text_modified(vis_file_text(win->file)) ? "[+]" : "", vis_macro_recording(vis) ? "recording": ""); char buf[win->width + 1]; int len = snprintf(buf, win->width, "%zd, %zd", pos.line, pos.col); @@ -660,7 +660,7 @@ static void ui_window_reload(UiWin *w, File *file) { UiCursesWin *win = (UiCursesWin*)w; win->file = file; win->sidebar_width = 0; - view_reload(win->view, file->text); + view_reload(win->view, vis_file_text(file)); ui_window_draw(w); } @@ -898,7 +898,7 @@ static void ui_prompt(Ui *ui, const char *title, const char *data) { if (uic->prompt_title[0]) return; size_t len = strlen(data); - Text *text = uic->prompt_win->file->text; + Text *text = vis_file_text(uic->prompt_win->file); strncpy(uic->prompt_title, title, sizeof(uic->prompt_title)-1); while (text_undo(text) != EPOS); text_insert(text, 0, data, len); @@ -911,7 +911,7 @@ static char *ui_prompt_input(Ui *ui) { UiCurses *uic = (UiCurses*)ui; if (!uic->prompt_win) return NULL; - Text *text = uic->prompt_win->file->text; + Text *text = vis_file_text(uic->prompt_win->file); char *buf = malloc(text_size(text) + 1); if (!buf) return NULL; diff --git a/vis.c b/vis.c index 4200bb9..609176d 100644 --- a/vis.c +++ b/vis.c @@ -38,8 +38,12 @@ #include "text-util.h" #include "text-motions.h" #include "text-objects.h" +#include "text-regex.h" #include "util.h" #include "map.h" +#include "ring-buffer.h" +#include "macro.h" + /* a mode contains a set of key bindings which are currently valid. * @@ -51,6 +55,7 @@ * if no binding is found, mode->input(...) is called and the user entered * keys are passed as argument. this is used to change the document content. */ +typedef struct Mode Mode; struct Mode { Mode *parent; /* if no match is found in this mode, search will continue there */ Map *bindings; @@ -67,8 +72,6 @@ struct Mode { }; -/* TODO make part of struct Vis? */ -static Mode vis_modes[VIS_MODE_LAST]; typedef struct { int count; /* how many times should the command be executed? */ @@ -79,11 +82,11 @@ typedef struct { const Arg *arg; /* arbitrary arguments */ } OperatorContext; -struct Operator { +typedef struct { size_t (*func)(Vis*, Text*, OperatorContext*); /* operator logic, returns new cursor position */ -}; +} Operator; -struct Movement { +typedef struct { /* TODO: merge types / use union to save space */ size_t (*cur)(Cursor*); /* a movement based on current window content from view.h */ size_t (*txt)(Text*, size_t pos); /* a movement form text-motions.h */ @@ -100,16 +103,94 @@ struct Movement { JUMP = 1 << 5, } type; int count; -}; +} Movement; -struct TextObject { +typedef struct { Filerange (*range)(Text*, size_t pos); /* a text object from text-objects.h */ enum { INNER, OUTER, } type; +} TextObject; + +typedef struct { /** collects all information until an operator is executed */ + int count; + enum VisMotionType type; + const Operator *op; + const Movement *movement; + const TextObject *textobj; + Register *reg; + enum VisMark mark; + Arg arg; +} Action; + +struct File { + Text *text; + const char *name; + volatile sig_atomic_t truncated; + bool is_stdin; + struct stat stat; + int refcount; + Mark marks[VIS_MARK_INVALID]; + File *next, *prev; +}; + +typedef struct { + time_t state; /* state of the text, used to invalidate change list */ + size_t index; /* #number of changes */ + size_t pos; /* where the current change occured */ +} ChangeList; + +struct Win { + Vis *editor; /* editor instance to which this window belongs */ + UiWin *ui; + File *file; /* file being displayed in this window */ + View *view; /* currently displayed part of underlying text */ + ViewEvent events; + RingBuffer *jumplist; /* LRU jump management */ + ChangeList changelist; /* state for iterating through least recently changes */ + Win *prev, *next; /* neighbouring windows */ }; +struct Vis { + Ui *ui; + File *files; + Win *windows; /* list of windows */ + Win *win; /* currently active window */ + Syntax *syntaxes; /* NULL terminated array of syntax definitions */ + Register registers[VIS_REGISTER_INVALID]; /* register used for copy and paste */ + Macro macros[VIS_MACRO_INVALID]; /* recorded macros */ + Macro *recording, *last_recording;/* currently and least recently recorded macro */ + Win *prompt; /* 1-line height window to get user input */ + Win *prompt_window; /* window which was focused before prompt was shown */ + char prompt_type; /* command ':' or search '/','?' prompt */ + Regex *search_pattern; /* last used search pattern */ + char search_char[8]; /* last used character to search for via 'f', 'F', 't', 'T' */ + int last_totill; /* last to/till movement used for ';' and ',' */ + int tabwidth; /* how many spaces should be used to display a tab */ + bool expandtab; /* whether typed tabs should be converted to spaces */ + bool autoindent; /* whether indentation should be copied from previous line on newline */ + Map *cmds; /* ":"-commands, used for unique prefix queries */ + Map *options; /* ":set"-options */ + Buffer buffer_repeat; /* holds data to repeat last insertion/replacement */ + Buffer input_queue; /* holds pending input keys */ + + Action action; /* current action which is in progress */ + Action action_prev; /* last operator action used by the repeat '.' key */ + Mode *mode; /* currently active mode, used to search for keybindings */ + Mode *mode_prev; /* previsouly active user mode */ + Mode *mode_before_prompt; /* user mode which was active before entering prompt */ + volatile bool running; /* exit main loop once this becomes false */ + int exit_status; + volatile sig_atomic_t cancel_filter; /* abort external command */ + volatile sig_atomic_t sigbus; + sigjmp_buf sigbus_jmpbuf; + Map *actions; /* built in special editor keys / commands */ +}; + +/* TODO make part of struct Vis? */ +static Mode vis_modes[VIS_MODE_LAST]; + enum CmdOpt { /* option flags for command definitions */ CMD_OPT_NONE, /* no option (default value) */ CMD_OPT_FORCE, /* whether the command can be forced by appending '!' */ @@ -2526,7 +2607,7 @@ bool vis_cmd(Vis *vis, const char *cmdline) { return true; } -bool vis_prompt_cmd(Vis *vis, char type, const char *cmd) { +static bool prompt_cmd(Vis *vis, char type, const char *cmd) { if (!cmd || !cmd[0]) return true; switch (type) { @@ -2702,7 +2783,7 @@ static void vis_args(Vis *vis, int argc, char *argv[]) { } else if (!vis_window_new(vis, argv[i])) { vis_die(vis, "Can not load `%s': %s\n", argv[i], strerror(errno)); } else if (cmd) { - vis_prompt_cmd(vis, cmd[0], cmd+1); + prompt_cmd(vis, cmd[0], cmd+1); cmd = NULL; } } @@ -2730,7 +2811,7 @@ static void vis_args(Vis *vis, int argc, char *argv[]) { vis_die(vis, "Can not create empty buffer\n"); } if (cmd) - vis_prompt_cmd(vis, cmd[0], cmd+1); + prompt_cmd(vis, cmd[0], cmd+1); } } @@ -3089,8 +3170,24 @@ void vis_prompt_enter(Vis *vis) { * on vis->win. */ mode_set(vis, vis->mode_before_prompt); - if (s && *s && vis_prompt_cmd(vis, vis->prompt_type, s) && vis->running) + if (s && *s && prompt_cmd(vis, vis->prompt_type, s) && vis->running) vis_mode_switch(vis, VIS_MODE_NORMAL); free(s); vis_draw(vis); } + +Text *vis_text(Vis *vis) { + return vis->win->file->text; +} + +View *vis_view(Vis *vis) { + return vis->win->view; +} + +Text *vis_file_text(File *file) { + return file->text; +} + +const char *vis_file_name(File *file) { + return file->name; +} \ No newline at end of file diff --git a/vis.h b/vis.h index cb578ae..3bafba0 100644 --- a/vis.h +++ b/vis.h @@ -13,12 +13,7 @@ typedef struct Win Win; #include "ui.h" #include "view.h" #include "register.h" -#include "macro.h" #include "syntax.h" -#include "ring-buffer.h" -#include "map.h" -#include "text-regex.h" - typedef union { bool b; @@ -323,8 +318,6 @@ void vis_repeat(Vis*); /* execute a :-command (call without without leading ':') */ bool vis_cmd(Vis*, const char *cmd); -/* TODO temporary. type is either '/', '?', '+', or ':' */ -bool vis_prompt_cmd(Vis *vis, char type, const char *cmd); const char *vis_key_next(Vis*, const char *keys); const char *vis_keys(Vis*, const char *input); @@ -332,85 +325,9 @@ const char *vis_keys(Vis*, const char *input); bool vis_signal_handler(Vis*, int signum, const siginfo_t *siginfo, const void *context); -/* TODO: temporary */ -typedef struct Mode Mode; -typedef struct Operator Operator; -typedef struct Movement Movement; -typedef struct TextObject TextObject; - -typedef struct { /** collects all information until an operator is executed */ - int count; - enum VisMotionType type; - const Operator *op; - const Movement *movement; - const TextObject *textobj; - Register *reg; - enum VisMark mark; - Arg arg; -} Action; - -struct File { - Text *text; - const char *name; - volatile sig_atomic_t truncated; - bool is_stdin; - struct stat stat; - int refcount; - Mark marks[VIS_MARK_INVALID]; - File *next, *prev; -}; - -typedef struct { - time_t state; /* state of the text, used to invalidate change list */ - size_t index; /* #number of changes */ - size_t pos; /* where the current change occured */ -} ChangeList; - -struct Win { - Vis *editor; /* editor instance to which this window belongs */ - UiWin *ui; - File *file; /* file being displayed in this window */ - View *view; /* currently displayed part of underlying text */ - ViewEvent events; - RingBuffer *jumplist; /* LRU jump management */ - ChangeList changelist; /* state for iterating through least recently changes */ - Win *prev, *next; /* neighbouring windows */ -}; - -struct Vis { - Ui *ui; - File *files; - Win *windows; /* list of windows */ - Win *win; /* currently active window */ - Syntax *syntaxes; /* NULL terminated array of syntax definitions */ - Register registers[VIS_REGISTER_INVALID]; /* register used for copy and paste */ - Macro macros[VIS_MACRO_INVALID]; /* recorded macros */ - Macro *recording, *last_recording;/* currently and least recently recorded macro */ - Win *prompt; /* 1-line height window to get user input */ - Win *prompt_window; /* window which was focused before prompt was shown */ - char prompt_type; /* command ':' or search '/','?' prompt */ - Regex *search_pattern; /* last used search pattern */ - char search_char[8]; /* last used character to search for via 'f', 'F', 't', 'T' */ - int last_totill; /* last to/till movement used for ';' and ',' */ - int tabwidth; /* how many spaces should be used to display a tab */ - bool expandtab; /* whether typed tabs should be converted to spaces */ - bool autoindent; /* whether indentation should be copied from previous line on newline */ - Map *cmds; /* ":"-commands, used for unique prefix queries */ - Map *options; /* ":set"-options */ - Buffer buffer_repeat; /* holds data to repeat last insertion/replacement */ - Buffer input_queue; /* holds pending input keys */ - - Action action; /* current action which is in progress */ - Action action_prev; /* last operator action used by the repeat '.' key */ - Mode *mode; /* currently active mode, used to search for keybindings */ - Mode *mode_prev; /* previsouly active user mode */ - Mode *mode_before_prompt; /* user mode which was active before entering prompt */ - volatile bool running; /* exit main loop once this becomes false */ - int exit_status; - volatile sig_atomic_t cancel_filter; /* abort external command */ - volatile sig_atomic_t sigbus; - sigjmp_buf sigbus_jmpbuf; - Map *actions; /* built in special editor keys / commands */ -}; +Text *vis_text(Vis*); +View *vis_view(Vis*); +Text *vis_file_text(File*); +const char *vis_file_name(File*); #endif -- cgit v1.2.3