diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-05-20 14:23:09 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-05-20 14:23:09 +0200 |
| commit | 9e3fcd953e7136b900d6aabafe1c64c083a927be (patch) | |
| tree | 87d504609b5518e47a515b8d269143831b206e39 /patches/ttym-config-file-2.0.diff | |
| download | ttym-9e3fcd953e7136b900d6aabafe1c64c083a927be.tar.gz ttym-9e3fcd953e7136b900d6aabafe1c64c083a927be.zip | |
initial commit
Diffstat (limited to 'patches/ttym-config-file-2.0.diff')
| -rw-r--r-- | patches/ttym-config-file-2.0.diff | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/patches/ttym-config-file-2.0.diff b/patches/ttym-config-file-2.0.diff new file mode 100644 index 0000000..422d724 --- /dev/null +++ b/patches/ttym-config-file-2.0.diff @@ -0,0 +1,237 @@ +diff -ruN a/config.def.h b/config.def.h +--- a/config.def.h 2026-05-20 13:18:06.149571116 +0200 ++++ b/config.def.h 2026-05-20 13:19:12.046956614 +0200 +@@ -1,23 +1,29 @@ + /* See LICENSE file for copyright and license details. */ + +-/* progress bar glyphs (ASCII default) */ ++/* progress bar glyphs (ASCII default). ++ * Runtime config file ~/.config/ttym/config can override these via ++ * bar_fill / bar_empty keys. ++ */ + static const char *const BAR_FILL = ">"; + static const char *const BAR_EMPTY = "-"; + + /* persistent alert: keep ringing the bell until any key is pressed. + * Foreground-only; backgrounded runs always fall through. +- * Override per-run with --no-persist. ++ * Override per-run with --no-persist, or via the alert_persist key ++ * in the runtime config file (~/.config/ttym/config). + */ + static const int ALERT_PERSIST = 1; + + /* reverse-video flash during the alert loop. +- * Override per-run with --flash on|off. ++ * Override per-run with --flash on|off, or via the flash key in the ++ * runtime config file (~/.config/ttym/config). + */ + static const int FLASH = 1; + + /* desktop notification on countdown completion. + * Tokens are split on whitespace; placeholders {title} and {msg} are expanded. + * Set NULL or "" to disable. ++ * The runtime config file can override these via title / notify_cmd keys. + */ + static const char *const TITLE = "Timer"; + static const char *const NOTIFY_CMD = "notify-send -u critical {title} {msg}"; +@@ -25,6 +31,7 @@ + /* sound on countdown completion. If SOUND_CMD is "" the binary autodetects + * a player (paplay/aplay/mpv/ffplay) and plays a default freedesktop sound. + * SOUND_CMD is split on whitespace; same token rules as NOTIFY_CMD. ++ * The runtime config file can override this via the sound_cmd key. + */ + static const char *const SOUND_CMD = ""; + +@@ -35,5 +42,6 @@ + + /* default bar style: "" autodetects (unicode if locale is UTF-8, else ascii). + * Available: unicode | ascii | hash | dots | line | block | arrow | minimal. ++ * The runtime config file can override this via the bar_style key. + */ + static const char *const BAR_STYLE = ""; +diff -ruN a/ttym.c b/ttym.c +--- a/ttym.c 2026-05-20 13:18:06.149571116 +0200 ++++ b/ttym.c 2026-05-20 13:19:12.046956614 +0200 +@@ -30,10 +30,12 @@ + int alert_persist; /* alert loop until keypress; --no-persist disables */ + int flash; /* reverse-video flash during alert loop */ + char comment[512]; /* -c TEXT: logged with each entry */ ++ char bar_fill[16]; /* override (utf-8 ok); from runtime config */ ++ char bar_empty[16]; /* override */ + char bar_style[32]; /* --bar STYLE */ +- const char *title; +- const char *notify_cmd; +- const char *sound_cmd; ++ char title[256]; /* override; from runtime config */ ++ char notify_cmd[512]; /* override; from runtime config */ ++ char sound_cmd[512]; /* override; from runtime config */ + char msg[1024]; + } Config; + +@@ -409,7 +411,7 @@ + static void + notify_and_sound(const Config *c) + { +- if (c->notify_cmd && c->notify_cmd[0] && command_exists("notify-send")) { ++ if (c->notify_cmd[0] && command_exists("notify-send")) { + char **a; + if (build_argv(c->notify_cmd, c, &a) > 0) { + spawn_bg(a); +@@ -417,7 +419,7 @@ + } + } + if (!c->quiet) { +- if (c->sound_cmd && c->sound_cmd[0]) { ++ if (c->sound_cmd[0]) { + char **a; + if (build_argv(c->sound_cmd, c, &a) > 0) { + spawn_bg(a); +@@ -832,6 +834,112 @@ + } + } + ++/* ===== runtime config file (~/.config/ttym/config) ===== ++ * key = value lines; '#' comments. Unknown keys ignored. ++ */ ++ ++static void ++trim(char *s) ++{ ++ char *p = s; ++ while (*p && isspace((unsigned char)*p)) p++; ++ if (p != s) memmove(s, p, strlen(p) + 1); ++ size_t n = strlen(s); ++ while (n > 0 && isspace((unsigned char)s[n-1])) s[--n] = '\0'; ++} ++ ++static void ++ensure_default_config_file(const char *path) ++{ ++ if (access(path, F_OK) == 0) return; ++ char dir[512]; ++ snprintf(dir, sizeof(dir), "%s", path); ++ char *slash = strrchr(dir, '/'); ++ if (slash) { *slash = '\0'; mkdir_p(dir, 0700); } ++ FILE *f = fopen(path, "w"); ++ if (!f) return; ++ fputs( ++"# ttym configuration file\n" ++"#\n" ++"# Location : ~/.config/ttym/config (/etc/ttym.conf is read first, if present)\n" ++"# Syntax : key = value -- one entry per line; '#' begins a comment.\n" ++"# A commented-out or absent key keeps its built-in default.\n" ++"# Command-line flags override anything set in this file.\n" ++"#\n" ++"# Every key below is recognised by this build. Uncomment and edit to taste.\n" ++"# ---------------------------------------------------------------------------\n" ++"\n" ++"# Progress-bar glyphs. Set BOTH or NEITHER -- mismatched display widths\n" ++"# break bar alignment. Multi-byte UTF-8 is fine. These override bar_style.\n" ++"# bar_fill = >\n" ++"# bar_empty = -\n" ++"\n" ++"# Named progress-bar style. One of:\n" ++"# unicode ascii hash dots line block arrow minimal\n" ++"# Leave unset to auto-detect (unicode on a UTF-8 locale, otherwise ascii).\n" ++"# bar_style = unicode\n" ++"\n" ++"# Reverse-video flash during the completion alert. on | off\n" ++"# flash = on\n" ++"\n" ++"# Persistent alert: keep ringing the bell until a key is pressed\n" ++"# (foreground runs only). on | off\n" ++"# alert_persist = on\n" ++"\n" ++"# Desktop-notification title.\n" ++"# title = Timer\n" ++"\n" ++"# Desktop-notification command run when a countdown finishes. Tokens are\n" ++"# split on whitespace; {title}/{msg} placeholders expand. Empty disables.\n" ++"# notify_cmd = notify-send -u critical {title} {msg}\n" ++"\n" ++"# Sound played when a countdown finishes. Leave unset to auto-detect a\n" ++"# player (paplay/aplay/mpv/ffplay) and play a default system sound.\n" ++"# Tokens are split on whitespace; {title}/{msg} placeholders expand.\n" ++"# sound_cmd = paplay /usr/share/sounds/freedesktop/stereo/complete.oga\n", ++ f); ++ fclose(f); ++ chmod(path, 0600); ++} ++ ++static void ++load_config_file(Config *c, const char *path) ++{ ++ FILE *f = fopen(path, "r"); ++ if (!f) return; ++ char line[1024]; ++ while (fgets(line, sizeof(line), f)) { ++ char *hash = strchr(line, '#'); ++ if (hash) *hash = '\0'; ++ char *eq = strchr(line, '='); ++ if (!eq) continue; ++ *eq = '\0'; ++ char *k = line, *v = eq + 1; ++ trim(k); trim(v); ++ if (!*k) continue; ++ if (!strcmp(k, "bar_fill")) snprintf(c->bar_fill, sizeof(c->bar_fill), "%s", v); ++ else if (!strcmp(k, "bar_empty")) snprintf(c->bar_empty, sizeof(c->bar_empty), "%s", v); ++ else if (!strcmp(k, "bar_style")) snprintf(c->bar_style, sizeof(c->bar_style), "%s", v); ++ else if (!strcmp(k, "flash")) c->flash = parse_bool_str(v); ++ else if (!strcmp(k, "alert_persist")) c->alert_persist = parse_bool_str(v); ++ else if (!strcmp(k, "title")) snprintf(c->title, sizeof(c->title), "%s", v); ++ else if (!strcmp(k, "notify_cmd")) snprintf(c->notify_cmd, sizeof(c->notify_cmd), "%s", v); ++ else if (!strcmp(k, "sound_cmd")) snprintf(c->sound_cmd, sizeof(c->sound_cmd), "%s", v); ++ } ++ fclose(f); ++} ++ ++static void ++load_config(Config *c) ++{ ++ load_config_file(c, "/etc/ttym.conf"); ++ char path[512]; ++ if (build_config_path(path, sizeof(path), "config") == 0) { ++ ensure_default_config_file(path); ++ load_config_file(c, path); ++ } ++} ++ + /* ===== bar styles ===== */ + + typedef struct { const char *name, *fill, *empty; } BarStyle; +@@ -908,7 +1016,8 @@ + " -h help\n" + "\n" + "controls: [space] pause/resume [q | Ctrl+C] quit\n" +-"hooks: ~/.config/ttym/hooks/{on_start,on_done,on_quit} (executable)\n"); ++"hooks: ~/.config/ttym/hooks/{on_start,on_done,on_quit} (executable)\n" ++"config: ~/.config/ttym/config (auto-generated on first run)\n"); + } + + /* ===== run loop ===== */ +@@ -924,6 +1033,10 @@ + const char *fill_glyph, *empty_glyph; + int minimal = 0; + resolve_bar(cfg, &fill_glyph, &empty_glyph, &minimal); ++ /* explicit per-glyph overrides from the runtime config file ++ * (bar_fill / bar_empty) win over the named --bar style. */ ++ if (cfg->bar_fill[0]) fill_glyph = cfg->bar_fill; ++ if (cfg->bar_empty[0]) empty_glyph = cfg->bar_empty; + + ttyfd = open("/dev/tty", O_RDONLY); + if (ttyfd >= 0 && isatty(ttyfd)) { +@@ -1075,10 +1188,11 @@ + Config cfg = {0}; + cfg.alert_persist = ALERT_PERSIST; + cfg.flash = FLASH; +- cfg.title = TITLE; +- cfg.notify_cmd = NOTIFY_CMD; +- cfg.sound_cmd = SOUND_CMD; ++ snprintf(cfg.title, sizeof(cfg.title), "%s", TITLE ? TITLE : ""); ++ snprintf(cfg.notify_cmd, sizeof(cfg.notify_cmd), "%s", NOTIFY_CMD ? NOTIFY_CMD : ""); ++ snprintf(cfg.sound_cmd, sizeof(cfg.sound_cmd), "%s", SOUND_CMD ? SOUND_CMD : ""); + snprintf(cfg.msg, sizeof(cfg.msg), "%s", "Time is up"); ++ load_config(&cfg); + + /* Pre-strip long-form flags before getopt. Stop at "--". */ + int new_argc = 0; |
