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

Pretty-print values in the REPL

Pretty-print values in the REPL by printing each item in a list or
attrset on a separate line. When possible, single-item lists and
attrsets are printed on one line, as long as they don't contain a nested
list, attrset, or thunk.

Before:
```
{ attrs = { a = { b = { c = { }; }; }; }; list = [ 1 ]; list' = [ 1 2 3 ]; }
```

After:
```
{
  attrs = {
    a = {
      b = {
        c = { };
      };
    };
  };
  list = [ 1 ];
  list' = [
    1
    2
    3
  ];
}
```
This commit is contained in:
Rebecca Turner 2024-02-04 00:40:30 -08:00
parent a31f2cb0cd
commit c0a15fb7d0
No known key found for this signature in database
6 changed files with 195 additions and 23 deletions

View file

@ -153,6 +153,7 @@ struct ImportantFirstAttrNameCmp
};
typedef std::set<const void *> ValuesSeen;
typedef std::vector<std::pair<std::string, Value *>> AttrVec;
class Printer
{
@ -163,6 +164,21 @@ private:
std::optional<ValuesSeen> seen;
size_t attrsPrinted = 0;
size_t listItemsPrinted = 0;
std::string indent;
void increaseIndent()
{
if (options.prettyPrint()) {
indent.append(options.prettyIndent, ' ');
}
}
void decreaseIndent()
{
if (options.prettyPrint()) {
indent.resize(indent.size() - options.prettyIndent);
}
}
void printRepeated()
{
@ -260,6 +276,28 @@ private:
}
}
bool shouldPrettyPrintAttrs(AttrVec & v)
{
if (!options.prettyPrint() || v.empty()) {
return false;
}
// Pretty-print attrsets with more than one item.
if (v.size() > 1) {
return true;
}
auto item = v[0].second;
if (!item) {
return true;
}
// Pretty-print single-item attrsets only if they contain nested
// structures.
auto itemType = item->type();
return itemType == nList || itemType == nAttrs || itemType == nThunk;
}
void printAttrs(Value & v, size_t depth)
{
if (seen && !seen->insert(v.attrs).second) {
@ -270,9 +308,10 @@ private:
if (options.force && options.derivationPaths && state.isDerivation(v)) {
printDerivation(v);
} else if (depth < options.maxDepth) {
output << "{ ";
increaseIndent();
output << "{";
std::vector<std::pair<std::string, Value *>> sorted;
AttrVec sorted;
for (auto & i : *v.attrs)
sorted.emplace_back(std::pair(state.symbols[i.name], i.value));
@ -281,7 +320,15 @@ private:
else
std::sort(sorted.begin(), sorted.end(), ImportantFirstAttrNameCmp());
auto prettyPrint = shouldPrettyPrintAttrs(sorted);
for (auto & i : sorted) {
if (prettyPrint) {
output << "\n" << indent;
} else {
output << " ";
}
if (attrsPrinted >= options.maxAttrs) {
printElided(sorted.size() - attrsPrinted, "attribute", "attributes");
break;
@ -290,13 +337,42 @@ private:
printAttributeName(output, i.first);
output << " = ";
print(*i.second, depth + 1);
output << "; ";
output << ";";
attrsPrinted++;
}
decreaseIndent();
if (prettyPrint) {
output << "\n" << indent;
} else {
output << " ";
}
output << "}";
} else
} else {
output << "{ ... }";
}
}
bool shouldPrettyPrintList(std::span<Value * const> list)
{
if (!options.prettyPrint() || list.empty()) {
return false;
}
// Pretty-print lists with more than one item.
if (list.size() > 1) {
return true;
}
auto item = list[0];
if (!item) {
return true;
}
// Pretty-print single-item lists only if they contain nested
// structures.
auto itemType = item->type();
return itemType == nList || itemType == nAttrs || itemType == nThunk;
}
void printList(Value & v, size_t depth)
@ -306,11 +382,20 @@ private:
return;
}
output << "[ ";
if (depth < options.maxDepth) {
for (auto elem : v.listItems()) {
increaseIndent();
output << "[";
auto listItems = v.listItems();
auto prettyPrint = shouldPrettyPrintList(listItems);
for (auto elem : listItems) {
if (prettyPrint) {
output << "\n" << indent;
} else {
output << " ";
}
if (listItemsPrinted >= options.maxListItems) {
printElided(v.listSize() - listItemsPrinted, "item", "items");
printElided(listItems.size() - listItemsPrinted, "item", "items");
break;
}
@ -319,13 +404,19 @@ private:
} else {
printNullptr();
}
output << " ";
listItemsPrinted++;
}
decreaseIndent();
if (prettyPrint) {
output << "\n" << indent;
} else {
output << " ";
}
output << "]";
} else {
output << "[ ... ]";
}
else
output << "... ";
output << "]";
}
void printFunction(Value & v)
@ -488,6 +579,7 @@ public:
{
attrsPrinted = 0;
listItemsPrinted = 0;
indent.clear();
if (options.trackRepeated) {
seen.emplace();