Add "nix edit" command
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.
This commit is contained in:
		
							parent
							
								
									7689181e4f
								
							
						
					
					
						commit
						03ae5e6459
					
				
					 1 changed files with 75 additions and 0 deletions
				
			
		
							
								
								
									
										75
									
								
								src/nix/edit.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/nix/edit.cc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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>());
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue