forked from lix-project/lix
nix repl ':doc': Render using lowdown
This commit is contained in:
parent
0f314f3c25
commit
d0690bc311
|
@ -15,11 +15,12 @@ nix_SOURCES := \
|
|||
$(wildcard src/nix-prefetch-url/*.cc) \
|
||||
$(wildcard src/nix-store/*.cc) \
|
||||
|
||||
nix_CXXFLAGS += -I src/libutil -I src/libstore -I src/libfetchers -I src/libexpr -I src/libmain
|
||||
# -fpermissive is needed by lowdown.
|
||||
nix_CXXFLAGS += -I src/libutil -I src/libstore -I src/libfetchers -I src/libexpr -I src/libmain -fpermissive
|
||||
|
||||
nix_LIBS = libexpr libmain libfetchers libstore libutil
|
||||
|
||||
nix_LDFLAGS = -pthread $(SODIUM_LIBS) $(EDITLINE_LIBS) $(BOOST_LDFLAGS) -lboost_context -lboost_thread -lboost_system
|
||||
nix_LDFLAGS = -pthread $(SODIUM_LIBS) $(EDITLINE_LIBS) $(BOOST_LDFLAGS) -lboost_context -lboost_thread -lboost_system -llowdown
|
||||
|
||||
$(foreach name, \
|
||||
nix-build nix-channel nix-collect-garbage nix-copy-closure nix-daemon nix-env nix-hash nix-instantiate nix-prefetch-url nix-shell nix-store, \
|
||||
|
|
50
src/nix/markdown.cc
Normal file
50
src/nix/markdown.cc
Normal file
|
@ -0,0 +1,50 @@
|
|||
#include "markdown.hh"
|
||||
#include "util.hh"
|
||||
#include "finally.hh"
|
||||
|
||||
#include <sys/queue.h>
|
||||
extern "C" {
|
||||
#include <lowdown.h>
|
||||
}
|
||||
|
||||
namespace nix {
|
||||
|
||||
std::string renderMarkdownToTerminal(std::string_view markdown)
|
||||
{
|
||||
struct lowdown_opts opts {
|
||||
.type = LOWDOWN_TERM,
|
||||
.maxdepth = 20,
|
||||
.cols = std::min(getWindowSize().second, (unsigned short) 80),
|
||||
.hmargin = 0,
|
||||
.vmargin = 0,
|
||||
.feat = LOWDOWN_COMMONMARK | LOWDOWN_FENCED | LOWDOWN_DEFLIST | LOWDOWN_TABLES,
|
||||
.oflags = 0,
|
||||
};
|
||||
|
||||
auto doc = lowdown_doc_new(&opts);
|
||||
if (!doc)
|
||||
throw Error("cannot allocate Markdown document");
|
||||
Finally freeDoc([&]() { lowdown_doc_free(doc); });
|
||||
|
||||
size_t maxn = 0;
|
||||
auto node = lowdown_doc_parse(doc, &maxn, markdown.data(), markdown.size());
|
||||
if (!node)
|
||||
throw Error("cannot parse Markdown document");
|
||||
Finally freeNode([&]() { lowdown_node_free(node); });
|
||||
|
||||
auto renderer = lowdown_term_new(&opts);
|
||||
if (!renderer)
|
||||
throw Error("cannot allocate Markdown renderer");
|
||||
Finally freeRenderer([&]() { lowdown_term_free(renderer); });
|
||||
|
||||
auto buf = lowdown_buf_new(16384);
|
||||
if (!buf)
|
||||
throw Error("cannot allocate Markdown output buffer");
|
||||
Finally freeBuffer([&]() { lowdown_buf_free(buf); });
|
||||
|
||||
lowdown_term_rndr(buf, nullptr, renderer, node);
|
||||
|
||||
return std::string(buf->data, buf->size);
|
||||
}
|
||||
|
||||
}
|
7
src/nix/markdown.hh
Normal file
7
src/nix/markdown.hh
Normal file
|
@ -0,0 +1,7 @@
|
|||
#include "types.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
std::string renderMarkdownToTerminal(std::string_view markdown);
|
||||
|
||||
}
|
|
@ -32,6 +32,7 @@ extern "C" {
|
|||
#include "globals.hh"
|
||||
#include "command.hh"
|
||||
#include "finally.hh"
|
||||
#include "markdown.hh"
|
||||
|
||||
#if HAVE_BOEHMGC
|
||||
#define GC_INCLUDE_NEW
|
||||
|
@ -518,10 +519,16 @@ bool NixRepl::processLine(string line)
|
|||
while (v2->type == tPrimOpApp)
|
||||
v2 = v2->primOpApp.left;
|
||||
if (v2->primOp->doc) {
|
||||
// FIXME: format markdown.
|
||||
if (!v2->primOp->args.empty())
|
||||
std::cout << fmt("Arguments: %s\n\n", concatStringsSep(" ", v2->primOp->args));
|
||||
std::cout << trim(stripIndentation(v2->primOp->doc)) << "\n";
|
||||
auto args = v2->primOp->args;
|
||||
for (auto & arg : args)
|
||||
arg = "*" + arg + "*";
|
||||
|
||||
auto markdown =
|
||||
"**Synopsis:** `builtins." + (std::string) v2->primOp->name + "` "
|
||||
+ concatStringsSep(" ", args) + "\n\n"
|
||||
+ trim(stripIndentation(v2->primOp->doc));
|
||||
|
||||
std::cout << renderMarkdownToTerminal(markdown);
|
||||
} else
|
||||
throw Error("builtin function '%s' does not have documentation", v2->primOp->name);
|
||||
} else
|
||||
|
|
Loading…
Reference in a new issue