Closed johnflavin closed 4 years ago
Wait, whatnow?
_.fish
(https://github.com/fish-shell/fish-shell/blob/master/share/functions/_.fish) explicitly checks for the existence of gettext (or ggettext) before defining the function. If it isn't available it defines a wrapper around echo
.
Something is *very wrong with your system.
I know! It's weird. I looked in _.fish
and saw the lines trying to check for gettext
:
if command -sq ggettext
...
else if command -sq gettext
...
When I run command -sq gettext
it exits with status 1
, as I would expect.
I'm betting your conda environment has gettext, and then you're taking it away when deactivating it.
Yes, that's something I noted in the issue. When the shell is activated, it starts with a default conda environment that does have gettext
. But when I switch to a different conda environment that does not have gettext
(or deactivate the environment, as I did in the reproduction), that's when I see the error.
Is this function caching the results of command -sq gettext
in the definition or something?
Is this function caching the results of command -sq gettext in the definition or something?
It's not in the function definition. The function is conditionally defined, depending on the result.
Hmm. That presents an issue in my case, where I can switch from an environment where gettext
is available to one where it is not.
Is there a reason not to check for the presence of gettext
in the function itself (and thus checking each time it is called), rather than defining a function that assumes the function will always be available if it was once? Like, is that an expensive check?
Like, is that an expensive check?
Yes. We've had performance issues with this.
Hmm. That presents an issue in my case, where I can switch from an environment where gettext is available to one where it is not.
Would it not be possible to just install gettext on the host? Or am I misunderstanding something?
One possible way to handle this is to make a _
builtin - we have access to gettext in c++, so we could just make that available. However gettext can potentially crash, I'm not sure how to handle this.
Here's a question that may help me remove this problem from the source. It seems that when I load a shell with a temp home, with sh -c 'env HOME=$(mktemp -d) fish'
, my default conda environment is still on my PATH
.
> sh -c 'env HOME=$(mktemp -d) fish'
Welcome to fish, the friendly interactive shell
Type `help` for instructions on how to use fish
me@machine /U/me> echo $PATH
/Users/me/anaconda3/envs/env/bin /Users/me/anaconda3/condabin /Users/me/bin /usr/local/bin /usr/bin /bin /usr/sbin /sbin /opt/X11/bin /usr/local/sbin /usr/local/MacGPG2/bin
Can you tell me how those PATH
components get configured? Like, did I (stupidly) set that as a global environment variable or something? I bet if I can figure out how that conda environment is getting in the PATH even though my home directory's config is not being loaded, I can make this problem go away.
Can you tell me how those PATH components get configured?
$PATH is a global and exported environment variable. Child processes inherit it. Your terminal process also has a $PATH, as has its parent. That's unix.
Ok, I think I see what's happening.
When I did my reproduction, I first opened a new terminal window. That starts a shell which gets all my user configuration applied, which means it loads my default conda environment, which means that conda environment is on the PATH. That's the seed of the issue. Then when I start a new shell with an empty HOME (with sh -c 'env HOME=$(mktemp -d) fish'
) that PATH, which was already set up with my user stuff, gets inherited into the child shell. So the issue persists even in the "clean" shell.
Now a question about how to solve this: I still want to have a default conda environment. But if possible, I would like it to not be active when _
gets defined; that way it won't think gettext
is available. Do you know when _
gets defined? Or if there is a way I can make that happen in my user config before I configure my conda environment?
Do you know when _ gets defined?
It is autoloaded whenever it is first executed. So the way to load it earlier is to execute it earlier, possibly by adding a bogus call like _ >/dev/null 2>&1
. Or you could call something that loads it to look up the definition like functions _
.
Or you could force one definition by creating your own .fish. Try `funced , and then
funcsave once you're happy. That'll create an
.fish` that will take precedence over our default one.
Awesome, thanks! I added a script in my ~/.config/fish/conf.d
directory that runs functions _ > /dev/null
, and named it so it occurs before the script that activates my conda environment. Now I can switch conda environments at will and the git tab completion works without error.
Problem
When using tab completion for git and the
gettext
command is not found, an error is raised from fish.This is the error message:
Note that the command substitution does still work, at least it did during my testing. But the error gets printed to the screen.
Reproduction
I could reproduce this in a shell with third-party plugins turned off. However, it was a bit tricky because of interactions with
conda
. When I activated the fresh shell, it still had my defaultconda
environment enabled, and that environment does havegettext
. So I had toconda init
, then deactivate conda, and then I could reproduce the issue.Reproduction was being in a git repo directory and running
git checkout <a letter that starts a branch name>
and pressing<TAB>
.In this log, most of the lines are getting conda set up. The last command is the one that produces the error.