[Toybox] Help text spacing.

Rob Landley rob at landley.net
Tue Oct 10 02:36:02 PDT 2023

It's time to explain "toybox help text indentation policy". Like the coding
style section of code.html, only end-user visible! Yeah yeah, "watching paint
dry" levels of thrilling, but I do try to get this right. Consistency helps
comprehension, and we don't give people a LOT of documentation so what's there
has to work hard.

Most toybox help text has one tab between command line short options and their
descriptions. (acpi, base32, base64, blkid, bunzip2, cal, cat, chgrp, chown,
cksum, cmp, comm, cmp, df, dmesg, du, echo, env, expand, factor, file, flock,
free, fsfreeze, fsync, ftpget, getconf, gpioget, gpioset, gunzip, reboot, halt,
poweroff, head, help, host, hostname, httpd, hwclock, i2cdetect, i2cdump,
i2cget, i2cset, i2ctransfer, iconv, id, install, ionice, iotop, kill, killall,
killall5, ln, logger, login, losetup, lsattr, lspci, lsusb, md5sum and friends,
microcom, mkdir, mknod, mkpasswd, mktemp, mount, mountpoint, mv, nbd-client,
nbd-server, netcat, netstat, nl, nproc, nsenter, od, oneit, paste, pgrep, pidof,
pkill, pmap, printenv, pwd, readlink, rm, rmmod, seq, setfattr, setsid, sha3sum,
shuf, sntp, sort, split, strings, su, swapon, switch_root, sysctl, tail,
taskset, tee, time, top, touch, truncate, tty, tunctl, umount, uname, uniq,
unshare, uptime, uudecode, uuencode, vmstat, watch, watchdog, wc, which, xargs,
xxd, zcat)

Some commands use TWO tabs (basename, blkdiscard, blockdev, fmt, mix, ping,
shred) when things like -s SUFFIX are longer than 8 columns so everything gets
bumped rather than having a misaligned column.

Some commands (test, ls, ps, inotifyd, tar, ulimit) with a lot of options to get
through use a multi-column display, which has two spaces after each option. Note
that when "inotifyd" does this what it's documenting ISN'T single character
short options starting with a dash, and "tar" cheats because "tar xvzf" doesn't
require a dash, so tar --help doesn't put a dash on its (multicolumn) initial
option display, which has two spaces. (While "ps" could similarly cheat, I
didn't and I haven't actually implemented the BSD style options yet, although
the plumbing in lib/args.c is there to distinguish "ps ax" from "ps -ax". It
can't handle "ps a -a" but neither can debian's ps, it gives an error if you do

Some commands (chattr, chrt, cp, cpio, date, echo, hexedit, ifconfig, makedevs,
patch, readelf, rmdir, route, rtcwake, sed, sh, stat, timeout) have a single tab
section for "standard" command line short options, and then a two space (or two
tab!) section that's either multicolumn or for things that aren't command line
sort options, or other generally weird bit usually at the end.

Note that "date" uses single space because it's a bit short on horizontal space
in 80 columns, but also the %X escapes are very regular. The real issue is some
entries have only a single space on the RIGHT before the next column, and having
two spaces between "%e day" makes that stand out and looks worse than just one.)
There's similar single spacing in the "sed" help, which is the longest help text
in the entire project, and inherently kind of of overwhelming.

The help text for "find" is just nuts, it cheats extensively: it uses two tabs
in the first column, and one tab in the second column, because everything is a
--longopt and commands are grouped semi-arbitrarily. They're not remotely
alphabetical, they're KIND of grouped by function, and sort of grouped-ish by
what argument they take after the option, and really I just did the best I could
to make it all line up and fit in the space. And then at the end it's got "%a
blah" with two spaces. Oh, and you notice how one help text entry WOULD have
only one space before the third column and instead I left a GAP in the third
column? Yeah, that one's all over the place. Suggestions welcome. That one's
help text is held together by spackle.

The help text for "dd" is also nuts, but then dd's command line options ARE
nuts. There is no sane way to explain dd's command line options because they're
not, and posix still thinks it should handle ebcdic, and some years ago people
on this list were honestly trying to convince me that the posix dd specification
was IEEE's version of the IETF April Fools RFC's, and not meant to be taken
seriously. I don't apologize for that one, it's the least bad I could manage.

Some minor cheats: "free" doesn't give -b -k -m -g individual lines and "rm"
does this with -rR, "patch" punts on the longopt alignment where "readelf"
leaves a blank space, which is preferable? (TODO question, that. See also rmdir,
and timeout, and... half the group starting with "chattr" above) "ps" ends with
a "Which FIELDs to show." section that's single column and COULD be tab spaced,
but having that at the end instead of the beginning would be weird and moving
it... peer pressure gain. Works in context.

The "grep" help text is possibly wrong. It has 31 commands and is
weird-because-long, but possibly that first section (both options of it) should
be single tab indent? Except once upon a time -e and -f were on the same line
(multicolumn!), so that having tab indents was out and everything being two
spaces was eh, close enough, even though the "file search:" section is one
column and could be a second section of tab indents. Then when -e and -f got
rephrased and didn't fit anymore, but everything ELSE being single space kinda
did a peer pressure thing. The "file search" section also _wants_ to be
multiline but I can't figure out how to phrase it tersely enough, and the
capitalization of the section names is inconsistent with other commands...

"mcookie". "modinfo", "openvt", "passwd", "pwgen", "realpath", "uclampset",
"wc", and "wget" are all just wrong, and I should fix them. And "renice" only
has a usage: line, it needs documenting. And "rfkill" needs... something. As
does "vconfig".

(Fixing pwgen: --longopt synonyms usually go at the end of the line (in
parentheses) so no need for a TRIPLE INDENT to make room for them, and -r is
just wrong, it should be [-r CHARS] in the usage and then -r CHARS\t in the
list, which fits in one tab. And then there's the --no-capitalize --no-numerals
command pairs that I really should figure out a good way for lib/args.c to
represent automatically, maybe the [-cA][-n0] blocks at the end could create a
--no-thingy option for the "switch off" short opt in the pair if it hasn't
already got one? Hmmm. Throw it on the todo heap.)

Some dubious things jumped out at me doing a review of "for i in $(toybox); do
toybox --help $i | less; done" and then hitting q a lot, like "usage: nice [-n
PRIORITY] COMMAND..." not actually having a -n line in the help text. (I mean,
the text describes what -n does, it's not WRONG...) And "ulimit" should have
"section labels:" rather than just an unexplained blank line, but I don't know
what to CALL the sections (the second group is what specific limit(s) to show or
set, the first group is control stuff).

Some commands are one tab instead of two tab because they don't stick the
argument NAME in between the short opt and the description. (setfattr and
sha3sum don't but then shred does, and then shuf and sntp don't again...)
Probably needs a look over everything to see which is doing what, and whether to
convert them all to one style or the other. Also, some commands still have
lowercase argument names in their usage: line and should be converted to the new

I'm annoyed by "usage: ???sum [bcs] [FILE]..." but don't have a mechanism to
swap in the current command name there. I feel I _should_ have such a mechanism,
and may need to try to address that. It comes up in a number of shared commands
(chgrp/chown, reboot/halt/poweroff, egrep and fgrep just claim to be "grep",
prlimit claims to be ulimit... basically grep for OLDTOY in toys/*/*.c and then
grep -v pending, and that's the ones that might need examining.) Sigh, throw it
on the todo heap...

I should try to describe "tac" vs "rev" better...

Anyway, there should probably be a section in code.html or design.html or
something explaining all that. Why the help text is like it is.


More information about the Toybox mailing list