Rounding the corner to completion on a project
I've worked on for 5 or 6 years & now I'm stumped
by a very simple thing...
When the user passes no arguments, I default to
the panel below, yet I wonder if its expressed
concisely enough to avoid confusion or promote it...
I don't feel its too bad, but then again I know
what its doing while others wont.
Hoping to read responses on you'd express this.
Syntax: tinybase OPTION - INPUT
Options (use 1 option per invocation):
Tag query: -q 'comma seperated queries'
Tag index: -t
Tinybase manual: -m
Input:
File list: - file1 file2 file3
Stdin: - <<EOF
Examples:
tinybase -q 'query1, query2, query3' - *.txt
tinybase -t - *.txt
tinybase -m > manual.txt
Rounding the corner to completion on a project
I've worked on for 5 or 6 years & now I'm stumped
by a very simple thing...
When the user passes no arguments, I default to
the panel below, yet I wonder if its expressed
concisely enough to avoid confusion or promote it...
I don't feel its too bad, but then again I know
what its doing while others wont.
Syntax: tinybase OPTION - INPUT
Options (use 1 option per invocation):
Tag query: -q 'comma seperated queries'
Input:
While file arguments are part of the interface syntax
redirections (like <<EOF) are just technical shell
building blocks; I wouldn't include them in the usage
description.
Examples are fine (but '-' is syntactically unnecessary).
A description is completely missing. (And a manual page
should also have information about exit status codes.)
My preference for usage information goes in the direction
(despite being also - like your "Syntax" line - formally
not perfectly accurate)...
Synopsis:
tinybase [ -q queries... | -t | -m ] files...
Options:
-q queries... comma separated list of queries
-t <tag index?>
-m show manual
Description:
...
Examples:
tinybase -q 'query1, query2, query3' - *.txt
tinybase -t - *.txt
tinybase -m > manual.txt
Don't try and teach in an if(argc <
People who type the program name alone need one of two things:
a) a brief description of the program's purpose;
OR
b) a brief reminder of usage.
Here's an example from my own corpus:
$ transpose
transpose infile amount [outfile]
transposes a Lilypond metafile ($TRANSPOSE$ tag present)
from one key to another.
infile: the file to transpose
amount: number of semitones to transpose (-ve = down, +ve = up)
outfile: if specified, output is written here.
Otherwise, the input file is modified.
That's enough to
a) tell you whether it's the program you wanted, or
b) remind you of how you use it
It doesn't try to teach you music theory. If your program needs a
manual, your descriptive passage should point at it - eg See
README for more details.
FILE(S) is less ambiguous. If your user doesn't know what files
are and you try to teach him, you're in for a world of hurt.
When the user passes no arguments, I default to
the panel below, yet I wonder if its expressed
concisely enough to avoid confusion or promote it...
Syntax: tinybase OPTION - INPUT
Options (use 1 option per invocation):
Tag query: -q 'comma seperated queries'
Tag index: -t
Tinybase manual: -m
Input:
File list: - file1 file2 file3
Stdin: - <<EOF
Examples:
tinybase -q 'query1, query2, query3' - *.txt
tinybase -t - *.txt
tinybase -m > manual.txt
These options are, essentially, "modes". The utility provides three
things it can do and they can't be mixed. Some utilities use alternate names: tinybase-query, tinybase-tag and tinybase-manual would all be
symbolic links to one executable. That's probably over the top for this program, but I would describe it as three separate use cases with three separate syntax lines.
Here's where I'm at (like your 'mode' anaology):
Usage: tinybase [ -q queries... | -t | -m ] [ files... ]
Options:
-q query mode: find blocks with matching tags or wildcards
example: tinybase -q 'query1, query2' files (if no files are
given, reads from standard input)
-t tag index mode: list all unique tags across the given files
example: tinybase -t files
-m manual mode: show the built-in documentation
Notes:
Multiple queries are comma-separated.
Wildcards (*, ?) are supported in queries.
When no files are provided, stdin is read automatically.
On Fri, 07 Nov 2025 13:08:26 +0000, Ben Bacarisse wrote:
These options are, essentially, "modes". The utility provides three
things it can do and they can't be mixed. Some utilities use alternate
names: tinybase-query, tinybase-tag and tinybase-manual would all be
symbolic links to one executable. That's probably over the top for this
program, but I would describe it as three separate use cases with three
separate syntax lines.
Well hey there Ben, hope you're doing alright.
Also hope Janis & Richard are reading too as I've tried
to incorporate the best of all three of your replies.
Here's where I'm at (like your 'mode' anaology):
Usage: tinybase [ -q queries... | -t | -m ] [ files... ]
Options:
-q query mode: find blocks with matching tags or wildcards
example: tinybase -q 'query1, query2' files
(if no files are given, reads from standard input)
Now you’re starting to write an entire man page within your program.
It is common for utilities to accept '-' as a filename
which indicates that input should come from stdin.
For example;
NAME
cat - concatenate files and print on the standard output
On Fri, 07 Nov 2025 13:08:26 +0000, Ben Bacarisse wrote:
These options are, essentially, "modes". The utility provides three
things it can do and they can't be mixed. Some utilities use alternate
names: tinybase-query, tinybase-tag and tinybase-manual would all be
symbolic links to one executable. That's probably over the top for this
program, but I would describe it as three separate use cases with three
separate syntax lines.
Well hey there Ben, hope you're doing alright.
Also hope Janis & Richard are reading too as I've tried
to incorporate the best of all three of your replies.
Here's where I'm at (like your 'mode' anaology):
Usage: tinybase [ -q queries... | -t | -m ] [ files... ]
Options:
-q query mode: find blocks with matching tags or wildcards
example: tinybase -q 'query1, query2' files
(if no files are given, reads from standard input)
-t tag index mode: list all unique tags across the given files
example: tinybase -t files
-m manual mode: show the built-in documentation
Notes:
Multiple queries are comma-separated.
Wildcards (*, ?) are supported in queries.
When no files are provided, stdin is read automatically.
I'm pretty sure I've read every article in this thread, but I
still have no idea what tinybase actually does. Is it an analyser
for alkaline chemical structures, or a nucleobase designer, or a
microRDBMS, or what?
tinybase really ought to tell you that, in just a sentence or two.
On Fri, 7 Nov 2025 21:25:52 +0000, Richard Heathfield wrote:
I'm pretty sure I've read every article in this thread, but I
still have no idea what tinybase actually does. Is it an analyser
for alkaline chemical structures, or a nucleobase designer, or a
microRDBMS, or what?
tinybase really ought to tell you that, in just a sentence or two.
Yup you're absolutely right. Here's my latest. Getting close...
Usage: tinybase [ -q queries... | -t | -r | -m ] [ files... ]
Synopsis: Tag based search tool
Options:
-q query mode: find blocks with matching tags or wildcards
example: tinybase -q 'query1, query2' files
-t tag index mode: list all unique tags across given files
example: tinybase -t files
-r repl mode: interactive shell for tag queries
example: tinybase -r files
-m manual mode: show built-in documentation
[...]
For a program that requires at least some command-line arguments, a very short message that points the user to a "-h" or "--help" option can be useful. Don't show a very long usage message unless the user explicitly
asks for it. [...]
"rm --help" prints a 39-line message. (I'm not going to get into
whether "-h" or "--help" is better. The latter is a GNU convention.)
Unfortunately, this doesn't work for a command that can validly be run
with no arguments, like cat.
Print error messages to stderr, usage messages (at least if
requested via some kind of help option) to stdout. I've seem
commands where "foo --help" prints more text than can fit on my
screen, and "foo --help | less" shows me nothing because the output
I asked for was sent to stderr.
[...]
The problem with a choice of -h for that is that this letter h might[...]
be a good choice for an existing functional option and would then not
be available any more for that. (I thus consider this "convention" a
badly decided thing as far as -h is concerned, while --help is okay.)
We've thus used -? for that usage purpose, a _non-letter_ character;
it was standard in all our tools and I'm still using that convention
in my private context.
"rm --help" prints a 39-line message.
On Fri, 7 Nov 2025 19:43:28 -0000 (UTC), Lawrence D’Oliveiro wrote:
Now you’re starting to write an entire man page within your program.
Emacs! =)
I'm working on whittling it down Lawrence, its just that I cant hit that elusive (for me) mark between terse/concise.
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
[...]
The problem with a choice of -h for that is that this letter h might[...]
be a good choice for an existing functional option and would then not
be available any more for that. (I thus consider this "convention" a
badly decided thing as far as -h is concerned, while --help is okay.)
We've thus used -? for that usage purpose, a _non-letter_ character;
it was standard in all our tools and I'm still using that convention
in my private context.
'?' is a shell wildcard, matching a single character in a file name.
"foo -?" will expand to "foo -x" if you happen to have a file in
the current directory named "-x" (and foo's "-x" option obviously
tells it to delete your home directory). If you have no such file,
the behavior of "foo -?" depends on your shell and its settings,
but typically no substitution takes place.
This is specific to the behavior of shells on Unix-like systems,
but if you're writing a C program intended to work on such systems
(and possibly others), it's good to be aware of the issue.
Few Unix commands use "-?" to mean "print a usage message".
For those that do, I would escape the question mark.
I would remove most or all of the blank lines, just to avoid using up
too much of the user's screen real estate. The longer your usage
message, the more of the user's on-screen information might be lost.
For a program that requires at least some command-line arguments, a very short message that points the user to a "-h" or "--help" option can be useful. Don't show a very long usage message unless the user explicitly
asks for it. GNU coreutils rm is a decent example:
$ rm
rm: missing operand
Try 'rm --help' for more information.
"rm --help" prints a 39-line message. (I'm not going to get into
whether "-h" or "--help" is better. The latter is a GNU convention.)
Unfortunately, this doesn't work for a command that can validly be run
with no arguments, like cat.
Print error messages to stderr, usage messages (at least if
requested via some kind of help option) to stdout. I've seem
commands where "foo --help" prints more text than can fit on my
screen, and "foo --help | less" shows me nothing because the output
I asked for was sent to stderr. (This is getting a bit OS-specific,
but it's applicable to any Unix-like system, and your use of '-'
to introduce arguments suggest that that's what you're aiming for.)
Something else you might consider is how you handle the different
modes. If I understand correctly (and I'm not at all sure I do),
"-q", "-t", "-r", and "-m" are distinct modes, and you have
to specify exactly one. If that's the case, you might consider
making them subcommands, similar to the way "git" has "git commit",
"git log", et al.
tinybase query ...
tinybase tag ...
tinybase repl ...
tinybase manual ...
If you like, you can allow the subcommand name to be abbreviated.
So I *still* don't know what tinybase does. It's like you're
trying to hide it.
trying to do the right thing.
Fair enough. Here the right thing is to describe in a few words
what your program does. Over a hundred isn't a few.
I'd give you a hand, but after reading your 114-word description
I was left none the wiser.
I don't be think I'll be replying again because I'm not sure I
can think of another way of saying 'describe in a few words what
your program does'.
On Sat, 8 Nov 2025 13:46:43 +0000, Richard Heathfield wrote:
Fair enough. Here the right thing is to describe in a few words what
your program does. Over a hundred isn't a few.
I'd give you a hand, but after reading your 114-word description I
was left none the wiser.
I don't be think I'll be replying again because I'm not sure I can
think of another way of saying 'describe in a few words what your
program does'.
Sorry I disagree: You're simultaneously telling me too much info
is bad while too little is bad as well?
No, the key thing he's pointing out it that it's not clear what the description you've provided means. At least, like Richard, after reading
your description I had no idea what it was supposed to mean.
I don't be think I'll be replying again because I'm not sure I
can think of another way of saying 'describe in a few words what
your program does'.
| Sysop: | DaiTengu |
|---|---|
| Location: | Appleton, WI |
| Users: | 1,076 |
| Nodes: | 10 (1 / 9) |
| Uptime: | 81:34:45 |
| Calls: | 13,805 |
| Files: | 186,990 |
| D/L today: |
7,334 files (2,461M bytes) |
| Messages: | 2,443,323 |