1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-29 10:31:15 +02:00

Unify and refactor value printing

Previously, there were two mostly-identical value printers -- one in
`libexpr/eval.cc` (which didn't force values) and one in
`libcmd/repl.cc` (which did force values and also printed ANSI color
codes).

This PR unifies both of these printers into `print.cc` and provides a
`PrintOptions` struct for controlling the output, which allows for
toggling whether values are forced, whether repeated values are tracked,
and whether ANSI color codes are displayed.

Additionally, `PrintOptions` allows tuning the maximum number of
attributes, list items, and bytes in a string that will be displayed;
this makes it ideal for contexts where printing too much output (e.g.
all of Nixpkgs) is distracting. (As requested by @roberth in
https://github.com/NixOS/nix/pull/9554#issuecomment-1845095735)

Please read the tests for example output.

Future work:
- It would be nice to provide this function as a builtin, perhaps
  `builtins.toStringDebug` -- a printing function that never fails would
  be useful when debugging Nix code.
- It would be nice to support customizing `PrintOptions` members on the
  command line, e.g. `--option to-string-max-attrs 1000`.
This commit is contained in:
Rebecca Turner 2023-12-12 13:57:36 -08:00
parent c9125603a5
commit 0fa08b4516
No known key found for this signature in database
18 changed files with 1174 additions and 278 deletions

View file

@ -9,6 +9,7 @@
#include "value/context.hh"
#include "input-accessor.hh"
#include "source-path.hh"
#include "print-options.hh"
#if HAVE_BOEHMGC
#include <gc/gc_allocator.h>
@ -70,7 +71,7 @@ struct Pos;
class StorePath;
class EvalState;
class XMLWriter;
class Printer;
typedef int64_t NixInt;
typedef double NixFloat;
@ -82,6 +83,7 @@ typedef double NixFloat;
class ExternalValueBase
{
friend std::ostream & operator << (std::ostream & str, const ExternalValueBase & v);
friend class Printer;
protected:
/**
* Print out the value
@ -139,11 +141,9 @@ private:
friend std::string showType(const Value & v);
void print(const SymbolTable &symbols, std::ostream &str, std::set<const void *> *seen, int depth) const;
public:
void print(const SymbolTable &symbols, std::ostream &str, bool showRepeated = false, int depth = INT_MAX) const;
void print(EvalState &state, std::ostream &str, PrintOptions options = PrintOptions {});
// Functions needed to distinguish the type
// These should be removed eventually, by putting the functionality that's
@ -364,10 +364,15 @@ public:
inline void mkPrimOpApp(Value * l, Value * r)
{
internalType = tPrimOpApp;
app.left = l;
app.right = r;
primOpApp.left = l;
primOpApp.right = r;
}
/**
* For a `tPrimOpApp` value, get the original `PrimOp` value.
*/
PrimOp * primOpAppPrimOp() const;
inline void mkExternal(ExternalValueBase * e)
{
clearValue();