Make a programming tools section and a programming modes section
This commit is contained in:
parent
1069693680
commit
ea4d1f6521
135
README.org
135
README.org
@ -2899,11 +2899,55 @@ Listing [[lst:configure-writegood-mode]] configures [[https://github.com/bnbeckw
|
||||
(global-set-key (kbd "C-c g") #'writegood-mode))
|
||||
#+end_src
|
||||
|
||||
* Programming
|
||||
* Programming Tools
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: sec:programming
|
||||
:CUSTOM_ID: sec:programming-tools
|
||||
:END:
|
||||
|
||||
*** [[https://github.com/joaotavora/eglot][Eglot]]
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: sec:eglot
|
||||
:END:
|
||||
|
||||
[[https://github.com/joaotavora/eglot#readme][Emacs polyGLOT (eglot)]] is an Emacs language-server-protocol client that stays
|
||||
out of the way. Listing [[lst:ensure-eglot-installation]] ensures installation of
|
||||
[[https://github.com/joaotavora/eglot][eglot]] with minimal configuration and listing [[lst:eglot-maybe-ensure]] starts [[https://github.com/joaotavora/eglot][eglot]]
|
||||
in case of proper programming modes and proper directory local variables
|
||||
(meaning in presence of a proper [[info:emacs#Directory Variables][.dir-locals.el]] file in the root directory of
|
||||
any project using proper programming modes).
|
||||
|
||||
#+caption[Ensure =eglot= installation]:
|
||||
#+caption: Ensure =eglot= installation.
|
||||
#+name: lst:ensure-eglot-installation
|
||||
#+begin_src emacs-lisp
|
||||
(when (ensure-package-installation 'eglot)
|
||||
;; (defvar eglot-server-programs
|
||||
;; `((python-mode . ("pylsp" "-vvv")))
|
||||
;; "Shadow the definition of `eglot-server-programs' in `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 p") #'flymake-goto-prev-error)
|
||||
(define-key eglot-mode-map (kbd "C-c r") 'eglot-rename)))
|
||||
#+end_src
|
||||
|
||||
#+caption[Start =eglot= in case of a proper =dir-local-variables-alist=]:
|
||||
#+caption: Start =eglot= in case of a proper =dir-local-variables-alist=.
|
||||
#+name: lst:eglot-maybe-ensure
|
||||
#+begin_src emacs-lisp
|
||||
(when (fboundp 'eglot-ensure)
|
||||
(defcustom eglot-maybe-derived-modes '(python-mode)
|
||||
"Modes to call `eglot-ensure' in case of proper directory local variables.")
|
||||
;; The two hooks `after-change-major-mode-hook' and
|
||||
;; `hack-local-variables-hook' are OK, but language mode hooks like
|
||||
;; `python-mode-hook' are not.
|
||||
(add-hook 'after-change-major-mode-hook
|
||||
(defun eglot-maybe-ensure ()
|
||||
(when (and (apply #'derived-mode-p eglot-maybe-derived-modes)
|
||||
(assoc 'eglot-workspace-configuration
|
||||
dir-local-variables-alist))
|
||||
(eglot-ensure)))))
|
||||
#+end_src
|
||||
|
||||
** [[https://github.com/lassik/emacs-format-all-the-code#readme][Format-all]]
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: sec:format-all
|
||||
@ -2937,6 +2981,19 @@ Listing [[lst:configure-format-all]]:
|
||||
(message "Saved reformatted tangled buffer `%s'" (buffer-file-name)))))))
|
||||
#+end_src
|
||||
|
||||
** [[info:flymake#Top][Flymake (info)]]
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: sec:flymake
|
||||
:END:
|
||||
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
|
||||
that do not visit a file.
|
||||
|
||||
* Programming Modes
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: sec:programming-languages
|
||||
:END:
|
||||
|
||||
** [[https://dept-info.labri.fr/~strandh/Teaching/PFS/Common/Strandh-Tutorial/Dir-symbolic.html][Common Lisp programming]]
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: sec:common-lisp-programming
|
||||
@ -3145,8 +3202,8 @@ server, before plunging into the configuring steps:
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: sec:python-mode
|
||||
:END:
|
||||
Listing [[lst:configure-python]] tells the Python shell to disregard its environment
|
||||
variables (in particular =PYTHONSTARTUPFILE=). The [[https://github.com/pythonic-emacs/pythonic#readme][pythonic]] and [[https://github.com/jorgenschaefer/pyvenv#readme][pyvenv]] packages
|
||||
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
|
||||
checker and [[https://ipython.org/][IPython]] as shell interpreter. The [[https://github.com/pythonic-emacs/pythonic#readme][pythonic]] and [[https://github.com/jorgenschaefer/pyvenv#readme][pyvenv]] packages
|
||||
provide support to handle Python virtual environments within Emacs. The [[https://github.com/pyenv/pyenv][pyenv]]
|
||||
package provides 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 different python versions (eventually each with different
|
||||
@ -3155,8 +3212,7 @@ environments). In the end, all those packages do is to set
|
||||
environment variables and restart the relevant Python child processes (in case
|
||||
of [[https://github.com/jorgenschaefer/pyvenv#readme][pyvenv]]). Therefore, this setup replaces those packages with listing
|
||||
[[lst:manage-pyenv]] to manage [[https://github.com/pyenv/pyenv#readme][pyenv]] from within Emacs and listing
|
||||
[[lst:setting-python-shell-virtualenv-root]] to set
|
||||
=python-shell-virtualenv-root=.
|
||||
[[lst:setting-python-shell-virtualenv-root]] to set =python-shell-virtualenv-root=.
|
||||
|
||||
#+caption[Configure =python=]:
|
||||
#+caption: Configure =python=.
|
||||
@ -3165,6 +3221,7 @@ of [[https://github.com/jorgenschaefer/pyvenv#readme][pyvenv]]). Therefore, thi
|
||||
(with-eval-after-load 'python
|
||||
(custom-set-variables
|
||||
`(python-check-command ,(executable-find "flake8"))
|
||||
`(python-flymake-command '(,(executable-find "flake8") "-"))
|
||||
'(python-indent-guess-indent-offset nil)
|
||||
'(python-shell-completion-native-disabled-interpreters '("ipython3" "pypy"))
|
||||
'(python-shell-interpreter "ipython3")
|
||||
@ -3257,53 +3314,39 @@ of [[https://github.com/jorgenschaefer/pyvenv#readme][pyvenv]]). Therefore, thi
|
||||
python-shell-virtualenv-root)))))
|
||||
#+end_src
|
||||
|
||||
*** [[https://github.com/joaotavora/eglot][Eglot]]
|
||||
*** [[https://github.com/joaotavora/eglot][Eglot]] for [[https://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/progmodes/python.el][python-mode]]
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: sec:eglot
|
||||
:CUSTOM_ID: sec:eglot-python
|
||||
:END:
|
||||
Listing [[lst:configure-eglot+python-lsp-server-for-python]] tangles to
|
||||
=user-init-file= and configures [[https://github.com/joaotavora/eglot][eglot]] for [[https://www.python.org][Python]] using the [[https://github.com/python-lsp/python-lsp-server][python-lsp-server]].
|
||||
In order to enable all builtin [[https://github.com/python-lsp/python-lsp-server][python-lsp-server]] capabilities, ensure
|
||||
installation of the 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-rope/rope#readme][rope]],
|
||||
and [[https://github.com/google/yapf#readme][yapf]]. In addition, install the [[https://github.com/emanspeaks/pyls-flake8#readme][pyls-flake8]] plugin to let [[https://github.com/python-lsp/python-lsp-server][python-lsp-server]]
|
||||
use [[https://github.com/PyCQA/flake8][flake8]]. The latest [[https://github.com/python-lsp/python-lsp-server#readme][python-lsp-server]] documentation tells to let it use
|
||||
[[https://github.com/PyCQA/flake8][flake8]] as in [[lst:broken-configure-eglot+python-lsp-server-for-python]], but it
|
||||
does not work.
|
||||
Listing [[lst:configure-eglot+python-lsp-server-for-python]] configures [[https://github.com/joaotavora/eglot][eglot]] for
|
||||
[[https://www.python.org][Python]] using the [[https://github.com/python-lsp/python-lsp-server][python-lsp-server]]. In order to enable all builtin
|
||||
[[https://github.com/python-lsp/python-lsp-server][python-lsp-server]] capabilities, ensure installation of the 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]], and [[https://github.com/google/yapf#readme][yapf]]. In
|
||||
addition, install the [[https://github.com/emanspeaks/pyls-flake8#readme][pyls-flake8]] plugin to let [[https://github.com/python-lsp/python-lsp-server][python-lsp-server]] use [[https://github.com/PyCQA/flake8][flake8]].
|
||||
The latest [[https://github.com/python-lsp/python-lsp-server#readme][python-lsp-server]] documentation tells to let it use [[https://github.com/PyCQA/flake8][flake8]] as in
|
||||
[[lst:broken-configure-eglot+python-lsp-server-for-python]], but it does not work.
|
||||
|
||||
Listing [[lst:on-hack-local-variables-hook-eglot-maybe]] defines a hook function to
|
||||
launch [[https://github.com/joaotavora/eglot][eglot]] in presence of a proper [[info:emacs#Directory Variables][.dir-locals.el]] file in the root directory
|
||||
of any [[https://www.python.org][Python]] project. Listing [[lst:eglot-directory-variables-for-python]] shows
|
||||
such a proper [[info:emacs#Directory Variables][.dir-locals.el]] file.
|
||||
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
|
||||
according to the configuration in listing [[lst:eglot-maybe-ensure]].
|
||||
|
||||
#+caption[Configure =eglot= with =python-lsp-server= for Python]:
|
||||
#+caption: Configure =eglot= with =python-lsp-server= for Python.
|
||||
#+name: lst:configure-eglot+python-lsp-server-for-python
|
||||
#+begin_src emacs-lisp
|
||||
(when (ensure-package-installation 'eglot)
|
||||
(defvar eglot-server-programs
|
||||
`((python-mode . ("pylsp")))
|
||||
"Shadow the definition of `eglot-server-programs' in `eglot'.")
|
||||
(with-eval-after-load 'eglot
|
||||
(setq-default
|
||||
eglot-workspace-configuration
|
||||
'(;; Disable the `:pyls_flake8' plugin to fall back to pycodestyle.
|
||||
(:pylsp . (:plugins (:pyls_flake8 (:enabled t))))
|
||||
(:pylsp . (:plugins (:jedi (:auto_import_modules ["numpy"]))))
|
||||
(:pylsp . (:plugins (:jedi_completion (:cache_for ["astropy"]))))))
|
||||
|
||||
(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 r") 'eglot-rename)))
|
||||
(:pylsp . (:plugins (:jedi_completion (:cache_for ["astropy"])))))))
|
||||
#+end_src
|
||||
|
||||
#+caption[Broken configure =eglot= with =python-lsp-server= for Python]:
|
||||
#+caption: Broken configure =eglot= with =python-lsp-server= for Python.
|
||||
#+name: lst:broken-configure-eglot+python-lsp-server-for-python
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(when (ensure-package-installation 'eglot)
|
||||
(defvar eglot-server-programs
|
||||
`((python-mode . ("pylsp" "-vvv")))
|
||||
"Shadow the definition of `eglot-server-programs' in `eglot'.")
|
||||
(with-eval-after-load 'eglot
|
||||
(setq-default
|
||||
eglot-workspace-configuration
|
||||
@ -3315,27 +3358,7 @@ such a proper [[info:emacs#Directory Variables][.dir-locals.el]] file.
|
||||
(:pylsp . (:plugins (:pyflakes (:enabled :json-false))))
|
||||
(:pylsp . (:plugins (:flake8 (:enabled t))))
|
||||
(:pylsp . (:plugins (:jedi (:auto_import_modules ["numpy"]))))
|
||||
(:pylsp . (:plugins (:jedi_completion (:cache_for ["astropy"]))))))
|
||||
|
||||
(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 r") 'eglot-rename)))
|
||||
#+end_src
|
||||
|
||||
#+caption[Start =eglot= in case of a proper =dir-local-variables-alist=]:
|
||||
#+caption: Start =eglot= in case of a proper =dir-local-variables-alist=.
|
||||
#+name: lst:on-hack-local-variables-hook-eglot-maybe
|
||||
#+begin_src emacs-lisp
|
||||
(when (fboundp 'eglot-ensure)
|
||||
;; The two hooks `after-change-major-mode-hook' and
|
||||
;; `hack-local-variables-hook' are OK, but language mode hooks like
|
||||
;; `python-mode-hook' are not.
|
||||
(add-hook 'hack-local-variables-hook
|
||||
(defun on-hack-local-variables-hook-eglot-maybe ()
|
||||
(when (and (derived-mode-p 'python-mode)
|
||||
(assoc 'eglot-workspace-configuration
|
||||
dir-local-variables-alist))
|
||||
(eglot-ensure)))))
|
||||
(:pylsp . (:plugins (:jedi_completion (:cache_for ["astropy"])))))))
|
||||
#+end_src
|
||||
|
||||
#+caption[Propose =directory-variables= to launch =eglot=]:
|
||||
@ -3397,9 +3420,9 @@ agree with [[https://black.readthedocs.io/en/stable/index.html][black's uncompro
|
||||
#+end_src
|
||||
|
||||
[[https://jedi.readthedocs.io/en/latest/][Jedi]] provides grammar checking and completion candidates to [[https://github.com/python-lsp/python-lsp-server][python-lsp-server]].
|
||||
Only [[https://jedi.readthedocs.io/en/latest/docs/changelog.html][jedi-0.18.1]] works with for instance [[https://numpy.org/][numpy-1.22.0]] in the sense that it does
|
||||
Only [[https://jedi.readthedocs.io/en/latest/docs/changelog.html][jedi-0.18.1]] works with for instance [[https://numpy.org/][numpy-1.23.0]] in the sense that it does
|
||||
not choke on universal functions provided that [[https://jedi.readthedocs.io/en/latest/][jedi]] does not parse but imports
|
||||
[[https://numpy.org/][numpy-1.22.0]] (see [[https://github.com/davidhalter/jedi/issues/1744][jedi issue #1744]], [[https://github.com/davidhalter/jedi/issues/1745][#1745]], and [[https://github.com/davidhalter/jedi/issues/1746][#1746]]). Since the universal
|
||||
[[https://numpy.org/][numpy-1.23.1]] (see [[https://github.com/davidhalter/jedi/issues/1744][jedi issue #1744]], [[https://github.com/davidhalter/jedi/issues/1745][#1745]], and [[https://github.com/davidhalter/jedi/issues/1746][#1746]]). Since the universal
|
||||
functions are neither builtin methods nor data instances but a kind of "callable
|
||||
instances", the [[https://docs.python.org/3/library/inspect.html][Python inspect]] module also fails to handle the universal
|
||||
functions properly.
|
||||
|
Loading…
Reference in New Issue
Block a user