nix edit: Support non-derivation attributes

E.g.

  $ nix edit .#nixosConfigurations.bla

now works.
This commit is contained in:
Eelco Dolstra 2020-02-07 14:22:01 +01:00
parent 0b013a54dc
commit d2032edb2f
6 changed files with 24 additions and 18 deletions

View file

@ -103,7 +103,7 @@ Pos findDerivationFilename(EvalState & state, Value & v, std::string what)
auto dummyArgs = state.allocBindings(0); auto dummyArgs = state.allocBindings(0);
v2 = findAlongAttrPath(state, "meta.position", *dummyArgs, v).first; v2 = findAlongAttrPath(state, "meta.position", *dummyArgs, v).first;
} catch (Error &) { } catch (Error &) {
throw Error("package '%s' has no source location information", what); throw NoPositionInfo("package '%s' has no source location information", what);
} }
// FIXME: is it possible to extract the Pos object instead of doing this // FIXME: is it possible to extract the Pos object instead of doing this

View file

@ -8,6 +8,7 @@
namespace nix { namespace nix {
MakeError(AttrPathNotFound, Error); MakeError(AttrPathNotFound, Error);
MakeError(NoPositionInfo, Error);
std::pair<Value *, Pos> findAlongAttrPath(EvalState & state, const string & attrPath, std::pair<Value *, Pos> findAlongAttrPath(EvalState & state, const string & attrPath,
Bindings & autoArgs, Value & vIn); Bindings & autoArgs, Value & vIn);

View file

@ -29,9 +29,15 @@ struct CmdEdit : InstallableCommand
{ {
auto state = getEvalState(); auto state = getEvalState();
auto v = installable->toValue(*state); auto [v, pos] = installable->toValue(*state);
Pos pos = findDerivationFilename(*state, *v, installable->what()); try {
pos = findDerivationFilename(*state, *v, installable->what());
} catch (NoPositionInfo &) {
}
if (pos == noPos)
throw Error("cannot find position information for '%s", installable->what());
stopProgressBar(); stopProgressBar();

View file

@ -52,7 +52,7 @@ struct CmdEval : MixJSON, InstallableCommand
auto state = getEvalState(); auto state = getEvalState();
auto v = installable->toValue(*state); auto v = installable->toValue(*state).first;
PathSet context; PathSet context;
stopProgressBar(); stopProgressBar();

View file

@ -130,7 +130,7 @@ App::App(EvalState & state, Value & vApp)
App Installable::toApp(EvalState & state) App Installable::toApp(EvalState & state)
{ {
return App(state, *toValue(state)); return App(state, *toValue(state).first);
} }
struct InstallableStorePath : Installable struct InstallableStorePath : Installable
@ -166,7 +166,7 @@ std::vector<flake::EvalCache::Derivation> InstallableValue::toDerivations()
{ {
auto state = cmd.getEvalState(); auto state = cmd.getEvalState();
auto v = toValue(*state); auto v = toValue(*state).first;
Bindings & autoArgs = *cmd.getAutoArgs(*state); Bindings & autoArgs = *cmd.getAutoArgs(*state);
@ -229,11 +229,11 @@ struct InstallableExpr : InstallableValue
std::string what() override { return text; } std::string what() override { return text; }
Value * toValue(EvalState & state) override std::pair<Value *, Pos> toValue(EvalState & state) override
{ {
auto v = state.allocValue(); auto v = state.allocValue();
state.eval(state.parseExprFromString(text, absPath(".")), *v); state.eval(state.parseExprFromString(text, absPath(".")), *v);
return v; return {v, noPos};
} }
}; };
@ -248,11 +248,11 @@ struct InstallableAttrPath : InstallableValue
std::string what() override { return attrPath; } std::string what() override { return attrPath; }
Value * toValue(EvalState & state) override std::pair<Value *, Pos> toValue(EvalState & state) override
{ {
auto vRes = findAlongAttrPath(state, attrPath, *cmd.getAutoArgs(state), *v).first; auto [vRes, pos] = findAlongAttrPath(state, attrPath, *cmd.getAutoArgs(state), *v);
state.forceValue(*vRes); state.forceValue(*vRes);
return vRes; return {vRes, pos};
} }
}; };
@ -391,7 +391,7 @@ std::vector<flake::EvalCache::Derivation> InstallableFlake::toDerivations()
return res; return res;
} }
Value * InstallableFlake::toValue(EvalState & state) std::pair<Value *, Pos> InstallableFlake::toValue(EvalState & state)
{ {
auto lockedFlake = lockFlake(state, flakeRef, cmd.lockFlags); auto lockedFlake = lockFlake(state, flakeRef, cmd.lockFlags);
@ -401,9 +401,9 @@ Value * InstallableFlake::toValue(EvalState & state)
for (auto & attrPath : getActualAttrPaths()) { for (auto & attrPath : getActualAttrPaths()) {
try { try {
auto * v = findAlongAttrPath(state, attrPath, *emptyArgs, *vOutputs).first; auto [v, pos] = findAlongAttrPath(state, attrPath, *emptyArgs, *vOutputs);
state.forceValue(*v); state.forceValue(*v);
return v; return {v, pos};
} catch (AttrPathNotFound & e) { } catch (AttrPathNotFound & e) {
} }
} }

View file

@ -3,14 +3,13 @@
#include "util.hh" #include "util.hh"
#include "path.hh" #include "path.hh"
#include "flake/eval-cache.hh" #include "flake/eval-cache.hh"
#include "eval.hh"
#include <optional> #include <optional>
namespace nix { namespace nix {
struct Value;
struct DrvInfo; struct DrvInfo;
class EvalState;
struct SourceExprCommand; struct SourceExprCommand;
struct Buildable struct Buildable
@ -45,7 +44,7 @@ struct Installable
App toApp(EvalState & state); App toApp(EvalState & state);
virtual Value * toValue(EvalState & state) virtual std::pair<Value *, Pos> toValue(EvalState & state)
{ {
throw Error("argument '%s' cannot be evaluated", what()); throw Error("argument '%s' cannot be evaluated", what());
} }
@ -91,7 +90,7 @@ struct InstallableFlake : InstallableValue
std::vector<flake::EvalCache::Derivation> toDerivations() override; std::vector<flake::EvalCache::Derivation> toDerivations() override;
Value * toValue(EvalState & state) override; std::pair<Value *, Pos> toValue(EvalState & state) override;
}; };
} }