2015-01-14 04:12:56 +00:00
|
|
|
|
;;; funcs.el --- Python Layer functions File for Spacemacs
|
|
|
|
|
;;
|
2021-03-22 20:11:29 +00:00
|
|
|
|
;; Copyright (c) 2012-2021 Sylvain Benner & Contributors
|
2015-01-14 04:12:56 +00:00
|
|
|
|
;;
|
|
|
|
|
;; Author: Sylvain Benner <sylvain.benner@gmail.com>
|
|
|
|
|
;; URL: https://github.com/syl20bnr/spacemacs
|
|
|
|
|
;;
|
|
|
|
|
;; This file is not part of GNU Emacs.
|
|
|
|
|
;;
|
2021-03-24 03:31:44 +00:00
|
|
|
|
;; This program is free software; you can redistribute it and/or modify
|
|
|
|
|
;; it under the terms of the GNU General Public License as published by
|
|
|
|
|
;; the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
;; (at your option) any later version.
|
|
|
|
|
;;
|
|
|
|
|
;; This program is distributed in the hope that it will be useful,
|
|
|
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
;; GNU General Public License for more details.
|
|
|
|
|
;;
|
|
|
|
|
;; You should have received a copy of the GNU General Public License
|
|
|
|
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
2015-01-14 04:12:56 +00:00
|
|
|
|
|
2020-12-21 20:59:28 +00:00
|
|
|
|
(defun spacemacs//poetry-activate ()
|
|
|
|
|
"Attempt to activate Poetry only if its configuration file is found."
|
|
|
|
|
(let ((root-path (locate-dominating-file default-directory "pyproject.toml")))
|
|
|
|
|
(when root-path
|
|
|
|
|
(message "Poetry configuration file found. Activating virtual environment.")
|
|
|
|
|
(poetry-venv-workon))
|
|
|
|
|
))
|
|
|
|
|
|
2018-02-19 05:08:27 +00:00
|
|
|
|
(defun spacemacs//python-setup-backend ()
|
|
|
|
|
"Conditionally setup python backend."
|
2021-04-09 18:52:42 +00:00
|
|
|
|
(when python-pipenv-activate (pipenv-activate))
|
|
|
|
|
(when python-poetry-activate (spacemacs//poetry-activate))
|
2021-03-18 04:53:49 +00:00
|
|
|
|
(pcase python-backend
|
|
|
|
|
('anaconda (spacemacs//python-setup-anaconda))
|
|
|
|
|
('lsp (spacemacs//python-setup-lsp))))
|
2018-02-19 05:08:27 +00:00
|
|
|
|
|
|
|
|
|
(defun spacemacs//python-setup-company ()
|
|
|
|
|
"Conditionally setup company based on backend."
|
2021-03-18 04:53:49 +00:00
|
|
|
|
(when (eq python-backend 'anaconda)
|
|
|
|
|
(spacemacs//python-setup-anaconda-company)))
|
2018-02-19 05:08:27 +00:00
|
|
|
|
|
2019-09-30 01:30:53 +00:00
|
|
|
|
(defun spacemacs//python-setup-dap ()
|
|
|
|
|
"Conditionally setup elixir DAP integration."
|
|
|
|
|
;; currently DAP is only available using LSP
|
2021-03-18 04:53:49 +00:00
|
|
|
|
(when (eq python-backend 'lsp)
|
|
|
|
|
(spacemacs//python-setup-lsp-dap)))
|
2019-09-30 01:30:53 +00:00
|
|
|
|
|
2018-02-19 05:08:27 +00:00
|
|
|
|
(defun spacemacs//python-setup-eldoc ()
|
|
|
|
|
"Conditionally setup eldoc based on backend."
|
2021-03-18 04:53:49 +00:00
|
|
|
|
(when (eq python-backend 'anaconda)
|
2018-02-19 05:08:27 +00:00
|
|
|
|
;; lsp setup eldoc on its own
|
2021-03-18 04:53:49 +00:00
|
|
|
|
(spacemacs//python-setup-anaconda-eldoc)))
|
|
|
|
|
|
2018-02-19 05:08:27 +00:00
|
|
|
|
|
|
|
|
|
;; anaconda
|
|
|
|
|
|
|
|
|
|
(defun spacemacs//python-setup-anaconda ()
|
|
|
|
|
"Setup anaconda backend."
|
2018-07-06 17:22:51 +00:00
|
|
|
|
(anaconda-mode))
|
2018-02-19 05:08:27 +00:00
|
|
|
|
|
|
|
|
|
(defun spacemacs//python-setup-anaconda-company ()
|
|
|
|
|
"Setup anaconda auto-completion."
|
|
|
|
|
(spacemacs|add-company-backends
|
|
|
|
|
:backends company-anaconda
|
2018-05-13 16:39:52 +00:00
|
|
|
|
:modes python-mode
|
|
|
|
|
:append-hooks nil
|
2018-05-24 02:10:22 +00:00
|
|
|
|
:call-hooks t)
|
2018-02-19 05:08:27 +00:00
|
|
|
|
(company-mode))
|
|
|
|
|
|
|
|
|
|
(defun spacemacs//python-setup-anaconda-eldoc ()
|
|
|
|
|
"Setup anaconda eldoc."
|
|
|
|
|
(eldoc-mode)
|
|
|
|
|
(when (configuration-layer/package-used-p 'anaconda-mode)
|
|
|
|
|
(anaconda-eldoc-mode)))
|
|
|
|
|
|
|
|
|
|
(defun spacemacs/anaconda-view-forward-and-push ()
|
|
|
|
|
"Find next button and hit RET"
|
|
|
|
|
(interactive)
|
|
|
|
|
(forward-button 1)
|
|
|
|
|
(call-interactively #'push-button))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;; lsp
|
|
|
|
|
|
|
|
|
|
(defun spacemacs//python-setup-lsp ()
|
|
|
|
|
"Setup lsp backend."
|
|
|
|
|
(if (configuration-layer/layer-used-p 'lsp)
|
2019-08-04 12:24:28 +00:00
|
|
|
|
(progn
|
2021-03-18 04:53:49 +00:00
|
|
|
|
(require (pcase python-lsp-server
|
2021-05-13 22:30:32 +00:00
|
|
|
|
('pylsp 'lsp-pylsp)
|
2021-03-18 04:53:49 +00:00
|
|
|
|
('mspyls 'lsp-python-ms)
|
2021-04-04 18:50:10 +00:00
|
|
|
|
('pyright 'lsp-pyright)
|
|
|
|
|
(x (user-error "Unknown value for `python-lsp-server': %s" x))))
|
2021-06-06 20:25:00 +00:00
|
|
|
|
(lsp-deferred))
|
2019-09-30 01:30:53 +00:00
|
|
|
|
(message "`lsp' layer is not installed, please add `lsp' layer to your dotfile.")))
|
2018-02-19 05:08:27 +00:00
|
|
|
|
|
2019-09-30 01:30:53 +00:00
|
|
|
|
(defun spacemacs//python-setup-lsp-dap ()
|
|
|
|
|
"Setup DAP integration."
|
|
|
|
|
(require 'dap-python))
|
|
|
|
|
|
2018-02-19 05:08:27 +00:00
|
|
|
|
|
|
|
|
|
;; others
|
|
|
|
|
|
2017-08-28 14:41:12 +00:00
|
|
|
|
(defun spacemacs//python-default ()
|
|
|
|
|
"Defaut settings for python buffers"
|
|
|
|
|
(setq mode-name "Python"
|
2019-12-15 12:56:49 +00:00
|
|
|
|
tab-width python-tab-width
|
|
|
|
|
fill-column python-fill-column)
|
2018-08-25 12:29:51 +00:00
|
|
|
|
|
2018-08-25 17:44:13 +00:00
|
|
|
|
;; since we changed the tab-width we need to manually call python-indent-guess-indent-offset here
|
2018-08-25 12:29:51 +00:00
|
|
|
|
(when python-spacemacs-indent-guess
|
|
|
|
|
(python-indent-guess-indent-offset))
|
|
|
|
|
|
2017-08-28 14:41:12 +00:00
|
|
|
|
(setq-local comment-inline-offset 2)
|
|
|
|
|
(spacemacs/python-annotate-pdb)
|
|
|
|
|
;; make C-j work the same way as RET
|
|
|
|
|
(local-set-key (kbd "C-j") 'newline-and-indent))
|
|
|
|
|
|
2014-11-10 04:54:10 +00:00
|
|
|
|
;; from http://pedrokroger.net/2010/07/configuring-emacs-as-a-python-ide-2/
|
2016-06-06 01:53:14 +00:00
|
|
|
|
(defun spacemacs/python-annotate-pdb ()
|
2014-11-10 04:54:10 +00:00
|
|
|
|
"Highlight break point lines."
|
|
|
|
|
(interactive)
|
2018-10-20 09:05:46 +00:00
|
|
|
|
(highlight-lines-matching-regexp "breakpoint()")
|
2016-11-06 02:40:16 +00:00
|
|
|
|
(highlight-lines-matching-regexp "import \\(pdb\\|ipdb\\|pudb\\|wdb\\)")
|
2018-02-07 20:17:35 +00:00
|
|
|
|
(highlight-lines-matching-regexp "\\(pdb\\|ipdb\\|pudb\\|wdb\\).set_trace()")
|
|
|
|
|
(highlight-lines-matching-regexp "trepan.api.debug()"))
|
2014-11-10 04:54:10 +00:00
|
|
|
|
|
2016-07-18 19:40:40 +00:00
|
|
|
|
(defun spacemacs/pyenv-executable-find (command)
|
2017-08-02 16:11:03 +00:00
|
|
|
|
"Find executable taking pyenv shims into account.
|
|
|
|
|
If the executable is a system executable and not in the same path
|
|
|
|
|
as the pyenv version then also return nil. This works around https://github.com/pyenv/pyenv-which-ext
|
|
|
|
|
"
|
2016-07-18 19:40:40 +00:00
|
|
|
|
(if (executable-find "pyenv")
|
|
|
|
|
(progn
|
2017-08-02 16:11:03 +00:00
|
|
|
|
(let ((pyenv-string (shell-command-to-string (concat "pyenv which " command)))
|
2018-07-27 08:43:33 +00:00
|
|
|
|
(pyenv-version-names (split-string (string-trim (shell-command-to-string "pyenv version-name")) ":"))
|
|
|
|
|
(executable nil)
|
|
|
|
|
(i 0))
|
|
|
|
|
(if (not (string-match "not found" pyenv-string))
|
|
|
|
|
(while (and (not executable)
|
2018-08-03 04:17:31 +00:00
|
|
|
|
(< i (length pyenv-version-names)))
|
2018-07-27 08:43:33 +00:00
|
|
|
|
(if (string-match (elt pyenv-version-names i) (string-trim pyenv-string))
|
|
|
|
|
(setq executable (string-trim pyenv-string)))
|
2018-08-27 06:48:07 +00:00
|
|
|
|
(if (string-match (elt pyenv-version-names i) "system")
|
|
|
|
|
(setq executable (string-trim (executable-find command))))
|
2018-07-27 08:43:33 +00:00
|
|
|
|
(setq i (1+ i))))
|
|
|
|
|
executable))
|
2016-07-18 19:40:40 +00:00
|
|
|
|
(executable-find command)))
|
|
|
|
|
|
2017-06-07 10:35:52 +00:00
|
|
|
|
(defun spacemacs//python-setup-shell (&rest args)
|
2016-07-18 19:40:40 +00:00
|
|
|
|
(if (spacemacs/pyenv-executable-find "ipython")
|
|
|
|
|
(progn (setq python-shell-interpreter "ipython")
|
2021-03-10 05:45:41 +00:00
|
|
|
|
(if (version< (replace-regexp-in-string "\\(\\.dev\\)?[\r\n|\n]$" "" (shell-command-to-string (format "\"%s\" --version" (string-trim (spacemacs/pyenv-executable-find "ipython"))))) "5")
|
2016-07-18 19:40:40 +00:00
|
|
|
|
(setq python-shell-interpreter-args "-i")
|
|
|
|
|
(setq python-shell-interpreter-args "--simple-prompt -i")))
|
|
|
|
|
(progn
|
|
|
|
|
(setq python-shell-interpreter-args "-i")
|
|
|
|
|
(setq python-shell-interpreter "python"))))
|
|
|
|
|
|
2017-06-07 10:35:52 +00:00
|
|
|
|
|
|
|
|
|
(defun spacemacs//python-setup-checkers (&rest args)
|
|
|
|
|
(when (fboundp 'flycheck-set-checker-executable)
|
|
|
|
|
(let ((pylint (spacemacs/pyenv-executable-find "pylint"))
|
|
|
|
|
(flake8 (spacemacs/pyenv-executable-find "flake8")))
|
|
|
|
|
(when pylint
|
|
|
|
|
(flycheck-set-checker-executable "python-pylint" pylint))
|
|
|
|
|
(when flake8
|
|
|
|
|
(flycheck-set-checker-executable "python-flake8" flake8)))))
|
|
|
|
|
|
|
|
|
|
(defun spacemacs/python-setup-everything (&rest args)
|
|
|
|
|
(apply 'spacemacs//python-setup-shell args)
|
|
|
|
|
(apply 'spacemacs//python-setup-checkers args))
|
2016-11-06 03:14:30 +00:00
|
|
|
|
|
2016-06-06 01:53:14 +00:00
|
|
|
|
(defun spacemacs/python-toggle-breakpoint ()
|
2014-11-10 04:54:10 +00:00
|
|
|
|
"Add a break point, highlight it."
|
|
|
|
|
(interactive)
|
2018-02-07 20:17:35 +00:00
|
|
|
|
(let ((trace (cond ((spacemacs/pyenv-executable-find "trepan3k") "import trepan.api; trepan.api.debug()")
|
|
|
|
|
((spacemacs/pyenv-executable-find "wdb") "import wdb; wdb.set_trace()")
|
2016-10-16 23:37:22 +00:00
|
|
|
|
((spacemacs/pyenv-executable-find "ipdb") "import ipdb; ipdb.set_trace()")
|
2016-07-25 21:27:15 +00:00
|
|
|
|
((spacemacs/pyenv-executable-find "pudb") "import pudb; pudb.set_trace()")
|
2016-10-20 08:03:18 +00:00
|
|
|
|
((spacemacs/pyenv-executable-find "ipdb3") "import ipdb; ipdb.set_trace()")
|
|
|
|
|
((spacemacs/pyenv-executable-find "pudb3") "import pudb; pudb.set_trace()")
|
2018-10-20 09:05:46 +00:00
|
|
|
|
((spacemacs/pyenv-executable-find "python3.7") "breakpoint()")
|
|
|
|
|
((spacemacs/pyenv-executable-find "python3.8") "breakpoint()")
|
2021-07-30 10:05:58 +00:00
|
|
|
|
((spacemacs/pyenv-executable-find "python3.9") "breakpoint()")
|
|
|
|
|
((spacemacs/pyenv-executable-find "python3.10") "breakpoint()")
|
|
|
|
|
((spacemacs/pyenv-executable-find "python3.11") "breakpoint()")
|
2015-05-02 22:54:22 +00:00
|
|
|
|
(t "import pdb; pdb.set_trace()")))
|
2014-11-10 04:54:10 +00:00
|
|
|
|
(line (thing-at-point 'line)))
|
|
|
|
|
(if (and line (string-match trace line))
|
|
|
|
|
(kill-whole-line)
|
|
|
|
|
(progn
|
|
|
|
|
(back-to-indentation)
|
2016-11-07 10:36:26 +00:00
|
|
|
|
(insert trace)
|
|
|
|
|
(insert "\n")
|
2014-11-10 04:54:10 +00:00
|
|
|
|
(python-indent-line)))))
|
2015-04-24 05:12:30 +00:00
|
|
|
|
|
|
|
|
|
;; from https://www.snip2code.com/Snippet/127022/Emacs-auto-remove-unused-import-statemen
|
2021-02-10 07:51:55 +00:00
|
|
|
|
(defun spacemacs/python-remove-unused-imports ()
|
2015-04-24 05:12:30 +00:00
|
|
|
|
"Use Autoflake to remove unused function"
|
|
|
|
|
"autoflake --remove-all-unused-imports -i unused_imports.py"
|
|
|
|
|
(interactive)
|
2015-04-25 02:15:02 +00:00
|
|
|
|
(if (executable-find "autoflake")
|
2019-12-15 12:56:49 +00:00
|
|
|
|
(progn
|
|
|
|
|
(shell-command (format "autoflake --remove-all-unused-imports -i %s"
|
|
|
|
|
(shell-quote-argument (buffer-file-name))))
|
|
|
|
|
(revert-buffer t t t))
|
2015-04-25 02:15:02 +00:00
|
|
|
|
(message "Error: Cannot find autoflake executable.")))
|
2015-12-07 12:58:36 +00:00
|
|
|
|
|
2016-06-06 01:53:14 +00:00
|
|
|
|
(defun spacemacs//pyenv-mode-set-local-version ()
|
2016-01-25 23:00:19 +00:00
|
|
|
|
"Set pyenv version from \".python-version\" by looking in parent directories."
|
2015-12-07 12:58:36 +00:00
|
|
|
|
(interactive)
|
2015-12-20 03:33:24 +00:00
|
|
|
|
(let ((root-path (locate-dominating-file default-directory
|
|
|
|
|
".python-version")))
|
2016-01-25 23:00:19 +00:00
|
|
|
|
(when root-path
|
2015-12-20 03:33:24 +00:00
|
|
|
|
(let* ((file-path (expand-file-name ".python-version" root-path))
|
2016-06-06 01:53:14 +00:00
|
|
|
|
(version
|
|
|
|
|
(with-temp-buffer
|
|
|
|
|
(insert-file-contents-literally file-path)
|
2017-01-27 09:06:47 +00:00
|
|
|
|
(nth 0 (split-string (buffer-substring-no-properties
|
2019-12-15 12:56:49 +00:00
|
|
|
|
(line-beginning-position)
|
|
|
|
|
(line-end-position)))))))
|
2015-12-20 03:33:24 +00:00
|
|
|
|
(if (member version (pyenv-mode-versions))
|
2019-12-02 01:04:34 +00:00
|
|
|
|
(progn
|
|
|
|
|
(setenv "VIRTUAL_ENV" version)
|
|
|
|
|
(pyenv-mode-set version))
|
2015-12-20 03:33:24 +00:00
|
|
|
|
(message "pyenv: version `%s' is not installed (set by %s)"
|
2016-01-25 23:00:19 +00:00
|
|
|
|
version file-path))))))
|
2016-04-13 02:38:48 +00:00
|
|
|
|
|
2016-10-25 17:25:57 +00:00
|
|
|
|
(defun spacemacs//pyvenv-mode-set-local-virtualenv ()
|
2019-10-20 20:16:39 +00:00
|
|
|
|
"Set pyvenv virtualenv from \".venv\" by looking in parent directories.
|
|
|
|
|
Handle \".venv\" being a virtualenv directory or a file specifying either
|
|
|
|
|
absolute or relative virtualenv path. Relative path is checked relative to
|
|
|
|
|
location of \".venv\" file, then relative to pyvenv-workon-home()."
|
2016-10-25 17:25:57 +00:00
|
|
|
|
(interactive)
|
2019-10-20 20:16:39 +00:00
|
|
|
|
(let ((root-path (locate-dominating-file default-directory ".venv")))
|
2016-10-25 17:25:57 +00:00
|
|
|
|
(when root-path
|
2019-10-20 20:16:39 +00:00
|
|
|
|
(let ((file-path (expand-file-name ".venv" root-path)))
|
2020-09-07 15:19:14 +00:00
|
|
|
|
(cond ((file-directory-p file-path)
|
|
|
|
|
(pyvenv-activate file-path) (setq-local pyvenv-activate file-path))
|
|
|
|
|
(t (let* ((virtualenv-path-in-file
|
|
|
|
|
(with-temp-buffer
|
|
|
|
|
(insert-file-contents-literally file-path)
|
|
|
|
|
(buffer-substring-no-properties (line-beginning-position)
|
|
|
|
|
(line-end-position))))
|
|
|
|
|
(virtualenv-abs-path
|
|
|
|
|
(if (file-name-absolute-p virtualenv-path-in-file)
|
|
|
|
|
virtualenv-path-in-file
|
|
|
|
|
(format "%s/%s" root-path virtualenv-path-in-file))))
|
|
|
|
|
(cond ((file-directory-p virtualenv-abs-path)
|
|
|
|
|
(pyvenv-activate virtualenv-abs-path)
|
|
|
|
|
(setq-local pyvenv-activate virtualenv-abs-path))
|
|
|
|
|
(t (pyvenv-workon virtualenv-path-in-file)
|
|
|
|
|
(setq-local pyvenv-workon virtualenv-path-in-file))))))))))
|
2016-06-06 01:53:14 +00:00
|
|
|
|
|
|
|
|
|
;; Tests
|
|
|
|
|
|
2016-10-15 08:34:11 +00:00
|
|
|
|
(defun spacemacs//python-imenu-create-index-use-semantic-maybe ()
|
2016-04-16 02:08:35 +00:00
|
|
|
|
"Use semantic if the layer is enabled."
|
2016-10-15 08:34:11 +00:00
|
|
|
|
(setq imenu-create-index-function 'spacemacs/python-imenu-create-index))
|
|
|
|
|
|
|
|
|
|
;; fix for issue #2569 (https://github.com/syl20bnr/spacemacs/issues/2569) and
|
|
|
|
|
;; Emacs 24.5 and older. use `semantic-create-imenu-index' only when
|
|
|
|
|
;; `semantic-mode' is enabled, otherwise use `python-imenu-create-index'
|
|
|
|
|
(defun spacemacs/python-imenu-create-index ()
|
|
|
|
|
(if (bound-and-true-p semantic-mode)
|
|
|
|
|
(semantic-create-imenu-index)
|
|
|
|
|
(python-imenu-create-index)))
|
2016-04-13 21:50:53 +00:00
|
|
|
|
|
2016-06-06 01:53:14 +00:00
|
|
|
|
(defun spacemacs//python-get-main-testrunner ()
|
2016-04-13 21:50:53 +00:00
|
|
|
|
"Get the main test runner."
|
|
|
|
|
(if (listp python-test-runner) (car python-test-runner) python-test-runner))
|
|
|
|
|
|
2016-06-06 01:53:14 +00:00
|
|
|
|
(defun spacemacs//python-get-secondary-testrunner ()
|
2016-04-13 21:50:53 +00:00
|
|
|
|
"Get the secondary test runner"
|
2016-06-06 01:53:14 +00:00
|
|
|
|
(cdr (assoc (spacemacs//python-get-main-testrunner) '((pytest . nose)
|
2019-12-15 12:56:49 +00:00
|
|
|
|
(nose . pytest)))))
|
2016-04-13 21:50:53 +00:00
|
|
|
|
|
2016-06-06 01:53:14 +00:00
|
|
|
|
(defun spacemacs//python-call-correct-test-function (arg funcalist)
|
2016-04-13 21:50:53 +00:00
|
|
|
|
"Call a test function based on the chosen test framework.
|
|
|
|
|
ARG is the universal-argument which chooses between the main and
|
|
|
|
|
the secondary test runner. FUNCALIST is an alist of the function
|
|
|
|
|
to be called for each testrunner. "
|
2017-12-22 10:16:38 +00:00
|
|
|
|
(when python-save-before-test
|
2019-12-15 12:56:49 +00:00
|
|
|
|
(save-buffer))
|
2016-10-20 11:18:05 +00:00
|
|
|
|
(let* ((test-runner (if arg
|
|
|
|
|
(spacemacs//python-get-secondary-testrunner)
|
|
|
|
|
(spacemacs//python-get-main-testrunner)))
|
|
|
|
|
(test-function (assq test-runner funcalist)))
|
|
|
|
|
(if test-function
|
|
|
|
|
(funcall (cdr (assoc test-runner funcalist)))
|
|
|
|
|
(user-error "This test function is not available with the `%S' runner."
|
|
|
|
|
test-runner))))
|
2016-04-13 21:50:53 +00:00
|
|
|
|
|
2018-01-30 11:15:55 +00:00
|
|
|
|
(defun spacemacs/python-test-last (arg)
|
|
|
|
|
"Re-run the last test command"
|
|
|
|
|
(interactive "P")
|
2020-04-16 21:37:25 +00:00
|
|
|
|
(spacemacs//python-call-correct-test-function arg '((pytest . pytest-again)
|
|
|
|
|
(nose . nosetests-again))))
|
2018-01-30 11:15:55 +00:00
|
|
|
|
|
2019-11-08 15:54:41 +00:00
|
|
|
|
(defun spacemacs/python-test-last-failed (arg)
|
|
|
|
|
"Re-run the tests that last failed."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(spacemacs//python-call-correct-test-function arg '((pytest . pytest-last-failed))))
|
|
|
|
|
|
|
|
|
|
(defun spacemacs/python-test-pdb-last-failed (arg)
|
|
|
|
|
"Re-run the tests that last failed in debug mode."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(spacemacs//python-call-correct-test-function arg '((pytest . pytest-pdb-last-failed))))
|
|
|
|
|
|
2016-06-06 01:53:14 +00:00
|
|
|
|
(defun spacemacs/python-test-all (arg)
|
2016-04-13 21:50:53 +00:00
|
|
|
|
"Run all tests."
|
|
|
|
|
(interactive "P")
|
2016-06-06 01:53:14 +00:00
|
|
|
|
(spacemacs//python-call-correct-test-function arg '((pytest . pytest-all)
|
2019-12-15 12:56:49 +00:00
|
|
|
|
(nose . nosetests-all))))
|
2016-04-13 21:50:53 +00:00
|
|
|
|
|
2016-06-06 01:53:14 +00:00
|
|
|
|
(defun spacemacs/python-test-pdb-all (arg)
|
2016-04-13 21:50:53 +00:00
|
|
|
|
"Run all tests in debug mode."
|
|
|
|
|
(interactive "P")
|
2016-06-06 01:53:14 +00:00
|
|
|
|
(spacemacs//python-call-correct-test-function arg '((pytest . pytest-pdb-all)
|
2019-12-15 12:56:49 +00:00
|
|
|
|
(nose . nosetests-pdb-all))))
|
2016-04-13 21:50:53 +00:00
|
|
|
|
|
2016-06-06 01:53:14 +00:00
|
|
|
|
(defun spacemacs/python-test-module (arg)
|
2016-04-13 21:50:53 +00:00
|
|
|
|
"Run all tests in the current module."
|
|
|
|
|
(interactive "P")
|
2016-06-06 01:53:14 +00:00
|
|
|
|
(spacemacs//python-call-correct-test-function arg '((pytest . pytest-module)
|
2019-12-15 12:56:49 +00:00
|
|
|
|
(nose . nosetests-module))))
|
2016-04-13 21:50:53 +00:00
|
|
|
|
|
2016-06-06 01:53:14 +00:00
|
|
|
|
(defun spacemacs/python-test-pdb-module (arg)
|
2016-04-13 21:50:53 +00:00
|
|
|
|
"Run all tests in the current module in debug mode."
|
|
|
|
|
(interactive "P")
|
2016-06-06 01:53:14 +00:00
|
|
|
|
(spacemacs//python-call-correct-test-function
|
|
|
|
|
arg
|
|
|
|
|
'((pytest . pytest-pdb-module)
|
|
|
|
|
(nose . nosetests-pdb-module))))
|
2016-04-13 21:50:53 +00:00
|
|
|
|
|
2016-10-20 11:18:05 +00:00
|
|
|
|
(defun spacemacs/python-test-suite (arg)
|
|
|
|
|
"Run all tests in the current suite."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(spacemacs//python-call-correct-test-function arg '((nose . nosetests-suite))))
|
|
|
|
|
|
|
|
|
|
(defun spacemacs/python-test-pdb-suite (arg)
|
|
|
|
|
"Run all tests in the current suite in debug mode."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(spacemacs//python-call-correct-test-function arg '((nose . nosetests-pdb-suite))))
|
|
|
|
|
|
2016-06-06 01:53:14 +00:00
|
|
|
|
(defun spacemacs/python-test-one (arg)
|
2016-04-13 21:50:53 +00:00
|
|
|
|
"Run current test."
|
|
|
|
|
(interactive "P")
|
2016-06-06 01:53:14 +00:00
|
|
|
|
(spacemacs//python-call-correct-test-function arg '((pytest . pytest-one)
|
2019-12-15 12:56:49 +00:00
|
|
|
|
(nose . nosetests-one))))
|
2016-04-13 21:50:53 +00:00
|
|
|
|
|
2016-06-06 01:53:14 +00:00
|
|
|
|
(defun spacemacs/python-test-pdb-one (arg)
|
2016-04-13 21:50:53 +00:00
|
|
|
|
"Run current test in debug mode."
|
|
|
|
|
(interactive "P")
|
2016-06-06 01:53:14 +00:00
|
|
|
|
(spacemacs//python-call-correct-test-function arg '((pytest . pytest-pdb-one)
|
2019-12-15 12:56:49 +00:00
|
|
|
|
(nose . nosetests-pdb-one))))
|
2016-04-13 21:50:53 +00:00
|
|
|
|
|
|
|
|
|
(defun spacemacs//bind-python-testing-keys ()
|
|
|
|
|
"Bind the keys for testing in Python."
|
2016-06-06 01:53:14 +00:00
|
|
|
|
(spacemacs/declare-prefix-for-mode 'python-mode "mt" "test")
|
2016-04-13 21:50:53 +00:00
|
|
|
|
(spacemacs/set-leader-keys-for-major-mode 'python-mode
|
2016-06-06 01:53:14 +00:00
|
|
|
|
"tA" 'spacemacs/python-test-pdb-all
|
|
|
|
|
"ta" 'spacemacs/python-test-all
|
|
|
|
|
"tB" 'spacemacs/python-test-pdb-module
|
|
|
|
|
"tb" 'spacemacs/python-test-module
|
2018-01-30 11:15:55 +00:00
|
|
|
|
"tl" 'spacemacs/python-test-last
|
2019-11-08 15:54:41 +00:00
|
|
|
|
"tf" 'spacemacs/python-test-last-failed
|
|
|
|
|
"tF" 'spacemacs/python-test-pdb-last-failed
|
2016-06-06 01:53:14 +00:00
|
|
|
|
"tT" 'spacemacs/python-test-pdb-one
|
|
|
|
|
"tt" 'spacemacs/python-test-one
|
|
|
|
|
"tM" 'spacemacs/python-test-pdb-module
|
2016-10-20 11:18:05 +00:00
|
|
|
|
"tm" 'spacemacs/python-test-module
|
|
|
|
|
"tS" 'spacemacs/python-test-pdb-suite
|
|
|
|
|
"ts" 'spacemacs/python-test-suite))
|
2016-08-21 15:49:20 +00:00
|
|
|
|
|
|
|
|
|
(defun spacemacs//python-sort-imports ()
|
|
|
|
|
;; py-isort-before-save checks the major mode as well, however we can prevent
|
|
|
|
|
;; it from loading the package unnecessarily by doing our own check
|
|
|
|
|
(when (and python-sort-imports-on-save
|
|
|
|
|
(derived-mode-p 'python-mode))
|
|
|
|
|
(py-isort-before-save)))
|
2016-11-28 11:08:20 +00:00
|
|
|
|
|
2018-12-30 17:30:40 +00:00
|
|
|
|
|
|
|
|
|
;; Formatters
|
|
|
|
|
|
|
|
|
|
(defun spacemacs//bind-python-formatter-keys ()
|
2019-08-31 20:55:34 +00:00
|
|
|
|
"Bind the python formatter keys.
|
2019-08-31 21:21:03 +00:00
|
|
|
|
Bind formatter to '==' for LSP and '='for all other backends."
|
2018-12-30 17:30:40 +00:00
|
|
|
|
(spacemacs/set-leader-keys-for-major-mode 'python-mode
|
2021-03-18 04:53:49 +00:00
|
|
|
|
(if (eq python-backend 'lsp)
|
2019-08-31 20:55:34 +00:00
|
|
|
|
"=="
|
2021-03-18 04:53:49 +00:00
|
|
|
|
"=")
|
|
|
|
|
'spacemacs/python-format-buffer))
|
2018-12-30 17:30:40 +00:00
|
|
|
|
|
|
|
|
|
(defun spacemacs/python-format-buffer ()
|
2019-08-31 21:21:03 +00:00
|
|
|
|
"Bind possible python formatters."
|
2018-12-30 17:30:40 +00:00
|
|
|
|
(interactive)
|
2021-03-18 04:53:49 +00:00
|
|
|
|
(pcase python-formatter
|
|
|
|
|
('yapf (yapfify-buffer))
|
|
|
|
|
('black (blacken-buffer))
|
|
|
|
|
('lsp (lsp-format-buffer))
|
2018-12-30 17:30:40 +00:00
|
|
|
|
(code (message "Unknown formatter: %S" code))))
|
|
|
|
|
|
2017-08-28 14:41:12 +00:00
|
|
|
|
|
|
|
|
|
;; REPL
|
|
|
|
|
|
|
|
|
|
(defun spacemacs/python-shell-send-buffer-switch ()
|
|
|
|
|
"Send buffer content to shell and switch to it in insert mode."
|
|
|
|
|
(interactive)
|
2019-04-13 07:31:08 +00:00
|
|
|
|
(let ((python-mode-hook nil))
|
|
|
|
|
(python-shell-send-buffer)
|
|
|
|
|
(python-shell-switch-to-shell)
|
|
|
|
|
(evil-insert-state)))
|
|
|
|
|
|
|
|
|
|
(defun spacemacs/python-shell-send-buffer ()
|
|
|
|
|
"Send buffer content to shell and switch to it in insert mode."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((python-mode-hook nil))
|
|
|
|
|
(python-shell-send-buffer)))
|
2017-08-28 14:41:12 +00:00
|
|
|
|
|
|
|
|
|
(defun spacemacs/python-shell-send-defun-switch ()
|
|
|
|
|
"Send function content to shell and switch to it in insert mode."
|
|
|
|
|
(interactive)
|
2019-04-13 07:31:08 +00:00
|
|
|
|
(let ((python-mode-hook nil))
|
|
|
|
|
(python-shell-send-defun nil)
|
|
|
|
|
(python-shell-switch-to-shell)
|
|
|
|
|
(evil-insert-state)))
|
|
|
|
|
|
|
|
|
|
(defun spacemacs/python-shell-send-defun ()
|
|
|
|
|
"Send function content to shell and switch to it in insert mode."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((python-mode-hook nil))
|
|
|
|
|
(python-shell-send-defun nil)))
|
2017-08-28 14:41:12 +00:00
|
|
|
|
|
|
|
|
|
(defun spacemacs/python-shell-send-region-switch (start end)
|
|
|
|
|
"Send region content to shell and switch to it in insert mode."
|
|
|
|
|
(interactive "r")
|
2019-04-13 07:31:08 +00:00
|
|
|
|
(let ((python-mode-hook nil))
|
|
|
|
|
(python-shell-send-region start end)
|
|
|
|
|
(python-shell-switch-to-shell)
|
|
|
|
|
(evil-insert-state)))
|
|
|
|
|
|
|
|
|
|
(defun spacemacs/python-shell-send-region (start end)
|
|
|
|
|
"Send region content to shell and switch to it in insert mode."
|
|
|
|
|
(interactive "r")
|
|
|
|
|
(let ((python-mode-hook nil))
|
|
|
|
|
(python-shell-send-region start end)))
|
2017-08-28 14:41:12 +00:00
|
|
|
|
|
2020-09-14 16:32:23 +00:00
|
|
|
|
(defun spacemacs/python-shell-send-line ()
|
2021-06-06 20:25:00 +00:00
|
|
|
|
"Send the current line to shell"
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((python-mode-hook nil)
|
|
|
|
|
(start (point-at-bol))
|
|
|
|
|
(end (point-at-eol)))
|
|
|
|
|
(python-shell-send-region start end)))
|
2020-09-18 19:15:53 +00:00
|
|
|
|
|
|
|
|
|
(defun spacemacs/python-shell-send-statement ()
|
2021-06-06 20:25:00 +00:00
|
|
|
|
"Send the current statement to shell, same as `python-shell-send-statement' in Emacs27."
|
|
|
|
|
(interactive)
|
2020-09-18 19:15:53 +00:00
|
|
|
|
(if (fboundp 'python-shell-send-statement)
|
|
|
|
|
(call-interactively #'python-shell-send-statement)
|
|
|
|
|
(if (region-active-p)
|
|
|
|
|
(call-interactively #'python-shell-send-region)
|
|
|
|
|
(let ((python-mode-hook nil))
|
2021-06-06 20:25:00 +00:00
|
|
|
|
(python-shell-send-region
|
2020-09-18 19:15:53 +00:00
|
|
|
|
(save-excursion (python-nav-beginning-of-statement))
|
|
|
|
|
(save-excursion (python-nav-end-of-statement)))))))
|
|
|
|
|
|
|
|
|
|
(defun spacemacs/python-shell-send-statement-switch ()
|
|
|
|
|
"Send statement to shell and switch to it in insert mode."
|
|
|
|
|
(interactive)
|
|
|
|
|
(call-interactively #'spacemacs/python-shell-send-statement)
|
|
|
|
|
(python-shell-switch-to-shell)
|
|
|
|
|
(evil-insert-state))
|
2020-09-14 16:32:23 +00:00
|
|
|
|
|
2017-08-28 14:41:12 +00:00
|
|
|
|
(defun spacemacs/python-start-or-switch-repl ()
|
|
|
|
|
"Start and/or switch to the REPL."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((shell-process
|
|
|
|
|
(or (python-shell-get-process)
|
|
|
|
|
;; `run-python' has different return values and different
|
|
|
|
|
;; errors in different emacs versions. In 24.4, it throws an
|
|
|
|
|
;; error when the process didn't start, but in 25.1 it
|
|
|
|
|
;; doesn't throw an error, so we demote errors here and
|
|
|
|
|
;; check the process later
|
|
|
|
|
(with-demoted-errors "Error: %S"
|
|
|
|
|
;; in Emacs 24.5 and 24.4, `run-python' doesn't return the
|
|
|
|
|
;; shell process
|
|
|
|
|
(call-interactively #'run-python)
|
|
|
|
|
(python-shell-get-process)))))
|
|
|
|
|
(unless shell-process
|
|
|
|
|
(error "Failed to start python shell properly"))
|
|
|
|
|
(pop-to-buffer (process-buffer shell-process))
|
|
|
|
|
(evil-insert-state)))
|
|
|
|
|
|
|
|
|
|
(defun spacemacs/python-execute-file (arg)
|
|
|
|
|
"Execute a python script in a shell."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
;; set compile command to buffer-file-name
|
|
|
|
|
;; universal argument put compile buffer in comint mode
|
|
|
|
|
(let ((universal-argument t)
|
|
|
|
|
(compile-command (format "%s %s"
|
|
|
|
|
(spacemacs/pyenv-executable-find python-shell-interpreter)
|
2018-07-28 00:12:17 +00:00
|
|
|
|
(shell-quote-argument (file-name-nondirectory buffer-file-name)))))
|
2017-08-28 14:41:12 +00:00
|
|
|
|
(if arg
|
|
|
|
|
(call-interactively 'compile)
|
|
|
|
|
(compile compile-command t)
|
|
|
|
|
(with-current-buffer (get-buffer "*compilation*")
|
|
|
|
|
(inferior-python-mode)))))
|
|
|
|
|
|
|
|
|
|
(defun spacemacs/python-execute-file-focus (arg)
|
|
|
|
|
"Execute a python script in a shell and switch to the shell buffer in
|
|
|
|
|
`insert state'."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(spacemacs/python-execute-file arg)
|
|
|
|
|
(switch-to-buffer-other-window "*compilation*")
|
|
|
|
|
(end-of-buffer)
|
|
|
|
|
(evil-insert-state))
|
|
|
|
|
|
2019-09-21 11:48:24 +00:00
|
|
|
|
(defun spacemacs//bind-python-repl-keys ()
|
|
|
|
|
"Bind the keys for testing in Python."
|
|
|
|
|
(spacemacs/declare-prefix-for-mode 'inferior-python-mode "mv" "virtualenv")
|
|
|
|
|
(spacemacs/set-leader-keys-for-major-mode 'inferior-python-mode
|
|
|
|
|
"c" 'comint-clear-buffer
|
|
|
|
|
"r" 'pyvenv-restart-python
|
|
|
|
|
"vw" 'pyvenv-workon))
|