From time to time I use the miniconda package manager. Normally, conda adds the following line to ~/.config/fish/config.fish
upon installation:
eval /home/quappas/.apps/miniconda3/bin/conda "shell.fish" "hook" $argv | source
This line must be executed before conda can be used. However, it is quite slow to execute and having it in config.fish
causes a significant startup delay every time I open a terminal. This is annoying because most of the time I don't even want to use conda when I open a terminal. So I decided to remove the line from config.fish
and define a function conda.fish
to wrap the conda command instead:
function conda --wraps 'conda'
if not set -q CONDA_INITIALIZED
echo 'Initializing conda...'
eval /home/quappas/.apps/miniconda3/bin/conda "shell.fish" "hook" | source
set -g CONDA_INITIALIZED 1
end
command conda $argv
end
With this function, for some reason I can do
conda
conda activate myenv
in a new terminal and it works just fine. However I do
conda activate myenv
directly in a new terminal, I get conda's "Your shell has not been properly configured to use 'conda activate'." error. Confusingly if I do
conda activate myenv
conda activate myenv
in a new terminal, the first command gives me the above error but the second one activates my environment successfully without complaint.
I'm not sure if this is a problem with my function, fish or conda. What can I do to be able to use the conda command normally, but only run the slow conda initialization script when I actually call conda?
CodePudding user response:
The issue is that the conda
integration happens by defining a function called conda
. So calling command conda
is wrong, they want it to be called via a wrapper function.
See what happens after you run conda
once and then use type conda
to see the definition:
conda is a function with definition
# Defined via `source`
function conda
set -l CONDA_EXE /opt/miniconda3/bin/conda
if [ (count $argv) -lt 1 ]
$CONDA_EXE
else
set -l cmd $argv[1]
set -e argv[1]
switch $cmd
case activate deactivate
eval ($CONDA_EXE shell.fish $cmd $argv)
case install update upgrade remove uninstall
$CONDA_EXE $cmd $argv
and eval ($CONDA_EXE shell.fish reactivate)
case '*'
$CONDA_EXE $cmd $argv
end
end
end
You can either do that in your own function, or call conda $argv
, which would ordinarily be an infinite loop.
Since that seems a bit awkward, how about this instead:
function conda --wraps 'conda'
echo 'Initializing conda...'
# We erase ourselves because conda defines a function of the same name.
# This allows checking that that happened and can prevent infinite loops
functions --erase conda
/home/quappas/.apps/miniconda3/bin/conda "shell.fish" "hook" | source
if not functions -q conda
# If the function wasn't defined, we should not do the call below.
echo 'Something went wrong initializing conda!' >&2
return 1
end
# Now we can call `conda`, which is a function, but not this one (because we erased it),
# so this is not an infinite loop.
conda $argv
end
The variable is now unnecessary since this function is never called twice in the same shell, and I removed the dangerous and unnecessary eval
.