purcell / emacs.d

An Emacs configuration bundle with batteries included
BSD 2-Clause "Simplified" License
6.82k stars 2.04k forks source link

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

Closed yszhang95 closed 7 months ago

yszhang95 commented 8 months ago

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!

arthurl commented 7 months ago

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.

purcell commented 7 months ago

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.

arthurl commented 7 months ago

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.

yszhang95 commented 7 months ago

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!

purcell commented 7 months ago

Nice, thanks for confirming.