diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index f292f06bb81..e9a076b20e0 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -66,6 +66,7 @@ struct NixRepl const static int envSize = 32768; std::shared_ptr staticEnv; + Value lastLoaded; Env * env; int displ; StringSet varNames; @@ -90,6 +91,7 @@ struct NixRepl void loadFile(const Path & path); void loadFlake(const std::string & flakeRef); void loadFiles(); + void showLastLoaded(); void reloadFiles(); void addAttrsToScope(Value & attrs); void addVarToScope(const Symbol name, Value & v); @@ -374,6 +376,7 @@ ProcessLineResult NixRepl::processLine(std::string line) << " current profile\n" << " :l, :load Load Nix expression and add it to scope\n" << " :lf, :load-flake Load Nix flake and add it to scope\n" + << " :ll, :last-loaded Show most recently loaded variables added to scope\n" << " :p, :print Evaluate and print expression recursively\n" << " Strings are printed directly, without escaping.\n" << " :q, :quit Exit nix-repl\n" @@ -464,6 +467,10 @@ ProcessLineResult NixRepl::processLine(std::string line) loadFlake(arg); } + else if (command == ":ll" || command == ":last-loaded") { + showLastLoaded(); + } + else if (command == ":r" || command == ":reload") { state->resetFileCache(); reloadFiles(); @@ -751,6 +758,16 @@ void NixRepl::initEnv() varNames.emplace(state->symbols[i.first]); } +void NixRepl::showLastLoaded() +{ + RunPager pager; + + for (auto & i : *lastLoaded.attrs()) { + std::string_view name = state->symbols[i.name]; + logger->cout(name); + } +} + void NixRepl::reloadFiles() { @@ -791,6 +808,27 @@ void NixRepl::addAttrsToScope(Value & attrs) staticEnv->sort(); staticEnv->deduplicate(); notice("Added %1% variables.", attrs.attrs()->size()); + + lastLoaded = attrs; + + const int max_print = 10; + int counter = 0; + std::ostringstream loaded; + for (auto & i : attrs.attrs()->lexicographicOrder(state->symbols)) { + if (counter >= max_print) + break; + + if (counter > 0) + loaded << ", "; + + printIdentifier(loaded, state->symbols[i->name]); + counter += 1; + } + + notice("%1%", loaded.str()); + + if (attrs.attrs()->size() > max_print) + notice("... and %1% more; view with :ll", attrs.attrs()->size() - max_print); } diff --git a/tests/functional/repl.sh b/tests/functional/repl.sh index 59d1f1be02a..ff4a74956ea 100755 --- a/tests/functional/repl.sh +++ b/tests/functional/repl.sh @@ -153,6 +153,32 @@ foo + baz ' "3" \ ./flake ./flake\#bar --experimental-features 'flakes' +testReplResponse $' +:a { a = 1; b = 2; longerName = 3; "with spaces" = 4; } +' 'Added 4 variables. +a, b, longerName, "with spaces" +' + +cat < attribute-set.nix +{ + a = 1; + b = 2; + longerName = 3; + "with spaces" = 4; +} +EOF +testReplResponse ' +:l ./attribute-set.nix +' 'Added 4 variables. +a, b, longerName, "with spaces" +' + +testReplResponseNoRegex $' +:a builtins.foldl\' (x: y: x // y) {} (map (x: { ${builtins.toString x} = x; }) (builtins.genList (x: x) 13)) +' 'Added 13 variables. +"0", "1", "10", "11", "12", "2", "3", "4", "5", "6" +... and 3 more; view with :ll' + # Test the `:reload` mechansim with flakes: # - Eval `./flake#changingThing` # - Modify the flake @@ -301,7 +327,8 @@ runRepl () { -e "s@$testDir@/path/to/tests/functional@g" \ -e "s@$testDirNoUnderscores@/path/to/tests/functional@g" \ -e "s@$nixVersion@@g" \ - -e "s@Added [0-9]* variables@Added variables@g" \ + -e "/Added [0-9]* variables/{s@ [0-9]* @ @;n;d}" \ + -e '/\.\.\. and [0-9]* more; view with :ll/d' \ | grep -vF $'warning: you don\'t have Internet access; disabling some network-dependent features' \ ; }