diff options
Diffstat (limited to 'nix-repl.cc')
-rw-r--r-- | nix-repl.cc | 68 |
1 files changed, 48 insertions, 20 deletions
diff --git a/nix-repl.cc b/nix-repl.cc index e17f73ae0cab..ab943f7bac1b 100644 --- a/nix-repl.cc +++ b/nix-repl.cc @@ -14,10 +14,18 @@ #include "get-drvs.hh" #include "derivations.hh" #include "affinity.hh" +#include "globals.hh" using namespace std; using namespace nix; +#define ESC_RED "\033[31m" +#define ESC_GRE "\033[32m" +#define ESC_YEL "\033[33m" +#define ESC_BLU "\033[34m" +#define ESC_MAG "\033[35m" +#define ESC_CYA "\033[36m" +#define ESC_END "\033[0m" struct NixRepl { @@ -39,6 +47,7 @@ struct NixRepl void mainLoop(const Strings & files); void completePrefix(string prefix); bool getLine(string & input, const char * prompt); + Path getDerivationPath(Value & v); bool processLine(string line); void loadFile(const Path & path); void initEnv(); @@ -107,6 +116,7 @@ NixRepl::NixRepl(const Strings & searchPath, nix::ref<Store> store) void NixRepl::mainLoop(const Strings & files) { + string error = ANSI_RED "error:" ANSI_NORMAL " "; std::cout << "Welcome to Nix version " << NIX_VERSION << ". Type :? for help." << std::endl << std::endl; for (auto & i : files) @@ -137,12 +147,12 @@ void NixRepl::mainLoop(const Strings & files) // input without clearing the input so far. continue; } else { - printMsg(lvlError, "error: " + e.msg()); + printMsg(lvlError, format(error + "%1%%2%") % (settings.showTrace ? e.prefix() : "") % e.msg()); } } catch (Error & e) { - printMsg(lvlError, "error: " + e.msg()); + printMsg(lvlError, format(error + "%1%%2%") % (settings.showTrace ? e.prefix() : "") % e.msg()); } catch (Interrupted & e) { - printMsg(lvlError, "error: " + e.msg()); + printMsg(lvlError, format(error + "%1%%2%") % (settings.showTrace ? e.prefix() : "") % e.msg()); } // We handled the current input fully, so we should clear it and read brand new input. @@ -300,6 +310,17 @@ bool isVarName(const string & s) } +Path NixRepl::getDerivationPath(Value & v) { + DrvInfo drvInfo(state); + if (!getDerivation(state, v, drvInfo, false)) + throw Error("expression does not evaluate to a derivation, so I can't build it"); + Path drvPath = drvInfo.queryDrvPath(); + if (drvPath == "" || !state.store->isValidPath(drvPath)) + throw Error("expression did not evaluate to a valid derivation"); + return drvPath; +} + + bool NixRepl::processLine(string line) { if (line == "") return true; @@ -327,7 +348,8 @@ bool NixRepl::processLine(string line) << " :q Exit nix-repl\n" << " :r Reload all files\n" << " :s <expr> Build dependencies of derivation, then start nix-shell\n" - << " :t <expr> Describe result of evaluation\n"; + << " :t <expr> Describe result of evaluation\n" + << " :u <expr> Build derivation, then start nix-shell\n"; } else if (command == ":a" || command == ":add") { @@ -350,17 +372,21 @@ bool NixRepl::processLine(string line) Value v; evalString(arg, v); std::cout << showType(v) << std::endl; + + } else if (command == ":u") { + Value v, f, result; + evalString(arg, v); + evalString("drv: (import <nixpkgs> {}).runCommand \"shell\" { buildInputs = [ drv ]; } \"\"", f); + state.callFunction(f, v, result, Pos()); + + Path drvPath = getDerivationPath(result); + runProgram("nix-shell", Strings{drvPath}); } else if (command == ":b" || command == ":i" || command == ":s") { Value v; evalString(arg, v); - DrvInfo drvInfo(state); - if (!getDerivation(state, v, drvInfo, false)) - throw Error("expression does not evaluate to a derivation, so I can't build it"); - Path drvPath = drvInfo.queryDrvPath(); - if (drvPath == "" || !state.store->isValidPath(drvPath)) - throw Error("expression did not evaluate to a valid derivation"); + Path drvPath = getDerivationPath(v); if (command == ":b") { /* We could do the build in this process using buildPaths(), @@ -523,23 +549,25 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m switch (v.type) { case tInt: - str << v.integer; + str << ESC_CYA << v.integer << ESC_END; break; case tBool: - str << (v.boolean ? "true" : "false"); + str << ESC_CYA << (v.boolean ? "true" : "false") << ESC_END; break; case tString: + str << ESC_YEL; printStringValue(str, v.string.s); + str << ESC_END; break; case tPath: - str << v.path; // !!! escaping? + str << ESC_GRE << v.path << ESC_END; // !!! escaping? break; case tNull: - str << "null"; + str << ESC_CYA "null" ESC_END; break; case tAttrs: { @@ -592,7 +620,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m try { printValue(str, *i.second, maxDepth - 1, seen); } catch (AssertionError & e) { - str << "«error: " << e.msg() << "»"; + str << ESC_RED "«error: " << e.msg() << "»" ESC_END; } str << "; "; } @@ -618,7 +646,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m try { printValue(str, *v.listElems()[n], maxDepth - 1, seen); } catch (AssertionError & e) { - str << "«error: " << e.msg() << "»"; + str << ESC_RED "«error: " << e.msg() << "»" ESC_END; } str << " "; } @@ -628,19 +656,19 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m break; case tLambda: - str << "«lambda defined at " << v.lambda.fun->pos << "»"; + str << ESC_BLU "«lambda defined at " << v.lambda.fun->pos << "»" ESC_END; break; case tPrimOp: - str << "«primop»"; + str << ESC_MAG "«primop»" ESC_END; break; case tPrimOpApp: - str << "«primop-app»"; + str << ESC_BLU "«primop-app»" ESC_END; break; default: - str << "«unknown»"; + str << ESC_RED "«unknown»" ESC_END; break; } |