Skip to content
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

Per-project opam switch autodetection #199

Open
actionshrimp opened this issue Jan 25, 2019 · 10 comments
Open

Per-project opam switch autodetection #199

actionshrimp opened this issue Jan 25, 2019 · 10 comments
Assignees

Comments

@actionshrimp
Copy link

Now that opam allows you to create 'directory' switches (e.g. opam switch create .) for a particular project, it would be great if we could detect the presence of an _opam directory for a particular project, and automatically call tuareg-update-opam-env to use that switch (or a similar function that sets a buffer-local exec-path), so that tooling works correctly across files that may use e.g. different OCaml versions.

Currently I put a .dir-locals.el file in each project with this line:
((tuareg-mode . ((eval . (tuareg-opam-update-env (projectile-project-root))))))
which works pretty well, but it'd be awesome if tuareg could detect this automatically, recursively searching up the file tree for an _opam folder.

Does this sound like a sensible approach, or am I just out of the ordinary in terms of the way I use switches? To me this would be more in line with the way things work in other language ecosystems, where tools are looked for on a project-local basis.

Would appreciate any feedback - if this sounds reasonable I'll try and take a look at implementing the functionality.

@Chris00
Copy link
Member

Chris00 commented Jan 25, 2019

It is not that simple: tuareg-opam-update-env updates the environment of Emacs so that, if you switch to the buffer of another project and compile it, the environment will be the one previously selected. What one can do is to update the environment each time one is compiling. This used to be the default but caused problems with e.g. Tramp. You can activate it setting tuareg-opam-insinuate to t. At the moment tuareg-opam-insinuate is global (must be set before loading Tuareg) but an improvement would be to be able to activate it or not for each file independently (with a local variable) or maybe "per project" (with a mechanism to define).

@actionshrimp
Copy link
Author

Thanks very much for the info - it looks like tuareg-opam-insinuate set to t pretty much does exactly what I want anyway for project-specific switches as opam does the env lookup automatically.

Am I correct in saying that manually calling tuareg-opam-update-env has no effect if you have insinuate set to true (if I run e.g. (merlin-command) after an update-env with insinuate set to t it still seems to be set to the insinuated value), and this is why you suggest that being able to turn insinuate off in a more granular fashion would be beneficial?

One other possible enhancement would be to allow setting of the opam config --switch flag via an emacs local/project-level variable so a project could specify a particular global switch to use, but it looks like other tools would need to be aware of this, e.g. merlin.el would need to support this as it calls out to opam if merlin-command is set to 'opam.

Ideally perhaps opam itself could read some kind of .opam-switch file in the project root so it set the right switch itself, but that's a separate issue!

Thanks for taking the time to respond this has been very enlightening!

@Chris00 Chris00 reopened this Jan 31, 2019
@Chris00
Copy link
Member

Chris00 commented Jan 31, 2019

Reopening as a reminder to develop per repo build environment — with caching.

@Chris00 Chris00 self-assigned this Jan 31, 2019
@rgrinberg
Copy link
Member

I'm not convinced that tuareg is the right place to do this stuff anymore. The LSP mode for OCaml should be aware of all of this stuff and work far smoother than whatever hacks we pile up in Elisp. IMO tuareg should stick to the functionality that can't be provided via LSP.

@Chris00
Copy link
Member

Chris00 commented Feb 1, 2019

@rgrinberg May you point some doc about LSP?

@Chris00
Copy link
Member

Chris00 commented Apr 11, 2019

@rgrinberg Were you referring to https://github.com/freebroccolo/ocaml-language-server or to some other work?

@Chris00
Copy link
Member

Chris00 commented Apr 11, 2019

(Incidentally there is already a package for Emacs.)

@monnier
Copy link
Contributor

monnier commented Apr 11, 2019 via email

@rgrinberg
Copy link
Member

Well, I think it's merlin itself that has the most functional lsp server for OCaml at the moment. But actually, I think I should retract my comment. The LSP server should probably be launched in the correct environment (sandbox), it probably shouldn't be aware of switches, esy sandboxes, etc. So I think I'm in favor of this PR after all

@yongweiy
Copy link

I came across this issue when I am looking for a way to detect local opam switch automatically. After setting tuareg-opam-insinuate to t, it seems like the environment is not updated correctly, i.e., exec-path does not include the local _opam/bin folder. FYI, here is how I set up tuareg,

(use-package tuareg :ensure t
  :defer t
  :init
  (setq tuareg-opam-insinuate t)
  )

A related question is that, though tuareg-update-opam-env is able to correctly update exec-path, load-path won't be updated. Is this behavior intended?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants