From ca40ce8671610605a642d5a0c2c3bf64c83bf3f4 Mon Sep 17 00:00:00 2001 From: Qyriad Date: Wed, 4 Mar 2026 19:45:48 +0100 Subject: [PATCH] repl: always reload, but restore on failure This might do more copies than are necessary. I think that's fine. Sorry, :reload not reloading has been bothering the shit out of us. Fixes #1115. Change-Id: I7f4caca3dad39696ce66ce57b1a520836a6a6964 --- lix/libcmd/repl.cc | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/lix/libcmd/repl.cc b/lix/libcmd/repl.cc index d5dcd6cb3..427ceba01 100644 --- a/lix/libcmd/repl.cc +++ b/lix/libcmd/repl.cc @@ -218,7 +218,7 @@ struct NixRepl void loadFile(const Path & path); void loadFlake(const std::string & flakeRef); - void loadFiles(); + void loadFiles(std::list const & loadables); void reloadFiles(); void addCommand( @@ -374,7 +374,8 @@ ReplExitStatus NixRepl::mainLoop() isFirstRepl = false; - loadFiles(); + std::list loadables = std::exchange(loaded, {}); + loadFiles(loadables); auto _guard = interacter->init(static_cast(this)); @@ -1383,24 +1384,26 @@ void NixRepl::initEnv() void NixRepl::reloadFiles() { - if (loaded.empty() && getValues().empty()) { - notice("No file to reload, skipping"); - return; + auto && newEnv = initNewEnv(evaluator, envSize); + swapEnv(newEnv); + + std::list saved = std::exchange(loaded, {}); + + try { + loadFiles(saved); + } catch (Error const & e) { + // Stop loading on the first error, but restore the environment so errors + // don't throw everything away. + swapEnv(newEnv); + std::swap(loaded, saved); + throw; } - - initEnv(); - - loadFiles(); } -void NixRepl::loadFiles() +void NixRepl::loadFiles(std::list const & loadables) { - std::list saved{loaded}; - - loaded.clear(); - - for (auto const & [spec, kind] : saved) { + for (auto const & [spec, kind] : loadables) { switch (kind) { case ReplLoadKind::File: notice("Loading '%s'...", Magenta(spec));