I’m just noticing that if I open a new bash terminal and run nix shell nixpkgs#cargo
completions for cargo
don’t appear to work (e.g. cargo bui<tab>
doesn’t do anything).
However, if I install cargo
under system packages or home-manager, close and re-open my shell, the completions do appear to work.
It appears bash
looks for completions under XDG_DATA_DIRS
. When I enter a nix shell, I notice that XDG_DATA_DIRS
doesn’t appear to change whether or not the package has a $out/share
output.
Should I not be expecting completions to work under nix shell
?
1 Like
nix shell
and Home Manager work very differently.
Setting XDG_DATA_DIR
through nix profile
was recently implemented here, including relevant design discussion that provides some background:
NixOS:master
← Hoverbear:set-xdg-data-dirs
opened 06:58PM - 15 Sep 23 UTC
# Motivation
On non-NixOS systems, the default `nix` install does not populat… e the `$XDG_DATA_DIRS`.
This populates it and enables things like bash-completion and `.desktop` file detection for `nix` profile installed packages.
With this PR:
* Bash completions like `nix r<tab>` and `nix build .#pro<tab>`, or `nix profile add nixpkgs#ripgrep` then `rg -<tab>` should show the expected output.
* `nix profile install nixpkgs#firefox` should result in firefox appearing in the user's Desktop environment menus via the `.desktop` file. (This may require a relog in some environments)
This PR sets `XDG_DATA_DIRS` appropriately in currently supported shells, ensuring to include the [spec](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)-defined defaults should the variable not exist.
This variable is a `PATH` style variable which is `:` separated, with a spec defined default of `/usr/local/share:/usr/share`.
I do not believe the implementation in this PR risks clobbering existing system settings or breaking things for users. We add the `nix` provided directories to the end of the `XDG_DATA_DIRS`, making them the lowest priority, meaning we won't break anything already existing on the user's system. We ensure the spec-defined default is set, meaning we won't break the system if the value is unset. Nix already manipulates the `PATH` variable and this PR manipulates `XDG_DATA_DIRS` in roughly the same way.
### Testing:
I have tested this on:
* [x] Ubuntu 22.04 multi-user install
* [x] Ubuntu 22.04 single-user install
* [x] The full `nix` repo's installer test suite (via `nix --extra-experimental-features 'nix-command flakes' run .#hydraJobs.installTests.x86_64-linux -L -j 8`)
If you'd like to test, you can add the line yourself to the file `/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh`, or build the appropriate `github:nixpkgs/nix#hydraJobs.binaryTarball.$SYSTEM` output and try it on a VM.
Doing that should result in new shells being able to complete `nix r<tab>` like so:
```bash
ana@ephemeral-ubuntu:~$ nix r<tab>
realisation registry repl run
```
Or `nix build github:nixos/nix#hydraJobs.<tab>` (you may need to be patient here -- takes a sec to do the network):
```bash
ana@ephemeral-ubuntu:~$ nix build github:nixos/nix#hydraJobs.<tab>
nixos/nix#hydraJobs.binaryTarball nixos/nix#hydraJobs.installerScript
nixos/nix#hydraJobs.binaryTarballCross nixos/nix#hydraJobs.installerScriptForGHA
nixos/nix#hydraJobs.build nixos/nix#hydraJobs.installerTests
nixos/nix#hydraJobs.buildCross nixos/nix#hydraJobs.installTests
nixos/nix#hydraJobs.buildNoGc nixos/nix#hydraJobs.internal-api-docs
nixos/nix#hydraJobs.buildNoTests nixos/nix#hydraJobs.metrics
nixos/nix#hydraJobs.buildStatic nixos/nix#hydraJobs.perlBindings
nixos/nix#hydraJobs.coverage nixos/nix#hydraJobs.tests
nixos/nix#hydraJobs.dockerImage
```
You can also test `.desktop` files:
```bash
ana@ephemeral-ubuntu:~$ nix profile install nixpkgs#xfce.thunar
```
Reload your DE (eg, relog) and observe:

# Context
Previously, https://github.com/NixOS/nix/pull/2443 suggested this change, however it was years ago and initially intermingled with another `man` related change (not present here). In https://github.com/NixOS/nix/pull/2443#issuecomment-423912395 @edolstra offered some insight into why this was not merged, it was focused on the `MANPATH` related changes.
In https://github.com/NixOS/nixpkgs/issues/78822, this issue was once again surfaced and referenced https://github.com/NixOS/nix/pull/2443#issuecomment-423912395.
In https://github.com/DeterminateSystems/nix-installer/issues/614, it was suggested that this be done in order to allow users to do something like `nix profile install nixpkgs#blender` and see blender in their desktop environment's menus.
In https://github.com/DeterminateSystems/nix-installer/issues/486, it was suggested that this be done in order to enable shell completion on an installed Nix.
In https://github.com/NixOS/nix/issues/6098, someone mentioned a gotcha around setting this value such that you don't overwrite the XDG spec defined defaults. (Spec here: https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)
In https://github.com/NixOS/nix/issues/4453 someone requested this feature as well, offering an alternative of doing this only inside of a `nix shell`, but that was a more complicated solution.
Despite the PR from several years ago not being merged, I believe it's worth revisiting the discussion in light of the numerous related issues as well as rather substantial potential benefits it can bring to users.
# Priorities
Add :+1: to [pull requests you find important](https://github.com/NixOS/nix/pulls?q=is%3Aopen+sort%3Areactions-%2B1-desc).
There is also a related discussion on whether we want Nix to be clever about environment variables: nix shell: set MANPATH for installables that have a man dir by sternenseemann · Pull Request #4702 · NixOS/nix · GitHub
Summary: Eelco finds we shouldn’t get into setting environment variables, because where would you draw the boundary?
I generally agree: Environment variables exposed by or relevant to packages should be an issue of the packages themselves, and nix shell
should simply stack the environments it’s explicitly given.
So while it would surely be pragmatic to just add the new nix profile
behavior to nix shell
as a stopgap, the sustainable thing that should happen before stabilizing those parts of the new CLI should be devising a sane interface for packages to expose environments.
4 Likes