vis

a vi-like editor based on Plan 9's structural regular expressions

git clone https://9o.is/git/vis.git

commit 74d57ce87a7b6f5e0d2ae8b2ce37543fa4a1c57a
parent 065c35034c86774c4a08f01173cbb745848906d4
Author: Florian Fischer <florian.fischer@muhq.space>
Date:   Fri, 10 May 2024 08:55:56 +0200

lua: allow changing the displayed file of a window

Change the file displayed in a window by writing the new file name
to the window's file member.

This is useful to change the displayed file during events.
Using the edit command during an event caused by a pervious edit
command causes a double free.

Diffstat:
Mvis-lua.c | 6++++++
Mvis.c | 12++++++++++++
Mvis.h | 2++
3 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/vis-lua.c b/vis-lua.c @@ -2019,6 +2019,12 @@ static int window_newindex(lua_State *L) { } lua_pop(L, 1); return ret; + } else if (strcmp(key, "file") == 0 && lua_isstring(L, 3)) { + const char* filename = lua_tostring(L, 3); + if (!vis_window_change_file(win, filename)) { + return luaL_argerror(L, 3, "failed to open"); + } + return 0; } } diff --git a/vis.c b/vis.c @@ -505,6 +505,18 @@ bool vis_window_reload(Win *win) { return true; } +bool vis_window_change_file(Win *win, const char* filename) { + File *file = file_new(win->vis, filename); + if (!file) + return false; + file->refcount++; + if (win->file) + file_free(win->vis, win->file); + win->file = file; + view_reload(win->view, file->text); + return true; +} + bool vis_window_split(Win *original) { vis_doupdates(original->vis, false); Win *win = window_new_file(original->vis, original->file, UI_OPTION_STATUSBAR); diff --git a/vis.h b/vis.h @@ -209,6 +209,8 @@ bool vis_window_new(Vis*, const char *filename); bool vis_window_new_fd(Vis*, int fd); /** Reload the file currently displayed in the window from disk. */ bool vis_window_reload(Win*); +/** Change the file currently displayed in the window. */ +bool vis_window_change_file(Win*, const char *filename); /** Check whether closing the window would loose unsaved changes. */ bool vis_window_closable(Win*); /** Close window, redraw user interface. */