diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-25 19:02:35 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-25 19:02:35 +0200 |
| commit | 8f99f1650e4a7363af1d83190b4082fb72a9f73f (patch) | |
| tree | 86ed3b714c376e95f98d33d7572e76d6b43f06d3 /patches/ttym-bar-styles-2.0.diff | |
| parent | 2f6b29abd0d766ef477eb29c5a7bf6c1e88e9630 (diff) | |
| download | ttym-8f99f1650e4a7363af1d83190b4082fb72a9f73f.tar.gz ttym-8f99f1650e4a7363af1d83190b4082fb72a9f73f.zip | |
ttym 3.0: fix terminal and config bugs, fold terminal-only patches into base
Correctness fixes:
- restore the terminal on SIGQUIT and SIGHUP. atexit never runs on an
uncaught fatal signal, so Ctrl+\ left the cursor hidden and autowrap
disabled.
- drop the unconditional newline in restore_tty. Every run emitted a
stray blank line, including piped output.
- treat EINTR as an interruption rather than a poll() failure, which
delayed Ctrl+C by up to one 100ms frame.
config-file patch:
- make comment stripping quote-aware so a value may contain '#', and
strip one matched pair of quotes. bar_fill = "#" was silently dropped,
despite '#' being the glyph of the hash style this build ships.
- resolve bar_fill/bar_empty inside resolve_bar and clear them on --bar,
so command-line flags beat the config file as documented. Previously
config glyphs silently overrode --bar.
- report unknown keys, unparseable booleans and malformed lines on
stderr. flash = enabled silently meant off.
- never write to disk. --dump-config prints a commented template on
stdout instead of the binary creating ~/.config/ttym/config on first
run.
Patch set:
- fold persist-alert, flash and bar-styles into the base. The base is
now terminal-only: it opens /dev/tty, draws and exits, with no file
writes and no subprocesses. Everything still in patches/ changes what
the program touches.
- seven patches become four; config-file's prerequisites drop from six
patches to one (notify), so it is regenerable mechanically.
- regenerate every patch. All apply with zero fuzz and compile.
Source:
- rewrite argv in place rather than into a malloc'd copy (C99
5.1.2.2.1), removing die(), four free() calls and <stdarg.h>.
- fold the duplicated elapsed-time expression into elapsed().
- drop dead code: have_any, (void)cfg, and an unreachable branch in
parse_duration.
- replace hand-counted padding with \033[K.
Docs and build:
- timer.1: -c is the third hook argument, not the fourth. Add EXIT
STATUS (a stopwatch always exits 130 -- it has no natural end) and
ENVIRONMENT. Document config precedence and quoting.
- wire VERSION into a dist target; it was defined and never used.
- track .gitignore, which previously ignored itself, so a fresh clone
had no ignore rules.
Claude-Session: https://claude.ai/code/session_01APLBs8RB1FcUaC4viVkzbP
Diffstat (limited to 'patches/ttym-bar-styles-2.0.diff')
| -rw-r--r-- | patches/ttym-bar-styles-2.0.diff | 155 |
1 files changed, 0 insertions, 155 deletions
diff --git a/patches/ttym-bar-styles-2.0.diff b/patches/ttym-bar-styles-2.0.diff deleted file mode 100644 index 2653cf5..0000000 --- a/patches/ttym-bar-styles-2.0.diff +++ /dev/null @@ -1,155 +0,0 @@ -diff -ruN a/config.def.h b/config.def.h ---- a/config.def.h 2026-05-20 12:05:11.699957443 +0200 -+++ b/config.def.h 2026-05-20 12:05:11.703957526 +0200 -@@ -3,3 +3,8 @@ - /* progress bar glyphs (ASCII default) */ - static const char *const BAR_FILL = ">"; - static const char *const BAR_EMPTY = "-"; -+ -+/* default bar style: "" autodetects (unicode if locale is UTF-8, else ascii). -+ * Available: unicode | ascii | hash | dots | line | block | arrow | minimal. -+ */ -+static const char *const BAR_STYLE = ""; -diff -ruN a/ttym.c b/ttym.c ---- a/ttym.c 2026-05-20 12:05:11.699957443 +0200 -+++ b/ttym.c 2026-05-20 12:06:26.161496315 +0200 -@@ -5,6 +5,7 @@ - #include <ctype.h> - #include <errno.h> - #include <fcntl.h> -+#include <locale.h> - #include <poll.h> - #include <signal.h> - #include <stdarg.h> -@@ -23,6 +24,7 @@ - typedef struct { - int quiet; /* -q: suppress completion bell */ - int silent; /* -s: no bell, no extras */ -+ char bar_style[32]; /* --bar STYLE */ - } Config; - - static struct termios oldtios; -@@ -186,7 +188,8 @@ - /* ===== drawing ===== */ - - static void --draw_countdown(long total, long elapsed_ms, int paused, int barw) -+draw_countdown(long total, long elapsed_ms, int paused, int barw, -+ const char *fill_glyph, const char *empty_glyph, int minimal) - { - if (total <= 0) return; - long total_ms = total * 1000L; -@@ -207,8 +210,15 @@ - const char *status = paused ? "PAUSED " : " "; - - printf("\r%sT-%s\033[0m \033[2m+%s\033[0m [", color, rem, el); -- for (int i = 0; i < fill; i++) fputs(BAR_FILL, stdout); -- for (int i = 0; i < empty; i++) fputs(BAR_EMPTY, stdout); -+ if (minimal) { -+ fputs("\033[7m", stdout); -+ for (int i = 0; i < fill; i++) fputc(' ', stdout); -+ fputs("\033[27m", stdout); -+ for (int i = 0; i < empty; i++) fputc(' ', stdout); -+ } else { -+ for (int i = 0; i < fill; i++) fputs(fill_glyph, stdout); -+ for (int i = 0; i < empty; i++) fputs(empty_glyph, stdout); -+ } - printf("] %3ld%% %s", pct, status); - fflush(stdout); - } -@@ -226,6 +236,55 @@ - fflush(stdout); - } - -+/* ===== bar styles ===== */ -+ -+typedef struct { const char *name, *fill, *empty; } BarStyle; -+ -+static const BarStyle bar_styles[] = { -+ { "unicode", "\xe2\x96\x88", "\xe2\x96\x91" }, /* U+2588 U+2591 */ -+ { "ascii", "=", "-" }, -+ { "hash", "#", "." }, -+ { "dots", "\xe2\x80\xa2", "\xc2\xb7" }, /* U+2022 U+00B7 */ -+ { "line", "\xe2\x94\x81", "\xe2\x94\x80" }, /* U+2501 U+2500 */ -+ { "block", "\xe2\x96\x93", "\xe2\x96\x91" }, /* U+2593 U+2591 */ -+ { "arrow", "\xe2\x96\xb6", "\xe2\x96\xb7" }, /* U+25B6 U+25B7 */ -+ { "minimal", "", "" }, -+ { NULL, NULL, NULL } -+}; -+ -+static const BarStyle * -+find_bar_style(const char *name) -+{ -+ if (!name || !*name) return NULL; -+ for (int i = 0; bar_styles[i].name; i++) -+ if (!strcmp(bar_styles[i].name, name)) return &bar_styles[i]; -+ return NULL; -+} -+ -+static int -+is_utf8(void) -+{ -+ const char *l = setlocale(LC_CTYPE, ""); -+ if (!l) return 0; -+ return strstr(l, "UTF-8") || strstr(l, "utf8") || strstr(l, "utf-8"); -+} -+ -+static void -+resolve_bar(const Config *c, const char **fill, const char **empty, int *minimal) -+{ -+ *minimal = 0; -+ const char *name = (c->bar_style[0]) ? c->bar_style : BAR_STYLE; -+ const BarStyle *s = find_bar_style(name); -+ if (!s) s = find_bar_style(is_utf8() ? "unicode" : "ascii"); -+ if (s && !strcmp(s->name, "minimal")) { -+ *minimal = 1; -+ *fill = " "; *empty = " "; -+ return; -+ } -+ *fill = s ? s->fill : BAR_FILL; -+ *empty = s ? s->empty : BAR_EMPTY; -+} -+ - /* ===== usage ===== - * Patches MUST update this in lockstep with new flags so -h always - * reflects the build. -@@ -243,6 +302,7 @@ - "FLAGS:\n" - " -q no sound\n" - " -s silent\n" -+" --bar STYLE bar style: unicode|ascii|hash|dots|line|block|arrow|minimal\n" - " -- end of options\n" - " -h help\n" - "\n" -@@ -259,6 +319,10 @@ - int barw = cols - 40; - if (barw < 10) barw = 10; - -+ const char *fill_glyph, *empty_glyph; -+ int minimal = 0; -+ resolve_bar(cfg, &fill_glyph, &empty_glyph, &minimal); -+ - ttyfd = open("/dev/tty", O_RDONLY); - if (ttyfd >= 0 && isatty(ttyfd)) { - if (tcgetattr(ttyfd, &oldtios) == 0) { -@@ -300,7 +364,8 @@ - draw_stopwatch(elapsed_ms, paused); - } else { - if (out_tty) -- draw_countdown(total, elapsed_ms, paused, barw); -+ draw_countdown(total, elapsed_ms, paused, barw, -+ fill_glyph, empty_glyph, minimal); - if (!paused && elapsed_ms >= total * 1000L) break; - } - -@@ -399,6 +464,10 @@ - new_argv[new_argc++] = argv[i]; - continue; - } -+ if (!past_dd && !strcmp(argv[i], "--bar") && i + 1 < argc) { -+ snprintf(cfg.bar_style, sizeof(cfg.bar_style), "%s", argv[++i]); -+ continue; -+ } - new_argv[new_argc++] = argv[i]; - } - new_argv[new_argc] = NULL; |
