diff options
Diffstat (limited to 'src/libcmd/repl.cc')
-rw-r--r-- | src/libcmd/repl.cc | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 45b56d012..0d7ad63a7 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -36,8 +36,26 @@ #include <gc/gc_cpp.h> #endif +// XXX: These are for nix-doc features and will be removed in a future rewrite where this functionality is integrated more natively. +extern "C" { + char const *nd_get_function_docs(char const *filename, size_t line, size_t col); + void nd_free_string(char const *str); +} + namespace nix { + +/** Wrapper around std::unique_ptr with a custom deleter for strings from nix-doc **/ +using NdString = std::unique_ptr<const char, decltype(&nd_free_string)>; + +/** + * Fetch a string representing the doc comment using nix-doc and wrap it in an RAII wrapper. + */ +NdString lambdaDocsForPos(SourcePath const path, nix::Pos const &pos) { + std::string const file = path.to_string(); + return NdString{nd_get_function_docs(file.c_str(), pos.line, pos.column), &nd_free_string}; +} + /** * Returned by `NixRepl::processLine`. */ @@ -400,7 +418,7 @@ ProcessLineResult NixRepl::processLine(std::string line) << " nix-shell\n" << " :t <expr> Describe result of evaluation\n" << " :u <expr> Build derivation, then start nix-shell\n" - << " :doc <expr> Show documentation of a builtin function\n" + << " :doc <expr> Show documentation for the provided function (experimental lambda support)\n" << " :log <expr> Show logs for a derivation\n" << " :te, :trace-enable [bool] Enable, disable or toggle showing traces for\n" << " errors\n" @@ -629,8 +647,24 @@ ProcessLineResult NixRepl::processLine(std::string line) markdown += stripIndentation(doc->doc); logger->cout(trim(renderMarkdownToTerminal(markdown))); - } else - throw Error("value does not have documentation"); + } else if (v.isLambda()) { + auto pos = state->positions[v.lambda.fun->pos]; + if (auto path = std::get_if<SourcePath>(&pos.origin)) { + // Path and position have now been obtained, feed to nix-doc library to get data. + auto docComment = lambdaDocsForPos(*path, pos); + if (!docComment) { + throw Error("lambda '%s' has no documentation comment", pos); + } + + // Build and print Markdown representation of documentation comment. + std::string markdown = stripIndentation(docComment.get()); + logger->cout(trim(renderMarkdownToTerminal(markdown))); + } else { + throw Error("lambda '%s' doesn't have a determinable source file", pos); + } + } else { + throw Error("value '%s' does not have documentation", arg); + } } else if (command == ":te" || command == ":trace-enable") { |