about summary refs log tree commit diff
path: root/nix-repl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'nix-repl.cc')
-rw-r--r--nix-repl.cc68
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;
     }