Skip to content

Instantly share code, notes, and snippets.

@siberex
Last active August 24, 2021 19:20
Show Gist options
  • Save siberex/904e7d834107b21470d07e382ac7dd85 to your computer and use it in GitHub Desktop.
Save siberex/904e7d834107b21470d07e382ac7dd85 to your computer and use it in GitHub Desktop.
CLI spinner fun

How it started:

let i = 0,
    spin = () => process.stdout.write(`  ${[...'⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'][i++ % 10]}\r`),
    stop = (id => () => clearInterval(id))(setInterval(spin, 100));

And I simply could not resist from sticking generator in it:

const spinIt = function* () {
    let s = [...'⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'],
        i = -1; 
    while (true) 
        yield s[i = ++i % s.length];
}

const it = spinIt(),
    spin = () => process.stdout.write(`  ${it.next().value}\r`),
    stop = (id => () => clearInterval(id))(setInterval(spin, 100));

A bit of explanation.

Using i = -1 and i = ++i % s.length are not strictly needed.

In case of integer overflow it will still work fine. So i++ % s.length is totally safe.

Also, the last line is just a shorthand for:

const stop = (function (id) {
    return function () {
        return clearInterval(id);
    };
})(
    setInterval(spin, 100)
);

OK, now I want to compact that in 3 lines or less...

const it = function* (){let s = [...'⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'], i = -1; while (true) yield s[++i % s.length]}(),
    spin = () => process.stdout.write(`  ${it.next().value}\r`),
    stop = (id => () => clearInterval(id))(setInterval(spin, 100));

And simplify a bit back to original:

const it = function* (){let i = 0; while (true) yield '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'[i++ % 10]}(),
    spin = () => process.stdout.write(`  ${it.next().value}\r`),
    stop = (id => () => clearInterval(id))(setInterval(spin, 100));

And I should really stop here.

But then I thought... What about good old Perl-style code golf?

let it = function* (){let i = 0; while (true) yield process.stdout.write(`  ${'⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'[i++ % 10]}\r`)}(),
    stop = (id => () => clearInterval(id))(setInterval(() => it.next(), 100));

Let it stop, lol.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment