From 7be72ca667609ceb0124fd6f424f74f1171abc2c Mon Sep 17 00:00:00 2001 From: Qyriad Date: Thu, 8 Jan 2026 18:01:23 +0100 Subject: [PATCH] libcmd/repl: refactor to preserve order across :l/:lf Change-Id: I109bdd21a69aa5e6d7a8cc86350662cd6a6a6964 --- lix/libcmd/repl.cc | 50 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/lix/libcmd/repl.cc b/lix/libcmd/repl.cc index 8e846ecb0..1e582184a 100644 --- a/lix/libcmd/repl.cc +++ b/lix/libcmd/repl.cc @@ -83,6 +83,21 @@ enum class ProcessLineResult { using namespace std::literals::string_view_literals; +enum class ReplLoadKind +{ + File, + Flake, +}; + +// std::variant or virtual inheritence would both be overkill for this. +struct ReplLoadable +{ + std::string spec; + ReplLoadKind kind; + + friend constexpr auto operator<=>(ReplLoadable const &, ReplLoadable const &) = default; +}; + struct NixRepl; using ReplFunction = std::function; using PrintDerivationOutputFunction = @@ -136,8 +151,7 @@ struct NixRepl Evaluator & evaluator; size_t debugTraceIndex; - Strings loadedFiles; - Strings loadedFlakeRefs; + std::list loaded; std::function getValues; std::map> registeredCommands; @@ -1271,8 +1285,12 @@ void NixRepl::generateHelpCommand() void NixRepl::loadFile(const Path & path) { - loadedFiles.remove(path); - loadedFiles.push_back(path); + ReplLoadable loadable{ + .spec = path, + .kind = ReplLoadKind::File, + }; + loaded.remove(loadable); + loaded.push_back(loadable); Value v, v2; state.evalFile(state.aio.blockOn(lookupFileArg(evaluator, path)).unwrap(always_progresses), v); state.autoCallFunction(*autoArgs, v, v2, noPos); @@ -1288,11 +1306,16 @@ void NixRepl::loadFlake(const std::string & flakeRefS) if (evalSettings.pureEval && !flakeRef.input.isLocked()) throw Error("cannot use ':load-flake' on locked flake reference '%s' (use --impure to override)", flakeRefS); + ReplLoadable loadable{ + .spec = flakeRefS, + .kind = ReplLoadKind::Flake, + }; + Value v; try { - loadedFlakeRefs.remove(flakeRefS); - loadedFlakeRefs.push_back(flakeRefS); + loaded.remove(loadable); + loaded.push_back(loadable); flake::callFlake( state, flake::lockFlake( @@ -1310,7 +1333,7 @@ void NixRepl::loadFlake(const std::string & flakeRefS) } catch (...) { // In case of failure, do not keep the flake reference. // Let the user re-load it again later. - loadedFlakeRefs.remove(flakeRefS); + loaded.remove(loadable); throw; } } @@ -1339,12 +1362,15 @@ void NixRepl::reloadFiles() void NixRepl::loadFiles() { - Strings old = loadedFiles; - loadedFiles.clear(); + std::list saved{loaded}; - for (auto & i : old) { - notice("Loading '%1%'...", Magenta(i)); - loadFile(i); + loaded.clear(); + + for (auto const & [spec, kind] : saved) { + if (kind == ReplLoadKind::File) { + notice("Loading '%s'...", Magenta(spec)); + loadFile(spec); + } } for (auto & [i, what] : getValues()) {