diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2021-09-13 14:41:28 +0200 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2021-09-13 14:45:21 +0200 |
commit | 49a932fb18add471feefc469fb45fc44313bd5c6 (patch) | |
tree | 716a8abc8682f190b22d1b2fecb4ed45bb87ae55 /src/nix/main.cc | |
parent | 14205debb244b925d685e3645c4deef937fa78ec (diff) |
nix --help: Display help using lowdown instead of man
Fixes #4476.
Fixes #5231.
Diffstat (limited to 'src/nix/main.cc')
-rw-r--r-- | src/nix/main.cc | 46 |
1 files changed, 42 insertions, 4 deletions
diff --git a/src/nix/main.cc b/src/nix/main.cc index 008482be3..8aaf08813 100644 --- a/src/nix/main.cc +++ b/src/nix/main.cc @@ -10,6 +10,7 @@ #include "filetransfer.hh" #include "finally.hh" #include "loggers.hh" +#include "markdown.hh" #include <sys/types.h> #include <sys/socket.h> @@ -163,9 +164,43 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs } }; -static void showHelp(std::vector<std::string> subcommand) +/* Render the help for the specified subcommand to stdout using + lowdown. */ +static void showHelp(std::vector<std::string> subcommand, MultiCommand & toplevel) { - showManPage(subcommand.empty() ? "nix" : fmt("nix3-%s", concatStringsSep("-", subcommand))); + auto mdName = subcommand.empty() ? "nix" : fmt("nix3-%s", concatStringsSep("-", subcommand)); + + evalSettings.restrictEval = false; + evalSettings.pureEval = false; + EvalState state({}, openStore("dummy://")); + + auto vGenerateManpage = state.allocValue(); + state.eval(state.parseExprFromString( + #include "generate-manpage.nix.gen.hh" + , "/"), *vGenerateManpage); + + auto vUtils = state.allocValue(); + state.cacheFile( + "/utils.nix", "/utils.nix", + state.parseExprFromString( + #include "utils.nix.gen.hh" + , "/"), + *vUtils); + + auto vJson = state.allocValue(); + mkString(*vJson, toplevel.toJSON().dump()); + + auto vRes = state.allocValue(); + state.callFunction(*vGenerateManpage, *vJson, *vRes, noPos); + + auto attr = vRes->attrs->get(state.symbols.create(mdName + ".md")); + if (!attr) + throw UsageError("Nix has no subcommand '%s'", concatStringsSep("", subcommand)); + + auto markdown = state.forceString(*attr->value); + + RunPager pager; + std::cout << renderMarkdownToTerminal(markdown) << "\n"; } struct CmdHelp : Command @@ -194,7 +229,10 @@ struct CmdHelp : Command void run() override { - showHelp(subcommand); + assert(parent); + MultiCommand * toplevel = parent; + while (toplevel->parent) toplevel = toplevel->parent; + showHelp(subcommand, *toplevel); } }; @@ -277,7 +315,7 @@ void mainWrapped(int argc, char * * argv) } else break; } - showHelp(subcommand); + showHelp(subcommand, args); return; } catch (UsageError &) { if (!completions) throw; |