1

I'm using Emacs 28.1 on macOS 11.6.6 (installed with brew) and want to setup a Python IDE with lsp-mode and 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, 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) is deprecated.

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

1 Answer 1

1

I tried your config, and it works for me. You can see the below figure. I faced an issue in using helm, so I disabled only the use-package declaration.

enter image description here

The relevant error is "npm because it is not present", which is what is used by lsp-mode or lsp-install-sever to install many language servers, including pyright. You can use the following link to install npm on your preferred OS (I am assuming Ubuntu).

How to Install Node.js and npm on Ubuntu 20.04

Note that you can also install pyright by yourself globally so that it is available in your $PATH. Then, lsp-mode clients will no longer try to install the server on your behalf. You can do either of the following:

npm install -g pyright 
# If you prefer snap: https://snapcraft.io/
sudo snap install pyright --classic 
2
  • 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!
    – user36782
    Commented May 20, 2022 at 19:10
  • Nice. You may want to accept and upvote the answer. Commented May 21, 2022 at 0:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.