Skip to content

Commit

Permalink
Improve Lua error reporting
Browse files Browse the repository at this point in the history
Display Lua errors in a dedicated window/file. A typo or missing
dependency (e.g. lpeg) in visrc.lua will no longer silently fail
without any indication.

The Lua integration in view.h is not yet converted.
  • Loading branch information
martanne committed Jan 30, 2016
1 parent 603a2d2 commit 979ab79
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 10 deletions.
6 changes: 6 additions & 0 deletions ui-curses.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions vis-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
36 changes: 29 additions & 7 deletions vis-lua.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}

Expand All @@ -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);
}
Expand All @@ -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);
Expand All @@ -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);
}
Expand All @@ -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);
Expand All @@ -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));
Expand Down
23 changes: 23 additions & 0 deletions vis-prompt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
7 changes: 5 additions & 2 deletions vis.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -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);
Expand Down
6 changes: 5 additions & 1 deletion vis.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 979ab79

Please sign in to comment.