Switch to python-lsp-ruff and overhaul the Python and Eglot sections
This commit is contained in:
parent
00a048ef5b
commit
eb6cda3025
352
README.org
352
README.org
@ -3824,8 +3824,9 @@ Listing [[lst:configure-writegood-mode]] configures [[https://github.com/bnbeckw
|
|||||||
[[https://github.com/joaotavora/eglot#readme][Emacs polyGLOT (Eglot)]] is an Emacs language-server-protocol client that stays
|
[[https://github.com/joaotavora/eglot#readme][Emacs polyGLOT (Eglot)]] is an Emacs language-server-protocol client that stays
|
||||||
out of the way. The following listings contribute to a programming language
|
out of the way. The following listings contribute to a programming language
|
||||||
mode independent [[https://github.com/joaotavora/eglot][Eglot]] configuration:
|
mode independent [[https://github.com/joaotavora/eglot][Eglot]] configuration:
|
||||||
1. Listing [[lst:ensure-eglot-installation]] ensures installation of [[https://github.com/joaotavora/eglot][Eglot]] with
|
1. Listing [[lst:minimal-eglot-setup][minimal Eglot setup]] ensures installation of [[https://github.com/joaotavora/eglot][Eglot]], shows how to get
|
||||||
minimal configuration.
|
debug information from the [[https://github.com/python-lsp/python-lsp-server][Python LSP server]], and adds key bindings to
|
||||||
|
=eglot-mode-keymap=.
|
||||||
2. Listing [[lst:help-setup-org-src-mode-for-eglot]] and
|
2. Listing [[lst:help-setup-org-src-mode-for-eglot]] and
|
||||||
[[lst:setup-python-org-src-mode-for-eglot]] try to prepare any =org-src-mode=
|
[[lst:setup-python-org-src-mode-for-eglot]] try to prepare any =org-src-mode=
|
||||||
buffers for use with [[https://github.com/joaotavora/eglot][Eglot]]. They are a refactored implementation of the post
|
buffers for use with [[https://github.com/joaotavora/eglot][Eglot]]. They are a refactored implementation of the post
|
||||||
@ -3841,15 +3842,20 @@ mode independent [[https://github.com/joaotavora/eglot][Eglot]] configuration:
|
|||||||
file [[info:emacs#Directory Variables][.dir-locals.el]] in the root directory of any project using proper
|
file [[info:emacs#Directory Variables][.dir-locals.el]] in the root directory of any project using proper
|
||||||
programming modes).
|
programming modes).
|
||||||
|
|
||||||
#+caption[Ensure =eglot= installation]:
|
#+caption[Ensure =eglot= installation with minimal configuration]:
|
||||||
#+caption: Ensure =eglot= installation.
|
#+caption: Ensure =eglot= installation with minimal configuration.
|
||||||
#+name: lst:ensure-eglot-installation
|
#+name: lst:minimal-eglot-setup
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(when (and (version< emacs-version "28.9.9")
|
(with-eval-after-load 'emacs
|
||||||
|
(when (version< emacs-version "28.9.9")
|
||||||
(ensure-package-installation 'eglot))
|
(ensure-package-installation 'eglot))
|
||||||
;; (defvar eglot-server-programs
|
|
||||||
;; `((python-mode . ("pylsp" "-vvv")))
|
;; Replace `nil' with `t' for debugging.
|
||||||
;; "Shadow the definition of `eglot-server-programs' in `eglot'.")
|
(when nil
|
||||||
|
(defvar eglot-server-programs
|
||||||
|
`((python-mode . ("pylsp" "-vvv")))
|
||||||
|
"Shadow the definition of `eglot-server-programs' in `eglot'."))
|
||||||
|
|
||||||
(with-eval-after-load 'eglot
|
(with-eval-after-load 'eglot
|
||||||
(define-key eglot-mode-map (kbd "C-c n") #'flymake-goto-next-error)
|
(define-key eglot-mode-map (kbd "C-c n") #'flymake-goto-next-error)
|
||||||
(define-key eglot-mode-map (kbd "C-c p") #'flymake-goto-prev-error)
|
(define-key eglot-mode-map (kbd "C-c p") #'flymake-goto-prev-error)
|
||||||
@ -4018,6 +4024,7 @@ Listing [[lst:configure-format-all]]:
|
|||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: sec:flymake
|
:CUSTOM_ID: sec:flymake
|
||||||
:END:
|
:END:
|
||||||
|
|
||||||
Flymake is an universal on-the-fly syntax checker for Emacs. It is a requirement
|
Flymake is an universal on-the-fly syntax checker for Emacs. It is a requirement
|
||||||
of [[https://github.com/joaotavora/eglot][eglot]], but you can use it without [[https://github.com/joaotavora/eglot][eglot]] for instance in [[https://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/progmodes/python.el][python-mode]] buffers
|
of [[https://github.com/joaotavora/eglot][eglot]], but you can use it without [[https://github.com/joaotavora/eglot][eglot]] for instance in [[https://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/progmodes/python.el][python-mode]] buffers
|
||||||
that do not visit a file.
|
that do not visit a file.
|
||||||
@ -4031,6 +4038,7 @@ that do not visit a file.
|
|||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: sec:common-lisp-programming
|
:CUSTOM_ID: sec:common-lisp-programming
|
||||||
:END:
|
:END:
|
||||||
|
|
||||||
Listing [[lst:configure-sly]] configures the [[info:sly#Top][Sly (info)]] Common Lisp IDE for Emacs
|
Listing [[lst:configure-sly]] configures the [[info:sly#Top][Sly (info)]] Common Lisp IDE for Emacs
|
||||||
for use with [[http://www.sbcl.org/][Steel Bank Common Lisp (sbcl)]]:
|
for use with [[http://www.sbcl.org/][Steel Bank Common Lisp (sbcl)]]:
|
||||||
1. It configures =sly-default-lisp= and =sly-lisp-implementations= as in the
|
1. It configures =sly-default-lisp= and =sly-lisp-implementations= as in the
|
||||||
@ -4302,45 +4310,62 @@ server, before plunging into the configuration steps:
|
|||||||
:CUSTOM_ID: sec:python-mode
|
:CUSTOM_ID: sec:python-mode
|
||||||
:END:
|
:END:
|
||||||
|
|
||||||
Listing [[lst:configure-python]] configures [[https://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/progmodes/python.el][python-mode]] to use [[https://flake8.pycqa.org/en/latest/][flake8]] as style
|
Listing [[lst:setup-python-mode][setup Python mode]] and [[lst:choose-common-python-interpreter][choose common Python interpreter]] select a common
|
||||||
checker and [[https://ipython.org/][IPython]] as shell interpreter and selects the Python interpreter by
|
Python interpreter in a virtual environment for use in =python-mode= and
|
||||||
means of src_emacs-lisp{(choose-common-python-interpreter)} defined in listing
|
=ob-python= by means of src_emacs-lisp{(choose-common-python-interpreter)}. The
|
||||||
[[lst:choose-common-python-interpreter]]. The [[https://github.com/pythonic-emacs/pythonic#readme][pythonic]] and [[https://github.com/jorgenschaefer/pyvenv#readme][pyvenv]] packages provide support
|
[[https://github.com/pythonic-emacs/pythonic#readme][pythonic]], [[https://github.com/jorgenschaefer/pyvenv#readme][pyvenv]], and [[https://github.com/jorgenschaefer/pyvenv#readme][pyvenv]] packages allow to handle Python virtual
|
||||||
to handle Python virtual environments within Emacs. The [[https://github.com/pyenv/pyenv][pyenv]] package provides
|
environments within Emacs. The [[https://github.com/pyenv/pyenv][pyenv]] package provides support to work with
|
||||||
support to work with [[https://github.com/pyenv/pyenv#readme][pyenv]] (eventually with [[https://github.com/pyenv/pyenv-virtualenv#readme][pyenv-virtualenv]]) to select between
|
[[https://github.com/pyenv/pyenv#readme][pyenv]] (eventually with [[https://github.com/pyenv/pyenv-virtualenv#readme][pyenv-virtualenv]]) to select between different python
|
||||||
different python versions (eventually each with different environments). In the
|
versions (eventually each with different environments). In the end, all those
|
||||||
end, all those packages do is to set =python-shell-virtualenv-root= (in case of
|
packages do is to set =python-shell-virtualenv-root= (in case of [[https://github.com/pyenv/pyenv#readme][pyenv]] and
|
||||||
[[https://github.com/pyenv/pyenv#readme][pyenv]] and [[https://github.com/pythonic-emacs/pythonic#readme][pythonic]]) and tweak the environment variables and restart the relevant
|
[[https://github.com/pythonic-emacs/pythonic#readme][pythonic]]) or tweak the environment variables and restart the relevant Python
|
||||||
Python child processes (in case of [[https://github.com/jorgenschaefer/pyvenv#readme][pyvenv]]). Therefore, this setup replaces
|
child processes (in case of [[https://github.com/jorgenschaefer/pyvenv#readme][pyvenv]]). Therefore, I replace those packages with
|
||||||
those packages with listing [[lst:manage-pyenv]] to manage [[https://github.com/pyenv/pyenv#readme][pyenv]] from within Emacs
|
listing [[lst:access-pyenv][access pyenv]] and [[lst:select-python-virtual-environment][select a Python interpreter in a virtual environment]] to
|
||||||
and listing [[lst:setting-python-shell-virtualenv-root]] to set
|
set =python-shell-virtualenv-root= from within Emacs.
|
||||||
=python-shell-virtualenv-root=.
|
|
||||||
|
|
||||||
#+caption[Configure =python=]:
|
Listing [[lst:setup-python-mode][setup Python mode]] and [[lst:choose-common-python-linter][choose common Python linter]] select a common Python
|
||||||
#+caption: Configure =python=.
|
linter for the =python-check-command= and the =python-flymake-command= by means
|
||||||
#+name: lst:configure-python
|
of src_emacs-lisp{(choose-common-python-linter)} from:
|
||||||
|
1. [[https://github.com/PyCQA/pyflakes][Pyflakes - simple tool which checks Python source files for errors]].
|
||||||
|
2. [[https://flake8.pycqa.org/en/latest/][Flake8 - your tool for style guide enforcement]].
|
||||||
|
3. [[https://github.com/charliermarsh/ruff][Ruff - an extremely fast Python linter written in Rust]].
|
||||||
|
I use [[https://pypi.org/project/ruff/][Ruff]] to replace [[https://pypi.org/project/flake8/][Flake8]] with a variety of its plugins. [[https://notes.crmarsh.com/][Charlie Marsh]]
|
||||||
|
explains why he started [[https://pypi.org/project/ruff/][Ruff]] in the post [[https://notes.crmarsh.com/python-tooling-could-be-much-much-faster][Python tooling could be much faster]].
|
||||||
|
|
||||||
|
Listing [[lst:pyproject-toml-kickoff][kickoff pyproject.toml proposal]] facilitates dropping a [[https://pip.pypa.io/en/stable/reference/build-system/pyproject-toml][pyproject.toml]]
|
||||||
|
file into Python projects which anyhow should switch to using a [[https://pip.pypa.io/en/stable/reference/build-system/pyproject-toml][pyproject.toml]]
|
||||||
|
file as explained in the post [[https://bbc.github.io/cloudfit-public-docs/packaging/this_way_up.html][This Way Up: A Bottom-Up Look At Python Packaging]].
|
||||||
|
|
||||||
|
Listing [[lst:setup-cfg-kickoff][kickoff setup.cfg proposal]] implements the [[https://black.readthedocs.io/en/stable/guides/using_black_with_other_tools.html][using black with other tools]]
|
||||||
|
rules which make [[https://flake8.pycqa.org/en/latest/][flake8]] or [[https://pycodestyle.pycqa.org/en/latest/][pycodestyle]] agree with [[https://black.readthedocs.io/en/stable/index.html][black's uncompromising style]].
|
||||||
|
|
||||||
|
Finally, listing [[lst:flake8-nocolor][flake8-nocolor]] and [[lst:ruff-nocolor][ruff-nocolor]] pipe the =stdout= output of the
|
||||||
|
[[https://pypi.org/project/flake8/][flake8]] and [[https://pypi.org/project/ruff/][ruff]] executables through =cat= to remove escape sequences.
|
||||||
|
|
||||||
|
#+caption[Setup Python mode]:
|
||||||
|
#+caption: Setup Python mode.
|
||||||
|
#+name: lst:setup-python-mode
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(with-eval-after-load 'python
|
(with-eval-after-load 'python
|
||||||
(custom-set-variables
|
(custom-set-variables
|
||||||
`(python-check-command ,(executable-find "flake8"))
|
|
||||||
`(python-flymake-command '(,(executable-find "flake8") "-"))
|
|
||||||
'(python-indent-guess-indent-offset nil)
|
'(python-indent-guess-indent-offset nil)
|
||||||
'(python-shell-completion-native-disabled-interpreters '("ipython3" "pypy")))
|
'(python-shell-completion-native-disabled-interpreters '("ipython3" "pypy")))
|
||||||
(choose-common-python-interpreter 'python))
|
(choose-common-python-interpreter 'python)
|
||||||
|
(choose-common-python-linter 'ruff-nocolor))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+caption[Choose common =python= interpreter for =ob-python= and =python-mode=]:
|
#+caption[Choose a common Python interpreter]:
|
||||||
#+caption: Choose =python= interpreter for =ob-python= and =python-mode=.
|
#+caption: Choose a common Python interpreter for =ob-python= and =python-mode=.
|
||||||
#+name: lst:choose-common-python-interpreter
|
#+name: lst:choose-common-python-interpreter
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(defun choose-common-python-interpreter (&optional program)
|
(defun choose-common-python-interpreter (&optional interpreter)
|
||||||
"Choose Python interpreter PROGRAM for `ob-python' and `python-mode'."
|
"Let `ob-python' and `python-mode' use the same Python INTERPRETER."
|
||||||
(interactive)
|
(interactive)
|
||||||
(let* ((prompt (format "Choose Python (%s): "
|
(let* ((prompt (format "Choose Python (%s): "
|
||||||
(bound-and-true-p python-shell-interpreter)))
|
(bound-and-true-p python-shell-interpreter)))
|
||||||
(choices '(ipython python))
|
(choices '(ipython python))
|
||||||
(choice (if (member program choices)
|
(choice (if (member interpreter choices)
|
||||||
(symbol-name program)
|
(symbol-name interpreter)
|
||||||
(completing-read prompt choices nil t))))
|
(completing-read prompt choices nil t))))
|
||||||
(when (boundp 'org-babel-python-command)
|
(when (boundp 'org-babel-python-command)
|
||||||
(pcase choice
|
(pcase choice
|
||||||
@ -4375,9 +4400,44 @@ and listing [[lst:setting-python-shell-virtualenv-root]] to set
|
|||||||
python-shell-interpreter))))
|
python-shell-interpreter))))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+caption[Manage =pyenv=]:
|
#+caption[Choose a common Python linter]:
|
||||||
#+caption: Manage =pyenv=.
|
#+caption: Choose a common Python linter for =python-check-command= and
|
||||||
#+name: lst:manage-pyenv
|
#+caption: =python-flymake-command=.
|
||||||
|
#+name: lst:choose-common-python-linter
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(defun choose-common-python-linter (&optional linter)
|
||||||
|
"Let `python-check-command' and `python-flymake-command' use the same LINTER."
|
||||||
|
(interactive)
|
||||||
|
(let* ((prompt (format "Choose Python checker (%s): "
|
||||||
|
(bound-and-true-p python-check-command)))
|
||||||
|
(choices '(flake8-nocolor pyflakes ruff-nocolor))
|
||||||
|
(choice (if (member linter choices)
|
||||||
|
(symbol-name linter)
|
||||||
|
(completing-read prompt choices nil t))))
|
||||||
|
(when (and (boundp 'python-check-command) (boundp 'python-flymake-command))
|
||||||
|
(pcase choice
|
||||||
|
("flake8-nocolor"
|
||||||
|
(custom-set-variables
|
||||||
|
`(python-check-command ,(executable-find choice))
|
||||||
|
`(python-flymake-command (list ,(executable-find choice) "-"))))
|
||||||
|
("pyflakes"
|
||||||
|
(custom-set-variables
|
||||||
|
`(python-check-command ,(executable-find choice))
|
||||||
|
`(python-flymake-command `(,(executable-find choice)))))
|
||||||
|
("ruff-nocolor"
|
||||||
|
(custom-set-variables
|
||||||
|
`(python-check-command ,(executable-find choice))
|
||||||
|
`(python-flymake-command
|
||||||
|
(list ,(executable-find choice) "--stdin-filename" "stdin" "-")))))
|
||||||
|
(when (bound-and-true-p python-check-custom-command)
|
||||||
|
(setq python-check-custom-command nil))
|
||||||
|
(message "Python checker commands are %S and %S"
|
||||||
|
python-check-command python-flymake-command))))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+caption[Access =pyenv=]:
|
||||||
|
#+caption: Access =pyenv=.
|
||||||
|
#+name: lst:access-pyenv
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(when (executable-find "pyenv")
|
(when (executable-find "pyenv")
|
||||||
(defun pyenv-full-path (version)
|
(defun pyenv-full-path (version)
|
||||||
@ -4421,9 +4481,9 @@ Complete the result with \"system\"."
|
|||||||
(error "%s" (string-trim output))))))
|
(error "%s" (string-trim output))))))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+caption[Setting =python-shell-virtualenv-root=]:
|
#+caption[Select the Python virtual environment]:
|
||||||
#+caption: Setting =python-shell-virtualenv-root=.
|
#+caption: Select the Python virtual environment.
|
||||||
#+name: lst:setting-python-shell-virtualenv-root
|
#+name: lst:select-python-virtual-environment
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(with-eval-after-load 'python
|
(with-eval-after-load 'python
|
||||||
(when (cl-every #'fboundp '(pyenv-full-path
|
(when (cl-every #'fboundp '(pyenv-full-path
|
||||||
@ -4464,65 +4524,174 @@ Complete the result with \"system\"."
|
|||||||
python-shell-virtualenv-root)))))
|
python-shell-virtualenv-root)))))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
#+caption[Kickoff =pyproject.toml= proposal]:
|
||||||
|
#+caption: Kickoff =pyproject.toml= proposal.
|
||||||
|
#+name: lst:pyproject-toml-kickoff
|
||||||
|
#+begin_src toml :tangle pyproject.toml
|
||||||
|
# [project]
|
||||||
|
# name = "fancy-name"
|
||||||
|
|
||||||
|
# [build-system]
|
||||||
|
# requires = ["setuptools", "wheel"]
|
||||||
|
# build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[tool.black]
|
||||||
|
line-length = 88
|
||||||
|
|
||||||
|
[tool.ruff]
|
||||||
|
line-length = 88
|
||||||
|
select = [
|
||||||
|
"ARG", # flake8-unused-arguments
|
||||||
|
"B", # flake8-bugbear
|
||||||
|
"C", # mccabe
|
||||||
|
"E", # pycodestyle
|
||||||
|
"D", # pydocstyle
|
||||||
|
"F", # pyflakes
|
||||||
|
# "W", # ruff emits no pycodestyle warnings yet
|
||||||
|
]
|
||||||
|
|
||||||
|
ignore = [
|
||||||
|
# https://www.pydocstyle.org/en/stable/error_codes.html#default-conventions
|
||||||
|
# pydocstyle numpy convention:
|
||||||
|
"D107", # ignore: missing docstring in __init__
|
||||||
|
"D203", # ignore: single blank line required before class docstring
|
||||||
|
"D212", # ignore: multi-line docstring summary should start at the first line
|
||||||
|
"D213", # ignore: multi-line docstring summary should start at the second line
|
||||||
|
"D402", # ignore: first line should not be the function signature
|
||||||
|
"D413", # ignore: missing blank line after last section
|
||||||
|
"D415", # ignore: 1st line should end with a ".", "?", or "?"
|
||||||
|
"D416", # ignore: section name should end with a ":"
|
||||||
|
"D417", # ignore: missing argument descriptions in the docstring
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.ruff.mccabe]
|
||||||
|
max-complexity = 15
|
||||||
|
|
||||||
|
# Local Variables:
|
||||||
|
# mode: conf-toml
|
||||||
|
# End:
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+caption[Kickoff =setup.cfg= proposal]:
|
||||||
|
#+caption: Kickoff =setup.cfg= proposal.
|
||||||
|
#+name: lst:setup-cfg-kickoff
|
||||||
|
#+begin_src toml :tangle setup.cfg
|
||||||
|
[flake8]
|
||||||
|
docstring-convention = numpy
|
||||||
|
extend-select = B,F,W
|
||||||
|
extend-ignore = W503
|
||||||
|
max-complexity = 15
|
||||||
|
max-line-length = 88
|
||||||
|
|
||||||
|
[pycodestyle]
|
||||||
|
ignore = W503
|
||||||
|
max-line-length = 88
|
||||||
|
|
||||||
|
# Local Variables:
|
||||||
|
# mode: conf-toml
|
||||||
|
# End:
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+caption[Wrap =flake8= to remove color from text output]:
|
||||||
|
#+caption: Wrap =flake8= to remove color from text output.
|
||||||
|
#+header: :tangle-mode (identity #o755)
|
||||||
|
#+name: lst:flake8-nocolor
|
||||||
|
#+begin_src shell :noeval :tangle ~/bin/flake8-nocolor
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
flake8 "$@" | cat
|
||||||
|
|
||||||
|
# Local Variables:
|
||||||
|
# mode: shell-script
|
||||||
|
# sh-indentation: 2
|
||||||
|
# sh-basic-offset: 2
|
||||||
|
# End:
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+caption[Wrap =ruff= to remove color from text output]:
|
||||||
|
#+caption: Wrap =ruff= to remove color from text output.
|
||||||
|
#+header: :tangle-mode (identity #o755)
|
||||||
|
#+name: lst:ruff-nocolor
|
||||||
|
#+begin_src shell :noeval :tangle ~/bin/ruff-nocolor
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
ruff "$@" | cat
|
||||||
|
|
||||||
|
# Local Variables:
|
||||||
|
# mode: shell-script
|
||||||
|
# sh-indentation: 2
|
||||||
|
# sh-basic-offset: 2
|
||||||
|
# End:
|
||||||
|
#+end_src
|
||||||
|
|
||||||
*** [[https://github.com/joaotavora/eglot][Eglot]] for [[https://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/progmodes/python.el][python-mode]]
|
*** [[https://github.com/joaotavora/eglot][Eglot]] for [[https://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/progmodes/python.el][python-mode]]
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: sec:eglot-python
|
:CUSTOM_ID: sec:eglot-python
|
||||||
:END:
|
:END:
|
||||||
|
|
||||||
Listing [[lst:configure-eglot+pylsp-with-pyls-flake8]] configures [[https://github.com/joaotavora/eglot][eglot]] for [[https://www.python.org][Python]]
|
Listing [[lst:configure-eglot+pylsp-ruff]] configures [[https://github.com/joaotavora/eglot][eglot]] for [[https://www.python.org][Python]] using the
|
||||||
using the [[https://github.com/python-lsp/python-lsp-server][python-lsp-server]] with the [[https://github.com/emanspeaks/pyls-flake8#readme][pyls-flake8]] plugin for the easiest way to
|
[[https://github.com/python-lsp/python-lsp-server][python-lsp-server]] with the [[https://github.com/python-lsp/python-lsp-ruff#readme][pylsp-ruff]] plugin for the easiest way to let
|
||||||
let [[https://github.com/python-lsp/python-lsp-server][python-lsp-server]] use [[https://github.com/PyCQA/flake8][flake8]]. In order to enable all builtin
|
[[https://github.com/python-lsp/python-lsp-server][python-lsp-server]] use [[https://pypi.org/project/ruff/][Ruff]]. The latest [[https://github.com/python-lsp/python-lsp-server#readme][python-lsp-server]] documentation tells to
|
||||||
[[https://github.com/python-lsp/python-lsp-server][python-lsp-server]] capabilities, ensure installation of the Python packages
|
configure it for [[https://github.com/PyCQA/flake8][flake8]] as in listing [[lst:configure-eglot+pylsp+flake8]]. In order
|
||||||
[[https://github.com/hhatto/autopep8#readme][autopep8]], [[https://github.com/PyCQA/flake8][flake8]], [[https://github.com/PyCQA/pydocstyle#readme][pydocstyle]], [[https://github.com/PyCQA/pylint#readme][pylint]], [[https://github.com/python-lsp/python-lsp-server][python-lsp-server]], [[https://github.com/python-rope/rope#readme][rope]], and [[https://github.com/google/yapf#readme][yapf]]. The
|
to enable all builtin [[https://github.com/python-lsp/python-lsp-server][python-lsp-server]] capabilities, ensure installation of the
|
||||||
latest [[https://github.com/python-lsp/python-lsp-server#readme][python-lsp-server]] documentation tells to configure it for [[https://github.com/PyCQA/flake8][flake8]] as in
|
Python packages [[https://github.com/hhatto/autopep8#readme][autopep8]], [[https://github.com/PyCQA/flake8][flake8]], [[https://github.com/PyCQA/pydocstyle#readme][pydocstyle]], [[https://github.com/PyCQA/pylint#readme][pylint]], [[https://github.com/python-lsp/python-lsp-server][python-lsp-server]], [[https://github.com/python-rope/rope#readme][rope]],
|
||||||
listing [[lst:configure-eglot+pylsp-sans-pyls-flake8]]. This method is under
|
and [[https://github.com/google/yapf#readme][yapf]]. This method is under investigation (it feels flaky since it shows
|
||||||
investigation (it feels flaky since it shows some error messages twice).
|
some error messages twice).
|
||||||
|
|
||||||
Listing [[lst:eglot-directory-variables-for-python]] shows a proper [[info:emacs#Directory Variables][.dir-locals.el]]
|
Listing [[lst:eglot-directory-variables-for-python]] shows a proper [[info:emacs#Directory Variables][.dir-locals.el]]
|
||||||
file in the root directory of any [[https://www.python.org][Python]] project to start [[https://github.com/joaotavora/eglot][eglot]] automatically
|
file in the root directory of any [[https://www.python.org][Python]] project to start [[https://github.com/joaotavora/eglot][eglot]] automatically
|
||||||
according to the configuration in listing [[lst:eglot-maybe-ensure]]. Type
|
according to the configuration in listing [[lst:eglot-maybe-ensure]]. Type
|
||||||
{{{kbd(M-x eglot-show-workspace-configuration)}}} to dump a =JSON=
|
{{{kbd(M-x eglot-show-workspace-configuration)}}} to dump a =JSON=
|
||||||
representation of src_emacs-lisp{eglot-workspace-configuration} for debugging.
|
representation of src_emacs-lisp{eglot-workspace-configuration} for debugging.
|
||||||
The comment in listing [[lst:ensure-eglot-installation]] also shows how to increase
|
The comment in listing [[lst:minimal-eglot-setup][minimal Eglot setup]] also shows how to decrease
|
||||||
the the verbosity of [[https://github.com/python-lsp/python-lsp-server][python-lsp-server]] log output for debugging.
|
or to increase the verbosity of [[https://github.com/python-lsp/python-lsp-server][Python LSP server]] log output for debugging.
|
||||||
|
|
||||||
#+caption[Configure =eglot= with =python-lsp-server= with =pyls_flake8=]:
|
#+caption[Configure =eglot= with =python-lsp-ruff=]:
|
||||||
#+caption: Configure =eglot= with =python-lsp-server= with =pyls_flake8=.
|
#+caption: Configure =eglot= with =python-lsp-ruff=.
|
||||||
#+name: lst:configure-eglot+pylsp-with-pyls-flake8
|
#+name: lst:configure-eglot+pylsp-ruff
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(with-eval-after-load 'eglot
|
(with-eval-after-load 'eglot
|
||||||
(setq-default
|
(setq-default
|
||||||
eglot-workspace-configuration
|
eglot-workspace-configuration
|
||||||
;; Disable the `:pyls_flake8' plugin to fall back to pycodestyle.
|
;; Enable the `:pyls_ruff' plugin and ensure to disable the
|
||||||
|
;; `:flake8', `:mccabe', and `:pycodestye' plugins.
|
||||||
'(:pylsp (:plugins
|
'(:pylsp (:plugins
|
||||||
(:pyls_flake8
|
(:pylsp_ruff
|
||||||
(:enabled t)
|
(:enabled t)
|
||||||
|
:flake8
|
||||||
|
(:enabled :json-false)
|
||||||
|
:mccabe
|
||||||
|
(:enabled :json-false)
|
||||||
|
:pycodestyle
|
||||||
|
(:enabled :json-false)
|
||||||
:jedi
|
:jedi
|
||||||
(:auto_import_modules ["numpy"])
|
(:auto_import_modules ["numpy"])
|
||||||
:jedi_completion
|
:jedi_completion
|
||||||
(:cache_for ["astropy"]))))))
|
(:cache_for ["astropy"]))))))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+caption[Configure =eglot= with =python-lsp-server= sans =pyls_flake8=]:
|
#+caption[Configure =eglot= with =python-lsp-server= and the =flake8= plugin]:
|
||||||
#+caption: Configure =eglot= with =python-lsp-server= sans =pyls_flake8=.
|
#+caption: Configure =eglot= with =python-lsp-server= and the =flake8= plugin.
|
||||||
#+name: lst:configure-eglot+pylsp-sans-pyls-flake8
|
#+name: lst:configure-eglot+pylsp+flake8
|
||||||
#+begin_src emacs-lisp :tangle no
|
#+begin_src emacs-lisp :tangle no
|
||||||
(with-eval-after-load 'eglot
|
(with-eval-after-load 'eglot
|
||||||
(setq-default
|
(setq-default
|
||||||
eglot-workspace-configuration
|
eglot-workspace-configuration
|
||||||
;; How to use flake8 instead of pycodestyle officially, see:
|
;; How to use flake8 instead of pycodestyle or ruff, see:
|
||||||
;; https://github.com/python-lsp/python-lsp-server#configuration
|
;; https://github.com/python-lsp/python-lsp-server#configuration
|
||||||
'(:pylsp (:configurationSources
|
'(:pylsp (:configurationSources
|
||||||
["flake8"]
|
["flake8"]
|
||||||
:plugins
|
:plugins
|
||||||
(:pycodestyle
|
(:flake8
|
||||||
(:enabled :json-false)
|
(:enabled t)
|
||||||
:mccabe
|
:mccabe
|
||||||
(:enabled :json-false)
|
(:enabled :json-false)
|
||||||
|
:pycodestyle
|
||||||
|
(:enabled :json-false)
|
||||||
:pyflakes
|
:pyflakes
|
||||||
(:enabled
|
(:enabled :json-false)
|
||||||
:json-false)
|
:pylsp-ruff
|
||||||
:flake8
|
(:enabled :json-false)
|
||||||
(:enabled t)
|
|
||||||
:jedi
|
:jedi
|
||||||
(:auto_import_modules ["numpy"])
|
(:auto_import_modules ["numpy"])
|
||||||
:jedi_completion
|
:jedi_completion
|
||||||
@ -4530,9 +4699,8 @@ the the verbosity of [[https://github.com/python-lsp/python-lsp-server][python-l
|
|||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+caption[A =.dir-locals.el= proposal to launch =eglot= automatically]:
|
#+caption[A =.dir-locals.el= proposal to launch =eglot= automatically]:
|
||||||
#+caption: A =.dir-locals.el= proposal for any Python project
|
#+caption: A =.dir-locals.el= file proposal for Python projects or Org-mode
|
||||||
#+caption: or any Org-mode project tangling Python files
|
#+caption: projects tangling Python files to launch =eglot= automatically.
|
||||||
#+caption: to launch =eglot= automatically.
|
|
||||||
#+name: lst:eglot-directory-variables-for-python
|
#+name: lst:eglot-directory-variables-for-python
|
||||||
#+begin_src emacs-lisp :tangle dir-locals.el
|
#+begin_src emacs-lisp :tangle dir-locals.el
|
||||||
;; A .dir-locals.el file proposal in the root of any
|
;; A .dir-locals.el file proposal in the root of any
|
||||||
@ -4540,10 +4708,17 @@ the the verbosity of [[https://github.com/python-lsp/python-lsp-server][python-l
|
|||||||
;; to launch eglot automatically.
|
;; to launch eglot automatically.
|
||||||
((nil ;; nil, since Emacs-29.1 filters out irrelevant variable names.
|
((nil ;; nil, since Emacs-29.1 filters out irrelevant variable names.
|
||||||
. ((eglot-workspace-configuration
|
. ((eglot-workspace-configuration
|
||||||
;; Disable the `:pyls_flake8' plugin to fall back to pycodestyle.
|
;; Enable the `:pyls_ruff' plugin and ensure to disable the
|
||||||
|
;; `:flake8', `:mccabe', and `:pycodestye' plugins.
|
||||||
. (:pylsp (:plugins
|
. (:pylsp (:plugins
|
||||||
(:pyls_flake8
|
(:pylsp_ruff
|
||||||
(:enabled t)
|
(:enabled t)
|
||||||
|
:flake8
|
||||||
|
(:enabled :json-false)
|
||||||
|
:mccabe
|
||||||
|
(:enabled :json-false)
|
||||||
|
:pycodestyle
|
||||||
|
(:enabled :json-false)
|
||||||
:jedi
|
:jedi
|
||||||
(:auto_import_modules ["numpy"])
|
(:auto_import_modules ["numpy"])
|
||||||
:jedi_completion
|
:jedi_completion
|
||||||
@ -4565,43 +4740,6 @@ the the verbosity of [[https://github.com/python-lsp/python-lsp-server][python-l
|
|||||||
| eldoc-doc-buffer | eglot-mode-map | {{{kbd(C-h .)}}} |
|
| eldoc-doc-buffer | eglot-mode-map | {{{kbd(C-h .)}}} |
|
||||||
|-------------------------+----------------+------------------|
|
|-------------------------+----------------+------------------|
|
||||||
|
|
||||||
Listing [[lst:pyproject-toml-kick-off]] and [[lst:setup-cfg-kick-off]] implement the
|
|
||||||
rules in [[https://black.readthedocs.io/en/stable/guides/using_black_with_other_tools.html][using black with other tools]] in order to make [[https://flake8.pycqa.org/en/latest/][flake8]] or [[https://pycodestyle.pycqa.org/en/latest/][pycodestyle]]
|
|
||||||
agree with [[https://black.readthedocs.io/en/stable/index.html][black's uncompromising style]].
|
|
||||||
|
|
||||||
#+caption[Kick starting a =pyproject.toml= file]:
|
|
||||||
#+caption: Kick starting a =pyproject.toml= file.
|
|
||||||
#+name: lst:pyproject-toml-kick-off
|
|
||||||
#+begin_src toml :tangle pyproject.toml
|
|
||||||
[build-system]
|
|
||||||
requires = ["setuptools", "wheel"]
|
|
||||||
build-backend = "setuptools.build_meta"
|
|
||||||
|
|
||||||
[tool.black]
|
|
||||||
line-length = 88
|
|
||||||
|
|
||||||
# Local Variables:
|
|
||||||
# mode: conf-toml
|
|
||||||
# End:
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+caption[Kick starting a =setup.cfg= file]:
|
|
||||||
#+caption: Kick starting a =setup.cfg= file.
|
|
||||||
#+name: lst:setup-cfg-kick-off
|
|
||||||
#+begin_src toml :tangle setup.cfg
|
|
||||||
[flake8]
|
|
||||||
max-line-length = 88
|
|
||||||
extend-ignore = E203
|
|
||||||
|
|
||||||
[pycodestyle]
|
|
||||||
ignore = E203
|
|
||||||
max-line-length = 88
|
|
||||||
|
|
||||||
# Local Variables:
|
|
||||||
# mode: conf-toml
|
|
||||||
# End:
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
Listing [[lst:make-pylsp-server-patch]] is useful to propagate eventual patches of
|
Listing [[lst:make-pylsp-server-patch]] is useful to propagate eventual patches of
|
||||||
a local fork of [[https://github.com/python-lsp/python-lsp-server][python-lsp-server]].
|
a local fork of [[https://github.com/python-lsp/python-lsp-server][python-lsp-server]].
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user