aboutsummaryrefslogtreecommitdiff
path: root/src/nix/main.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/nix/main.cc')
-rw-r--r--src/nix/main.cc46
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;