aboutsummaryrefslogtreecommitdiff
path: root/src/libcmd/repl.cc
diff options
context:
space:
mode:
authorBen Burdette <bburdette@protonmail.com>2022-04-28 12:32:57 -0600
committerBen Burdette <bburdette@protonmail.com>2022-04-28 12:32:57 -0600
commit6e19947993119dec3c9fb9581150d1184948bae9 (patch)
tree978fd122eb69168974a3a90063114b97b976f8f3 /src/libcmd/repl.cc
parent93b8d315087921b0a024bf87555ac6c3bca6882d (diff)
parent4bb111c8d4c5692db2f735c2803f632f8c30b6ab (diff)
Merge branch 'master' into debug-merge-master
Diffstat (limited to 'src/libcmd/repl.cc')
-rw-r--r--src/libcmd/repl.cc72
1 files changed, 42 insertions, 30 deletions
diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc
index 5c25183cc..d9ba7e7a4 100644
--- a/src/libcmd/repl.cc
+++ b/src/libcmd/repl.cc
@@ -33,6 +33,7 @@ extern "C" {
#include "command.hh"
#include "finally.hh"
#include "markdown.hh"
+#include "local-fs-store.hh"
#if HAVE_BOEHMGC
#define GC_INCLUDE_NEW
@@ -75,7 +76,7 @@ struct NixRepl
void loadFiles();
void reloadFiles();
void addAttrsToScope(Value & attrs);
- void addVarToScope(const Symbol & name, Value & v);
+ void addVarToScope(const Symbol name, Value & v);
Expr * parseString(std::string s);
void evalString(std::string s, Value & v);
void loadDebugTraceEnv(DebugTrace &dt);
@@ -124,7 +125,7 @@ std::string runNix(Path program, const Strings & args,
});
if (!statusOk(res.first))
- throw ExecError(res.first, fmt("program '%1%' %2%", program, statusToString(res.first)));
+ throw ExecError(res.first, "program '%1%' %2%", program, statusToString(res.first));
return res.second;
}
@@ -389,9 +390,9 @@ StringSet NixRepl::completePrefix(const std::string & prefix)
state->forceAttrs(v, noPos);
for (auto & i : *v.attrs) {
- std::string name = i.name;
+ std::string_view name = state->symbols[i.name];
if (name.substr(0, cur2.size()) != cur2) continue;
- completions.insert(prev + expr + "." + name);
+ completions.insert(concatStrings(prev, expr, ".", name));
}
} catch (ParseError & e) {
@@ -480,7 +481,8 @@ bool NixRepl::processLine(std::string line)
<< " <expr> Evaluate and print expression\n"
<< " <x> = <expr> Bind expression to variable\n"
<< " :a <expr> Add attributes from resulting set to scope\n"
- << " :b <expr> Build derivation\n"
+ << " :b <expr> Build a derivation\n"
+ << " :bl <expr> Build a derivation, creating GC roots in the working directory\n"
<< " :e <expr> Open package or function in $EDITOR\n"
<< " :i <expr> Build derivation, then install result into current profile\n"
<< " :l <path> Load Nix expression and add it to scope\n"
@@ -586,21 +588,23 @@ bool NixRepl::processLine(std::string line)
Value v;
evalString(arg, v);
- Pos pos;
-
- if (v.type() == nPath || v.type() == nString) {
- PathSet context;
- auto filename = state->coerceToString(noPos, v, context);
- pos.file = state->symbols.create(*filename);
- } else if (v.isLambda()) {
- pos = v.lambda.fun->pos;
- } else {
- // assume it's a derivation
- pos = findPackageFilename(*state, v, arg);
- }
+ const auto [file, line] = [&] () -> std::pair<std::string, uint32_t> {
+ if (v.type() == nPath || v.type() == nString) {
+ PathSet context;
+ auto filename = state->coerceToString(noPos, v, context).toOwned();
+ state->symbols.create(filename);
+ return {filename, 0};
+ } else if (v.isLambda()) {
+ auto pos = state->positions[v.lambda.fun->pos];
+ return {pos.file, pos.line};
+ } else {
+ // assume it's a derivation
+ return findPackageFilename(*state, v, arg);
+ }
+ }();
// Open in EDITOR
- auto args = editorFor(pos);
+ auto args = editorFor(file, line);
auto editor = args.front();
args.pop_front();
@@ -623,24 +627,32 @@ bool NixRepl::processLine(std::string line)
Value v, f, result;
evalString(arg, v);
evalString("drv: (import <nixpkgs> {}).runCommand \"shell\" { buildInputs = [ drv ]; } \"\"", f);
- state->callFunction(f, v, result, Pos());
+ state->callFunction(f, v, result, PosIdx());
StorePath drvPath = getDerivationPath(result);
runNix("nix-shell", {state->store->printStorePath(drvPath)});
}
- else if (command == ":b" || command == ":i" || command == ":s" || command == ":log") {
+ else if (command == ":b" || command == ":bl" || command == ":i" || command == ":s" || command == ":log") {
Value v;
evalString(arg, v);
StorePath drvPath = getDerivationPath(v);
Path drvPathRaw = state->store->printStorePath(drvPath);
- if (command == ":b") {
+ if (command == ":b" || command == ":bl") {
state->store->buildPaths({DerivedPath::Built{drvPath}});
auto drv = state->store->readDerivation(drvPath);
logger->cout("\nThis derivation produced the following outputs:");
- for (auto & [outputName, outputPath] : state->store->queryDerivationOutputMap(drvPath))
- logger->cout(" %s -> %s", outputName, state->store->printStorePath(outputPath));
+ for (auto & [outputName, outputPath] : state->store->queryDerivationOutputMap(drvPath)) {
+ auto localStore = state->store.dynamic_pointer_cast<LocalFSStore>();
+ if (localStore && command == ":bl") {
+ std::string symlink = "repl-result-" + outputName;
+ localStore->addPermRoot(outputPath, absPath(symlink));
+ logger->cout(" ./%s -> %s", symlink, state->store->printStorePath(outputPath));
+ } else {
+ logger->cout(" %s -> %s", outputName, state->store->printStorePath(outputPath));
+ }
+ }
} else if (command == ":i") {
runNix("nix-env", {"-i", drvPathRaw});
} else if (command == ":log") {
@@ -791,7 +803,7 @@ void NixRepl::initEnv()
varNames.clear();
for (auto & i : state->staticBaseEnv->vars)
- varNames.insert(i.first);
+ varNames.emplace(state->symbols[i.first]);
}
@@ -827,7 +839,7 @@ void NixRepl::addAttrsToScope(Value & attrs)
for (auto & i : *attrs.attrs) {
staticEnv->vars.emplace_back(i.name, displ);
env->values[displ++] = i.value;
- varNames.insert((std::string) i.name);
+ varNames.emplace(state->symbols[i.name]);
}
staticEnv->sort();
staticEnv->deduplicate();
@@ -835,7 +847,7 @@ void NixRepl::addAttrsToScope(Value & attrs)
}
-void NixRepl::addVarToScope(const Symbol & name, Value & v)
+void NixRepl::addVarToScope(const Symbol name, Value & v)
{
if (displ >= envSize)
throw Error("environment full; cannot add more variables");
@@ -844,7 +856,7 @@ void NixRepl::addVarToScope(const Symbol & name, Value & v)
staticEnv->vars.emplace_back(name, displ);
staticEnv->sort();
env->values[displ++] = &v;
- varNames.insert((std::string) name);
+ varNames.emplace(state->symbols[name]);
}
@@ -925,7 +937,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m
Bindings::iterator i = v.attrs->find(state->sDrvPath);
PathSet context;
if (i != v.attrs->end())
- str << state->store->printStorePath(state->coerceToStorePath(*i->pos, *i->value, context));
+ str << state->store->printStorePath(state->coerceToStorePath(i->pos, *i->value, context));
else
str << "???";
str << "»";
@@ -937,7 +949,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m
typedef std::map<std::string, Value *> Sorted;
Sorted sorted;
for (auto & i : *v.attrs)
- sorted[i.name] = i.value;
+ sorted.emplace(state->symbols[i.name], i.value);
for (auto & i : sorted) {
if (isVarName(i.first))
@@ -987,7 +999,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m
case nFunction:
if (v.isLambda()) {
std::ostringstream s;
- s << v.lambda.fun->pos;
+ s << state->positions[v.lambda.fun->pos];
str << ANSI_BLUE "«lambda @ " << filterANSIEscapes(s.str()) << "»" ANSI_NORMAL;
} else if (v.isPrimOp()) {
str << ANSI_MAGENTA "«primop»" ANSI_NORMAL;