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))
|
(global-set-key (kbd "C-c g") #'writegood-mode))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
* Programming
|
* Programming Tools
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: sec:programming
|
:CUSTOM_ID: sec:programming-tools
|
||||||
:END:
|
: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]]
|
** [[https://github.com/lassik/emacs-format-all-the-code#readme][Format-all]]
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: sec:format-all
|
:CUSTOM_ID: sec:format-all
|
||||||
@ -2937,6 +2981,19 @@ Listing [[lst:configure-format-all]]:
|
|||||||
(message "Saved reformatted tangled buffer `%s'" (buffer-file-name)))))))
|
(message "Saved reformatted tangled buffer `%s'" (buffer-file-name)))))))
|
||||||
#+end_src
|
#+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]]
|
** [[https://dept-info.labri.fr/~strandh/Teaching/PFS/Common/Strandh-Tutorial/Dir-symbolic.html][Common Lisp programming]]
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: sec:common-lisp-programming
|
:CUSTOM_ID: sec:common-lisp-programming
|
||||||
@ -3145,8 +3202,8 @@ server, before plunging into the configuring steps:
|
|||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: sec:python-mode
|
:CUSTOM_ID: sec:python-mode
|
||||||
:END:
|
:END:
|
||||||
Listing [[lst:configure-python]] tells the Python shell to disregard its environment
|
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
|
||||||
variables (in particular =PYTHONSTARTUPFILE=). The [[https://github.com/pythonic-emacs/pythonic#readme][pythonic]] and [[https://github.com/jorgenschaefer/pyvenv#readme][pyvenv]] packages
|
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]]
|
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]])
|
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
|
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
|
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
|
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:manage-pyenv]] to manage [[https://github.com/pyenv/pyenv#readme][pyenv]] from within Emacs and listing
|
||||||
[[lst:setting-python-shell-virtualenv-root]] to set
|
[[lst:setting-python-shell-virtualenv-root]] to set =python-shell-virtualenv-root=.
|
||||||
=python-shell-virtualenv-root=.
|
|
||||||
|
|
||||||
#+caption[Configure =python=]:
|
#+caption[Configure =python=]:
|
||||||
#+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
|
(with-eval-after-load 'python
|
||||||
(custom-set-variables
|
(custom-set-variables
|
||||||
`(python-check-command ,(executable-find "flake8"))
|
`(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"))
|
||||||
'(python-shell-interpreter "ipython3")
|
'(python-shell-interpreter "ipython3")
|
||||||
@ -3257,53 +3314,39 @@ of [[https://github.com/jorgenschaefer/pyvenv#readme][pyvenv]]). Therefore, thi
|
|||||||
python-shell-virtualenv-root)))))
|
python-shell-virtualenv-root)))))
|
||||||
#+end_src
|
#+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:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: sec:eglot
|
:CUSTOM_ID: sec:eglot-python
|
||||||
:END:
|
:END:
|
||||||
Listing [[lst:configure-eglot+python-lsp-server-for-python]] tangles to
|
Listing [[lst:configure-eglot+python-lsp-server-for-python]] configures [[https://github.com/joaotavora/eglot][eglot]] for
|
||||||
=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]].
|
[[https://www.python.org][Python]] using the [[https://github.com/python-lsp/python-lsp-server][python-lsp-server]]. In order to enable all builtin
|
||||||
In order to enable all builtin [[https://github.com/python-lsp/python-lsp-server][python-lsp-server]] capabilities, ensure
|
[[https://github.com/python-lsp/python-lsp-server][python-lsp-server]] capabilities, ensure installation of the Python packages
|
||||||
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]],
|
[[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
|
||||||
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]]
|
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]].
|
||||||
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
|
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
|
||||||
[[https://github.com/PyCQA/flake8][flake8]] as in [[lst:broken-configure-eglot+python-lsp-server-for-python]], but it
|
[[lst:broken-configure-eglot+python-lsp-server-for-python]], but it does not work.
|
||||||
does not work.
|
|
||||||
|
|
||||||
Listing [[lst:on-hack-local-variables-hook-eglot-maybe]] defines a hook function to
|
Listing [[lst:eglot-directory-variables-for-python]] shows a proper [[info:emacs#Directory Variables][.dir-locals.el]]
|
||||||
launch [[https://github.com/joaotavora/eglot][eglot]] in presence of a proper [[info:emacs#Directory Variables][.dir-locals.el]] file in the root directory
|
file in the root directory of any [[https://www.python.org][Python]] project to start [[https://github.com/joaotavora/eglot][eglot]] automatically
|
||||||
of any [[https://www.python.org][Python]] project. Listing [[lst:eglot-directory-variables-for-python]] shows
|
according to the configuration in listing [[lst:eglot-maybe-ensure]].
|
||||||
such a proper [[info:emacs#Directory Variables][.dir-locals.el]] file.
|
|
||||||
|
|
||||||
#+caption[Configure =eglot= with =python-lsp-server= for Python]:
|
#+caption[Configure =eglot= with =python-lsp-server= for Python]:
|
||||||
#+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
|
#+name: lst:configure-eglot+python-lsp-server-for-python
|
||||||
#+begin_src emacs-lisp
|
#+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
|
(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.
|
'(;; Disable the `:pyls_flake8' plugin to fall back to pycodestyle.
|
||||||
(:pylsp . (:plugins (:pyls_flake8 (:enabled t))))
|
(:pylsp . (:plugins (:pyls_flake8 (:enabled t))))
|
||||||
(:pylsp . (:plugins (:jedi (:auto_import_modules ["numpy"]))))
|
(:pylsp . (:plugins (:jedi (:auto_import_modules ["numpy"]))))
|
||||||
(:pylsp . (:plugins (:jedi_completion (:cache_for ["astropy"]))))))
|
(: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
|
#+end_src
|
||||||
|
|
||||||
#+caption[Broken configure =eglot= with =python-lsp-server= for Python]:
|
#+caption[Broken configure =eglot= with =python-lsp-server= for Python]:
|
||||||
#+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
|
#+name: lst:broken-configure-eglot+python-lsp-server-for-python
|
||||||
#+begin_src emacs-lisp :tangle no
|
#+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
|
(with-eval-after-load 'eglot
|
||||||
(setq-default
|
(setq-default
|
||||||
eglot-workspace-configuration
|
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 (:pyflakes (:enabled :json-false))))
|
||||||
(:pylsp . (:plugins (:flake8 (:enabled t))))
|
(:pylsp . (:plugins (:flake8 (:enabled t))))
|
||||||
(:pylsp . (:plugins (:jedi (:auto_import_modules ["numpy"]))))
|
(:pylsp . (:plugins (:jedi (:auto_import_modules ["numpy"]))))
|
||||||
(:pylsp . (:plugins (:jedi_completion (:cache_for ["astropy"]))))))
|
(: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)))))
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+caption[Propose =directory-variables= to launch =eglot=]:
|
#+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
|
#+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]].
|
[[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
|
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
|
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
|
instances", the [[https://docs.python.org/3/library/inspect.html][Python inspect]] module also fails to handle the universal
|
||||||
functions properly.
|
functions properly.
|
||||||
|
Loading…
Reference in New Issue
Block a user