Revise python layer

Make LSP be used as default backend
Request DAP layer when LSP is used as backend
Update README.org with latest pyls package dependencies
Remove obsolete getter functions
This commit is contained in:
Maximilian Wolff 2019-12-15 13:56:49 +01:00
parent 7f6b4205cb
commit 9720127282
No known key found for this signature in database
GPG key ID: 2DD07025BFDBD89A
5 changed files with 55 additions and 70 deletions

View file

@ -49,9 +49,9 @@ This layer adds support for the Python language.
** Features: ** Features:
- Support for the following backends: - Support for the following backends:
- [[https://github.com/proofit404/anaconda-mode][anaconda]] (default), - [[https://github.com/proofit404/anaconda-mode][anaconda]],
- [[https://github.com/emacs-lsp/lsp-python][Language Server Protocol]] (experimental - 2 implementations), - [[https://github.com/emacs-lsp/lsp-python][Language Server Protocol]]
- python-language-server - python-language-server (default)
- Microsoft python language server - Microsoft python language server
- Auto-completion - Auto-completion
- Code Navigation - Code Navigation
@ -81,10 +81,7 @@ To choose a default backend set the layer variable =python-backend=:
(python :variables python-backend 'anaconda) (python :variables python-backend 'anaconda)
#+END_SRC #+END_SRC
Alternatively the =lsp= backend will be automatically chosen if the layer =lsp= A Backend can be chosen on a per project basis using directory local variables
is used and you did not specify any value for =python-backend=.
Backend can be chosen on a per project basis using directory local variables
(files named =.dir-locals.el= at the root of a project), an example to use the (files named =.dir-locals.el= at the root of a project), an example to use the
=lsp= backend: =lsp= backend:
@ -148,7 +145,7 @@ layer variable as follows:
You just have to install python language server package: You just have to install python language server package:
#+BEGIN_SRC sh #+BEGIN_SRC sh
pip install python-language-server pip install python-language-server[all]
#+END_SRC #+END_SRC
Additionally you can install the following other packages: Additionally you can install the following other packages:
@ -158,6 +155,7 @@ Additionally you can install the following other packages:
pip install pyls-isort pip install pyls-isort
# for mypy checking (python 3.4+ is needed) # for mypy checking (python 3.4+ is needed)
pip install pyls-mypy pip install pyls-mypy
pip install pyls-black
#+END_SRC #+END_SRC
If you've installed the language server and related packages as development If you've installed the language server and related packages as development
@ -228,17 +226,15 @@ directory local variable in your project root. ~SPC f v d~ in Spacemacs. See
The root of the project is detected with a =.git= directory or a =setup.cfg= file. The root of the project is detected with a =.git= directory or a =setup.cfg= file.
** Buffer formatting ** Buffer formatting
One of [[https://github.com/google/yapf][YAPF]] (the default), [[https://github.com/ambv/black][black]] or =lsp= may be selected as the formatter, via One of [[https://github.com/google/yapf][YAPF]], [[https://github.com/ambv/black][black]] or =lsp= may be selected as the formatter, via
=python-formatter=, as ='yapf=, ='black= or =lsp= respectively. =python-formatter=, as =yapf=, =black= or =lsp= respectively. If non is selected
either =yapf= or =lsp= is used depending on the selected backend.
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(setq-default dotspacemacs-configuration-layers '( (setq-default dotspacemacs-configuration-layers '(
(python :variables python-formatter 'yapf))) (python :variables python-formatter 'yapf)))
#+END_SRC #+END_SRC
Alternatively the =lsp= formatter will be automatically chosen if the layer =lsp=
is used and you did not specify any value for =python-formatter=.
The key binding ~SPC m =~ invokes the selected formatter on the current buffer The key binding ~SPC m =~ invokes the selected formatter on the current buffer
when in non LSP python mode otherwise ~SPC m ==~ is used. when in non LSP python mode otherwise ~SPC m ==~ is used.

View file

@ -1,6 +1,6 @@
;;; config.el --- Python Layer Configuration File for Spacemacs ;;; config.el --- Python Layer Configuration File for Spacemacs
;; ;;
;; Copyright (c) 2012-2018 Sylvain Benner & Contributors ;; Copyright (c) 2012-2019 Sylvain Benner & Contributors
;; ;;
;; Author: Sylvain Benner <sylvain.benner@gmail.com> ;; Author: Sylvain Benner <sylvain.benner@gmail.com>
;; URL: https://github.com/syl20bnr/spacemacs ;; URL: https://github.com/syl20bnr/spacemacs
@ -14,10 +14,9 @@
(spacemacs|define-jump-handlers python-mode) (spacemacs|define-jump-handlers python-mode)
(spacemacs|define-jump-handlers cython-mode anaconda-mode-goto) (spacemacs|define-jump-handlers cython-mode anaconda-mode-goto)
(defvar python-backend 'nil (defvar python-backend 'lsp
"The backend to use for IDE features. "The backend to use for IDE features.
Possible values are `anaconda'and `lsp'. Possible values are `anaconda' and `lsp'.")
If `nil' then `anaconda' is the default backend unless `lsp' layer is used.")
(defvar python-lsp-server 'pyls (defvar python-lsp-server 'pyls
"Language server to use for lsp backend. Possible values are `pyls' "Language server to use for lsp backend. Possible values are `pyls'
@ -31,7 +30,7 @@ and `mspyls'")
(defvar python-formatter nil (defvar python-formatter nil
"The formatter to use. Possible values are `yapf', "The formatter to use. Possible values are `yapf',
`black' and 'lsp'.") `black' and `lsp'. If left empty a default will be selected based on the backend.")
(defvar python-format-on-save nil (defvar python-format-on-save nil
"If non-nil, automatically format code with formatter selected "If non-nil, automatically format code with formatter selected

View file

@ -1,6 +1,6 @@
;;; funcs.el --- Python Layer functions File for Spacemacs ;;; funcs.el --- Python Layer functions File for Spacemacs
;; ;;
;; Copyright (c) 2012-2018 Sylvain Benner & Contributors ;; Copyright (c) 2012-2019 Sylvain Benner & Contributors
;; ;;
;; Author: Sylvain Benner <sylvain.benner@gmail.com> ;; Author: Sylvain Benner <sylvain.benner@gmail.com>
;; URL: https://github.com/syl20bnr/spacemacs ;; URL: https://github.com/syl20bnr/spacemacs
@ -9,44 +9,34 @@
;; ;;
;;; License: GPLv3 ;;; License: GPLv3
(defun spacemacs//python-backend ()
"Returns selected backend."
(if python-backend
python-backend
(cond
((configuration-layer/layer-used-p 'lsp) 'lsp)
(t 'anaconda))))
(defun spacemacs//python-formatter () (defun spacemacs//python-formatter ()
"Returns selected backend." "Returns selected python-formatter."
(if python-formatter (or python-formatter (pcase python-backend
python-formatter ('lsp 'lsp)
(cond ('anaconda 'yapf))))
((configuration-layer/layer-used-p 'lsp) 'lsp)
(t 'yapf))))
(defun spacemacs//python-setup-backend () (defun spacemacs//python-setup-backend ()
"Conditionally setup python backend." "Conditionally setup python backend."
(when python-pipenv-activate (pipenv-activate)) (when python-pipenv-activate (pipenv-activate))
(pcase (spacemacs//python-backend) (pcase python-backend
(`anaconda (spacemacs//python-setup-anaconda)) (`anaconda (spacemacs//python-setup-anaconda))
(`lsp (spacemacs//python-setup-lsp)))) (`lsp (spacemacs//python-setup-lsp))))
(defun spacemacs//python-setup-company () (defun spacemacs//python-setup-company ()
"Conditionally setup company based on backend." "Conditionally setup company based on backend."
(pcase (spacemacs//python-backend) (pcase python-backend
(`anaconda (spacemacs//python-setup-anaconda-company)) (`anaconda (spacemacs//python-setup-anaconda-company))
(`lsp (spacemacs//python-setup-lsp-company)))) (`lsp (spacemacs//python-setup-lsp-company))))
(defun spacemacs//python-setup-dap () (defun spacemacs//python-setup-dap ()
"Conditionally setup elixir DAP integration." "Conditionally setup elixir DAP integration."
;; currently DAP is only available using LSP ;; currently DAP is only available using LSP
(pcase (spacemacs//python-backend) (pcase python-backend
(`lsp (spacemacs//python-setup-lsp-dap)))) (`lsp (spacemacs//python-setup-lsp-dap))))
(defun spacemacs//python-setup-eldoc () (defun spacemacs//python-setup-eldoc ()
"Conditionally setup eldoc based on backend." "Conditionally setup eldoc based on backend."
(pcase (spacemacs//python-backend) (pcase python-backend
;; lsp setup eldoc on its own ;; lsp setup eldoc on its own
(`anaconda (spacemacs//python-setup-anaconda-eldoc)))) (`anaconda (spacemacs//python-setup-anaconda-eldoc))))
@ -111,8 +101,8 @@
(defun spacemacs//python-default () (defun spacemacs//python-default ()
"Defaut settings for python buffers" "Defaut settings for python buffers"
(setq mode-name "Python" (setq mode-name "Python"
tab-width python-tab-width tab-width python-tab-width
fill-column python-fill-column) fill-column python-fill-column)
;; since we changed the tab-width we need to manually call python-indent-guess-indent-offset here ;; since we changed the tab-width we need to manually call python-indent-guess-indent-offset here
(when python-spacemacs-indent-guess (when python-spacemacs-indent-guess
@ -209,10 +199,10 @@ as the pyenv version then also return nil. This works around https://github.com/
"autoflake --remove-all-unused-imports -i unused_imports.py" "autoflake --remove-all-unused-imports -i unused_imports.py"
(interactive) (interactive)
(if (executable-find "autoflake") (if (executable-find "autoflake")
(progn (progn
(shell-command (format "autoflake --remove-all-unused-imports -i %s" (shell-command (format "autoflake --remove-all-unused-imports -i %s"
(shell-quote-argument (buffer-file-name)))) (shell-quote-argument (buffer-file-name))))
(revert-buffer t t t)) (revert-buffer t t t))
(message "Error: Cannot find autoflake executable."))) (message "Error: Cannot find autoflake executable.")))
(defun spacemacs//pyenv-mode-set-local-version () (defun spacemacs//pyenv-mode-set-local-version ()
@ -226,8 +216,8 @@ as the pyenv version then also return nil. This works around https://github.com/
(with-temp-buffer (with-temp-buffer
(insert-file-contents-literally file-path) (insert-file-contents-literally file-path)
(nth 0 (split-string (buffer-substring-no-properties (nth 0 (split-string (buffer-substring-no-properties
(line-beginning-position) (line-beginning-position)
(line-end-position))))))) (line-end-position)))))))
(if (member version (pyenv-mode-versions)) (if (member version (pyenv-mode-versions))
(progn (progn
(setenv "VIRTUAL_ENV" version) (setenv "VIRTUAL_ENV" version)
@ -281,7 +271,7 @@ location of \".venv\" file, then relative to pyvenv-workon-home()."
(defun spacemacs//python-get-secondary-testrunner () (defun spacemacs//python-get-secondary-testrunner ()
"Get the secondary test runner" "Get the secondary test runner"
(cdr (assoc (spacemacs//python-get-main-testrunner) '((pytest . nose) (cdr (assoc (spacemacs//python-get-main-testrunner) '((pytest . nose)
(nose . pytest))))) (nose . pytest)))))
(defun spacemacs//python-call-correct-test-function (arg funcalist) (defun spacemacs//python-call-correct-test-function (arg funcalist)
"Call a test function based on the chosen test framework. "Call a test function based on the chosen test framework.
@ -289,7 +279,7 @@ ARG is the universal-argument which chooses between the main and
the secondary test runner. FUNCALIST is an alist of the function the secondary test runner. FUNCALIST is an alist of the function
to be called for each testrunner. " to be called for each testrunner. "
(when python-save-before-test (when python-save-before-test
(save-buffer)) (save-buffer))
(let* ((test-runner (if arg (let* ((test-runner (if arg
(spacemacs//python-get-secondary-testrunner) (spacemacs//python-get-secondary-testrunner)
(spacemacs//python-get-main-testrunner))) (spacemacs//python-get-main-testrunner)))
@ -308,19 +298,19 @@ to be called for each testrunner. "
"Run all tests." "Run all tests."
(interactive "P") (interactive "P")
(spacemacs//python-call-correct-test-function arg '((pytest . pytest-all) (spacemacs//python-call-correct-test-function arg '((pytest . pytest-all)
(nose . nosetests-all)))) (nose . nosetests-all))))
(defun spacemacs/python-test-pdb-all (arg) (defun spacemacs/python-test-pdb-all (arg)
"Run all tests in debug mode." "Run all tests in debug mode."
(interactive "P") (interactive "P")
(spacemacs//python-call-correct-test-function arg '((pytest . pytest-pdb-all) (spacemacs//python-call-correct-test-function arg '((pytest . pytest-pdb-all)
(nose . nosetests-pdb-all)))) (nose . nosetests-pdb-all))))
(defun spacemacs/python-test-module (arg) (defun spacemacs/python-test-module (arg)
"Run all tests in the current module." "Run all tests in the current module."
(interactive "P") (interactive "P")
(spacemacs//python-call-correct-test-function arg '((pytest . pytest-module) (spacemacs//python-call-correct-test-function arg '((pytest . pytest-module)
(nose . nosetests-module)))) (nose . nosetests-module))))
(defun spacemacs/python-test-pdb-module (arg) (defun spacemacs/python-test-pdb-module (arg)
"Run all tests in the current module in debug mode." "Run all tests in the current module in debug mode."
@ -344,13 +334,13 @@ to be called for each testrunner. "
"Run current test." "Run current test."
(interactive "P") (interactive "P")
(spacemacs//python-call-correct-test-function arg '((pytest . pytest-one) (spacemacs//python-call-correct-test-function arg '((pytest . pytest-one)
(nose . nosetests-one)))) (nose . nosetests-one))))
(defun spacemacs/python-test-pdb-one (arg) (defun spacemacs/python-test-pdb-one (arg)
"Run current test in debug mode." "Run current test in debug mode."
(interactive "P") (interactive "P")
(spacemacs//python-call-correct-test-function arg '((pytest . pytest-pdb-one) (spacemacs//python-call-correct-test-function arg '((pytest . pytest-pdb-one)
(nose . nosetests-pdb-one)))) (nose . nosetests-pdb-one))))
(defun spacemacs//bind-python-testing-keys () (defun spacemacs//bind-python-testing-keys ()
"Bind the keys for testing in Python." "Bind the keys for testing in Python."
@ -382,7 +372,7 @@ to be called for each testrunner. "
"Bind the python formatter keys. "Bind the python formatter keys.
Bind formatter to '==' for LSP and '='for all other backends." Bind formatter to '==' for LSP and '='for all other backends."
(spacemacs/set-leader-keys-for-major-mode 'python-mode (spacemacs/set-leader-keys-for-major-mode 'python-mode
(if (eq (spacemacs//python-backend) 'lsp) (if (eq python-backend 'lsp)
"==" "=="
"=") 'spacemacs/python-format-buffer)) "=") 'spacemacs/python-format-buffer))

View file

@ -11,4 +11,4 @@
(when (and (boundp 'python-backend) (when (and (boundp 'python-backend)
(eq python-backend 'lsp)) (eq python-backend 'lsp))
(configuration-layer/declare-layer-dependencies '(lsp))) (configuration-layer/declare-layer-dependencies '(lsp dap)))

View file

@ -1,6 +1,6 @@
;;; packages.el --- Python Layer packages File for Spacemacs ;;; packages.el --- Python Layer packages File for Spacemacs
;; ;;
;; Copyright (c) 2012-2018 Sylvain Benner & Contributors ;; Copyright (c) 2012-2019 Sylvain Benner & Contributors
;; ;;
;; Author: Sylvain Benner <sylvain.benner@gmail.com> ;; Author: Sylvain Benner <sylvain.benner@gmail.com>
;; URL: https://github.com/syl20bnr/spacemacs ;; URL: https://github.com/syl20bnr/spacemacs
@ -50,11 +50,11 @@
(defun python/init-anaconda-mode () (defun python/init-anaconda-mode ()
(use-package anaconda-mode (use-package anaconda-mode
:if (eq (spacemacs//python-backend) 'anaconda) :if (eq python-backend 'anaconda)
:defer t :defer t
:init :init
(setq anaconda-mode-installation-directory (setq anaconda-mode-installation-directory
(concat spacemacs-cache-directory "anaconda-mode")) (concat spacemacs-cache-directory "anaconda-mode"))
:config :config
(progn (progn
(spacemacs/set-leader-keys-for-major-mode 'python-mode (spacemacs/set-leader-keys-for-major-mode 'python-mode
@ -76,7 +76,7 @@
(defadvice anaconda-mode-goto (before python/anaconda-mode-goto activate) (defadvice anaconda-mode-goto (before python/anaconda-mode-goto activate)
(evil--jumps-push)) (evil--jumps-push))
(add-to-list 'spacemacs-jump-handlers-python-mode (add-to-list 'spacemacs-jump-handlers-python-mode
'(anaconda-mode-find-definitions :async t))))) '(anaconda-mode-find-definitions :async t)))))
(defun python/post-init-company () (defun python/post-init-company ()
;; backend specific ;; backend specific
@ -94,7 +94,7 @@
(defun python/init-company-anaconda () (defun python/init-company-anaconda ()
(use-package company-anaconda (use-package company-anaconda
:if (eq (spacemacs//python-backend) 'anaconda) :if (eq python-backend 'anaconda)
:defer t :defer t
;; see `spacemacs//python-setup-anaconda-company' ;; see `spacemacs//python-setup-anaconda-company'
)) ))
@ -114,7 +114,7 @@
(use-package cython-mode (use-package cython-mode
:defer t :defer t
:config :config
(when (eq (spacemacs//python-backend) 'anaconda) (when (eq python-backend 'anaconda)
(spacemacs/set-leader-keys-for-major-mode 'cython-mode (spacemacs/set-leader-keys-for-major-mode 'cython-mode
"hh" 'anaconda-mode-show-doc "hh" 'anaconda-mode-show-doc
"gu" 'anaconda-mode-find-references)))) "gu" 'anaconda-mode-find-references))))
@ -243,13 +243,13 @@
:init :init
(progn (progn
(pcase python-auto-set-local-pyenv-version (pcase python-auto-set-local-pyenv-version
(`on-visit (`on-visit
(dolist (m spacemacs--python-pyenv-modes) (dolist (m spacemacs--python-pyenv-modes)
(add-hook (intern (format "%s-hook" m)) (add-hook (intern (format "%s-hook" m))
'spacemacs//pyenv-mode-set-local-version))) 'spacemacs//pyenv-mode-set-local-version)))
(`on-project-switch (`on-project-switch
(add-hook 'projectile-after-switch-project-hook (add-hook 'projectile-after-switch-project-hook
'spacemacs//pyenv-mode-set-local-version))) 'spacemacs//pyenv-mode-set-local-version)))
;; setup shell correctly on environment switch ;; setup shell correctly on environment switch
(dolist (func '(pyenv-mode-set pyenv-mode-unset)) (dolist (func '(pyenv-mode-set pyenv-mode-unset))
(advice-add func :after 'spacemacs/python-setup-everything)) (advice-add func :after 'spacemacs/python-setup-everything))
@ -295,7 +295,7 @@
(setq pylookup-dir (concat dir "pylookup/") (setq pylookup-dir (concat dir "pylookup/")
pylookup-program (concat pylookup-dir "pylookup.py") pylookup-program (concat pylookup-dir "pylookup.py")
pylookup-db-file (concat pylookup-dir "pylookup.db"))) pylookup-db-file (concat pylookup-dir "pylookup.db")))
(setq pylookup-completing-read 'completing-read)))) (setq pylookup-completing-read 'completing-read))))
(defun python/init-pytest () (defun python/init-pytest ()
(use-package pytest (use-package pytest
@ -381,8 +381,8 @@
(defun python/post-init-semantic () (defun python/post-init-semantic ()
(when (configuration-layer/package-used-p 'anaconda-mode) (when (configuration-layer/package-used-p 'anaconda-mode)
(add-hook 'python-mode-hook (add-hook 'python-mode-hook
'spacemacs//disable-semantic-idle-summary-mode t)) 'spacemacs//disable-semantic-idle-summary-mode t))
(spacemacs/add-to-hook 'python-mode-hook (spacemacs/add-to-hook 'python-mode-hook
'(semantic-mode '(semantic-mode
spacemacs//python-imenu-create-index-use-semantic-maybe)) spacemacs//python-imenu-create-index-use-semantic-maybe))