-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is a little convenience command that opens the Nix expression of the specified package. For example, nix edit nixpkgs.perlPackages.Moose opens <nixpkgs/pkgs/top-level/perl-packages.nix> in $EDITOR (at the right line number for some editors). This requires the package to have a meta.position attribute.
- Loading branch information
Showing
1 changed file
with
75 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
#include "command.hh" | ||
#include "shared.hh" | ||
#include "eval.hh" | ||
#include "attr-path.hh" | ||
|
||
#include <unistd.h> | ||
|
||
using namespace nix; | ||
|
||
struct CmdEdit : InstallablesCommand | ||
{ | ||
std::string name() override | ||
{ | ||
return "edit"; | ||
} | ||
|
||
std::string description() override | ||
{ | ||
return "open the Nix expression of a Nix package in $EDITOR"; | ||
} | ||
|
||
Examples examples() override | ||
{ | ||
return { | ||
Example{ | ||
"To open the Nix expression of the GNU Hello package:", | ||
"nix edit nixpkgs.hello" | ||
}, | ||
}; | ||
} | ||
|
||
void run(ref<Store> store) override | ||
{ | ||
auto state = getEvalState(); | ||
|
||
for (auto & i : installables) { | ||
auto v = i->toValue(*state); | ||
|
||
Value * v2; | ||
try { | ||
auto dummyArgs = state->allocBindings(0); | ||
v2 = findAlongAttrPath(*state, "meta.position", *dummyArgs, *v); | ||
} catch (Error &) { | ||
throw Error("package ‘%s’ has no source location information", i->what()); | ||
} | ||
|
||
auto pos = state->forceString(*v2); | ||
debug("position is %s", pos); | ||
|
||
auto colon = pos.rfind(':'); | ||
if (colon == std::string::npos) | ||
throw Error("cannot parse meta.position attribute ‘%s’", pos); | ||
|
||
std::string filename(pos, 0, colon); | ||
int lineno = std::stoi(std::string(pos, colon + 1)); | ||
|
||
auto editor = getEnv("EDITOR", "cat"); | ||
|
||
Strings args{editor}; | ||
|
||
if (editor.find("emacs") != std::string::npos || | ||
editor.find("nano") != std::string::npos || | ||
editor.find("vim") != std::string::npos) | ||
args.push_back(fmt("+%d", lineno)); | ||
|
||
args.push_back(filename); | ||
|
||
execvp(editor.c_str(), stringsToCharPtrs(args).data()); | ||
|
||
throw SysError("cannot run editor ‘%s’", editor); | ||
} | ||
} | ||
}; | ||
|
||
static RegisterCommand r1(make_ref<CmdEdit>()); |
03ae5e6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't most users find that the editor points at a read-only file in the store? Otherwise seems like a cool feature.
03ae5e6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! I'm glad these more user-facing commands are getting into nix.
I actually already have a similar script if anyone's interested: https://github.com/matthewbauer/nix-utils/blob/master/nix-edit
Another one inspired by Homebrew that might be useful is "nix log". It pulls open the "git log" results for an attribute: https://github.com/matthewbauer/nix-utils/blob/master/nix-log
03ae5e6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copumpkin Yes, in that case it's more of a "nix view". Still useful though.
@matthewbauer Yeah, I've been using a similar nix-edit shell function for years. Regarding git log, that's pretty nice, but it does require a git tree (so it wouldn't work with channels). Maybe channels could include the URL of the repo, which nix could then use...
03ae5e6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the URL of the repo, we could also make a more interactive prompt:
nix edit foo
$EDITOR
etc.
Probably excessive but making that workflow super smooth would probably get us a ton more contributions.
03ae5e6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe nix-channel eventually can learn about fetching directly from git repos?