-
Notifications
You must be signed in to change notification settings - Fork 652
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for loading shell completion scripts #443
Comments
I was exactly looking for this feature. For example I use |
It seems to me that the most general way to get this working (as well as other features requiring shell-specific commands) would by implementing something like what was suggested in #73 (comment). Essentially, this would allow people to write bash functions to be ran in @zimbatm Would you take a patch implementing something along that lines? |
As long as the implementation includes proper tests. direnv is missing too many tests at the moment that I feel confident shipping new features. The DIRENV_DIFF format needs to be changed to accommodate for the diffing of more things than environment variables as well. |
If we can get something like
We actually want |
And one can then make |
Any movement on this? I'd love to have this feature, it's the one thing keeping me from using direnv currently. At work we have python-based CLIs in our repos, and being able to auto-activate their virtualenvs and add their shell completions when cd'ing into a repo without permanently polluting the environment would make using the CLIs much, much easier. So all that to say "bump" I guess 😄 |
Yeah, this would be fantastic to have. |
Yeah, it is quite annoying to have not completion at all with direnv zsh shell ... Somehow you need to install everything with nix-env to get completion in a straightforward manner which defeats the whole direnv philosophy. |
One open question is; even if direnv supported this, do shells support unmapping completion functions? |
@zimbatm: How about an opt in post hook to allow dynamic completion to be reloaded from In nix, I usually have the following shell hook:
Which With the opt-in, once the new env is ready, the following post hook would be systematically run, effectively reloading the completion from . ${bash-completion}/etc/profile.d/bash_completion.sh Would it unregister existing completion, I'm unsure. EDIT: Please disregard, the above nix shell hook already work fine with direnv + |
Basically, to do this the direnv way(TM) with proper backup&restore support, bash would have to send all its local variables and functions to direnv so it can diff and re-export properly. But that's not all because bash can also spawn sub-shells where that information would be lost (unlike environment variables which are inherited). So to make this work in a coherent manner direnv would also need to be able to detect and handle that as well. |
This feels like a lot of work. I'd personally be fine having some escape hatch in the meantime, that I could use to register completions for example. I don't really want to use |
So far, the best option is to assume that the user has the bash-completion package installed. And then use direnv to set That's what I added to numtide/devshell#48 recently and it works quite well. The only downside is that completions don't get unloaded when exiting an environment. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This has been solved for bash on unstable with NixOS/nixpkgs#103501. Packages just need to be added to NixOS/nixpkgs#104225 is another alternative, I may re-open it if there's interest, as it would potentially work with zsh and fish as well. Another alternative would be to make zsh and fish completions also load XDG_DATA_DIRS lazily. |
One thing I noticed is that the bash-completion package loads a shim whenever a completion is not found. Once the shim is installed, it won't try to look for another completion. So if a user goes to the project, direnv doesn't load for some reason (eg: the .envrc needs to be allowed), and then type the |
If you use fish shell, you can run `bash -c 'source ./setup.sh Debug; exec fish'` or with Nix `nix-shell --run fish`. Unfortunately, we cannot get away with using direnv for now. direnv/direnv#443 fish-shell/fish-shell#8261
If you use fish shell, you can run `bash -c 'source ./setup.sh Debug; exec fish'` or with Nix `nix-shell --run fish`. Unfortunately, we cannot get away with using direnv for now. direnv/direnv#443 fish-shell/fish-shell#8261
If you use fish shell, you can run `bash -c 'source ./setup.sh Debug; exec fish'` or with Nix `nix-shell --run fish`. Unfortunately, we cannot get away with using direnv for now. direnv/direnv#443 fish-shell/fish-shell#8261
If you use fish shell, you can run `bash -c 'source ./setup.sh Debug; exec fish'` or with Nix `nix-shell --run fish`. Unfortunately, we cannot get away with using direnv for now. direnv/direnv#443 fish-shell/fish-shell#8261
If you use fish shell, you can run `bash -c 'source ./setup.sh Debug; exec fish'` or with Nix `nix-shell --run fish`. Unfortunately, we cannot get away with using direnv for now. direnv/direnv#443 fish-shell/fish-shell#8261
If you use fish shell, you can run `bash -c 'source ./setup.sh Debug; exec fish'` or with Nix `nix-shell --run fish`. Unfortunately, we cannot get away with using direnv for now. direnv/direnv#443 fish-shell/fish-shell#8261
I’m interested in fish completions. Anything I could do to help? |
yes, talk to upstream so they automatically load completions in $XDG_DATA_DIRS. You can point them to this issue. |
@jtojnar do I read it correctly: they claim loading/unloading is already possible by calling some fish functions so they are unwilling to implement a solution based on XDG_DATA_DIRS? |
I am looking for a way to add bash completions without using nix. I use asdf to install several CLI tools and asdf allows me to manage them in the same directory: Is there any workaround or alternative? |
FWIW, I made https://github.com/pfgray/fish-completion-sync, a fish plugin which has the same effect as It works by listening on changes to It's not perfect, but it's been working well for me so far |
Now I can get autocomplete for CLIs installed through nix+direnv. See: direnv/direnv#443
My issue with this is that when loading an activation script like the one that |
IMHO this is not an issue of direnv but a problem of some shells that still could not respect $XDG_DATA_DIRS. In any case, I came up with a dirty hack for zsh. For this to work one has to first export #!/bin/bash
# ~/.config/direnv/lib/fpath_prepend.sh
# add missing zsh functions for executables
# for this to work, one has to export $FPATH in e.g. ~/.zshrc
fpath_prepend() {
if [[ -z $FPATH ]]; then
>&2 echo "\$FPATH empty, not adding: $*"
exit 0
fi
local executable exec_path extra_fpath;
extra_fpath=""
for executable in "$@"; do
if exec_path=$(which "$executable" 2>/dev/null); then
extra_fpath="$extra_fpath$(dirname "$exec_path")/../share/zsh/site-functions:"
fi
done
export FPATH="$extra_fpath$FPATH"
} With this under |
I've been adding the following to the end of my if [[ "${SHELL##*/}" == zsh ]]; then
direnv_load ${SHELL} -c 'export FPATH; direnv dump'
PREFIX=${PWD}/dist # or wherever your local prefix is
path_add FPATH "${PREFIX}/share/zsh/site-functions"
path_add MANPATH "${PREFIX}/share/man"
path_add XDG_DATA_DIRS "${PREFIX}/share"
fi I have noticed some strangeness in restoring |
@bryango well it's also an issue for bash. I think it's more do to with the fact that direnv does its activation using a non-interactive shell which doesn't support loading completions. |
I think bash should work if you supply it with the correct $XDG_DATA_DIRS, and at least for me, it works out of the box (I use nix, by the way). It seems that bash does load completions from $XDG_DATA_DIRS and nix properly exports $XDG_DATA_DIRS as per #443 (comment). I was probably too harsh on zsh though, which is unfair for the people volunteering to maintain it... Sorry, amended my answer.
I am not sure if "interactive-ness" is the matter here. Even if I enter a new interactive zsh with the correct $XDG_DATA_DIRS, as long as $FPATH (or $fpath) is not updated, zsh fails to load the completion. Also, as evidenced by previous comments, zsh (and fish?) indeed did not respect $XDG_DATA_DIRS. |
Interesting. The specific issue for me is that I’m trying to load a shell hook from |
Oh, I see... this is an interesting edge case. I cannot see a way out of this for direnv, as it runs in a subshell and I don't think the |
With zsh on macos with nix-darwin, I wasn't finding that the shell was loading completions even though _direnv_hook() {
trap -- '' SIGINT
eval "$("/opt/homebrew/bin/direnv" export zsh)"
compinit
trap - SIGINT
}
typeset -ag precmd_functions
if (( ! ${precmd_functions[(I)_direnv_hook]} )); then
precmd_functions=(_direnv_hook $precmd_functions)
fi
typeset -ag chpwd_functions
if (( ! ${chpwd_functions[(I)_direnv_hook]} )); then
chpwd_functions=(_direnv_hook $chpwd_functions)
fi |
Hey, just wanted to say, thanks for that code snippet, it helped me start create my own solution for this, and I extended it into a whole plugin that automatically tracks changes to FPATH, XDG_DATA_DIRS, and optionally PATH to discover new/removed completion paths and reloads compinit as needed |
It would be nice to be able to load new {bash/zsh/etc}-completions from an
.envrc
script. A typical use case would be whenuse nix
provisions some commands that you don't have globally installed (or are for different versions so their command-line args differ).This could work for example like this:
add_completions
to register completion scripts inside.envrc
. E.g.direnv export
action emits, along with theexport
/unset
commands, code to add (and remove) the registered completions.The text was updated successfully, but these errors were encountered: