Confusion about bash completions (flake related)

Hi, after a bit of initial messing around, I’ve been using NixOS for everything for a few days now without many issues which has been great, but ran into an issue today I couldn’t figure out.

I’m running NixOS 21.05 and also have a few projects with builds managed by flakes. When I enter the shell for a flake with nix develop I lose bash completion for applications not included in the flake shell dependencies. It seems odd I can still use applications installed on the system via PATH but don’t have bash completion for them. Is this expected behavior?

I noticed from the shell for the flake that XDG_DATA_DIRS seems like it’s populated by only the build dependencies for the shell, but PATH seems to be those dependencies in addition to the normal PATH.

If anyone is able to shed light on why this is like this, or if I’m misunderstanding a use case or how bash completions get sourced in NixOS let me know. I’m interested in understanding and resolving this in a proper way without resorting to any hacky solutions if possible.

Thanks for any help!

I use zsh, so I’m not fresh on the details of bash completions, but I have run into similar issues in projects that import their own version of nix in the shell, or wrap nix in a script or something along those lines. It’s possible that the nix develop command is doing something funny as well. Have you tried simply using direnv as an alternative, to automatically enter the flake devShell? It may just fix your issue.

You can get around it by using a different shell builder. There are two that I know of

Thanks for the direnv idea, I’ll probably see how that works out just for convenience, but for this issue hoping for something more flexible since it’s for multi-developer projects. I just tried with and without nix in the nativeBuildDeps in the flake and didn’t see a difference in XDG_DATA_DIRS that would preserve the host completions. I’ll follow up on this thread if I figure out what if any solution there is using mkShell and nix develop

Thanks, devshell seems a bit overkill since I don’t want most of what they put in there, but I like what you did with make-shell expanding off their stripped down shell; just tried it out and seems to resolve my issue without any other problems so far.

1 Like

devshell is supposed to be extremely minimal. It’s certainly a lot more minimal than mkShell from nixpkgs at least.

Just out of curiosity, what is the output of which nix and is it a binary, function, or script? I had an issue once where the any-nix-shell plugin overrode nix with a shell function, and it broke completions, but I didn’t realize it for a long while :sweat_smile:

I wrote about this issue: `nix develop` overwrites SHELL with stdenv runtime shell · Issue #5131 · NixOS/nix · GitHub

Essentially, nix develop will give you the shell used in the derivation, which is a non-interactive bash shell.

which nix gives me the nix binary in my path at /run/current-system/sw/bin/nix, both inside the nix develop shell and outside so I think I’m okay there, good to know though

Update: I’m pretty sure this is just a result of the existing XDG_DATA_DIRS value being cleared when entering nix develop, as opposed to PATH which is appended to. It would be nice to get this resolved so PATH and other environment variables are consistent with each other. This is also matter of how you call your bash completion scripts, if you have them hardcoded in .bashrc then this isn’t an issue, but on my setup they are called by traversing XDG_DATA_DIRS so if they’re not present when starting bash they don’t get called.

I guess this is pretty specific to bash users as well since if you’re using another shell and then launch the bash shell from nix develop, you might not have bash completions configured anyway

Usually I use direnv to load a shell.nix/#devShell, which does keep my usual environment mostly intact and especially retains my shell.

Sometimes though I want to debug the actual build, and then I use nix-shell/nix develop, in which case I explicitely expect as much of my environment beeing busted and replaced to be as much like it would be during a nix build.

nix develop should not merge PATH or any other environment variable, it should overwrite.

1 Like

does nix develop have a flag similar to the old --pure yet for this overwriting behavior?

1 Like

I guess I’m confused about the purpose of each. I’ve been using nix develop exclusively. If I run nix shell It starts building my default package (which is about 2 hours so I didn’t wait for it to finish to see what it did after)

EDIT: Or are you saying to create a derivation with dependencies only and specify that with nix shell?

Based on the man page I thought maybe --ignore-environment would do that. But I still have my host paths in PATH when running nix develop with that flag.

What I’m now talking about is about flake enabled nix 2.4pre.

Here nix shell gives you an ephemeral shell that has a certain “installable” (I borrow this term from the help output).

nix develop though gives you a shell that has all the various *Inputs of an “installable”, as well as all the env vars as set during the installables build.

nix shell is also incomplete in this regard bash autocompletion in nix shell (nix command) · Issue #4453 · NixOS/nix · GitHub

It looks like this has merged just now:

https://github.com/NixOS/nix/pull/6702

2 Likes