Why blinking?

I can’t be the only person who can’t stand it when a command spews a load of blinking text onto my screen.

A few days ago, I installed ``gh’’, github’s CLI and much to my dismay, there was much in the way of blinken lights. A simply command like:

: arioch; gh pr view 2451

would display the vast majority of its text blinking.

This makes it unreadable.

Unreadable, I say. At least, it takes well over twice as long to read the blob of text as it’s only on the screen for half the time. And to make things worse, you lose your place when the text is gone and so you have quite a limited time when the text finally reappears to (a) find where you were when the text was rudely yanked from your sight, and (b) make further progress reading it before it is snatched away again.

It is one thing to have but a single word blink. Annoying, yes, incredibly annoying to have this ugly blinking bit of text constantly begging for your visual attention. But, at least you can easily read a single blinking word. A blinking paragraph or a whole blinking blob on the other hand is an absolute abomination.

Now that we have our problem statement, let’s get to work. What should we do about this problem?

One way would be to edit the term{cap,info} entry of my terminal. I decided against this because I would need to update the terminfo on remote systems into which I ssh and the like. I could try and get less(1) or more(1) to do my dirty work for me, but this is even more fragile than term{cap,info} hackery. And, let’s be honest, lots of 1337 kids today just hard-code xterm/ansi escape sequences into their scripts completely ignoring term{cap,info}, so that wouldn’t even be complete.

No, I needed a solution that is simple and will completely solve the problem.

I decided that the most obvious thing to do would be to ask my terminal to stop das blinken lights for me. No matter what the 1337 developer does, nothing will make the lights blinken on my screen.

I am currently running st from suckless.org. This means that my option will be implemented in C. The code is simple, I define two preprocessor vars: ENABLE_ANNOYING_BLINKING_TEXT and ENABLE_ANNOYING_COLOURS. If these are set and true, the annoyance will be compiled in. By default, it is left out.

Please find the code in my copy of st as a single commit on the branch eliminate-annoying. The commit id is: 77a1374.

: arioch; git log -1 -p
commit 77a1374f6793f1d34b3cda70c753962ddefbe624
Author: Roland C. Dowdeswell <elric@imrryr.org>
Date:   Mon Aug 1 17:40:50 2022 +0800

    eliminate annoying blinking and colours

diff --git a/st.c b/st.c
index 6ba467d..4eb9ebb 100644
--- a/st.c
+++ b/st.c
@@ -1381,7 +1381,9 @@ tsetattr(const int *attr, int l)
                 case 5: /* slow blink */
                         /* FALLTHROUGH */
                 case 6: /* rapid blink */
+#if ENABLE_ANNOYING_BLINKING_TEXT
                         term.c.attr.mode |= ATTR_BLINK;
+#endif
                         break;
                 case 7:
                         term.c.attr.mode |= ATTR_REVERSE;
@@ -1414,28 +1416,40 @@ tsetattr(const int *attr, int l)
                         term.c.attr.mode &= ~ATTR_STRUCK;
                         break;
                 case 38:
+#if ENABLE_ANNOYING_COLOURS
                         if ((idx = tdefcolor(attr, &i, l)) >= 0)
                                 term.c.attr.fg = idx;
+#endif
                         break;
                 case 39:
                         term.c.attr.fg = defaultfg;
                         break;
                 case 48:
+#if ENABLE_ANNOYING_COLOURS
                         if ((idx = tdefcolor(attr, &i, l)) >= 0)
                                 term.c.attr.bg = idx;
+#endif
                         break;
                 case 49:
                         term.c.attr.bg = defaultbg;
                         break;
                 default:
                         if (BETWEEN(attr[i], 30, 37)) {
+#if ENABLE_ANNOYING_COLOURS
                                 term.c.attr.fg = attr[i] - 30;
+#endif
                         } else if (BETWEEN(attr[i], 40, 47)) {
+#if ENABLE_ANNOYING_COLOURS
                                 term.c.attr.bg = attr[i] - 40;
+#endif
                         } else if (BETWEEN(attr[i], 90, 97)) {
+#if ENABLE_ANNOYING_COLOURS
                                 term.c.attr.fg = attr[i] - 90 + 8;
+#endif
                         } else if (BETWEEN(attr[i], 100, 107)) {
+#if ENABLE_ANNOYING_COLOURS
                                 term.c.attr.bg = attr[i] - 100 + 8;
+#endif
                         } else {
                                 fprintf(stderr,
                                         "erresc(default): gfx attr %d unknown\n",

Take that 1337 script kiddies.

Written on August 1, 2022