Skip to content

Commit

Permalink
allow lua to change line number styles
Browse files Browse the repository at this point in the history
Export the new function win:style_lineno(style, lineno) to lua.
Line number styles are stored in a sorted doubly linked list in the
corresponding UiTermWin struct.
Setting a line number's style to win.STYLE_DEFAULT resets the
style and frees the style descriptor.

This is useful to present information to the user without
cluttering or changing the interface to much.
initial commit adding styles to line numbers
  • Loading branch information
fischerling committed Mar 9, 2024
1 parent eaf6b72 commit 8e2ded3
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 11 deletions.
120 changes: 109 additions & 11 deletions ui-terminal.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,25 @@ typedef struct {
bool doupdate; /* Whether to update the screen after refreshing contents */
} UiTerm;

typedef struct LinenoStyle LinenoStyle;

struct LinenoStyle {
size_t lineno; /* linenumber to style */
enum UiStyle style; /* style to use for the line number */
LinenoStyle *next, *prev; /* pointer to the neighbouring descriptors */
};

struct UiTermWin {
UiWin uiwin; /* generic interface, has to be the first struct member */
UiTerm *ui; /* ui which manages this window */
Win *win; /* editor window being displayed */
int id; /* unique identifier for this window */
int width, height; /* window dimension including status bar */
int x, y; /* window position */
int sidebar_width; /* width of the sidebar showing line numbers etc. */
UiTermWin *next, *prev; /* pointers to neighbouring windows */
enum UiOption options; /* display settings for this window */
UiWin uiwin; /* generic interface, has to be the first struct member */
UiTerm *ui; /* ui which manages this window */
Win *win; /* editor window being displayed */
int id; /* unique identifier for this window */
int width, height; /* window dimension including status bar */
int x, y; /* window position */
int sidebar_width; /* width of the sidebar showing line numbers etc. */
LinenoStyle *lineno_styles; /* line number styles */
UiTermWin *next, *prev; /* pointers to neighbouring windows */
enum UiOption options; /* display settings for this window */
};

#if CONFIG_CURSES
Expand Down Expand Up @@ -260,6 +269,10 @@ static void ui_window_draw(UiWin *w) {
Cell *cells = ui->cells + y * ui->width;
if (x + sidebar_width + view_width > ui->width)
view_width = ui->width - x - sidebar_width;
LinenoStyle *lineno_style = win->lineno_styles;
while (line->lineno && lineno_style && line->lineno > lineno_style->lineno)
lineno_style = lineno_style->next; // skip not visible lineno styles

for (const Line *l = line; l; l = l->next, y++) {
if (sidebar) {
if (!l->lineno || !l->len || l->lineno == prev_lineno) {
Expand All @@ -276,8 +289,15 @@ static void ui_window_draw(UiWin *w) {
}
snprintf(buf, sizeof buf, "%*zu ", sidebar_width-1, number);
}
ui_draw_string(ui, x, y, buf, win,
(l->lineno == cursor_lineno) ? UI_STYLE_LINENUMBER_CURSOR : UI_STYLE_LINENUMBER);

enum UiStyle style;
if (lineno_style && lineno_style->lineno == l->lineno) {
style = lineno_style->style;
lineno_style = lineno_style->next;
} else
style = (l->lineno == cursor_lineno) ? UI_STYLE_LINENUMBER_CURSOR : UI_STYLE_LINENUMBER;

ui_draw_string(ui, x, y, buf, win, style);
prev_lineno = l->lineno;
}
debug("draw-window: [%d][%d] ... cells[%d][%d]\n", y, x+sidebar_width, y, view_width);
Expand All @@ -286,6 +306,84 @@ static void ui_window_draw(UiWin *w) {
}
}

static LinenoStyle* lineno_style_new(size_t lineno, enum UiStyle s) {
LinenoStyle* style = calloc(1, sizeof(LinenoStyle));
if (!style)
return NULL;
style->lineno = lineno;
style->style = s;
return style;
}

void ui_window_unstyle_lineno(UiWin *w, size_t lineno) {
UiTermWin *win = (UiTermWin*)w;
LinenoStyle *style = win->lineno_styles;
LinenoStyle *prev = NULL;
if (!style)
return;

while (style && style->lineno != lineno) {
prev = style;
style = style->next;
}

if (!style)
return;

if (!prev)
win->lineno_styles = NULL;
else {
prev->next = style->next;
if (style->next)
style->next->prev = prev;
}

free(style);
}

void ui_window_style_lineno(UiWin *w, size_t lineno, enum UiStyle s) {
UiTermWin *win = (UiTermWin*)w;
LinenoStyle *style = win->lineno_styles;
LinenoStyle *prev = NULL;

// First line number style
if (!style) {
win->lineno_styles = lineno_style_new(lineno, s);
return;
}

while (style && style->lineno < lineno) {
prev = style;
style = style->next;
}

if (style && style->lineno == lineno) {
style->style = s;
return;
}

LinenoStyle *new = lineno_style_new(lineno, s);
if (!new)
return;

// Append new style to list
if (!style) {
new->prev = prev;
prev->next = new;
}
else if (!prev) { // Prepend new style to list
win->lineno_styles = new;
new->next = style;
style->prev = new;
} else { // Insert new style into the list
new->prev = prev;
new->next = style;

style->prev = new;
prev->next = new;
}
}

static CellStyle ui_window_style_get(UiWin *w, enum UiStyle style) {
UiTermWin *win = (UiTermWin*)w;
UiTerm *tui = win->ui;
Expand Down
3 changes: 3 additions & 0 deletions ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,7 @@ struct UiWin {
bool is_default_color(CellColor c);
enum UiLayout ui_layout_get(Ui *ui);

void ui_window_unstyle_lineno(UiWin*, size_t);
void ui_window_style_lineno(UiWin*, size_t, enum UiStyle);

#endif
23 changes: 23 additions & 0 deletions vis-lua.c
Original file line number Diff line number Diff line change
Expand Up @@ -2093,6 +2093,28 @@ static int window_style(lua_State *L) {
return 0;
}

/***
* Style a window line number.
*
* The style will never be cleared and must be reset manually.
* @function style_lineno
* @tparam int id the display style as registered with @{style_define}
* @tparam int lineno the absolute file position in bytes
* @see style_define
* @usage
* win:style_lineno(win.STYLE_DEFAULT, 42)
*/
static int window_style_lineno(lua_State *L) {
Win *win = obj_ref_check(L, 1, VIS_LUA_TYPE_WINDOW);
enum UiStyle style = luaL_checkunsigned(L, 2);
size_t lineno = checkpos(L, 3);
if (style == UI_STYLE_DEFAULT)
ui_window_unstyle_lineno(win->ui, lineno);
else
ui_window_style_lineno(win->ui, lineno, style);
return 0;
}

/***
* Set window status line.
*
Expand Down Expand Up @@ -2162,6 +2184,7 @@ static const struct luaL_Reg window_funcs[] = {
{ "unmap", window_unmap },
{ "style_define", window_style_define },
{ "style", window_style },
{ "style_lineno", window_style_lineno },
{ "status", window_status },
{ "draw", window_draw },
{ "close", window_close },
Expand Down

0 comments on commit 8e2ded3

Please sign in to comment.