Why is there no code navigation for nix?

Wouldn’t it save us all a ton of time if there was an IDE or code editor for nix that allows navigation (i.e. jump-to-definition).

Also, wouldn’t this remove one of the biggest (if not the biggest) obstacle for beginners to overcome?

When I think about the times when I started with nix, I remember that I had absolutely no clue how packages were built and how modules worked and how to modify stuff, simply because I didn’t know where to find the relevant pieces.

There is the search website where one can search options and get a link to their definition. But always those definitions are built ontop other stuff that is defined at completely different places. So you are again in the dark.

Navigating nixpkgs is far away from trivial and it took me a significant amount of time and caused lot’s of frustration to learn it. It requires a significant understanding of patterns which are established in nixpkgs. And it is hard to grasp these patterns since there is no easy navigation. It’s a huge chicken egg problem that every beginner has to overcome before even getting close of being somehow productive.

Why doesn’t have nix code navigation like any other programming language? Is there some fundamental issue that prevents it? Or did just nobody ever implement it?

3 Likes

although not impossible to do some code navigation/completion, it’s typically difficult to these things well in pure functional languages because they lack a lot of context as to what you’re going to do next. In OOP languages, once you reference an object, it’s assumed that you will access a property or method, and those are known ahead of time.

Although it would be nice to have something like, “I mentioned this in buildInputs, please add it to the attr parameter at the top of the expression”, similar to jetbrains “add import module/class” Alt+Enter behavior

1 Like

Jump to definition could work within files, but I think it’s hopeless for the case that would really help, which is between files. This is also because of the way we handle dependencies in nixpkgs: we take them as function arguments. But we don’t have static typing, so you have no idea from the file what they are. Indeed, the function could get called in multiple places, potentially with different arguments.

Consider the following common pattern:

foo.nix

{ pkg1 }: mkDerivation { ... }

all-packages.nix

foo = import ./foo.nix { inherit pkg1; }
fooOld = import ./foo.nix { pkg1 = oldPkg1; }

If I hit “jump to definition” on pkg1, where should it take me?

Even if we solve that problem, we still potentially have to whole-project dataflow analysis to work out where things come from.

1 Like

If there are multiple possible definitions for something, then the IDE could ask the user which one to display. Intellj does it the same way if you ask for the definition of an inherited function for example. If there are multiple super classes which provide that function, you can select via context menu the one you like. That’s not perfect but still magnitudes better than no navigation at all.

In your specific example, if one asks for the definition of pkg1, one could be presented with the definitions of foo and fooOld, and from there continue either to pkg1 of oldPkg1.

I agree with you that it would require whole project dataflow analysis. But I think it is the same with many other languages where it has already been solved.

If it’s the case that nix makes it especially hard to navigate for machines, then it also means that it is especially hard for humans to navigate. This should motivate us even more to solve that problem :slight_smile:

I believe it’s definitely possible to implement it (somewhat), but that just nobody has had the resources to actually do it yet. I personally have played around a bunch with how this could be implemented, and my conclusion is that it’s definitely not easy. If I had enough time I’d definitely want to give it a try though.

2 Likes

Thanks for suggestion. Implemented a new feature inspired from your words :slight_smile:

Give it a Ctrl + click!

goto-def-pkg-2

You can use goto-declaration for modules (this is a home-manager module) :stuck_out_tongue:

home-options-decl

10 Likes

Wow, this looks impressive. A good reason to dust off my old emacs for sure!
I’m struggling to understand how some of the nix definitions are created, and where they come from. Just searching through is really difficult if you’re not sure where narrow it down.