Improve sections on Org and Python
* Add patch for python-lsp-server. * Swap order of sections on programming and editing.
This commit is contained in:
parent
ae2c0fd48e
commit
8ba219f045
482
README.org
482
README.org
@ -956,6 +956,7 @@ The code in listing [[lst:customize-org-babel]], [[lst:customize-org]], and
|
||||
'(org-latex-listings 'minted)
|
||||
'(org-latex-minted-langs '((cc "c++")
|
||||
(cperl "perl")
|
||||
(diff "diff")
|
||||
(shell-script "bash")
|
||||
(caml "ocaml")
|
||||
(org "latex")))
|
||||
@ -1273,25 +1274,45 @@ blocks) do not work in [[info:org#Export Settings][#+SETUPFILE: <FILE>]], but on
|
||||
:CUSTOM_ID: sec:setupfile+include-usage
|
||||
:END:
|
||||
|
||||
Listing [[lst:source-file-export-keyword-settings]] shows a copie of the first six
|
||||
lines of this [[file:README.org]] file. The last two lines shows that the file
|
||||
[[file:setup-include]] serves as a [[info:org#Export Settings][#+SETUPFILE:FILE]] file and as a [[info:org#Export Settings][#+INCLUDE: FILE]].
|
||||
Evaluation of the source block in listing
|
||||
[[lst:make-source-block-with-export-keyword-settings]] produces the source block
|
||||
that exports to listing [[lst:source-file-export-keyword-settings]] which shows the
|
||||
first six lines of this [[file:README.org]] file. The last two lines show that
|
||||
[[file:setup-include.org][setup-include.org]] is argument for [[info:org#Export Settings][#+SETUPFILE:]] *and* [[info:org#Export Settings][#+INCLUDE:]].
|
||||
|
||||
#+caption[Make setup and include file export keyword settings source block]:
|
||||
#+caption: The shell script to make the source block containing the export
|
||||
#+caption: keyword settings.
|
||||
#+name: lst:make-source-block-with-export-keyword-settings
|
||||
#+begin_src shell :exports both :results drawer
|
||||
echo "#+caption[Source file export keyword settings]:"
|
||||
echo "#+caption: The first six lines of README.org containing the export"
|
||||
echo "#+caption: keyword settings."
|
||||
echo "#+name: lst:source-file-export-keyword-settings"
|
||||
echo "#+begin_src org :tangle no"
|
||||
head -n 6 README.org
|
||||
echo -n "#+end_src"
|
||||
#+end_src
|
||||
|
||||
#+RESULTS: lst:make-source-block-with-export-keyword-settings
|
||||
:results:
|
||||
#+caption[Source file export keyword settings]:
|
||||
#+caption: Source file export keyword settings.
|
||||
#+caption: The first six lines of README.org containing the export
|
||||
#+caption: keyword settings.
|
||||
#+name: lst:source-file-export-keyword-settings
|
||||
#+begin_src org :tangle no
|
||||
,#+title: Emacs setup for use with LaTeX, Org, and Python
|
||||
,#+author: Gerard Vermeulen
|
||||
,#+latex_class: article
|
||||
,#+latex_class_options: [11pt,a4paper,english,svgnames,tables]
|
||||
,#+setupfile: "setup-include.org"
|
||||
,#+include: "setup-include.org"
|
||||
#+title: Emacs setup for use with LaTeX, Org, and Python
|
||||
#+author: Gerard Vermeulen
|
||||
#+latex_class: article
|
||||
#+latex_class_options: [11pt,a4paper,english,svgnames,tables]
|
||||
#+setupfile: "setup-include.org"
|
||||
#+include: "setup-include.org"
|
||||
#+end_src
|
||||
:end:
|
||||
|
||||
Listing [[lst:setup-include-export-keyword-settings]], [[lst:use-latex-header-1]],
|
||||
[[lst:use-latex-header-2]], [[lst:use-latex-header-3]], and [[lst:use-latex-header-4]]
|
||||
tangle into the [[file:setup-include]] file.
|
||||
tangle into the [[file:setup-include.org][setup-include.org]] file.
|
||||
|
||||
#+caption[Setup and include file export keyword settings]:
|
||||
#+caption: Setup and include file export keyword settings.
|
||||
@ -1523,6 +1544,260 @@ Listing [[lst:emacs-lisp-setup-call]] initializes the buffer local variables
|
||||
\end{titlepage}
|
||||
#+end_src
|
||||
|
||||
* Programming
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: sec:programming
|
||||
:END:
|
||||
|
||||
** Emacs-lisp programming
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: sec:emacs-lisp-programming
|
||||
:END:
|
||||
|
||||
** [[https://www.seas.upenn.edu/~chaoliu/2017/09/01/python-programming-in-emacs/][Python programming]]
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: sec:python-coding
|
||||
:END:
|
||||
|
||||
The [[https://www.emacswiki.org/emacs/PythonProgrammingInEmacs][Python Programming in Emacs]] wiki page lists options to enhance Emacs's
|
||||
built-in ~python-mode~. Here, the focus is on two packages:
|
||||
1. [[https://github.com/joaotavora/eglot][Eglot - Emacs polyGLOT: an Emacs LSP client that stays out of your way]]. The
|
||||
maintainer also contributes to Emacs itself and has a deep understanding of
|
||||
[[https://sheer.tj/the_way_of_emacs.html][the Way of Emacs]]. He refuses to add new features without seeing how they fit
|
||||
into [[https://sheer.tj/the_way_of_emacs.html][the Way of Emacs]] as this discussion on [[https://github.com/joaotavora/eglot/issues/523][org-mode source code blocks]]
|
||||
shows.
|
||||
2. [[https://github.com/pythonic-emacs/anaconda-mode][Anaconda - code navigation, documentation lookup, and completion for Python]].
|
||||
In my opinion, [[https://github.com/joaotavora/eglot][eglot]] has more potential than [[https://github.com/pythonic-emacs/anaconda-mode][anaconda]], but [[https://github.com/pythonic-emacs/anaconda-mode][anaconda]] is
|
||||
compatible with [[info:org#Editing Source Code][source code block editing]] while [[https://github.com/joaotavora/eglot][eglot]] is not. Listing
|
||||
[[lst:configure-python]] configures [[https://www.python.org][Python]].
|
||||
|
||||
*** [[https://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/progmodes/python.el][Python-mode]]
|
||||
|
||||
#+caption[Configure =python=]:
|
||||
#+caption: Configure =python=.
|
||||
#+name: lst:configure-python
|
||||
#+begin_src elisp
|
||||
(with-eval-after-load 'python
|
||||
(custom-set-variables
|
||||
'(python-indent-guess-indent-offset nil)
|
||||
'(python-shell-interpreter-args "-i -E")))
|
||||
#+end_src
|
||||
|
||||
*** [[https://github.com/joaotavora/eglot][Eglot]]
|
||||
|
||||
Listing [[lst:configure-eglot-for-python]] configures [[https://github.com/joaotavora/eglot][eglot]] with [[https://github.com/python-lsp/python-lsp-server][python-lsp-server]]
|
||||
for [[https://www.python.org][Python]]. It defines a hook function to launch [[https://github.com/joaotavora/eglot][eglot]] when it sees 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.
|
||||
|
||||
#+caption[Configure =eglot= for Python]:
|
||||
#+caption: Configure =eglot= for Python.
|
||||
#+name: lst:configure-eglot-for-python
|
||||
#+begin_src emacs-lisp
|
||||
(with-eval-after-load 'eglot
|
||||
(add-to-list 'eglot-server-programs '(python-mode "pylsp"))
|
||||
|
||||
(setq-default
|
||||
eglot-workspace-configuration
|
||||
'((:pylsp . (:plugins (:jedi
|
||||
(:auto_import_modules ["numpy" "scipy"]))))
|
||||
(:pylsp . (:plugins (:jedi_completion
|
||||
(:cache_for ["astropy"]))))
|
||||
(:pylsp . (:plugins (:jedi_completion (:eager t)))))))
|
||||
|
||||
(when (fboundp 'eglot-ensure)
|
||||
;; The two hooks `after-change-major-mode-hook' and
|
||||
;; `hack-local-variables-hook' are OK, but `<ANY>-mode-hook' is 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
|
||||
|
||||
#+caption[Propose =directory-variables= to launch =eglot=]:
|
||||
#+caption: Propose =directory-variables= in the root of any Python project to
|
||||
#+caption: launch =eglot=.
|
||||
#+name: lst:eglot-directory-variables-for-python
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
;; Proposal for a .dir-locals.el file in the root of any Python project.
|
||||
((python-mode
|
||||
. ((eglot-workspace-configuration
|
||||
. ((:pylsp . (:plugins (:jedi
|
||||
(:auto_import_modules ["numpy" "scipy"]))))
|
||||
(:pylsp . (:plugins (:jedi_completion
|
||||
(:cache_for ["astropy"]))))
|
||||
(:pylsp . (:plugins (:jedi_completion (:eager nil)))))))))
|
||||
#+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.21.5]] in the sense that it
|
||||
handles builtins and universal functions provided that [[https://jedi.readthedocs.io/en/latest/][jedi]] does not parse but
|
||||
imports [[https://numpy.org/][numpy-1.21.5]] (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]]).
|
||||
|
||||
#+header: :wrap "src diff :exports code :tangle pylsp-auto-import-modules.patch"
|
||||
#+begin_src shell :exports both :results org
|
||||
git -C $HOME/VCS/python-lsp-server diff
|
||||
#+end_src
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_src diff :exports code :tangle pylsp-auto-import-modules.patch
|
||||
diff --git a/pylsp/config/schema.json b/pylsp/config/schema.json
|
||||
index c29d78b..f54b67a 100644
|
||||
--- a/pylsp/config/schema.json
|
||||
+++ b/pylsp/config/schema.json
|
||||
@@ -69,6 +69,14 @@
|
||||
"default": null,
|
||||
"description": "List of errors and warnings to enable."
|
||||
},
|
||||
+ "pylsp.plugins.jedi.auto_import_modules": {
|
||||
+ "type": "array",
|
||||
+ "default": ["numpy", "scipy", "gi"],
|
||||
+ "items": {
|
||||
+ "type": "string"
|
||||
+ },
|
||||
+ "description": "List of module names for jedi to import (jedi.settings.auto_import_modules)."
|
||||
+ },
|
||||
"pylsp.plugins.jedi.extra_paths": {
|
||||
"type": "array",
|
||||
"default": [],
|
||||
diff --git a/pylsp/workspace.py b/pylsp/workspace.py
|
||||
index bf312f6..49e967a 100644
|
||||
--- a/pylsp/workspace.py
|
||||
+++ b/pylsp/workspace.py
|
||||
@@ -14,6 +14,8 @@ from . import lsp, uris, _utils
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
+DEFAULT_AUTO_IMPORT_MODULES = ["numpy", "scipy", "gi"]
|
||||
+
|
||||
# TODO: this is not the best e.g. we capture numbers
|
||||
RE_START_WORD = re.compile('[A-Za-z_0-9]*$')
|
||||
RE_END_WORD = re.compile('^[A-Za-z_0-9]*')
|
||||
@@ -252,6 +254,8 @@ class Document:
|
||||
|
||||
if self._config:
|
||||
jedi_settings = self._config.plugin_settings('jedi', document_path=self.path)
|
||||
+ jedi.settings.auto_import_modules = jedi_settings.get('auto_import_modules',
|
||||
+ DEFAULT_AUTO_IMPORT_MODULES)
|
||||
environment_path = jedi_settings.get('environment')
|
||||
extra_paths = jedi_settings.get('extra_paths') or []
|
||||
env_vars = jedi_settings.get('env_vars')
|
||||
#+end_src
|
||||
|
||||
*** [[https://github.com/pythonic-emacs/anaconda-mode][Anaconda]]
|
||||
|
||||
Listing [[lst:configure-anaconda-for-python]] configures [[https://github.com/pythonic-emacs/anaconda-mode][anaconda]]. See
|
||||
[[https://github.com/jorgenschaefer/elpy/blob/8d0de310d41ebf06b22321a8534546447456870c/elpy.el#L2775][elpy-module-company]] for how to handle ~company-backends~ as a local variable and
|
||||
the call to [[info:elisp#Advising Functions][advice-add]] opens Python org-mode edit-buffers in ~anaconda-mode~.
|
||||
|
||||
#+caption[Configure =anaconda= for Python]:
|
||||
#+caption: Configure =anaconda= for Python.
|
||||
#+name: lst:configure-anaconda-for-python
|
||||
#+begin_src emacs-lisp
|
||||
(with-eval-after-load 'python
|
||||
(with-eval-after-load 'company
|
||||
(when (and (fboundp 'anaconda-mode)
|
||||
(fboundp 'company-anaconda))
|
||||
(defun my-disable-anaconda-mode ()
|
||||
(when (derived-mode-p 'python-mode)
|
||||
(anaconda-mode -1)
|
||||
(make-variable-buffer-local 'company-backends)
|
||||
(setq company-backends
|
||||
(delq 'company-anaconda
|
||||
(mapcar #'identity company-backends)))
|
||||
(anaconda-eldoc-mode -1)))
|
||||
(defun my-enable-anaconda-mode ()
|
||||
(when (derived-mode-p 'python-mode)
|
||||
(anaconda-mode +1)
|
||||
(make-variable-buffer-local 'company-backends)
|
||||
(setq company-backends
|
||||
(cons 'company-anaconda
|
||||
(delq 'company-semantic
|
||||
(delq 'company-capf
|
||||
(mapcar #'identity company-backends)))))
|
||||
(anaconda-eldoc-mode
|
||||
(if (file-remote-p default-directory) -1 1))))))
|
||||
|
||||
(unless (and (fboundp 'my-disable-anaconda-mode)
|
||||
(fboundp 'my-enable-anaconda-mode))
|
||||
(when (fboundp 'anaconda-mode)
|
||||
(defun my-disable-anaconda-mode ()
|
||||
(when (derived-mode-p 'python-mode)
|
||||
(anaconda-mode -1)
|
||||
(anaconda-eldoc-mode -1)))
|
||||
(defun my-enable-anaconda-mode ()
|
||||
(when (derived-mode-p 'python-mode)
|
||||
(anaconda-mode +1)
|
||||
(anaconda-eldoc-mode
|
||||
(if (file-remote-p default-directory) -1 1))))))
|
||||
|
||||
(when (fboundp 'my-enable-anaconda-mode)
|
||||
(advice-add 'org-edit-src-code :after #'my-enable-anaconda-mode))
|
||||
(when (and (fboundp 'my-disable-anaconda-mode)
|
||||
(fboundp 'my-enable-anaconda-mode))
|
||||
(defun my-toggle-anaconda-mode ()
|
||||
"Toggle anaconda-mode with bells and whistles."
|
||||
(interactive)
|
||||
(if (bound-and-true-p anaconda-mode)
|
||||
(my-disable-anaconda-mode)
|
||||
(my-enable-anaconda-mode)))))
|
||||
#+end_src
|
||||
|
||||
*** [[https://jedi.readthedocs.io/en/latest/][Jedi]]
|
||||
|
||||
Listing [[lst:example-py]] is a [[https://www.python.org][Python]] example to test whether [[https://jedi.readthedocs.io/en/latest/][jedi]] in combination
|
||||
with and either [[https://github.com/pythonic-emacs/anaconda-mode][anaconda]] or [[https://github.com/joaotavora/eglot][eglot]] works when coding certain functions of for
|
||||
instance [[https://numpy.org/][numpy]] and [[https://scipy.org/][scipy]].
|
||||
|
||||
#+caption[Tangle the =example.py= file]:
|
||||
#+caption: Tangle the =example.py= file.
|
||||
#+name: lst:example-py
|
||||
#+begin_src python :tangle example.py
|
||||
import numpy
|
||||
import astropy.units as apu
|
||||
|
||||
a = numpy.arange(0, 11)
|
||||
a = numpy.linspace(0, 10, num=11)
|
||||
a = numpy.arccos(a)
|
||||
q = apu.Quantity(a, apu.meter)
|
||||
print(q)
|
||||
#+end_src
|
||||
|
||||
*** [[https://github.com/pyenv/pyenv][Pyenv]]
|
||||
|
||||
Listing [[lst:enable-pyenv-mode]] configures and enables =pyenv-mode=.
|
||||
|
||||
#+caption[Enable =pyenv-mode=]:
|
||||
#+caption: Enable =pyenv-mode=.
|
||||
#+name: lst:enable-pyenv-mode
|
||||
#+begin_src emacs-lisp
|
||||
(when (and (executable-find "pyenv")
|
||||
(require 'pyenv-mode nil 'noerror))
|
||||
(pyenv-mode +1)
|
||||
(pyenv-mode-set "3.9.9/envs/python-3.9.9"))
|
||||
#+end_src
|
||||
|
||||
*** Info
|
||||
|
||||
Listing [[lst:configure-info]] adds a path in my home directory to the places where
|
||||
=info= looks for files.
|
||||
|
||||
#+caption[Configure =info=]:
|
||||
#+caption: Configure =info=.
|
||||
#+name: lst:configure-info
|
||||
#+begin_src emacs-lisp
|
||||
(with-eval-after-load 'info
|
||||
(add-to-list 'Info-directory-list
|
||||
(expand-file-name "~/.local/share/info")))
|
||||
#+end_src
|
||||
|
||||
*** TODO Look into: editing facilities
|
||||
1. [[https://github.com/douglasdavis/numpydoc.el/blob/main/numpydoc.el][Emacs extension to insert numpy style docstrings in function definitions]]
|
||||
|
||||
* Editing
|
||||
|
||||
** [[https://www.emacswiki.org/emacs/DisabledCommands][Enable disabled commands and inform]]
|
||||
@ -1624,7 +1899,7 @@ on tables by means of =org-narrow-to-table=.
|
||||
(add-hook 'text-mode-hook #'ws-butler-mode)))
|
||||
#+end_src
|
||||
|
||||
** Structural editing
|
||||
** [[https://countvajhula.com/2021/09/25/the-animated-guide-to-symex/][Structural editing]]
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: sec:structural-editing
|
||||
:END:
|
||||
@ -1737,189 +2012,6 @@ code formatter for Python]].
|
||||
(yas-global-mode +1))
|
||||
#+end_src
|
||||
|
||||
* Coding
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: sec:coding
|
||||
:END:
|
||||
|
||||
** Emacs-lisp coding
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: sec:emacs-lisp-coding
|
||||
:END:
|
||||
|
||||
** Python coding
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: sec:python-coding
|
||||
:END:
|
||||
|
||||
The [[https://www.emacswiki.org/emacs/PythonProgrammingInEmacs][Python Programming in Emacs]] wiki page lists options to enhance Emacs's
|
||||
built-in ~python-mode~. Here, the focus is on two packages:
|
||||
1. [[https://github.com/joaotavora/eglot][Eglot - Emacs polyGLOT: an Emacs LSP client that stays out of your way]]. The
|
||||
maintainer also contributes to Emacs itself and has a deep understanding of
|
||||
[[https://sheer.tj/the_way_of_emacs.html][the Way of Emacs]]. He refuses to add new features without seeing how they fit
|
||||
into [[https://sheer.tj/the_way_of_emacs.html][the Way of Emacs]] as this discussion on [[https://github.com/joaotavora/eglot/issues/523][org-mode source code blocks]]
|
||||
shows.
|
||||
2. [[https://github.com/pythonic-emacs/anaconda-mode][Anaconda - code navigation, documentation lookup, and completion for Python]].
|
||||
In my opinion, [[https://github.com/joaotavora/eglot][eglot]] has more potential than [[https://github.com/pythonic-emacs/anaconda-mode][anaconda]], but [[https://github.com/pythonic-emacs/anaconda-mode][anaconda]] is
|
||||
compatible with [[info:org#Editing Source Code][source code block editing]] while [[https://github.com/joaotavora/eglot][eglot]] is not. Listing
|
||||
[[lst:configure-python]] configures [[https://www.python.org][Python]].
|
||||
|
||||
#+caption[Configure =python=]:
|
||||
#+caption: Configure =python=.
|
||||
#+name: lst:configure-python
|
||||
#+begin_src elisp
|
||||
(with-eval-after-load 'python
|
||||
(custom-set-variables
|
||||
'(python-indent-guess-indent-offset nil)
|
||||
'(python-shell-interpreter-args "-i -E")))
|
||||
#+end_src
|
||||
|
||||
Listing [[lst:configure-eglot-for-python]] configures [[https://github.com/joaotavora/eglot][eglot]] for [[https://www.python.org][Python]]. It defines
|
||||
a hook function to launch [[https://github.com/joaotavora/eglot][eglot]] by means of a proper [[info:emacs#Directory Variables][directory variables]] file in
|
||||
the root directory of any [[https://www.python.org][Python]] project. Listing
|
||||
[[lst:eglot-directory-variables-for-python]] does shows such a proper [[info:emacs#Directory Variables][directory
|
||||
variables]] file.
|
||||
|
||||
#+caption[Configure =eglot= for Python]:
|
||||
#+caption: Configure =eglot= for Python.
|
||||
#+name: lst:configure-eglot-for-python
|
||||
#+begin_src emacs-lisp
|
||||
(with-eval-after-load 'eglot
|
||||
(add-to-list 'eglot-server-programs '(python-mode "pylsp"))
|
||||
(setq-default
|
||||
eglot-workspace-configuration
|
||||
'((:pylsp . (:plugins (:jedi_completion
|
||||
(:cache_for ["astropy" "numpy" "scipy"]))))
|
||||
(:pylsp . (:plugins (:jedi_completion (:eager nil)))))))
|
||||
|
||||
(when (fboundp 'eglot-ensure)
|
||||
;; The two hooks `after-change-major-mode-hook' and
|
||||
;; `hack-local-variables-hook' are OK, but `<ANY>-mode-hook' is 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
|
||||
|
||||
#+caption[Propose =directory-variables= to launch =eglot=]:
|
||||
#+caption: Propose =directory-variables= in the root of any Python project to
|
||||
#+caption: launch =eglot=.
|
||||
#+name: lst:eglot-directory-variables-for-python
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
;; Proposal for a .dir-locals.el file in the root of any Python project.
|
||||
((python-mode
|
||||
. ((eglot-workspace-configuration
|
||||
. ((:pylsp . (:plugins (:jedi_completion
|
||||
(:cache_for ["astropy" "numpy" "scipy"]))))
|
||||
(:pylsp . (:plugins (:jedi_completion (:eager nil)))))))))
|
||||
#+end_src
|
||||
|
||||
Listing [[lst:configure-anaconda-for-python]] configures [[https://github.com/pythonic-emacs/anaconda-mode][anaconda]]. See
|
||||
[[https://github.com/jorgenschaefer/elpy/blob/8d0de310d41ebf06b22321a8534546447456870c/elpy.el#L2775][elpy-module-company]] for how to handle ~company-backends~ as a local variable and
|
||||
the call to [[info:elisp#Advising Functions][advice-add]] opens Python org-mode edit-buffers in ~anaconda-mode~.
|
||||
|
||||
#+caption[Configure =anaconda= for Python]:
|
||||
#+caption: Configure =anaconda= for Python.
|
||||
#+name: lst:configure-anaconda-for-python
|
||||
#+begin_src emacs-lisp
|
||||
(with-eval-after-load 'python
|
||||
(with-eval-after-load 'company
|
||||
(when (and (fboundp 'anaconda-mode)
|
||||
(fboundp 'company-anaconda))
|
||||
(defun my-disable-anaconda-mode ()
|
||||
(when (derived-mode-p 'python-mode)
|
||||
(anaconda-mode -1)
|
||||
(make-variable-buffer-local 'company-backends)
|
||||
(setq company-backends
|
||||
(delq 'company-anaconda
|
||||
(mapcar #'identity company-backends)))
|
||||
(anaconda-eldoc-mode -1)))
|
||||
(defun my-enable-anaconda-mode ()
|
||||
(when (derived-mode-p 'python-mode)
|
||||
(anaconda-mode +1)
|
||||
(make-variable-buffer-local 'company-backends)
|
||||
(setq company-backends
|
||||
(cons 'company-anaconda
|
||||
(delq 'company-semantic
|
||||
(delq 'company-capf
|
||||
(mapcar #'identity company-backends)))))
|
||||
(anaconda-eldoc-mode
|
||||
(if (file-remote-p default-directory) -1 1))))))
|
||||
|
||||
(unless (and (fboundp 'my-disable-anaconda-mode)
|
||||
(fboundp 'my-enable-anaconda-mode))
|
||||
(when (fboundp 'anaconda-mode)
|
||||
(defun my-disable-anaconda-mode ()
|
||||
(when (derived-mode-p 'python-mode)
|
||||
(anaconda-mode -1)
|
||||
(anaconda-eldoc-mode -1)))
|
||||
(defun my-enable-anaconda-mode ()
|
||||
(when (derived-mode-p 'python-mode)
|
||||
(anaconda-mode +1)
|
||||
(anaconda-eldoc-mode
|
||||
(if (file-remote-p default-directory) -1 1))))))
|
||||
|
||||
(when (fboundp 'my-enable-anaconda-mode)
|
||||
(advice-add 'org-edit-src-code :after #'my-enable-anaconda-mode))
|
||||
(when (and (fboundp 'my-disable-anaconda-mode)
|
||||
(fboundp 'my-enable-anaconda-mode))
|
||||
(defun my-toggle-anaconda-mode ()
|
||||
"Toggle anaconda-mode with bells and whistles."
|
||||
(interactive)
|
||||
(if (bound-and-true-p anaconda-mode)
|
||||
(my-disable-anaconda-mode)
|
||||
(my-enable-anaconda-mode)))))
|
||||
#+end_src
|
||||
|
||||
Listing [[lst:example-py]] is a [[https://www.python.org][Python]] example showing differences in the handling
|
||||
of compiled foreign language modules and pure [[https://www.python.org][Python]] modules. The underlying
|
||||
[[https://jedi.readthedocs.io/en/latest/][jedi]] library parses modules (instead of imports) in order to handle completion
|
||||
and documentation request. Therefore, [[https://jedi.readthedocs.io/en/latest/][jedi]] and consequently [[https://github.com/joaotavora/eglot][eglot]] as well as
|
||||
[[https://github.com/pythonic-emacs/anaconda-mode][anaconda]] treat compiled foreign language modules as second zone citizens. This
|
||||
is noticible when coding certain functions of for instance [[https://numpy.org/][numpy]] and [[https://scipy.org/][scipy]].
|
||||
|
||||
#+caption[Tangle the =example.py= file]:
|
||||
#+caption: Tangle the =example.py= file.
|
||||
#+name: lst:example-py
|
||||
#+begin_src python :tangle example.py :comments link
|
||||
import numpy
|
||||
import astropy.units as apu
|
||||
|
||||
a = numpy.arange(0, 11)
|
||||
a = numpy.linspace(0, 10, num=11)
|
||||
q = apu.Quantity(a, apu.meter)
|
||||
print(q)
|
||||
#+end_src
|
||||
|
||||
Listing [[lst:enable-pyenv-mode]] configures and enables =pyenv-mode=.
|
||||
|
||||
#+caption[Enable =pyenv-mode=]:
|
||||
#+caption: Enable =pyenv-mode=.
|
||||
#+name: lst:enable-pyenv-mode
|
||||
#+begin_src emacs-lisp
|
||||
(when (and (executable-find "pyenv")
|
||||
(require 'pyenv-mode nil 'noerror))
|
||||
(pyenv-mode +1)
|
||||
(pyenv-mode-set "3.9.9/envs/python-3.9.9"))
|
||||
#+end_src
|
||||
|
||||
Listing [[lst:configure-info]] adds a path in my home directory to the places where
|
||||
=info= looks for files.
|
||||
|
||||
#+caption[Configure =info=]:
|
||||
#+caption: Configure =info=.
|
||||
#+name: lst:configure-info
|
||||
#+begin_src emacs-lisp
|
||||
(with-eval-after-load 'info
|
||||
(add-to-list 'Info-directory-list
|
||||
(expand-file-name "~/.local/share/info")))
|
||||
#+end_src
|
||||
|
||||
Look into:
|
||||
1. [[https://github.com/douglasdavis/numpydoc.el/blob/main/numpydoc.el][Emacs extension to insert numpy style docstrings in function definitions]]
|
||||
|
||||
* [[https://lists.gnu.org/archive/html/emacs-devel/2020-04/msg00775.html][Appearance]]
|
||||
|
||||
** [[info:emacs#Faces][Text faces (or styles)]]
|
||||
|
41
pylsp-auto-import-modules.patch
Normal file
41
pylsp-auto-import-modules.patch
Normal file
@ -0,0 +1,41 @@
|
||||
diff --git a/pylsp/config/schema.json b/pylsp/config/schema.json
|
||||
index c29d78b..f54b67a 100644
|
||||
--- a/pylsp/config/schema.json
|
||||
+++ b/pylsp/config/schema.json
|
||||
@@ -69,6 +69,14 @@
|
||||
"default": null,
|
||||
"description": "List of errors and warnings to enable."
|
||||
},
|
||||
+ "pylsp.plugins.jedi.auto_import_modules": {
|
||||
+ "type": "array",
|
||||
+ "default": ["numpy", "scipy", "gi"],
|
||||
+ "items": {
|
||||
+ "type": "string"
|
||||
+ },
|
||||
+ "description": "List of module names for jedi to import (jedi.settings.auto_import_modules)."
|
||||
+ },
|
||||
"pylsp.plugins.jedi.extra_paths": {
|
||||
"type": "array",
|
||||
"default": [],
|
||||
diff --git a/pylsp/workspace.py b/pylsp/workspace.py
|
||||
index bf312f6..49e967a 100644
|
||||
--- a/pylsp/workspace.py
|
||||
+++ b/pylsp/workspace.py
|
||||
@@ -14,6 +14,8 @@ from . import lsp, uris, _utils
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
+DEFAULT_AUTO_IMPORT_MODULES = ["numpy", "scipy", "gi"]
|
||||
+
|
||||
# TODO: this is not the best e.g. we capture numbers
|
||||
RE_START_WORD = re.compile('[A-Za-z_0-9]*$')
|
||||
RE_END_WORD = re.compile('^[A-Za-z_0-9]*')
|
||||
@@ -252,6 +254,8 @@ class Document:
|
||||
|
||||
if self._config:
|
||||
jedi_settings = self._config.plugin_settings('jedi', document_path=self.path)
|
||||
+ jedi.settings.auto_import_modules = jedi_settings.get('auto_import_modules',
|
||||
+ DEFAULT_AUTO_IMPORT_MODULES)
|
||||
environment_path = jedi_settings.get('environment')
|
||||
extra_paths = jedi_settings.get('extra_paths') or []
|
||||
env_vars = jedi_settings.get('env_vars')
|
Loading…
Reference in New Issue
Block a user