diff options
author | wrmr | 2025-08-25 18:57:09 -0400 |
---|---|---|
committer | wrmr | 2025-08-25 18:57:09 -0400 |
commit | c33cd57aa83ad6d6a8c5bcfd4686e5ce7c190044 (patch) | |
tree | 2185e68c6022463ad41d29a2af711857db6bd064 /main.c | |
parent | 71237ea0c5eb0c7b0d7894e0b3b01dbcf8a43982 (diff) |
add pronouns
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 94 |
1 files changed, 61 insertions, 33 deletions
@@ -46,6 +46,8 @@ #define GFX_TEXT_MARGIN_X 1 #define GFX_TEXT_MARGIN_Y 0 #define GFX_POST_SPACING 1 +#define GFX_PRONOUNS_MARGIN 1 +#define GFX_PRONOUNS_FMT "<%S>" #define PFP_LINES 3 #define PFP_COLS 7 @@ -55,16 +57,17 @@ #define CPAIR_INIT_X(cp, fg, bg) init_pair(cp, fg, bg); #define CPAIR_ENUM_X(cp, fg, bg) cp, #define CPAIR_LIST(X)\ - X(CPAIR_TEXT , COLOR_WHITE , COLOR_BLACK)\ - X(CPAIR_MENTION , COLOR_BLACK , COLOR_WHITE)\ - X(CPAIR_USER , COLOR_YELLOW , COLOR_BLACK)\ - X(CPAIR_TIME , COLOR_BLUE , COLOR_BLACK)\ - X(CPAIR_PFP , COLOR_BLUE , COLOR_BLACK)\ - X(CPAIR_PFP_SELF , COLOR_YELLOW , COLOR_BLACK)\ - X(CPAIR_BORDER , COLOR_BLUE , COLOR_BLACK)\ - X(CPAIR_TAGLINE_OK , COLOR_GREEN , COLOR_BLACK)\ - X(CPAIR_TAGLINE_WARN , COLOR_YELLOW , COLOR_BLACK)\ - X(CPAIR_TAGLINE_ERR , COLOR_RED , COLOR_BLACK) + X(CPAIR_TEXT , COLOR_WHITE , COLOR_BLACK)\ + X(CPAIR_MENTION , COLOR_BLACK , COLOR_WHITE)\ + X(CPAIR_USER , COLOR_YELLOW , COLOR_BLACK)\ + X(CPAIR_PRONOUNS , COLOR_CYAN , COLOR_BLACK)\ + X(CPAIR_TIME , COLOR_BLUE , COLOR_BLACK)\ + X(CPAIR_PFP , COLOR_BLUE , COLOR_BLACK)\ + X(CPAIR_PFP_SELF , COLOR_YELLOW , COLOR_BLACK)\ + X(CPAIR_BORDER , COLOR_BLUE , COLOR_BLACK)\ + X(CPAIR_TAGLINE_OK , COLOR_GREEN , COLOR_BLACK)\ + X(CPAIR_TAGLINE_WARN , COLOR_YELLOW , COLOR_BLACK)\ + X(CPAIR_TAGLINE_ERR , COLOR_RED , COLOR_BLACK) typedef enum { CPAIR_LIST(CPAIR_ENUM_X) @@ -95,10 +98,25 @@ typedef enum { (da)->len += n;\ } while(0) +/* utf8 */ + +int fast_utf8_width(Str s) { + int n = 0; + for (int i = 0; i < s.n; i++) { + if (s.s[i] & 0x80) { + i += stdc_leading_ones((unsigned)i) - 1; + } + n++; + } + return n; +} + /* options */ typedef struct { - int pfp_vis; + struct { + int pfp, pronouns; + } see; struct { int left, right, top, bottom; } margin; @@ -108,7 +126,10 @@ typedef struct { regex_t re_mention; Options opt = { - .pfp_vis = 1, + .see = { + .pfp = 1, + .pronouns = 1 + }, .margin = { .left = 0, .right = 0 @@ -189,20 +210,10 @@ typedef struct { typedef struct { Str name; + Str pronouns; Pfp pfp; } User; -int fast_utf8_width(Str s) { - int n = 0; - for (int i = 0; i < s.n; i++) { - if (s.s[i] & 0x80) { - i += stdc_leading_ones((unsigned)i) - 1; - } - n++; - } - return n; -} - void pfp_load(Pfp *pfp, Str src, Arena *a) { int lines = 0, cols = 0; for (Str s = src, l = {0}; next_line(&s, &l);) { @@ -226,6 +237,7 @@ User *user_load(Str name, Str homedir, Str binkdir, Arena *a) { (void)binkdir; User *u = new(a, User); u->name = str_dup(name, a); + FILE *f = fopen(cstr_fmt(a, "%S/.binkpfp", homedir), "r/o"); Str pfp_src = {0}; if (f) { @@ -239,6 +251,16 @@ User *user_load(Str name, Str homedir, Str binkdir, Arena *a) { ); } pfp_load(&u->pfp, pfp_src, a); + + f = fopen(cstr_fmt(a, "%S/.pronouns", homedir), "r/o"); + if (f) { + Str buf = { 0 }; + read_all(f, &buf, a); + fclose(f); + buf = str_trim(buf); + next_line(&buf, &u->pronouns); + } + return u; } @@ -417,7 +439,7 @@ typedef struct { int post_left_margin(Post *post) { int lm = opt.margin.left; - if (opt.pfp_vis && post->user->pfp.cols >= lm) lm = post->user->pfp.cols + 1; + if (opt.see.pfp && post->user->pfp.cols >= lm) lm = post->user->pfp.cols + 1; return lm; } @@ -460,11 +482,11 @@ void gfx_predraw_post(GfxPost *post) { int gfx_post_height(GfxPost *post) { int n = 0; - if (opt.pfp_vis && post->src->user->pfp.lines > post->lines + 2) n = post->src->user->pfp.lines - post->lines - 2; + if (opt.see.pfp && post->src->user->pfp.lines > post->lines + 2) n = post->src->user->pfp.lines - post->lines - 2; return post->lines + 2 + GFX_TEXT_MARGIN_Y * 2 + n; } -void gfx_draw_post(GfxPost *post, int y, int x, int width) { +void gfx_draw_post(GfxPost *post, int y, int x, int width, Arena *scratch) { int height = gfx_post_height(post); if (!post->drawn) { @@ -475,6 +497,7 @@ void gfx_draw_post(GfxPost *post, int y, int x, int width) { int left = x + post_left_margin(post->src), top = y + opt.margin.top; int right = left + width - 1, bottom = top + height - 1; int self = is_post_mine(post->src); + User *u = post->src->user; color_set(CPAIR_BORDER, 0); gfx_hline(top, left, right - left, ACS_HLINE); @@ -491,9 +514,9 @@ void gfx_draw_post(GfxPost *post, int y, int x, int width) { Str s = str_trim(str_from_cstr(ctime(&(time_t){post->src->timestamp.tv_sec}))); mvaddnstr(y, right - s.n, s.s, s.n); - if (opt.pfp_vis) { + if (opt.see.pfp) { color_set(self ? CPAIR_PFP_SELF : CPAIR_PFP, 0); - Pfp *pfp = &post->src->user->pfp; + Pfp *pfp = &u->pfp; int pfptop = top + GFX_TEXT_MARGIN_Y; if (height > pfp->lines) pfptop += (height - pfp->lines) >> 1; int pfpleft = left - pfp->cols - GFX_TEXT_MARGIN_X; @@ -503,7 +526,12 @@ void gfx_draw_post(GfxPost *post, int y, int x, int width) { } color_set(CPAIR_USER, 0); - mvaddnstr(y, left + 2, post->src->user->name.s, post->src->user->name.n); + mvaddnstr(y, left + 2, u->name.s, u->name.n); + + if (opt.see.pronouns && u->pronouns.n) { + color_set(CPAIR_PRONOUNS, 0); + mvaddstr(y, left + 2 + fast_utf8_width(u->name) + GFX_PRONOUNS_MARGIN, cstr_fmt(scratch, GFX_PRONOUNS_FMT, u->pronouns)); + } color_set(post->has_mention ? CPAIR_MENTION : CPAIR_TEXT, 0); @@ -515,10 +543,10 @@ void gfx_draw_post(GfxPost *post, int y, int x, int width) { } } -void gfx_draw(Gfx *gfx, int cur) { +void gfx_draw(Gfx *gfx, int cur, Arena *scratch) { erase(); for (int i = cur, y = GFX_MARGIN_Y; i < gfx->len && y < getmaxy(stdscr) - GFX_MARGIN_Y; i++) { - gfx_draw_post(&gfx->posts[i], y, GFX_MARGIN_X, gfx_post_width(gfx->posts[i].src)); + gfx_draw_post(&gfx->posts[i], y, GFX_MARGIN_X, gfx_post_width(gfx->posts[i].src), scratch); y += gfx_post_height(&gfx->posts[i]) + GFX_POST_SPACING; } } @@ -669,7 +697,7 @@ int main(void) { if (cur < 0) cur = 0; arena_reset(&temp_arena); - gfx_draw(&gfx, cur); + gfx_draw(&gfx, cur, &temp_arena); switch (tagline_status) { case TAGLINE_OK: color_set(CPAIR_TAGLINE_OK, 0); break; case TAGLINE_WARN: color_set(CPAIR_TAGLINE_WARN, 0); break; @@ -738,7 +766,7 @@ refresh: post_stats.gather_ns / 1000000); goto resize; case '\t': - opt.pfp_vis = !opt.pfp_vis; + opt.see.pfp = !opt.see.pfp; /* fallthrough */ case KEY_RESIZE: |