Setup bash completion when running under nix-shell on macosx

I have a derivation that contains bash completion scripts:

$ nix-build
...
$ tree ./result/
result/
|-- bin
|   `-- my-cli
`-- share
    `-- bash-completion
        `-- completions
            `-- my-cli

When I run this derivation in nix-shell on NixOS, completions just work. I don’t appear to have to do any sort of setup:

$ nix-shell -p ./result
# Now I'm in the nix-shell.
# Next, I type in `my-cli` and hit the tab key.
$ my-cli <TAB>
--option1 --option2 --option3 --help
$

Above, I’ve used the TAB key to trigger a completion. Everything works as expected.

However, on MacOSX, when launching into the nix-shell, I don’t get any completions for my-cli.

I get completions for other programs, like rm, cp, etc, but not for my-cli.

I should add that on MacOSX, my default shell is bash-3.2.57 from /bin/bash, but in the nix-shell I’m running bash-4.4:

$ echo $BASH_VERSION # this is from outside the nix-shell
3.2.57(1)-release
$ nix-shell -p ./result
$ echo $BASH_VERSION # this is from inside the nix-shell
4.4.23(1)-release

I just tested on NixOS and it’s not working for me.

$ nix-build -A ffsend '<nixpkgs>'
/nix/store/5l4hdpl5mq054nl95jh40iwqj85jqakz-ffsend-0.2.51
$ nix-shell -p ./result
[nix-shell]$ ffsend <tab>

It’s just offering the default options (e.g. filenames), and ffsend -<tab> gives nothing at all.

@lilyball Thanks for testing this out.

Turns out you’re right!

I think what happened is that on NixOS, I had installed the executable with nix-env (which appears to make bash completions work), and then forgotten about it. When I went into the nix-shell, it appeared that completions were working, but really just the normal completions that were picked up from nix-env were being used.

However, on MacOSX, this doesn’t seem to work. Even if I install the executable with nix-build && nix-env -i ./result, completions don’t work. My guess is that this is because my main bash executable is bash-3.2.57 (and not bash-4.4 like on nixos).

On MacOSX, trying to directly run /Users/me/.nix-profile/bin/bash doesn’t appear to work. When running this bash, the tab key inserts a literal tab (instead of triggering completion), the arrow keys insert their keycodes instead of actually doing stuff, etc. Something appears to be significantly messed up, maybe termcap?? (Although this is basically a completely separate question.)

In macOS, you don’t get bash completions from Nix stuff, that’s true. This is because on NixOS the system-wide /etc/bashrc sets up the completions based on $NIX_PROFILES, which is itself set indirectly by /etc/profile (I say indirectly because that script sources the “set environment” script, which on my machine is /nix/store/1k5qwqi8dmab6j44vw4x3qn09pmr9bic-set-environment, and this is where NIX_PROFILES is set up).

On macOS using system bash, this of course doesn’t happen because /etc/bashrc isn’t managed by Nix, and the ~/.nix-profile/etc/profile.d/nix.sh script doesn’t do anything with completions. But even with Nix-installed bash it doesn’t work, because this doesn’t set up anything special.

If you want completions to work, you’ll need to edit your ~/.bashrc to do something similar to what NixOS /etc/bashrc does to set up completions.

2 Likes

BTW, I think this tool has set out to propose a generic solutions (as far as it can probably get):

1 Like

Sorry to revive a “dead thread”, but there’s now two PRs related to this:
Adding /share folders to XDG_DATA_DIRS: https://github.com/NixOS/nixpkgs/pull/103501
Adding separate sourceInputDerivationHook for mkShell: sourceInputCompletionHook: init by jonringer · Pull Request #104225 · NixOS/nixpkgs · GitHub

2 Likes