Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Command syntax: Avoid repetition for shorter rendering (simplifications) #118

Open
zuiderkwast opened this issue Aug 31, 2024 · 1 comment
Labels
enhancement New feature or request

Comments

@zuiderkwast
Copy link
Contributor

Some command syntaxes are extremely long on the website, for example CLIENT KILL:

CLIENT KILL 〈 old-format | 〈 [ ID client-id ] | [ TYPE normal | master | primary | slave | replica | pubsub ] | [ USER username ] | [ ADDR addr ] | [ LADDR laddr ] | [ SKIPME yes | no ] | [ MAXAGE maxage ] 〉 [ 〈 [ ID client-id ] | [ TYPE normal | master | primary | slave | replica | pubsub ] | [ USER username ] | [ ADDR addr ] | [ LADDR laddr ] | [ SKIPME yes | no ] | [ MAXAGE maxage ] 〉 ... ] 〉

It's a bit hard to read it.

Describe the solution you'd like

In the man pages, there is another rendering, equivalent but shorter:

CLIENT KILL ip:port
CLIENT KILL [<ID client-id | TYPE <NORMAL | MASTER | PRIMARY | SLAVE | REPLICA | PUBSUB> | USER username | ADDR ip:port | LADDR ip:port | SKIPME <YES | NO> | MAXAGE maxage>...]

Differences:

  1. When everything after the command and subcommand name is a single "oneof" argument, the syntax can be split into multiple lines, so COMMAND SUBCOMMAND <old-format | new-format> becomes COMMAND SUBCOMMAND old-format and on a separate line COMMAND SUBCOMMAND new-format. This multiline display is often used on man pages and --help output of commands, for example this one:

    SYNOPSIS
           git diff [<options>] [<commit>] [--] [<path>...]
           git diff [<options>] --cached [--merge-base] [<commit>] [--] [<path>...]
           git diff [<options>] [--merge-base] <commit> [<commit>...] <commit> [--] [<path>...]
           git diff [<options>] <commit>...<commit> [--] [<path>...]
           git diff [<options>] <blob> <blob>
           git diff [<options>] --no-index [--] <path> <path>
    
  2. ip:port instead of old-format. Just use the "display" field in the JSON defintion, if it's available. This argument has a JSON definition like this:

                 {
                     "name": "old-format",
                     "display": "ip:port",
                     "type": "string",
                     "deprecated_since": "2.8.12"
                 },
    
  3. Rewrite to simplify. When an argument has "type": "oneof" and not optional, but all of its arguments have "optional": true, then we can move the optional property to the outer "oneof" argument.

    < [a] | [b] | [c] > ...
    

    becomes

    [ <a | b | c> ... ]
    

    In the CLIENT KILL example, the argument that starts with 〈 [ ID client-id ] | ... 〉 can benefit from this rewrite.

  4. When a "oneof" that is not optional, it is rendered as <a | b>. If this thing also has the "multiple": true propery, then it's currently rendered as <a | b> [ <a | b> ... ], i.e. the whole oneof thing is repeated. This combination often becomes too long to be readable.

    When I experimented with combinations of "oneof", "multiple", "optional" and "block", I realized that it's good to consider combinations of these and define a syntax for each combinatio. I ended up with the following style, which is what's applied in the suggestion above.

    simple                       foo
    optional                     [foo]
    multiple                     foo [foo...]
    multiple + optional          [foo...]
    
    oneof                        <foo | bar>
    oneof + optional             [foo | bar]
    oneof + multiple             <foo | bar> [<foo | bar>...]
    oneof + multiple + optional  [<foo | bar>...]
    
    block                        foo bar
    block + optional             [foo bar]
    block + multiple             foo bar [foo bar ...]
    block + multiple + optional  [foo bar [foo bar ...]]
    

Additional context

  • There's an implementation of all of the above ideas in the Python script utils/command_syntax.py in the doc repo. It can be used for inspiration and probably be translated to Zola.

  • Redis webpage isn't much better. It renders this command as:

  CLIENT KILL <ip:port | <[ID client-id] | [TYPE <NORMAL | MASTER |
  SLAVE | REPLICA | PUBSUB>] | [USER username] | [ADDR ip:port] |
  [LADDR ip:port] | [SKIPME <YES | NO>] | [MAXAGE maxage]
  [[ID client-id] | [TYPE <NORMAL | MASTER | SLAVE | REPLICA |
  PUBSUB>] | [USER username] | [ADDR ip:port] | [LADDR ip:port] |
  [SKIPME <YES | NO>] | [MAXAGE maxage] ...]>>`.
@zuiderkwast zuiderkwast added the enhancement New feature or request label Aug 31, 2024
@stockholmux
Copy link
Member

The multiple line version is definitely clearer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants