aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ui-curses.c6
-rw-r--r--ui.h1
-rw-r--r--vis-core.h1
-rw-r--r--vis-lua.c36
-rw-r--r--vis-prompt.c23
-rw-r--r--vis.c7
-rw-r--r--vis.h6
7 files changed, 70 insertions, 10 deletions
diff --git a/ui-curses.c b/ui-curses.c
index 40e5c13..671fa61 100644
--- a/ui-curses.c
+++ b/ui-curses.c
@@ -988,6 +988,11 @@ static void ui_info_hide(Ui *ui) {
static bool ui_init(Ui *ui, Vis *vis) {
UiCurses *uic = (UiCurses*)ui;
uic->vis = vis;
+ return true;
+}
+
+static bool ui_start(Ui *ui) {
+ Vis *vis = ((UiCurses*)ui)->vis;
const char *theme = getenv("VIS_THEME");
if (theme && theme[0]) {
if (!vis_theme_load(vis, theme))
@@ -1087,6 +1092,7 @@ Ui *ui_curses_new(void) {
*ui = (Ui) {
.init = ui_init,
+ .start = ui_start,
.free = ui_curses_free,
.termkey_get = ui_termkey_get,
.suspend = ui_suspend,
diff --git a/ui.h b/ui.h
index 6c5b63d..61fa4df 100644
--- a/ui.h
+++ b/ui.h
@@ -44,6 +44,7 @@ enum UiStyles {
struct Ui {
bool (*init)(Ui*, Vis*);
+ bool (*start)(Ui*);
void (*free)(Ui*);
void (*resize)(Ui*);
UiWin* (*window_new)(Ui*, View*, File*, enum UiOption);
diff --git a/vis-core.h b/vis-core.h
index 9010ea4..91bdf58 100644
--- a/vis-core.h
+++ b/vis-core.h
@@ -132,6 +132,7 @@ struct Vis {
File *search_file; /* special internal file used to store /,? search prompt */
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 */
Register registers[VIS_REG_INVALID]; /* registers used for yank and put */
Macro macros[VIS_MACRO_INVALID]; /* recorded macros */
Macro *recording, *last_recording; /* currently (if non NULL) and least recently recorded macro */
diff --git a/vis-lua.c b/vis-lua.c
index 5b44ea1..7549cc1 100644
--- a/vis-lua.c
+++ b/vis-lua.c
@@ -78,6 +78,28 @@ static void stack_dump(lua_State *L, const char *format, ...) {
#endif
+static int error_function(lua_State *L) {
+ Vis *vis = lua_touserdata(L, lua_upvalueindex(1));
+ size_t len;
+ const char *msg = lua_tostring(L, 1);
+ if (msg)
+ luaL_traceback(L, L, msg, 1);
+ msg = lua_tolstring(L, 1, &len);
+ vis_message_show(vis, msg);
+ return 1;
+}
+
+static int pcall(Vis *vis, lua_State *L, int nargs, int nresults) {
+ /* insert a custom error function below all arguments */
+ int msgh = lua_gettop(L) - nargs;
+ lua_pushlightuserdata(L, vis);
+ lua_pushcclosure(L, error_function, 1);
+ lua_insert(L, msgh);
+ int ret = lua_pcall(L, nargs, nresults, msgh);
+ lua_remove(L, msgh);
+ return ret;
+}
+
static void *obj_new(lua_State *L, size_t size, const char *type) {
void *obj = lua_newuserdata(L, size);
luaL_getmetatable(L, type);
@@ -586,10 +608,10 @@ void vis_lua_start(Vis *vis) {
lua_getglobal(L, "require");
lua_pushstring(L, "visrc");
- lua_pcall(L, 1, 0, 0);
+ pcall(vis, L, 1, 0);
vis_lua_event(vis, "start");
if (lua_isfunction(L, -1))
- lua_pcall(L, 0, 0, 0);
+ pcall(vis, L, 0, 0);
lua_pop(L, 1);
}
@@ -599,7 +621,7 @@ void vis_lua_quit(Vis *vis) {
return;
vis_lua_event(vis, "quit");
if (lua_isfunction(L, -1))
- lua_pcall(L, 0, 0, 0);
+ pcall(vis, L, 0, 0);
lua_pop(L, 1);
lua_close(L);
}
@@ -617,7 +639,7 @@ void vis_lua_file_close(Vis *vis, File *file) {
vis_lua_event(vis, "file_close");
if (lua_isfunction(L, -1)) {
obj_ref_new(L, file, "vis.file");
- lua_pcall(L, 1, 0, 0);
+ pcall(vis, L, 1, 0);
}
obj_ref_free(L, file->text);
obj_ref_free(L, file);
@@ -629,7 +651,7 @@ void vis_lua_win_open(Vis *vis, Win *win) {
vis_lua_event(vis, "win_open");
if (lua_isfunction(L, -1)) {
obj_ref_new(L, win, "vis.window");
- lua_pcall(L, 1, 0, 0);
+ pcall(vis, L, 1, 0);
}
lua_pop(L, 1);
}
@@ -639,7 +661,7 @@ void vis_lua_win_close(Vis *vis, Win *win) {
vis_lua_event(vis, "win_close");
if (lua_isfunction(L, -1)) {
obj_ref_new(L, win, "vis.window");
- lua_pcall(L, 1, 0, 0);
+ pcall(vis, L, 1, 0);
}
obj_ref_free(L, win->view);
obj_ref_free(L, win);
@@ -663,7 +685,7 @@ bool vis_theme_load(Vis *vis, const char *name) {
lua_pop(L, 2);
lua_getglobal(L, "require");
lua_pushvalue(L, -2);
- if (lua_pcall(L, 1, 0, 0))
+ if (pcall(vis, L, 1, 0))
return false;
for (Win *win = vis->windows; win; win = win->next)
view_syntax_set(win->view, view_syntax_get(win->view));
diff --git a/vis-prompt.c b/vis-prompt.c
index 4db1057..2441fa4 100644
--- a/vis-prompt.c
+++ b/vis-prompt.c
@@ -187,3 +187,26 @@ void vis_info_hide(Vis *vis) {
vis->ui->info_hide(vis->ui);
}
+void vis_message_show(Vis *vis, const char *msg) {
+ if (!msg)
+ return;
+ if (!vis->message_window) {
+ if (!vis_window_new(vis, NULL))
+ return;
+ vis->message_window = vis->win;
+ }
+
+ Win *win = vis->message_window;
+ Text *txt = win->file->text;
+ size_t pos = text_size(txt);
+ text_appendf(txt, "%s\n", msg);
+ text_save(txt, NULL);
+ view_cursor_to(win->view, pos);
+}
+
+void vis_message_hide(Vis *vis) {
+ if (!vis->message_window)
+ return;
+ vis_window_close(vis->message_window);
+ vis->message_window = NULL;
+}
diff --git a/vis.c b/vis.c
index 1602674..2c0d625 100644
--- a/vis.c
+++ b/vis.c
@@ -297,6 +297,8 @@ void vis_window_close(Win *win) {
vis->windows = win->next;
if (vis->win == win)
vis->win = win->next ? win->next : win->prev;
+ if (win == vis->message_window)
+ vis->message_window = NULL;
window_free(win);
if (vis->win)
vis->ui->window_focus(vis->win->ui);
@@ -309,8 +311,6 @@ Vis *vis_new(Ui *ui, VisEvent *event) {
Vis *vis = calloc(1, sizeof(Vis));
if (!vis)
return NULL;
- if (event && event->vis_start)
- event->vis_start(vis);
vis->ui = ui;
vis->ui->init(vis->ui, vis);
vis->tabwidth = 8;
@@ -324,6 +324,9 @@ Vis *vis_new(Ui *ui, VisEvent *event) {
goto err;
vis->mode_prev = vis->mode = &vis_modes[VIS_MODE_NORMAL];
vis->event = event;
+ if (event && event->vis_start)
+ event->vis_start(vis);
+ vis->ui->start(vis->ui);
return vis;
err:
vis_free(vis);
diff --git a/vis.h b/vis.h
index 477ffe4..f749a63 100644
--- a/vis.h
+++ b/vis.h
@@ -81,10 +81,14 @@ void vis_window_prev(Vis*);
/* display a user prompt with a certain title and default text */
void vis_prompt_show(Vis*, const char *title);
-/* display a message to the user */
+/* display a one line message to the user, will be hidden upon keypress */
void vis_info_show(Vis*, const char *msg, ...);
void vis_info_hide(Vis*);
+/* display an arbitrary long message in a special window/file */
+void vis_message_show(Vis*, const char *msg);
+void vis_message_hide(Vis*);
+
/* these function operate on the currently focused window but make sure
* that all windows which show the affected region are redrawn too. */
void vis_insert(Vis*, size_t pos, const char *data, size_t len);