diff options
| author | Randy Palamar <palamar@ualberta.ca> | 2023-07-27 16:53:49 -0600 |
|---|---|---|
| committer | Randy Palamar <palamar@ualberta.ca> | 2023-08-24 20:43:48 -0600 |
| commit | 3a93220f7589ad4a198a0bc654682f696673a368 (patch) | |
| tree | ff05d73fecb8ca9c7ebb3bc0b5d6065fc71ede71 | |
| parent | 09ba77aa561cae40234167890c4383b92f8b94d8 (diff) | |
| download | vis-3a93220f7589ad4a198a0bc654682f696673a368.tar.gz vis-3a93220f7589ad4a198a0bc654682f696673a368.tar.xz | |
Lua API: access and set all available options
The first point of this commit is to allow all options to be read from
lua. This has a number of uses for plugin writers. They are grouped into
a couple of tables depending on what they control:
`vis.options`: table with global configuration
`win.options`: table with window specific configuration
The second point is to allow you to set all these options as if they
were simply lua variables. Technically this is already possible by
using `vis:command("set ...")` but personally I think this interface
is cleaner. Note that this already possible for some things like the
current mode (eg. vis.mode = vis.modes.VISUAL). Examples:
`vis.options.ai = true`
`win.options.brk = " !?."`
`win.options = { showeof = true, showtabs = true }
There are a number of related issues and pull requests:
closes #803: Lua API: let plugins read the values of options
closes #812: Window layout property
supersedes/closes #717: Add ability to access tabwidth from Lua
supersedes/closes #1066: expose UI layout and allow it to be set from lua API
| -rw-r--r-- | ui-terminal.c | 5 | ||||
| -rw-r--r-- | ui.h | 1 | ||||
| -rw-r--r-- | view.c | 8 | ||||
| -rw-r--r-- | view.h | 2 | ||||
| -rw-r--r-- | vis-cmds.c | 24 | ||||
| -rw-r--r-- | vis-lua.c | 416 | ||||
| -rw-r--r-- | vis.h | 4 |
7 files changed, 433 insertions, 27 deletions
diff --git a/ui-terminal.c b/ui-terminal.c index 27afb26..babc5a6 100644 --- a/ui-terminal.c +++ b/ui-terminal.c @@ -678,6 +678,11 @@ err: return false; } +enum UiLayout ui_layout_get(Ui *ui) { + UiTerm *tui = (UiTerm *)ui; + return tui->layout; +} + Ui *ui_term_new(void) { size_t styles_size = UI_STYLE_MAX * sizeof(CellStyle); CellStyle *styles = calloc(1, styles_size); @@ -117,5 +117,6 @@ struct UiWin { }; bool is_default_color(CellColor c); +enum UiLayout ui_layout_get(Ui *ui); #endif @@ -910,6 +910,10 @@ void view_wrapcolumn_set(View *view, int col) { 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) @@ -919,6 +923,10 @@ 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) @@ -359,7 +359,9 @@ 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); @@ -129,7 +129,7 @@ static void windows_arrange(Vis *vis, enum UiLayout layout) { vis->ui->arrange(vis->ui, layout); } -static void tabwidth_set(Vis *vis, int tabwidth) { +void vis_tabwidth_set(Vis *vis, int tabwidth) { if (tabwidth < 1 || tabwidth > 8) return; for (Win *win = vis->windows; win; win = win->next) @@ -137,6 +137,16 @@ static void tabwidth_set(Vis *vis, int tabwidth) { vis->tabwidth = tabwidth; } +void vis_shell_set(Vis *vis, const char *new_shell) { + char *shell = strdup(new_shell); + if (!shell) { + vis_info_show(vis, "Failed to change shell"); + } else { + free(vis->shell); + vis->shell = shell; + } +} + /* parse human-readable boolean value in s. If successful, store the result in * outval and return true. Else return false and leave outval alone. */ static bool parse_bool(const char *s, bool *outval) { @@ -241,16 +251,8 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Select switch (opt_index) { case OPTION_SHELL: - { - char *shell = strdup(arg.s); - if (!shell) { - vis_info_show(vis, "Failed to change shell"); - return false; - } - free(vis->shell); - vis->shell = shell; + vis_shell_set(vis, arg.s); break; - } case OPTION_ESCDELAY: { TermKey *termkey = vis->ui->termkey_get(vis->ui); @@ -264,7 +266,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: - tabwidth_set(vis, arg.i); + vis_tabwidth_set(vis, arg.i); break; case OPTION_SHOW_SPACES: case OPTION_SHOW_TABS: @@ -31,6 +31,8 @@ #endif #define VIS_LUA_TYPE_VIS "vis" +#define VIS_LUA_TYPE_WIN_OPTS "winoptions" +#define VIS_LUA_TYPE_VIS_OPTS "visoptions" #define VIS_LUA_TYPE_FILE "file" #define VIS_LUA_TYPE_TEXT "text" #define VIS_LUA_TYPE_MARK "mark" @@ -1343,7 +1345,7 @@ static int pipe_func(lua_State *L) { } const char *cmd = luaL_checkstring(L, cmd_idx); bool fullscreen = lua_isboolean(L, cmd_idx + 1) && lua_toboolean(L, cmd_idx + 1); - + if (!file) return luaL_error(L, "vis:pipe(cmd = '%s'): win not open, file can't be nil", cmd); @@ -1454,6 +1456,11 @@ static int vis_index(lua_State *L) { return 1; } + if (strcmp(key, "options") == 0) { + obj_ref_new(L, &vis->options, VIS_LUA_TYPE_VIS_OPTS); + return 1; + } + if (strcmp(key, "ui") == 0) { obj_ref_new(L, vis->ui, VIS_LUA_TYPE_UI); return 1; @@ -1463,6 +1470,38 @@ static int vis_index(lua_State *L) { return index_common(L); } +static int vis_options_assign(Vis *vis, lua_State *L, const char *key, int next) { + if (strcmp(key, "autoindent") == 0 || strcmp(key, "ai") == 0) { + vis->autoindent = lua_toboolean(L, 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_set_waittime(tk, luaL_checkint(L, next)); + } else if (strcmp(key, "expandtab") == 0 || strcmp(key, "et") == 0) { + vis->expandtab = lua_toboolean(L, next); + } else if (strcmp(key, "ignorecase") == 0 || strcmp(key, "ic") == 0) { + vis->ignorecase = lua_toboolean(L, next); + } else if (strcmp(key, "loadmethod") == 0) { + if (!lua_isstring(L, next)) + return newindex_common(L); + const char *lm = lua_tostring(L, next); + if (strcmp(lm, "auto") == 0) + vis->load_method = TEXT_LOAD_AUTO; + else if (strcmp(lm, "read") == 0) + vis->load_method = TEXT_LOAD_READ; + else if (strcmp(lm, "mmap") == 0) + vis->load_method = TEXT_LOAD_MMAP; + } else if (strcmp(key, "shell") == 0) { + if (!lua_isstring(L, next)) + return newindex_common(L); + vis_shell_set(vis, lua_tostring(L, next)); + } else if (strcmp(key, "tabwidth") == 0 || strcmp(key, "tw") == 0) { + vis_tabwidth_set(vis, luaL_checkint(L, next)); + } + return 0; +} + static int vis_newindex(lua_State *L) { Vis *vis = obj_ref_check(L, 1, "vis"); if (lua_isstring(L, 2)) { @@ -1501,6 +1540,25 @@ static int vis_newindex(lua_State *L) { vis_mark(vis, vis_mark_from(vis, name[0])); return 0; } + + if (strcmp(key, "options") == 0 && lua_istable(L, 3)) { + int ret = 0; + /* since we don't know which keys are in the table we push + * a nil then use lua_next() to remove it and push the + * table's key-value pairs to the stack. these can then be + * used to assign options + */ + lua_pushnil(L); + while (lua_next(L, 3)) { + if (lua_isstring(L, 4)) + ret += vis_options_assign(vis, L, lua_tostring(L, 4), 5); + else + ret += newindex_common(L); + lua_pop(L, 1); + } + lua_pop(L, 1); + return ret; + } } return newindex_common(L); } @@ -1537,8 +1595,126 @@ static const struct luaL_Reg vis_lua[] = { { NULL, NULL }, }; +/*** + * Vis Options + * @table options + * @tfield[opt=false] boolean autoindent {ai} + * @tfield[opt=false] boolean changecolors + * @tfield[opt=50] int escdelay + * @tfield[opt=false] boolean expandtab {et} + * @tfield[opt=false] boolean ignorecase {ic} + * @tfield[opt="auto"] string loadmethod `"auto"`, `"read"`, or `"mmap"`. + * @tfield[opt="/bin/sh"] string shell + * @tfield[opt=8] int tabwidth {tw} + */ + +static int vis_options_index(lua_State *L) { + Vis *vis = obj_ref_check_containerof(L, 1, VIS_LUA_TYPE_VIS_OPTS, offsetof(Vis, options)); + if (!vis) + return -1; + if (lua_isstring(L, 2)) { + const char *key = lua_tostring(L, 2); + if (strcmp(key, "autoindent") == 0 || strcmp(key, "ai") == 0) { + lua_pushboolean(L, vis->autoindent); + return 1; + } else if (strcmp(key, "changecolors") == 0) { + lua_pushboolean(L, vis->change_colors); + return 1; + } else if (strcmp(key, "escdelay") == 0) { + TermKey *tk = vis->ui->termkey_get(vis->ui); + lua_pushunsigned(L, termkey_get_waittime(tk)); + return 1; + } else if (strcmp(key, "expandtab") == 0 || strcmp(key, "et") == 0) { + lua_pushboolean(L, vis->expandtab); + return 1; + } else if (strcmp(key, "ignorecase") == 0 || strcmp(key, "ic") == 0) { + lua_pushboolean(L, vis->ignorecase); + return 1; + } else if (strcmp(key, "loadmethod") == 0) { + switch (vis->load_method) { + case TEXT_LOAD_AUTO: + lua_pushstring(L, "auto"); + break; + case TEXT_LOAD_READ: + lua_pushstring(L, "read"); + break; + case TEXT_LOAD_MMAP: + lua_pushstring(L, "mmap"); + break; + } + return 1; + } else if (strcmp(key, "shell") == 0) { + lua_pushstring(L, vis->shell); + return 1; + } else if (strcmp(key, "tabwidth") == 0 || strcmp(key, "tw") == 0) { + lua_pushinteger(L, vis->tabwidth); + return 1; + } + } + return index_common(L); +} + +static int vis_options_newindex(lua_State *L) { + Vis *vis = obj_ref_check_containerof(L, 1, VIS_LUA_TYPE_VIS_OPTS, offsetof(Vis, options)); + if (!vis) + return 0; + if (lua_isstring(L, 2)) + return vis_options_assign(vis, L, lua_tostring(L, 2), 3); + return newindex_common(L); +} + +static const struct luaL_Reg vis_option_funcs[] = { + { "__index", vis_options_index }, + { "__newindex", vis_options_newindex}, + { NULL, NULL }, +}; + +/*** + * The user interface. + * + * @type Ui + */ +/*** + * Number of available colors. + * @tfield int colors + */ +/*** + * Current layout. + * @tfield layouts layout current window layout. + */ + +static int ui_index(lua_State *L) { + Ui *ui = obj_ref_check(L, 1, VIS_LUA_TYPE_UI); + + if (lua_isstring(L, 2)) { + const char *key = lua_tostring(L, 2); + + if (strcmp(key, "layout") == 0) { + lua_pushunsigned(L, ui_layout_get(ui)); + return 1; + } + } + + return index_common(L); +} + +static int ui_newindex(lua_State *L) { + Ui *ui = obj_ref_check(L, 1, VIS_LUA_TYPE_UI); + + if (lua_isstring(L, 2)) { + const char *key = lua_tostring(L, 2); + + if (strcmp(key, "layout") == 0) { + ui->arrange(ui, luaL_checkint(L, 3)); + return 0; + } + } + return newindex_common(L); +} + static const struct luaL_Reg ui_funcs[] = { - { "__index", index_common }, + { "__index", ui_index }, + { "__newindex", ui_newindex }, { NULL, NULL }, }; @@ -1677,11 +1853,98 @@ static int window_index(lua_State *L) { obj_ref_new(L, &win->saved_selections, VIS_LUA_TYPE_MARKS); return 1; } + if (strcmp(key, "options") == 0) { + obj_ref_new(L, &win->view, VIS_LUA_TYPE_WIN_OPTS); + return 1; + } } return index_common(L); } +static int window_options_assign(Win *win, lua_State *L, const char *key, int next) { + enum UiOption flags = view_options_get(win->view); + if (strcmp(key, "breakat") == 0 || strcmp(key, "brk") == 0) { + 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)); + } 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); + } 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); + } 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); + } 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); + } 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); + } 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); + } 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); + } else if (strcmp(key, "wrapcolumn") == 0 || strcmp(key, "wc") == 0) { + view_wrapcolumn_set(win->view, luaL_checkint(L, next)); + } + return 0; +} + +static int window_newindex(lua_State *L) { + Win *win = obj_ref_check(L, 1, VIS_LUA_TYPE_WINDOW); + + if (lua_isstring(L, 2)) { + const char *key = lua_tostring(L, 2); + if (strcmp(key, "options") == 0 && lua_istable(L, 3)) { + int ret = 0; + /* since we don't know which keys are in the table we push + * a nil then use lua_next() to remove it and push the + * table's key-value pairs to the stack. these can then be + * used to assign options + */ + lua_pushnil(L); + while (lua_next(L, 3)) { + if (lua_isstring(L, 4)) + ret += window_options_assign(win, L, lua_tostring(L, 4), 5); + else + ret += newindex_common(L); + lua_pop(L, 1); + } + lua_pop(L, 1); + return ret; + } + } + + return newindex_common(L); +} + static int window_selections_iterator_next(lua_State *L) { Selection **handle = lua_touserdata(L, lua_upvalueindex(1)); if (!*handle) @@ -1834,7 +2097,7 @@ static int window_close(lua_State *L) { static const struct luaL_Reg window_funcs[] = { { "__index", window_index }, - { "__newindex", newindex_common }, + { "__newindex", window_newindex }, { "selections_iterator", window_selections_iterator }, { "map", window_map }, { "unmap", window_unmap }, @@ -1846,6 +2109,77 @@ static const struct luaL_Reg window_funcs[] = { { NULL, NULL }, }; +/*** + * Window Options + * @table options + * @tfield[opt=""] string breakat {brk} + * @tfield[opt=0] int colorcolumn {cc} + * @tfield[opt=false] boolean cursorline {cul} + * @tfield[opt=false] boolean numbers {nu} + * @tfield[opt=false] boolean relativenumbers {rnu} + * @tfield[opt=true] boolean showeof + * @tfield[opt=false] boolean shownewlines + * @tfield[opt=false] boolean showspaces + * @tfield[opt=false] boolean showtabs + * @tfield[opt=0] int wrapcolumn {wc} + */ + +static int window_options_index(lua_State *L) { + Win *win = obj_ref_check_containerof(L, 1, VIS_LUA_TYPE_WIN_OPTS, offsetof(Win, view)); + if (!win) + return -1; + 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)); + return 1; + } else if (strcmp(key, "colorcolumn") == 0 || strcmp(key, "cc") == 0) { + lua_pushunsigned(L, view_colorcolumn_get(win->view)); + return 1; + } else if (strcmp(key, "cursorline") == 0 || strcmp(key, "cul") == 0) { + lua_pushboolean(L, view_options_get(win->view) & UI_OPTION_CURSOR_LINE); + 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); + 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); + return 1; + } else if (strcmp(key, "showeof") == 0) { + lua_pushboolean(L, view_options_get(win->view) & UI_OPTION_SYMBOL_EOF); + return 1; + } else if (strcmp(key, "shownewlines") == 0) { + lua_pushboolean(L, view_options_get(win->view) & UI_OPTION_SYMBOL_EOL); + return 1; + } else if (strcmp(key, "showspaces") == 0) { + lua_pushboolean(L, view_options_get(win->view) & UI_OPTION_SYMBOL_SPACE); + return 1; + } else if (strcmp(key, "showtabs") == 0) { + lua_pushboolean(L, view_options_get(win->view) & UI_OPTION_SYMBOL_TAB); + return 1; + } else if (strcmp(key, "wrapcolumn") == 0 || strcmp(key, "wc") == 0) { + lua_pushunsigned(L, view_wrapcolumn_get(win->view)); + return 1; + } + } + return index_common(L); +} + +static int window_options_newindex(lua_State *L) { + Win *win = obj_ref_check_containerof(L, 1, VIS_LUA_TYPE_WIN_OPTS, offsetof(Win, view)); + if (!win) + return 0; + if (lua_isstring(L, 2)) + return window_options_assign(win, L, lua_tostring(L, 2), 3); + return newindex_common(L); +} + +static const struct luaL_Reg window_option_funcs[] = { + { "__index", window_options_index }, + { "__newindex", window_options_newindex}, + { NULL, NULL }, +}; + 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); @@ -2111,6 +2445,10 @@ static const struct luaL_Reg window_selection_funcs[] = { * end */ /*** + * File save method + * @tfield[opt="auto"] string savemethod `"auto"`, `"atomic"`, or `"inplace"`. + */ +/*** * File size in bytes. * @tfield int size the current file size in bytes */ @@ -2157,6 +2495,21 @@ static int file_index(lua_State *L) { lua_pushunsigned(L, stat.st_mode & 0777); return 1; } + + if (strcmp(key, "savemethod") == 0) { + switch (file->save_method) { + case TEXT_SAVE_AUTO: + lua_pushstring(L, "auto"); + break; + case TEXT_SAVE_ATOMIC: + lua_pushstring(L, "atomic"); + break; + case TEXT_SAVE_INPLACE: + lua_pushstring(L, "inplace"); + break; + } + return 1; + } } return index_common(L); @@ -2178,6 +2531,19 @@ static int file_newindex(lua_State *L) { } return 0; } + + if (strcmp(key, "savemethod") == 0) { + if (!lua_isstring(L, 3)) + return newindex_common(L); + const char *sm = lua_tostring(L, 3); + if (strcmp(sm, "auto") == 0) + file->save_method = TEXT_SAVE_AUTO; + else if (strcmp(sm, "atomic") == 0) + file->save_method = TEXT_SAVE_ATOMIC; + else if (strcmp(sm, "inplace") == 0) + file->save_method = TEXT_SAVE_INPLACE; + return 0; + } } return newindex_common(L); @@ -2499,16 +2865,6 @@ static const struct luaL_Reg window_marks_funcs[] = { }; /*** - * The user interface. - * - * @type Ui - */ -/*** - * Number of available colors. - * @tfield int colors - */ - -/*** * A file range. * * For a valid range `start <= finish` holds. @@ -2525,6 +2881,18 @@ static const struct luaL_Reg window_marks_funcs[] = { */ /*** + * Layouts. + * @section Layouts + */ + +/*** + * Layout Constants. + * @table layouts + * @tfield int HORIZONTAL + * @tfield int VERTICAL + */ + +/*** * Modes. * @section Modes */ @@ -2856,6 +3224,9 @@ void vis_lua_init(Vis *vis) { lua_setfield(L, -2, styles[i].name); } + obj_type_new(L, VIS_LUA_TYPE_WIN_OPTS); + luaL_setfuncs(L, window_option_funcs, 0); + obj_type_new(L, VIS_LUA_TYPE_MARK); obj_type_new(L, VIS_LUA_TYPE_MARKS); lua_pushlightuserdata(L, vis); @@ -2870,6 +3241,19 @@ void vis_lua_init(Vis *vis) { luaL_setfuncs(L, ui_funcs, 0); lua_pushunsigned(L, vis->ui->colors(vis->ui)); lua_setfield(L, -2, "colors"); + lua_newtable(L); + static const struct { + enum UiLayout id; + const char *name; + } layouts[] = { + { UI_LAYOUT_HORIZONTAL, "HORIZONTAL" }, + { UI_LAYOUT_VERTICAL, "VERTICAL" }, + }; + for (size_t i = 0; i < LENGTH(layouts); i++) { + lua_pushunsigned(L, layouts[i].id); + lua_setfield(L, -2, layouts[i].name); + } + lua_setfield(L, -2, "layouts"); obj_type_new(L, VIS_LUA_TYPE_REGISTERS); lua_pushlightuserdata(L, vis); @@ -2884,7 +3268,6 @@ void vis_lua_init(Vis *vis) { lua_setfield(L, -2, "VERSION"); lua_newtable(L); - static const struct { enum VisMode id; const char *name; @@ -2896,14 +3279,15 @@ void vis_lua_init(Vis *vis) { { VIS_MODE_INSERT, "INSERT" }, { VIS_MODE_REPLACE, "REPLACE" }, }; - for (size_t i = 0; i < LENGTH(modes); i++) { lua_pushunsigned(L, modes[i].id); lua_setfield(L, -2, modes[i].name); } - lua_setfield(L, -2, "modes"); + obj_type_new(L, VIS_LUA_TYPE_VIS_OPTS); + luaL_setfuncs(L, vis_option_funcs, 0); + if (!package_exist(vis, L, "visrc")) { vis_info_show(vis, "WARNING: failed to load visrc.lua"); } else { @@ -584,6 +584,10 @@ int vis_count_get(Vis*); 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); +/** Set the shell */ +void vis_shell_set(Vis*, const char *new_shell); typedef struct { Vis *vis; |
