Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Direct access to cell styling via API #1180

Merged
merged 3 commits into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lua/vis.lua
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ local events = {
WIN_STATUS = "Event::WIN_STATUS", -- see @{win_status}
TERM_CSI = "Event::TERM_CSI", -- see @{term_csi}
PROCESS_RESPONSE = "Event::PROCESS_RESPONSE", -- see @{process_response}
UI_DRAW = "Event::UI_DRAW", -- see @{ui_draw}
}

events.file_close = function(...) events.emit(events.FILE_CLOSE, ...) end
Expand All @@ -183,6 +184,7 @@ events.win_open = function(...) events.emit(events.WIN_OPEN, ...) end
events.win_status = function(...) events.emit(events.WIN_STATUS, ...) end
events.term_csi = function(...) events.emit(events.TERM_CSI, ...) end
events.process_response = function(...) events.emit(events.PROCESS_RESPONSE, ...) end
events.ui_draw = function(...) events.emit(events.UI_DRAW, ...) end

local handlers = {}

Expand Down
1 change: 1 addition & 0 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2229,6 +2229,7 @@ int main(int argc, char *argv[]) {
.win_highlight = vis_lua_win_highlight,
.win_status = vis_lua_win_status,
.term_csi = vis_lua_term_csi,
.ui_draw = vis_lua_ui_draw,
};

vis = vis_new(ui_term_new(), &event);
Expand Down
16 changes: 16 additions & 0 deletions ui-terminal.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ struct UiTermWin {
#include "ui-terminal-vt100.c"
#endif

/* helper macro for handling UiTerm.cells */
#define CELL_AT_POS(UI, X, Y) (((UI)->cells) + (X) + ((Y) * (UI)->width));

__attribute__((noreturn)) static void ui_die(Ui *ui, const char *msg, va_list ap) {
UiTerm *tui = (UiTerm*)ui;
ui_term_backend_free(tui);
Expand Down Expand Up @@ -305,6 +308,17 @@ static void ui_window_style_set(UiWin *w, Cell *cell, enum UiStyle id) {
memcpy(&cell->style, &set, sizeof(CellStyle));
}

static bool ui_window_style_set_pos(UiWin *w, int x, int y, enum UiStyle id) {
UiTermWin *win = (UiTermWin*)w;
UiTerm *tui = win->ui;
if (x < 0 || y < 0 || y >= win->height || x >= win->width) {
return false;
}
Cell *cell = CELL_AT_POS(tui, win->x + x, win->y + y)
ui_window_style_set(w, cell, id);
return true;
}

static void ui_window_status(UiWin *w, const char *status) {
UiTermWin *win = (UiTermWin*)w;
if (!(win->options & UI_OPTION_STATUSBAR))
Expand Down Expand Up @@ -378,6 +392,7 @@ static void ui_draw(Ui *ui) {
ui_window_draw((UiWin*)win);
if (tui->info[0])
ui_draw_string(tui, 0, tui->height-1, tui->info, NULL, UI_STYLE_INFO);
vis_event_emit(tui->vis, VIS_EVENT_UI_DRAW);
ui_term_backend_blit(tui);
}

Expand Down Expand Up @@ -534,6 +549,7 @@ static UiWin *ui_window_new(Ui *ui, Win *w, enum UiOption options) {

win->uiwin = (UiWin) {
.style_set = ui_window_style_set,
.style_set_pos = ui_window_style_set_pos,
.status = ui_window_status,
.options_set = ui_window_options_set,
.options_get = ui_window_options_get,
Expand Down
1 change: 1 addition & 0 deletions ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ struct Ui {

struct UiWin {
void (*style_set)(UiWin*, Cell*, enum UiStyle);
bool (*style_set_pos)(UiWin*, int x, int y, enum UiStyle);
void (*status)(UiWin*, const char *txt);
void (*options_set)(UiWin*, enum UiOption);
enum UiOption (*options_get)(UiWin*);
Expand Down
1 change: 1 addition & 0 deletions vis-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ enum VisEvents {
VIS_EVENT_WIN_HIGHLIGHT,
VIS_EVENT_WIN_STATUS,
VIS_EVENT_TERM_CSI,
VIS_EVENT_UI_DRAW,
};

bool vis_event_emit(Vis*, enum VisEvents, ...);
Expand Down
55 changes: 51 additions & 4 deletions vis-lua.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ void vis_lua_win_status(Vis *vis, Win *win) { window_status_update(vis, win); }
void vis_lua_term_csi(Vis *vis, const long *csi) { }
void vis_lua_process_response(Vis *vis, const char *name,
char *buffer, size_t len, ResponseType rtype) { }

void vis_lua_ui_draw(Vis *vis) { }

#else

Expand Down Expand Up @@ -1833,8 +1833,10 @@ static const struct luaL_Reg registers_funcs[] = {
* Viewport currently being displayed.
* Changing these values will not move the viewport.
* @table viewport
* @tfield Range bytes
* @tfield Range lines
* @tfield Range bytes file bytes, from 0, at the start and end of the viewport
* @tfield Range lines file lines, from 1, at the top and bottom of the viewport
* @tfield int height lines in viewport, accounting for window decoration
* @tfield int width columns in viewport, accounting for window decoration
*/
/***
* The window width.
Expand Down Expand Up @@ -1875,13 +1877,19 @@ static int window_index(lua_State *L) {
l.start = view_lines_first(win->view)->lineno;
l.end = view_lines_last(win->view)->lineno;

lua_createtable(L, 0, 2);
lua_createtable(L, 0, 4);
lua_pushstring(L, "bytes");
pushrange(L, &b);
lua_settable(L, -3);
lua_pushstring(L, "lines");
pushrange(L, &l);
lua_settable(L, -3);
lua_pushstring(L, "width");
lua_pushunsigned(L, view_width_get(win->view));
lua_settable(L, -3);
lua_pushstring(L, "height");
lua_pushunsigned(L, view_height_get(win->view));
lua_settable(L, -3);
return 1;
}

Expand Down Expand Up @@ -2106,6 +2114,32 @@ static int window_style(lua_State *L) {
return 0;
}

/***
* Style the single terminal cell at the given coordinates, relative to this window.
*
* Completely independent of the file buffer, and can be used to style UI elements,
* such as the status bar.
* The style will be cleared after every window redraw.
* @function style_pos
* @tparam int id display style registered with @{style_define}
* @tparam int x 0-based x coordinate within Win, where (0,0) is the top left corner
* @tparam int y See above
* @treturn bool false if the coordinates would be outside the window's dimensions
* @see style_define
* @usage
* win:style_pos(win.STYLE_COLOR_COLUMN, 0, win.height - 1)
* -- Styles the first character of the status bar (or the last line, if disabled)
*/
static int window_style_pos(lua_State *L) {
Win *win = obj_ref_check(L, 1, VIS_LUA_TYPE_WINDOW);
enum UiStyle style = luaL_checkunsigned(L, 2);
size_t x = checkpos(L, 3);
size_t y = checkpos(L, 4);
bool ret = win->ui->style_set_pos(win->ui, (int)x, (int)y, style);
lua_pushboolean(L, ret);
return 1;
}

/***
* Set window status line.
*
Expand Down Expand Up @@ -2175,6 +2209,7 @@ static const struct luaL_Reg window_funcs[] = {
{ "unmap", window_unmap },
{ "style_define", window_style_define },
{ "style", window_style },
{ "style_pos", window_style_pos },
{ "status", window_status },
{ "draw", window_draw },
{ "close", window_close },
Expand Down Expand Up @@ -3662,4 +3697,16 @@ void vis_lua_process_response(Vis *vis, const char *name,
lua_pop(L, 1);
}

/***
* Emitted immediately before the UI is drawn to the screen.
* Allows last-minute overrides to the styling of UI elements.
*
* *WARNING:* This is emitted every screen draw!
* Use sparingly and check for `nil` values!
* @function ui_draw
*/
void vis_lua_ui_draw(Vis *vis) {
vis_lua_event_call(vis, "ui_draw");
}

#endif
1 change: 1 addition & 0 deletions vis-lua.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,6 @@ void vis_lua_win_highlight(Vis*, Win*);
void vis_lua_win_status(Vis*, Win*);
void vis_lua_term_csi(Vis*, const long *);
void vis_lua_process_response(Vis *, const char *, char *, size_t, ResponseType);
void vis_lua_ui_draw(Vis*);

#endif
4 changes: 4 additions & 0 deletions vis.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ bool vis_event_emit(Vis *vis, enum VisEvents id, ...) {
if (vis->event->term_csi)
vis->event->term_csi(vis, va_arg(ap, const long *));
break;
case VIS_EVENT_UI_DRAW:
if (vis->event->ui_draw)
vis->event->ui_draw(vis);
break;
}

va_end(ap);
Expand Down
1 change: 1 addition & 0 deletions vis.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ typedef struct {
void (*win_highlight)(Vis*, Win*);
void (*win_status)(Vis*, Win*);
void (*term_csi)(Vis*, const long *);
void (*ui_draw)(Vis*);
} VisEvent;

/** Union used to pass arguments to key action functions. */
Expand Down
Loading