Local switches in vscode (bug around creating a terminal)

I am trying to set up a project to use a local switch and it’s mostly working fine but my main issue is that the integrated terminal does not use the appropriate switch. I could just configure it by hand to run eval (opam env) at startup, but I see from some older thread that the command “OCaml: create terminal” is supposed to solve this problem and start a terminal in the appropriate environment. However, this does not work for me: in spite of the appropriate switch being selected, if I try using for instance dune in the terminal created by “Create terminal”, it will call the version from the global default switch. Is this expected? If not, does anybody have an idea what could be causing it?

I am on ubuntu, I use fish as my terminal. I notice that the command displayed when I hover over the name of the terminal looks like this:

/usr/bin/opam exec --switch=/path/to/project --set-switch --root /home/myname/.opam -- /usr/bin/fish

This seems wrong? Why is ~/.opam involved at all?

Are you using vscode locally or vscode remote? I have a similar problem when using vscode to work on a remote server through ssh. In my case the problem is that vscode server is running in a non interactive session.

opam init installs the hook in ~/.opam/opam-init/init.sh. This file needs to be loaded by the shell. It usually happens automatically because opam also edited ~/.profile to source ~/.opam/opam-init/init.sh. But the top of init.sh looks like this:

if [ -t 0 ]; then
  test -r /home/louis.roche/.opam/opam-init/complete.sh && . /home/louis.roche/.opam/opam-init/complete.sh > /dev/null 2> /dev/null || true

  test -r /home/louis.roche/.opam/opam-init/env_hook.sh && . /home/louis.roche/.opam/opam-init/env_hook.sh > /dev/null 2> /dev/null || true

test -r /home/louis.roche/.opam/opam-init/variables.sh && . /home/louis.roche/.opam/opam-init/variables.sh > /dev/null 2> /dev/null || true

It does not enable the hook when the session isn’t interactive. The quick solution is to source init.sh from ~/.bashrc instead of ~/.profile.

For fish it might be a little bit different but not that much.

No, it’s all local in my case. The opam hooks are getting executed since otherwise dune would not be in the path at all (or it would be the version installed by the package manager but I don’t think I have it).