Local opam switch and emacs

I have a project that uses a local opam switch, and when I open one of its files, the version of OCaml is correctly set to the local switch one. The problem is that I no longer can switch to the global switch later, even when opening a file out of the local switch.

More precisely, here is what happens:

  • launch emacs → global opam switch (detected by doing which ocaml from emacs)
  • open ml file in local switch → local switch
  • open ml file elsewhere (out of local switch) → still local switch

Do you know of a way to reevaluate the current switch from within emacs?

If you use the tuareg mode, I think tuareg-opam-update-env may work:

tuareg-opam-update-env is an interactive compiled Lisp function in
‘~/.opam/4.14.1/share/emacs/site-lisp/tuareg-opam.el’.

It is bound to C-c C-w.

(tuareg-opam-update-env SWITCH)

Update the environment to follow current OPAM switch configuration.
1 Like

I’m not aware of the most recent emacs developments. But when I was actively using emacs daily I was relying on dotenv to load the right switch in the right place. If you don’t want dotenv you can emulate something similar with a hook that runs eval $(opam env) when you open the file.

For Emacs I use direnv for switching on local opam switches. This in my personal init.el

(use-package direnv
  :config
  (direnv-mode))

and this .envrc in each project.

eval $(opam env)

Alternatively you can use this config for direnv

# Usage: use ocaml <version-switch> 
#
# Loads the specified ocaml version switch into the environent.
#
use_ocaml() {
  opam switch $1
  eval $(opam env)
}

and put use ocaml <switch_name> into your .envrc. It is useful if you want to have global switches that you share between projects. I wrote up my config from last year as OCaml with Emacs in 2022 · Perpetually Curious Blog but it has changed with some more lsp-mode customisations.

1 Like

Thanks a lot for all the suggestions. I ended up using tuareg-opam-update-env which worked great.

1 Like