xonsh/py-bash-completion

Leverage the fact that systemwide bashrc is a working, albeit a slower one, bcd candidate

Opened this issue · 3 comments

As per discussion in xonsh/xonsh#2814, a systemwide bashrc might be used as a completion script fallback.

The downside seems to be slower execution.

On the upside, I'd argue that it might be a better source of truth here.
At least at NixOS, the necessary quirkfest is already there, probably well maintained and ready to reuse.

Thanks for opening this @t184256!

I don't understand:

substituteInPlace xonsh/platform.py --replace \
    '/usr/share/bash-completion/bash_completion' \
    '${pkgs.bash-completion}/etc/profile.d/bash_completion.sh'

Is substituteInPlace a command that comes with NixOS? And is ${pkgs.bash-completion} a valid environment variable? (I didn't think . was allowed in env var names...)

As I already said, don't lose much sleep over NixOS support specifically. They broke everything and it's their task to fix it =)

This was an excerpt from a packaging shell script written in bash and embedded into a Nix derivation. substituteInPlace is provided by Nix, {$pkgs.bash-completion} is not an env var, but some string interpolation done by Nix before executing the excerpt with bash.

The gist of it is that /usr/share/bash-completion/bash_completion is OK in distros that follow FHS, but not OK in NixOS, where it is located in a sub-tree specific to bash-completion package. The official way to make programs expecting FHS to work on NixOS is to patch the source at build-time.

The idea of that bug was not 'stop relying on FHS'. It'd be stupid, actually. It's just an observation that no matter how your quirky and specific your setup is, providing a working bashrc as a completion script sourced by your lib should probably work fine, albeit slowly. On NixOS, for example, bashrc has some more special magic:

if shopt -q progcomp &>/dev/null; then
  . "/nix/store/jqmvcfrydy3klry61x0615yphqax49wl-bash-completion-2.7/etc/profile.d/bash_completion.sh"
  nullglobStatus=$(shopt -p nullglob)
  shopt -s nullglob
  for p in $NIX_PROFILES; do
    for m in "$p/etc/bash_completion.d/"*; do
      . $m
    done
  done
  eval "$nullglobStatus"
  unset nullglobStatus p m
fi

I'd never guess I needed that, you'd never guess I needed that, but what we can avoid that guessing altogether and just source bashrc and know it may work everywhere.
The performance downside seems hefty, and I do understand that it's not something to be done blindly for some intangible benefit, so weight it in too.

We could possibly:

  1. Note the fact 'bashrc is fine too, if not better' in the docs/source and save time of the next person figuring that out.
  2. Go a bit further and add typical bashrc paths as fallback paths, possibly sacrificing some performance in this scenario
  3. Go overboard and prefer bashrc over bash-completion script.

Feel free to dismiss the idea if you don't feel like it. After all, it's not like I claim that py-bash-completion is doing something wrong or suboptimally, I just found out there is another possibility.

Ahh OK! Thanks for the detailed write up @t184256. I think I am unlikely to code this up myself, but would be very interested in a PR to this effect.