reddit / emacs

Unable to setup lsp-mode with lsp-pyright

SilkyRock · 2022-05-20 18:22
I'm using Emacs 28.1 on macOS 11.6.6 (installed with `brew`) and want to setup a Python IDE with [`lsp-mode`](https://github.com/emacs-lsp/lsp-mode) and [`lsp-pyright`](https://github.com/emacs-lsp/lsp-pyright). My (not full) `init.el` looks like this (LSP and Python setups are at the bottom of the file): ;; Define and load custom.el file (setq custom-file (expand-file-name "custom.el" user-emacs-directory)) (when (file-exists-p custom-file) (load custom-file)) ;; Modify package repositories (require 'package) (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) ;; Load and activate Emacs packages (package-initialize) ;; Install use-package if it's not installed (unless (package-installed-p 'use-package) (package-refresh-contents) (package-install 'use-package)) ;; Load use-package (require 'use-package) (setq use-package-hook-name-suffix nil) ;; Do not append text to the name of hooks mentioned by :hook ;; Load use-package-ensure ;; Support for :ensure and :pin keywords in use-package declarations (require 'use-package-ensure) (setq use-package-always-ensure t) ;; exec-path-from-shell (use-package exec-path-from-shell :ensure t :if (eq system-type 'darwin) :custom (exec-path-from-shell-variables '("PATH" "MANPATH" "XDG_CONFIG_HOME" "WORKON_HOME" "LSP_USE_PLISTS" "PYTHONPATH" "IPYTHONDIR" "MPLCONFIGDIR")) (exec-path-from-shell-arguments nil) :config ;; (setenv "PKG_CONFIG_PATH" "/usr/local/Cellar/zlib/1.2.11/lib/pkgconfig:/usr/local/lib/pkgconfig")) (exec-path-from-shell-initialize)) ;; Helm ;; Input completion (use-package helm :ensure t :init (helm-mode 1) (require 'helm-config) :bind ;; ("C-c i" . helm-imenu) ;; Select document heading ("C-x b" . helm-mini) ;; Select buffers ("C-x C-f" . helm-find-files) ;; Open or create files ("C-x C-r" . helm-recentf) ;; Select recently saved files ("M-x" . helm-M-x) ;; Evaluate functions ("M-y" . helm-show-kill-ring) ;; Show the kill ring (:map helm-map ("<tab>" . helm-execute-persistent-action) ("C-z" . helm-select-action))) ;; which-key ;; Input completion (use-package which-key :ensure t :custom (which-key-idle-delay 0.5) (which-key-idle-secondary-delay 0.5) :config (which-key-mode 1) (which-key-setup-side-window-bottom)) ;; Company ;; Text completion (use-package company :ensure t :custom (company-idle-delay 0.0) (company-minimum-prefix-length 4) (company-selection-wrap-around t) :hook ((text-mode-hook . company-mode) (prog-mode-hook . company-mode)) :bind (:map company-active-map ("<tab>" . nil) ("TAB" . nil) ("M-<tab>" . company-complete-common-or-cycle) ("M-<tab>" . company-complete-selection))) ;; Flyspell ;; Spell checking for text (requires aspell) (use-package flyspell :ensure t :init (setq ispell-program-name "aspell") :hook ((text-mode-hook . flyspell-mode) (prog-mode-hook . flyspell-prog-mode)) :bind ("<f7>" . flyspell-word) ("M-<f7>" . flyspell-buffer)) ;; Flycheck ;; Spell checking for code (use-package flycheck :ensure t :init (setq flycheck-highlighting-mode 'symbols flycheck-indication-mode 'left-fringe flycheck-standard-error-navigation t) :hook (prog-mode-hook . flycheck-mode)) ;; LSP Mode ;; Language Server Protocol Support (use-package lsp-mode :ensure t :hook (lsp-mode-hook . lsp-enable-which-key-integration) :bind ("s-l" . lsp-keymap-prefix) :commands lsp) (use-package lsp-ui :ensure t :after lsp-mode :hook (lsp-mode-hook . lsp-ui-mode) :bind (:map lsp-ui-mode-map ("C-c i" . lsp-ui-menu))) (use-package lsp-pyright :ensure t :after (python lsp-mode) :custom (lsp-pyright-venv-path (getenv "WORKON_HOME")) :hook (python-mode-hook . (lambda () (require 'lsp-pyright) (lsp)))) ;; Python (use-package python :ensure t :custom ;; (python-shell-completion-native-enable nil) (python-indent-guess-indent-offset-verbose nil) (python-shell-buffer-name "IPython") (python-shell-interpreter "ipython") (python-shell-interpreter-args "-i --simple-prompt") :hook ((python-mode-hook . flyspell-prog-mode) (python-mode-hook . flycheck-mode) (python-mode-hook . company-mode) (python-mode-hook . lsp))) ;; pyenv-mode ;; Integrate pyenv with python-mode (use-package pyenv-mode :ensure t :if (eq system-type 'darwin) :after python :hook (python-mode-hook . pyenv-mode)) ;; pyvenv ;; Python virtual environment support (use-package pyvenv :ensure t :after python :custom (pyvenv-workon "env") :hook ((python-mode-hook . pyvenv-mode) (pyvenv-post-activate-hooks . pyvenv-restart-python) (pyvenv-post-deactivate-hooks . pyvenv-restart-python)) :config (defalias 'workon 'pyvenv-workon) (defalias 'deactivate 'pyvenv-deactivate)) ;;; init.el ends here Basically, I use `pyenv` to manage different Python versions on my machine. I also manage virtual environments under `WORKON_HOME`, which is defined in my `.profile` file as `~/.python/venv`. Generally, I use just a single venv called `env` for all my scripting purposes. My goal is to use LSP for Python whenever I open a `.py` file. According to [this](https://github.com/microsoft/pyright#emacs), `lsp-mode` and `lsp-pyright` are the only necessary parts to run LSP for Python in Emacs. Now, in my current setup, whenever I run Emacs (from Applications) and open a `.py` file, I get this in my minibuffer: Unable to find installed server supporting this file. The following servers could be installed automatically: The only possible choice I have is `pyright` (it seems that it doesn't find `lsp-pyright`). I choose it, press `Enter` and get the following message in `*Messages*` buffer: LSP :: Download pyright started. LSP :: Server pyright install process failed with the following error message: Unable to find a way to install pyright. Check `*lsp-install*' and `*lsp-log*' buffer. The `*lsp-log*` looks like this: Command "pyls" is not present on the path. Command "pylsp" is not present on the path. Unable to install pyright via `npm' because it is not present ~~Why is it not finding my `lsp-pyright` installation?~~ Perhaps I am missing something on Python's side (some packages, etc.)? Sidenotes: 1. I use `(setq use-package-hook-name-suffix nil)` so all of my `:hook` definitions involve `-hook(s)` at the end. 2. As I understand, `pyls` (also know as [python-language-server](https://github.com/palantir/python-language-server)) is [deprecated](https://emacs-lsp.github.io/lsp-mode/page/lsp-pyls/). --- UPDATE: All I needed to do to solve this problem was to install the actual language server for Python. I did this by using `brew`, as `pyright` is available there: brew install pyright
anaumann · 2022-05-20 18:45
lsp-pyright is the emacs portion of the pyright integration via lsp, you still need to install the actual languageserver. There are people maintaining a python package for it: [https://pypi.org/project/pyright/](https://pypi.org/project/pyright/), you would have to install that into your virtualenv. Personally, I had a bit of a shaky experience with the python package and just installed pyright the "regular" way via npm. Once the `pyls` or `pylsp` commands are on your path, lsp-pyright should work just fine.
SilkyRock · 2022-05-20 19:05
Oh, so this clears things up a bit as I was actually missing something (the `npm` part). For me personally, various documentations I read were very unclear as to what I actually need in order make this setup work (I have never heard about `npm` up until today). Anyway, thanks for clearing this up! Also, in your opinion, what is the "most correct" way to setup Python IDE in Emacs as of today? Given the many possible choices for different Python LSP's (with some of them being deprecated), it can get kind of confusing.
Extension_Try_6870 · 2022-05-20 19:11
You could also use your package manager. "pacman -Syu pyright" for example. Not sure it's available on Macos.
SilkyRock · 2022-05-20 19:15
I checked now, and `pyright` is actually available on `brew`. I just wonder if it's the "community-maintained" version or the "normal" version which is available on `npm`. EDIT: I think it's the `npm` version, since one of the dependencies for `pyright` on `brew` is `node`.
anaumann · 2022-05-20 19:21
I've only just switched to pyright after using lsp-python-ms for quite a while(because the one by Palantir is deprecated and well, it's Palantir)... I found both of them reasonably easy to install, but pyright feels a bit snappier when completing things and to me it seems that it knows about more language constructs than the "old" Microsoft server. As for setting things up as an IDE.. there are a couple of Python modes available from times when LSP wasn't available, but I switch languages quite a number of times every day, so having everything work with the same interface(ie. lsp) works best for me. But I don't really have much to complain about.. Most I do is writing up moderately complex scripts, no huge projects and no Java(for that, I'd still prefer IDEA).. It just works.. Some servers don't allow for refactoring which can be a bummer, but as I said, with my projects, it can also be done with a bit of elbow grease :)
White86ec · 2022-05-20 19:21
Personally, I prefer pylsp over pyright as it doesn't require extra npm bloat. And I have .dir-locals at the root of my project with these commands: ``` ((python-mode . ((fill-column . 90) (projectile-project-run-cmd . "python -m src") ;; don't prompt for command on `projectile-run-project' (compilation-read-command . nil) ;; default is jedi (slow and old) (lsp-pylsp-rename-backend . 'rope) (eval . (lsp-deferred)) (eval . (add-hook 'before-save-hook #'lsp-format-buffer nil t)) (eval . (require 'dap-python)) (eval . (dap-register-debug-template <...>))))) ```
anaumann · 2022-05-20 19:30
That "community maintained" version is just a repackage, as I read it.. so you can get by with just python tools and don't need to install node.. I had node anyway and the npm installation worked better for me than the pip one(and I switch virtualenvs quite a lot) :)
heathm55 · 2022-05-20 20:38
I use poetry and usually include it in my pyproject.toml: >\[tool.poetry.dev-dependencies\] > >pyright = "\^0.06" > > > >\[tool.pyright\] > >exclude=\[\*\*/\_\_pycache\_\_\] reportMissingImports = true > >reportMissingTypeStubs = false > >reportLibraryCodeForTypes = true > >venv=venvName > >pythonVersion="3.x.x" > >venvPath = /path/to/your/venvs/venvName > >typeChecking = "basic"
heathm55 · 2022-05-20 20:41
This allows for per project differences in versioning / typechecking / etc.. I also use .dir-locals.el file so emacs picks up my projects specific debugging options. Works out well.
SilkyRock · 2022-05-21 15:01
Thanks for the info. I'm not a programmer myself, but my current endeavor requires some scripting (and will require more in the near future) so I'm just trying to learn all of these things "correctly".
SilkyRock · 2022-05-21 15:02
Hmm, I will definitely have this in mind, thanks!
SilkyRock · 2022-05-21 15:04
Seems interesting. Currently I just mainly do various simple scripts (still learning), so no complex projects for me yet. But I will have this in mind as well, thanks.