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

lsp mode awkwardness #25

Open
cwhatley opened this issue Aug 24, 2020 · 7 comments
Open

lsp mode awkwardness #25

cwhatley opened this issue Aug 24, 2020 · 7 comments

Comments

@cwhatley
Copy link

Do you use lsp-mode in conjunction with poetry.el? I'm using lsp-deferred, but the connection to the language server is still to early to pick up the right env and run pyls from within the venv. I've tried all three tracking strategies.

@jidicula
Copy link

jidicula commented Aug 25, 2020

@cwhatley I've been trying to set up a config like this too. I think I have lsp-python-ms set up for non-Poetry projects using .dir-locals.el to manually set the path to the virtual environment's Python binary, but that approach doesn't seem to work for Poetry projects. At the moment I'm trying to add a hook to lsp-python-ms to check if poetry.el has found a project root, but I'm running into the same wall as you where the language server connection always starts first before anything else is evaluated.

;; lsp Python
(use-package lsp-python-ms
  :after lsp-mode poetry
  :ensure t
  :init
  (setq lsp-python-ms-auto-install-server t)
  :config
  (put 'lsp-python-ms-python-executable 'safe-local-variable 'stringp)
  :hook
  (hack-local-variables-hook . (lambda ()
				 (when ('stringp (poetry-find-project-root))
				   (poetry-venv-workon)
				   (print "hello")
				   )
				 (when (derived-mode-p 'python-mode)
				   (require 'lsp-python-ms)
				   (lsp-deferred))
				 ))
  )

@jidicula
Copy link

jidicula commented Aug 25, 2020

@cwhatley I figured it out 🎉 ! Here are the relevant use-package snippets:

;; poetry
(use-package poetry
  :ensure t
  :hook
  ;; activate poetry-tracking-mode when python-mode is active
  (python-mode . poetry-tracking-mode)
  )

;; ....

;; lsp-mode configs
(use-package lsp-mode
  :ensure t
  :init
  (setq lsp-keymap-prefix "C-c l")
  :custom
  (lsp-auto-guess-root +1)
  :config
  (lsp-enable-imenu)
  ;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l")
  :hook (;; replace XXX-mode with concrete major-mode(e. g. python-mode)
         (python-mode . lsp-deferred)
         ;; if you want which-key integration
         (lsp-mode . lsp-enable-which-key-integration)
	 (lsp-after-open . 'lsp-enable-imenu)
	 )
  :commands (lsp lsp-deferred))

;; lsp Python
(use-package lsp-python-ms
  :after poetry
  :ensure t
  :init
  (setq lsp-python-ms-auto-install-server t)
  :config
  (put 'lsp-python-ms-python-executable 'safe-local-variable 'stringp)
		    ;; attempt to activate Poetry env first
		    (when (stringp (poetry-find-project-root))
		      (poetry-venv-workon)
		      )
  :hook
  (
   (python-mode . (lambda ()
                    (require 'lsp-python-ms)
                    (lsp-deferred)
		    ))
   ;; if .dir-locals exists, read it first, then activate mspyls
   (hack-local-variables . (lambda ()
			     (when (derived-mode-p 'python-mode)
			       (require 'lsp-python-ms)
			       (lsp-deferred))
			     ))
   )
  )

It seems awfully hacky to me, but importantly it works automatically with Poetry projects and projects where I manually define a Python (and mypy) path in a .dir-locals.el file.

@cwhatley
Copy link
Author

Thanks for the snippet. What's the when...poetry-venv-workon clause doing in the middle of the lsp-python-ms package statement? That seems to conflict with having poetry tracking mode on.

Sounds like the moral of the story is to not have poetry.el automatically track.

@jidicula
Copy link

What's the when...poetry-venv-workon clause doing in the middle of the lsp-python-ms package statement? That seems to conflict with having poetry tracking mode on.

The poetry.el init process seems to be too slow, so the connection to the mspyls always happens as soon as the -python-mode-hook runs. I found that the important part of the init process is the poetry-venv-workon so mspyls can see the Poetry virtualenv Python binary before it spins up, so I just added that to the package statement.

Sounds like the moral of the story is to not have poetry.el automatically track.

Fully agree – it runs far too slowly and runs the virtualenv activation too late. If it provided a minor mode and a mode-hook, I could use that instead in my package declaration.

@cwhatley
Copy link
Author

I actually use pyls (I should try the MS one, I think) and inspired by your snippet, I tried the following and found this seems to work pretty well so far:

(use-package poetry
  :hook
  (python-mode . (lambda () (when (poetry-venv-exist-p)
                              (setq-local lsp-pyls-server-command '("poetry" "run" "pyls"))
                              (poetry-venv-workon))))
  )

@jidicula
Copy link

Very cool! I only just started using LSP and opted for mspyls since some threads on Reddit suggested it has better performance and is more actively developed.

@hekinami
Copy link

a better config based on @cwhatley 's

(use-package poetry
  :straight t
  :config
  (poetry-tracking-mode)
  )

(use-package python
  :mode "python-mode"
  :after (poetry)
  :hook
  (python-mode
   . (lambda () (when (poetry-venv-exist-p)
                  (setq-local lsp-pyls-server-command '("poetry" "run" "pyls"))
                  )
       (lsp-deferred)
       )
  )
  :config
  (setq python-indent-guess-indent-offset nil))

(use-package pyvenv
  :straight t
  :hook (after-init . pyvenv-mode)
  )

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

3 participants