purcell/emacs.d

Question on combining `eglot` + `nix` + `poetry`

yszhang95 opened this issue · 5 comments

I tried to follow the recording in init-python.el. It is interesting to find poetry works in shell.

However, I have a question on how to reconcile eglot and nix+poetry.

An example would be:
In shell.nix

{ pkgs ? import <nixpkgs> {} }:

pkgs.mkShell {
  buildInputs = [
    pkgs.python3
    pkgs.poetry
  ];
}

and then echo "use_nix" > .envrc.

After steps above, in emacs, I executed M-x shell. Inside *shell*, I did

poetry init -n -name sk
poetry add matplotlib

This means nix + poetry works well.
Then I create a python file, filling in import matplotlib.pyplot as plt.

After enabling M-x eglot, I do not find any in-buffer completion of plt.x and the definition of pyplot cannot be found either via M-..

Sorry for the stupid question. There are some other ways to hack on the internet but may corrupt the setup here, which give me concerns.

Thanks for your valuable time and support!

All you need to do is to make sure that the language server is launched in the correct virtualenv (in your case, the virtualenv created by poetry). Personally, I use direnv; see the comment on the top of init-python.el.

Hey! I've been playing with LSPs and this sort of setup recently.

A simple thing you can do is to install your LSP server, e.g. pyright, as a dev dependency inside the poetry project. Then you can use poetry run pyright as the LSP command for eglot.

There's a further trick you can use to make direnv (and therefore Emacs, assuming you use my envrc package, or the direnv package) "see" the inside of the virtual environment built by poetry: you can change your .envrc to

use_nix
direnv_load poetry run direnv dump

I have the impression this second trick sometimes confuses poetry, though, so I probably would recommend the first approach instead.

I've never had a problem with using the latter (though I recall that there was a bug with poetry in the past where poetry env info --path fails occasionally, so simply putting export PATH="$(poetry env info --path)/bin:${PATH}" in .envrc will occasionally not work). The good thing about using the direnv solution is that it sorts out the path for other tools too, e.g. black.

Thanks for the suggestions! I am sorry that I reply so late. It took me a long time to figure things out. Asking eglot to use poetry run pyright helps me out!

Nice, thanks for confirming.