From 8ba219f045d0df22db3199e7f52ef94deeabc7db Mon Sep 17 00:00:00 2001 From: Gerard Vermeulen Date: Sat, 1 Jan 2022 11:42:28 +0100 Subject: [PATCH] Improve sections on Org and Python * Add patch for python-lsp-server. * Swap order of sections on programming and editing. --- README.org | 482 +++++++++++++++++++------------- pylsp-auto-import-modules.patch | 41 +++ 2 files changed, 328 insertions(+), 195 deletions(-) create mode 100644 pylsp-auto-import-modules.patch diff --git a/README.org b/README.org index 883e2d0..33aafe2 100644 --- a/README.org +++ b/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: ]], 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 `-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 `-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)]] diff --git a/pylsp-auto-import-modules.patch b/pylsp-auto-import-modules.patch new file mode 100644 index 0000000..8978682 --- /dev/null +++ b/pylsp-auto-import-modules.patch @@ -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')