Klimi's new dotfiles with stow.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4223 lines
159 KiB

4 years ago
  1. ;;; elpy.el --- Emacs Python Development Environment -*- lexical-binding: t -*-
  2. ;; Copyright (C) 2012-2016 Jorgen Schaefer
  3. ;; Author: Jorgen Schaefer <contact@jorgenschaefer.de>
  4. ;; URL: https://github.com/jorgenschaefer/elpy
  5. ;; Version: 1.30.0
  6. ;; Keywords: Python, IDE, Languages, Tools
  7. ;; Package-Requires: ((company "0.9.2") (emacs "24.4") (find-file-in-project "3.3") (highlight-indentation "0.5.0") (pyvenv "1.3") (yasnippet "0.8.0") (s "1.12.0"))
  8. ;; This program is free software; you can redistribute it and/or
  9. ;; modify it under the terms of the GNU General Public License
  10. ;; as published by the Free Software Foundation; either version 3
  11. ;; of the License, or (at your option) any later version.
  12. ;; This program is distributed in the hope that it will be useful,
  13. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. ;; GNU General Public License for more details.
  16. ;; You should have received a copy of the GNU General Public License
  17. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. ;;; Commentary:
  19. ;; The Emacs Lisp Python Environment in Emacs
  20. ;; Elpy is an Emacs package to bring powerful Python editing to Emacs.
  21. ;; It combines a number of existing Emacs packages, both written in
  22. ;; Emacs Lisp as well as Python.
  23. ;; For more information, read the Elpy manual:
  24. ;; https://elpy.readthedocs.io/en/latest/index.html
  25. ;;; Code:
  26. (require 'cus-edit)
  27. (require 'etags)
  28. (require 'files-x)
  29. (require 'grep)
  30. (require 'ido)
  31. (require 'json)
  32. (require 'python)
  33. (require 'subr-x)
  34. (require 'xref nil t)
  35. (require 'cl-lib) ; for `cl-every', `cl-copy-list', `cl-delete-if-not'
  36. (require 'elpy-refactor)
  37. (require 'elpy-django)
  38. (require 'elpy-profile)
  39. (require 'elpy-shell)
  40. (require 'pyvenv)
  41. (require 'find-file-in-project)
  42. (defconst elpy-version "1.30.0"
  43. "The version of the Elpy lisp code.")
  44. ;;;;;;;;;;;;;;;;;;;;;;
  45. ;;; User customization
  46. (defgroup elpy nil
  47. "The Emacs Lisp Python Environment."
  48. :prefix "elpy-"
  49. :group 'languages)
  50. (defcustom elpy-mode-hook nil
  51. "Hook run when `elpy-mode' is enabled.
  52. This can be used to enable minor modes for Python development."
  53. :type 'hook
  54. :options '(subword-mode hl-line-mode)
  55. :group 'elpy)
  56. (defcustom elpy-modules '(elpy-module-sane-defaults
  57. elpy-module-company
  58. elpy-module-eldoc
  59. elpy-module-flymake
  60. elpy-module-highlight-indentation
  61. elpy-module-pyvenv
  62. elpy-module-yasnippet
  63. elpy-module-django)
  64. "Which Elpy modules to use.
  65. Elpy can use a number of modules for additional features, which
  66. can be inidividually enabled or disabled."
  67. :type '(set (const :tag "Inline code completion (company-mode)"
  68. elpy-module-company)
  69. (const :tag "Show function signatures (ElDoc)"
  70. elpy-module-eldoc)
  71. (const :tag "Highlight syntax errors (Flymake)"
  72. elpy-module-flymake)
  73. (const :tag "Show the virtualenv in the mode line (pyvenv)"
  74. elpy-module-pyvenv)
  75. (const :tag "Display indentation markers (highlight-indentation)"
  76. elpy-module-highlight-indentation)
  77. (const :tag "Expand code snippets (YASnippet)"
  78. elpy-module-yasnippet)
  79. (const :tag "Django configurations (Elpy-Django)"
  80. elpy-module-django)
  81. (const :tag "Automatically update documentation (Autodoc)."
  82. elpy-module-autodoc)
  83. (const :tag "Configure some sane defaults for Emacs"
  84. elpy-module-sane-defaults))
  85. :group 'elpy)
  86. (defcustom elpy-project-ignored-directories
  87. '(".tox" "build" "dist" ".cask" ".ipynb_checkpoints")
  88. "Directories ignored by functions working on the whole project.
  89. This is in addition to `vc-directory-exclusion-list'
  90. and `grep-find-ignored-directories', as appropriate."
  91. :type '(repeat string)
  92. :safe (lambda (val)
  93. (cl-every #'stringp val))
  94. :group 'elpy)
  95. (defun elpy-project-ignored-directories ()
  96. "Compute the list of ignored directories for project.
  97. Combines
  98. `elpy-project-ignored-directories'
  99. `vc-directory-exclusion-list'
  100. `grep-find-ignored-directories'"
  101. (delete-dups
  102. (append elpy-project-ignored-directories
  103. vc-directory-exclusion-list
  104. (if (fboundp 'rgrep-find-ignored-directories)
  105. (rgrep-find-ignored-directories (elpy-project-root))
  106. (cl-delete-if-not #'stringp (cl-copy-list
  107. grep-find-ignored-directories))))))
  108. (defcustom elpy-project-root nil
  109. "The root of the project the current buffer is in.
  110. There is normally no use in setting this variable directly, as
  111. Elpy tries to detect the project root automatically. See
  112. `elpy-project-root-finder-functions' for a way of influencing
  113. this.
  114. Setting this variable globally will override Elpy's automatic
  115. project detection facilities entirely.
  116. Alternatively, you can set this in file- or directory-local
  117. variables using \\[add-file-local-variable] or
  118. \\[add-dir-local-variable].
  119. Do not use this variable in Emacs Lisp programs. Instead, call
  120. the `elpy-project-root' function. It will do the right thing."
  121. :type 'directory
  122. :safe 'file-directory-p
  123. :group 'elpy)
  124. (make-variable-buffer-local 'elpy-project-root)
  125. (defcustom elpy-project-root-finder-functions
  126. '(elpy-project-find-projectile-root
  127. elpy-project-find-python-root
  128. elpy-project-find-git-root
  129. elpy-project-find-hg-root
  130. elpy-project-find-svn-root)
  131. "List of functions to ask for the current project root.
  132. These will be checked in turn. The first directory found is used."
  133. :type '(set (const :tag "Projectile project root"
  134. elpy-project-find-projectile-root)
  135. (const :tag "Python project (setup.py, setup.cfg)"
  136. elpy-project-find-python-root)
  137. (const :tag "Git repository root (.git)"
  138. elpy-project-find-git-root)
  139. (const :tag "Mercurial project root (.hg)"
  140. elpy-project-find-hg-root)
  141. (const :tag "Subversion project root (.svn)"
  142. elpy-project-find-svn-root))
  143. :group 'elpy)
  144. (make-obsolete-variable 'elpy-company-hide-modeline
  145. 'elpy-remove-modeline-lighter
  146. "1.10.0")
  147. (defcustom elpy-remove-modeline-lighter t
  148. "Non-nil if Elpy should remove most mode line display.
  149. Modeline shows many minor modes currently active. For Elpy, this is mostly
  150. uninteresting information, but if you rely on your modeline in other modes,
  151. you might want to keep it."
  152. :type 'boolean
  153. :group 'elpy)
  154. (defcustom elpy-rpc-maximum-buffer-age (* 5 60)
  155. "Seconds after which Elpy automatically closes an unused RPC buffer.
  156. Elpy creates RPC buffers over time, depending on python interpreters
  157. and the project root. When there are many projects being worked on,
  158. these can accumulate. Setting this variable to an integer will close
  159. buffers and processes when they have not been used for this amount of
  160. seconds.
  161. Setting this variable to nil will disable the behavior."
  162. :type '(choice (const :tag "Never" nil)
  163. integer)
  164. :group 'elpy)
  165. (defcustom elpy-rpc-large-buffer-size 4096
  166. "Size for a source buffer up to which it will be sent directly.
  167. The Elpy RPC protocol uses JSON as the serialization format.
  168. Large buffers take a long time to encode, so Elpy can transmit
  169. them via temporary files. If a buffer is larger than this value,
  170. it is sent via a temporary file."
  171. :type 'integer
  172. :safe #'integerp
  173. :group 'elpy)
  174. (defcustom elpy-rpc-ignored-buffer-size 102400
  175. "Size for a source buffer over which Elpy completion will not work.
  176. To provide completion, Elpy's backends have to parse the whole
  177. file every time. For very large files, this is slow, and can make
  178. Emacs laggy. Elpy will simply not work on buffers larger than
  179. this to prevent this from happening."
  180. :type 'integer
  181. :safe #'integerp
  182. :group 'elpy)
  183. (defcustom elpy-rpc-python-command (if (equal system-type 'windows-nt)
  184. (or (executable-find "py")
  185. (executable-find "pythonw")
  186. "python")
  187. "python")
  188. "The Python interpreter for the RPC backend.
  189. This should be the same interpreter the project will be run with,
  190. and not an interactive shell like ipython."
  191. :type '(choice (const :tag "python" "python")
  192. (const :tag "python2" "python2")
  193. (const :tag "python3" "python3")
  194. (const :tag "pythonw (Python on Windows)" "pythonw")
  195. (const :tag "py (other Python on Windows)" "py")
  196. (string :tag "Other"))
  197. :safe (lambda (val)
  198. (member val '("python" "python2" "python3" "pythonw")))
  199. :group 'elpy)
  200. (defcustom elpy-rpc-pythonpath (file-name-directory (locate-library "elpy"))
  201. "A directory to add to the PYTHONPATH for the RPC process.
  202. This should be a directory where the elpy module can be found. If
  203. this is nil, it's assumed elpy can be found in the standard path.
  204. Usually, there is no need to change this."
  205. :type 'directory
  206. :safe #'file-directory-p
  207. :group 'elpy)
  208. (defcustom elpy-rpc-timeout 1
  209. "Number of seconds to wait for a response when blocking.
  210. When Elpy blocks Emacs to wait for a response from the RPC
  211. process, it will assume it won't come or wait too long after this
  212. many seconds. On a slow computer, or if you have a large project,
  213. you might want to increase this.
  214. A setting of nil means to block indefinitely."
  215. :type '(choice (const :tag "Block indefinitely" nil)
  216. integer)
  217. :safe (lambda (val)
  218. (or (integerp val)
  219. (null val)))
  220. :group 'elpy)
  221. (defcustom elpy-rpc-error-timeout 30
  222. "Minimum number of seconds between error popups.
  223. When Elpy encounters an error in the backend, it will display a
  224. lengthy description of the problem for a bug report. This hangs
  225. Emacs for a moment, and can be rather annoying if it happens
  226. repeatedly while editing a source file.
  227. If this variabl is non-nil, Elpy will not display the error
  228. message again within this amount of seconds."
  229. :type 'integer
  230. :group 'elpy)
  231. (defcustom elpy-company-post-completion-function 'ignore
  232. "Your preferred Company post completion function.
  233. Elpy can automatically insert parentheses after completing
  234. callable objects.
  235. The heuristic on when to insert these parentheses can easily be
  236. wrong, though, so this is disabled by default. Set this variable
  237. to the function `elpy-company-post-complete-parens' to enable
  238. this feature."
  239. :type '(choice (const :tag "Ignore post complete" ignore)
  240. (const :tag "Complete callables with parens"
  241. elpy-company-post-complete-parens)
  242. (function :tag "Other function"))
  243. :group 'elpy)
  244. (defcustom elpy-get-info-from-shell nil
  245. "If t, use the shell to gather docstrings and completions.
  246. Normally elpy provides completion and documentation using static code analysis (from jedi). With this option set to t, elpy will add the completion candidates and the docstrings from the associated python shell; This activates fallback completion candidates for cases when static code analysis fails."
  247. :type 'boolean
  248. :group 'elpy)
  249. (defcustom elpy-get-info-from-shell-timeout 1
  250. "Timeout (in seconds) for gathering information from the shell."
  251. :type 'number
  252. :group 'elpy)
  253. (defcustom elpy-eldoc-show-current-function t
  254. "If true, show the current function if no calltip is available.
  255. When Elpy can not find the calltip of the function call at point,
  256. it can show the name of the function or class and method being
  257. edited instead. Setting this variable to nil disables this feature."
  258. :type 'boolean
  259. :group 'elpy)
  260. (defcustom elpy-test-runner 'elpy-test-discover-runner
  261. "The test runner to use to run tests."
  262. :type '(choice (const :tag "Unittest Discover" elpy-test-discover-runner)
  263. (const :tag "Green" elpy-test-green-runner)
  264. (const :tag "Django Discover" elpy-test-django-runner)
  265. (const :tag "Nose" elpy-test-nose-runner)
  266. (const :tag "py.test" elpy-test-pytest-runner)
  267. (const :tag "Twisted Trial" elpy-test-trial-runner))
  268. :safe 'elpy-test-runner-p
  269. :group 'elpy)
  270. (defcustom elpy-test-discover-runner-command '("python" "-m" "unittest")
  271. "The command to use for `elpy-test-discover-runner'."
  272. :type '(repeat string)
  273. :group 'elpy)
  274. (defcustom elpy-test-green-runner-command '("green")
  275. "The command to use for `elpy-test-green-runner'."
  276. :type '(repeat string)
  277. :group 'elpy)
  278. (defcustom elpy-test-nose-runner-command '("nosetests")
  279. "The command to use for `elpy-test-nose-runner'."
  280. :type '(repeat string)
  281. :group 'elpy)
  282. (defcustom elpy-test-trial-runner-command '("trial")
  283. "The command to use for `elpy-test-trial-runner'."
  284. :type '(repeat string)
  285. :group 'elpy)
  286. (defcustom elpy-test-pytest-runner-command '("py.test")
  287. "The command to use for `elpy-test-pytest-runner'."
  288. :type '(repeat string)
  289. :group 'elpy)
  290. (defcustom elpy-test-compilation-function 'compile
  291. "Function used by `elpy-test-run' to run a test command.
  292. The function should behave similarly to `compile'. Another good
  293. option is `pdb'."
  294. :type 'string
  295. :group 'elpy)
  296. (defcustom elpy-rgrep-file-pattern "*.py"
  297. "FILES to use for `elpy-rgrep-symbol'."
  298. :type 'string
  299. :group 'elpy)
  300. (defcustom elpy-disable-backend-error-display t
  301. "Non-nil if Elpy should disable backend error display."
  302. :type 'boolean
  303. :group 'elpy)
  304. (defcustom elpy-syntax-check-command "flake8"
  305. "The command to use for `elpy-check'."
  306. :type 'string
  307. :group 'elpy)
  308. ;;;;;;;;;;;;;
  309. ;;; Elpy Mode
  310. (defvar elpy-refactor-map
  311. (let ((map (make-sparse-keymap "Refactor")))
  312. (define-key map (kbd "i") (cons (format "%smport fixup"
  313. (propertize "i" 'face 'bold))
  314. 'elpy-importmagic-fixup))
  315. (define-key map (kbd "f") (cons (format "%sormat code"
  316. (propertize "f" 'face 'bold))
  317. 'elpy-format-code))
  318. (define-key map (kbd "r") (cons (format "%sefactor"
  319. (propertize "r" 'face 'bold))
  320. 'elpy-refactor))
  321. map)
  322. "Key map for the refactor command")
  323. (defvar elpy-mode-map
  324. (let ((map (make-sparse-keymap)))
  325. ;; Alphabetical order to make it easier to find free C-c C-X
  326. ;; bindings in the future. Heh.
  327. ;; (define-key map (kbd "<backspace>") 'python-indent-dedent-line-backspace)
  328. ;; (define-key map (kbd "<backtab>") 'python-indent-dedent-line)
  329. ;; (define-key map (kbd "C-M-x") 'python-shell-send-defun)
  330. ;; (define-key map (kbd "C-c <") 'python-indent-shift-left)
  331. ;; (define-key map (kbd "C-c >") 'python-indent-shift-right)
  332. (define-key map (kbd "C-c RET") 'elpy-importmagic-add-import)
  333. (define-key map (kbd "C-c C-b") 'elpy-nav-expand-to-indentation)
  334. (define-key map (kbd "C-c C-c") 'elpy-shell-send-region-or-buffer)
  335. (define-key map (kbd "C-c C-d") 'elpy-doc)
  336. (define-key map (kbd "C-c C-e") 'elpy-multiedit-python-symbol-at-point)
  337. (define-key map (kbd "C-c C-f") 'elpy-find-file)
  338. (define-key map (kbd "C-c C-n") 'elpy-flymake-next-error)
  339. (define-key map (kbd "C-c C-o") 'elpy-occur-definitions)
  340. (define-key map (kbd "C-c C-p") 'elpy-flymake-previous-error)
  341. (define-key map (kbd "C-c C-s") 'elpy-rgrep-symbol)
  342. (define-key map (kbd "C-c C-t") 'elpy-test)
  343. (define-key map (kbd "C-c C-v") 'elpy-check)
  344. (define-key map (kbd "C-c C-z") 'elpy-shell-switch-to-shell)
  345. (define-key map (kbd "C-c C-k") 'elpy-shell-kill)
  346. (define-key map (kbd "C-c C-K") 'elpy-shell-kill-all)
  347. (define-key map (kbd "C-c C-r") elpy-refactor-map)
  348. (define-key map (kbd "C-c C-x") elpy-django-mode-map)
  349. (define-key map (kbd "<S-return>") 'elpy-open-and-indent-line-below)
  350. (define-key map (kbd "<C-S-return>") 'elpy-open-and-indent-line-above)
  351. (define-key map (kbd "<C-return>") 'elpy-shell-send-statement-and-step)
  352. (define-key map (kbd "<C-down>") 'elpy-nav-forward-block)
  353. (define-key map (kbd "<C-up>") 'elpy-nav-backward-block)
  354. (define-key map (kbd "<C-left>") 'elpy-nav-backward-indent)
  355. (define-key map (kbd "<C-right>") 'elpy-nav-forward-indent)
  356. (define-key map (kbd "<M-down>") 'elpy-nav-move-line-or-region-down)
  357. (define-key map (kbd "<M-up>") 'elpy-nav-move-line-or-region-up)
  358. (define-key map (kbd "<M-left>") 'elpy-nav-indent-shift-left)
  359. (define-key map (kbd "<M-right>") 'elpy-nav-indent-shift-right)
  360. (if (not (fboundp 'xref-find-definitions))
  361. (define-key map (kbd "M-.") 'elpy-goto-definition))
  362. (if (not (fboundp 'xref-find-definitions-other-window))
  363. (define-key map (kbd "C-x 4 M-.") 'elpy-goto-definition-other-window)
  364. (define-key map (kbd "C-x 4 M-.") 'xref-find-definitions-other-window))
  365. (if (fboundp 'xref-pop-marker-stack)
  366. (define-key map (kbd "M-*") 'xref-pop-marker-stack))
  367. (define-key map (kbd "M-TAB") 'elpy-company-backend)
  368. map)
  369. "Key map for the Emacs Lisp Python Environment.")
  370. (defvar elpy-shell-map
  371. (let ((map (make-sparse-keymap)))
  372. (define-key map (kbd "e") 'elpy-shell-send-statement)
  373. (define-key map (kbd "E") 'elpy-shell-send-statement-and-go)
  374. (define-key map (kbd "s") 'elpy-shell-send-top-statement)
  375. (define-key map (kbd "S") 'elpy-shell-send-top-statement-and-go)
  376. (define-key map (kbd "f") 'elpy-shell-send-defun)
  377. (define-key map (kbd "F") 'elpy-shell-send-defun-and-go)
  378. (define-key map (kbd "c") 'elpy-shell-send-defclass)
  379. (define-key map (kbd "C") 'elpy-shell-send-defclass-and-go)
  380. (define-key map (kbd "o") 'elpy-shell-send-group)
  381. (define-key map (kbd "O") 'elpy-shell-send-group-and-go)
  382. (define-key map (kbd "w") 'elpy-shell-send-codecell)
  383. (define-key map (kbd "W") 'elpy-shell-send-codecell-and-go)
  384. (define-key map (kbd "r") 'elpy-shell-send-region-or-buffer)
  385. (define-key map (kbd "R") 'elpy-shell-send-region-or-buffer-and-go)
  386. (define-key map (kbd "b") 'elpy-shell-send-buffer)
  387. (define-key map (kbd "B") 'elpy-shell-send-buffer-and-go)
  388. (define-key map (kbd "C-e") 'elpy-shell-send-statement-and-step)
  389. (define-key map (kbd "C-S-E") 'elpy-shell-send-statement-and-step-and-go)
  390. (define-key map (kbd "C-s") 'elpy-shell-send-top-statement-and-step)
  391. (define-key map (kbd "C-S-S") 'elpy-shell-send-top-statement-and-step-and-go)
  392. (define-key map (kbd "C-f") 'elpy-shell-send-defun-and-step)
  393. (define-key map (kbd "C-S-F") 'elpy-shell-send-defun-and-step-and-go)
  394. (define-key map (kbd "C-c") 'elpy-shell-send-defclass-and-step)
  395. (define-key map (kbd "C-S-C") 'elpy-shell-send-defclass-and-step-and-go)
  396. (define-key map (kbd "C-o") 'elpy-shell-send-group-and-step)
  397. (define-key map (kbd "C-S-O") 'elpy-shell-send-group-and-step-and-go)
  398. (define-key map (kbd "C-w") 'elpy-shell-send-codecell-and-step)
  399. (define-key map (kbd "C-S-W") 'elpy-shell-send-codecell-and-step-and-go)
  400. (define-key map (kbd "C-r") 'elpy-shell-send-region-or-buffer-and-step)
  401. (define-key map (kbd "C-S-R") 'elpy-shell-send-region-or-buffer-and-step-and-go)
  402. (define-key map (kbd "C-b") 'elpy-shell-send-buffer-and-step)
  403. (define-key map (kbd "C-S-B") 'elpy-shell-send-buffer-and-step-and-go)
  404. map)
  405. "Key map for the shell related commands")
  406. (fset 'elpy-shell-map elpy-shell-map)
  407. (defcustom elpy-shell-command-prefix-key "C-c C-y"
  408. "Prefix key used to call elpy shell related commands.
  409. This option need to bet set through `customize' or `customize-set-variable' to be taken into account."
  410. :type 'string
  411. :group 'elpy
  412. :set
  413. (lambda (var key)
  414. (when (and (boundp var) (symbol-value var))
  415. (define-key elpy-mode-map (kbd (symbol-value var)) nil))
  416. (when key
  417. (define-key elpy-mode-map (kbd key) 'elpy-shell-map)
  418. (set var key))))
  419. (defvar elpy-pdb-map
  420. (let ((map (make-sparse-keymap)))
  421. (define-key map (kbd "g") 'elpy-pdb-debug-buffer)
  422. (define-key map (kbd "p") 'elpy-pdb-break-at-point)
  423. (define-key map (kbd "e") 'elpy-pdb-debug-last-exception)
  424. (define-key map (kbd "b") 'elpy-pdb-toggle-breakpoint-at-point)
  425. map)
  426. "Key map for the shell related commands")
  427. (fset 'elpy-pdb-map elpy-pdb-map)
  428. (define-key elpy-mode-map (kbd "C-c C-g") 'elpy-pdb-map)
  429. (easy-menu-define elpy-menu elpy-mode-map
  430. "Elpy Mode Menu"
  431. '("Elpy"
  432. ["Documentation" elpy-doc
  433. :help "Get documentation for symbol at point"]
  434. ["Run Tests" elpy-test
  435. :help "Run test at point, or all tests in the project"]
  436. ["Go to Definition" elpy-goto-definition
  437. :help "Go to the definition of the symbol at point"]
  438. ["Go to previous definition" pop-tag-mark
  439. :active (not (ring-empty-p find-tag-marker-ring))
  440. :help "Return to the position"]
  441. ["Complete" elpy-company-backend
  442. :keys "M-TAB"
  443. :help "Complete at point"]
  444. ["Refactor" elpy-refactor
  445. :help "Refactor options"]
  446. "---"
  447. ("Interactive Python"
  448. ["Switch to Python Shell" elpy-shell-switch-to-shell
  449. :help "Start and switch to the interactive Python"]
  450. ["Send Region or Buffer" elpy-shell-send-region-or-buffer
  451. :label (if (use-region-p)
  452. "Send Region to Python"
  453. "Send Buffer to Python")
  454. :help "Send the current region or the whole buffer to Python"]
  455. ["Send Definition" python-shell-send-defun
  456. :help "Send current definition to Python"]
  457. ["Kill Python shell" elpy-shell-kill
  458. :help "Kill the current Python shell"]
  459. ["Kill all Python shells" elpy-shell-kill-all
  460. :help "Kill all Python shells"])
  461. ("Debugging"
  462. ["Debug buffer" elpy-pdb-debug-buffer
  463. :help "Debug the current buffer using pdb"]
  464. ["Debug at point" elpy-pdb-break-at-point
  465. :help "Debug the current buffer and stop at the current position"]
  466. ["Debug last exception" elpy-pdb-debug-last-exception
  467. :help "Run post-mortem pdb on the last exception"]
  468. ["Add/remove breakpoint" elpy-pdb-toggle-breakpoint-at-point
  469. :help "Add or remove a breakpoint at the current position"])
  470. ("Project"
  471. ["Find File" elpy-find-file
  472. :help "Interactively find a file in the current project"]
  473. ["Find Symbol" elpy-rgrep-symbol
  474. :help "Find occurrences of a symbol in the current project"]
  475. ["Set Project Root" elpy-set-project-root
  476. :help "Change the current project root"]
  477. ["Set Project Variable" elpy-set-project-variable
  478. :help "Configure a project-specific option"])
  479. ("Syntax Check"
  480. ["Check Syntax" elpy-check
  481. :help "Check the syntax of the current file"]
  482. ["Next Error" elpy-flymake-next-error
  483. :help "Go to the next inline error, if any"]
  484. ["Previous Error" elpy-flymake-previous-error
  485. :help "Go to the previous inline error, if any"])
  486. ("Indentation Blocks"
  487. ["Dedent" python-indent-shift-left
  488. :help "Dedent current block or region"
  489. :suffix (if (use-region-p) "Region" "Block")]
  490. ["Indent" python-indent-shift-right
  491. :help "Indent current block or region"
  492. :suffix (if (use-region-p) "Region" "Block")]
  493. ["Up" elpy-nav-move-line-or-region-up
  494. :help "Move current block or region up"
  495. :suffix (if (use-region-p) "Region" "Block")]
  496. ["Down" elpy-nav-move-line-or-region-down
  497. :help "Move current block or region down"
  498. :suffix (if (use-region-p) "Region" "Block")])
  499. "---"
  500. ["Configure" elpy-config t]))
  501. (defvar elpy-enabled-p nil
  502. "Is Elpy enabled or not.")
  503. ;;;###autoload
  504. (defun elpy-enable (&optional ignored)
  505. "Enable Elpy in all future Python buffers."
  506. (interactive)
  507. (unless elpy-enabled-p
  508. (when (< emacs-major-version 24)
  509. (error "Elpy requires Emacs 24 or newer"))
  510. (when ignored
  511. (warn "The argument to `elpy-enable' is deprecated, customize `elpy-modules' instead"))
  512. (let ((filename (find-lisp-object-file-name 'python-mode
  513. 'symbol-function)))
  514. (when (and filename
  515. (string-match "/python-mode\\.el\\'"
  516. filename))
  517. (error (concat "You are using python-mode.el. "
  518. "Elpy only works with python.el from "
  519. "Emacs 24 and above"))))
  520. (elpy-modules-global-init)
  521. (define-key inferior-python-mode-map (kbd "C-c C-z") 'elpy-shell-switch-to-buffer)
  522. (add-hook 'python-mode-hook 'elpy-mode)
  523. (add-hook 'pyvenv-post-activate-hooks 'elpy-rpc--disconnect)
  524. (add-hook 'inferior-python-mode-hook 'elpy-shell--enable-output-filter)
  525. ;; Enable Elpy-mode in the opened python buffer
  526. (dolist (buffer (buffer-list))
  527. (and (not (string-match "^ ?\\*" (buffer-name buffer)))
  528. (with-current-buffer buffer
  529. (when (string= major-mode 'python-mode)
  530. (elpy-mode t)))))
  531. (setq elpy-enabled-p t)))
  532. (defun elpy-disable ()
  533. "Disable Elpy in all future Python buffers."
  534. (interactive)
  535. (remove-hook 'python-mode-hook 'elpy-mode)
  536. (remove-hook 'inferior-python-mode-hook 'elpy-shell--enable-output-filter)
  537. (elpy-modules-global-stop)
  538. (setq elpy-enabled-p nil))
  539. ;;;###autoload
  540. (define-minor-mode elpy-mode
  541. "Minor mode in Python buffers for the Emacs Lisp Python Environment.
  542. This mode fully supports virtualenvs. Once you switch a
  543. virtualenv using \\[pyvenv-workon], you can use
  544. \\[elpy-rpc-restart] to make the elpy Python process use your
  545. virtualenv.
  546. \\{elpy-mode-map}"
  547. :lighter " Elpy"
  548. (when (not (derived-mode-p 'python-mode))
  549. (error "Elpy only works with `python-mode'"))
  550. (when (boundp 'xref-backend-functions)
  551. (add-hook 'xref-backend-functions #'elpy--xref-backend nil t))
  552. (cond
  553. (elpy-mode
  554. (elpy-modules-buffer-init))
  555. ((not elpy-mode)
  556. (elpy-modules-buffer-stop))))
  557. ;;;;;;;;;;;;;
  558. ;;; Elpy News
  559. (defun elpy-news ()
  560. "Display Elpy's release notes."
  561. (interactive)
  562. (message "The Elpy News command is deprecated and will be removed in future versions of Elpy"))
  563. ;;;;;;;;;;;;;;;
  564. ;;; Elpy Config
  565. (defvar elpy-config--related-custom-groups
  566. '(("Elpy" elpy "elpy-")
  567. ("Python" python "python-")
  568. ("Virtual Environments (Pyvenv)" pyvenv "pyvenv-")
  569. ("Completion (Company)" company "company-")
  570. ("Call Signatures (ElDoc)" eldoc "eldoc-")
  571. ("Inline Errors (Flymake)" flymake "flymake-")
  572. ("Snippets (YASnippet)" yasnippet "yas-")
  573. ("Directory Grep (rgrep)" grep "grep-")
  574. ("Search as You Type (ido)" ido "ido-")
  575. ("Django extension" elpy-django "elpy-django-")
  576. ("Autodoc extension" elpy-autodoc "elpy-autodoc-")
  577. ;; ffip does not use defcustom
  578. ;; highlight-indent does not use defcustom, either. Its sole face
  579. ;; is defined in basic-faces.
  580. ))
  581. (defvar elpy-config--get-config "import json
  582. import sys
  583. import warnings
  584. warnings.filterwarnings('ignore', category=FutureWarning)
  585. try:
  586. import urllib2 as urllib
  587. except ImportError:
  588. import urllib.request as urllib
  589. from distutils.version import LooseVersion
  590. def latest(package, version=None):
  591. try:
  592. response = urllib.urlopen('https://pypi.org/pypi/{package}/json'.format(package=package)).read()
  593. latest = json.loads(response)['info']['version']
  594. if version is None or LooseVersion(version) < LooseVersion(latest):
  595. return latest
  596. else:
  597. return None
  598. except:
  599. return None
  600. config = {}
  601. config['python_version'] = ('{major}.{minor}.{micro}'
  602. .format(major=sys.version_info[0],
  603. minor=sys.version_info[1],
  604. micro=sys.version_info[2]))
  605. try:
  606. import elpy
  607. config['elpy_version'] = elpy.__version__
  608. except:
  609. config['elpy_version'] = None
  610. try:
  611. import jedi
  612. if isinstance(jedi.__version__, tuple):
  613. config['jedi_version'] = '.'.join(str(x) for x in jedi.__version__)
  614. else:
  615. config['jedi_version'] = jedi.__version__
  616. config['jedi_latest'] = latest('jedi', config['jedi_version'])
  617. except:
  618. config['jedi_version'] = None
  619. config['jedi_latest'] = latest('jedi')
  620. try:
  621. import rope
  622. config['rope_version'] = rope.VERSION
  623. if sys.version_info[0] <= 2:
  624. config['rope_latest'] = latest('rope', config['rope_version'])
  625. else:
  626. config['rope_latest'] = latest('rope_py3k', config['rope_version'])
  627. except:
  628. config['rope_version'] = None
  629. config['rope_latest'] = latest('rope')
  630. try:
  631. import autopep8
  632. config['autopep8_version'] = autopep8.__version__
  633. config['autopep8_latest'] = latest('autopep8', config['autopep8_version'])
  634. except:
  635. config['autopep8_version'] = None
  636. config['autopep8_latest'] = latest('autopep8')
  637. try:
  638. import yapf
  639. config['yapf_version'] = yapf.__version__
  640. config['yapf_latest'] = latest('yapf', config['yapf_version'])
  641. except:
  642. config['yapf_version'] = None
  643. config['yapf_latest'] = latest('yapf')
  644. try:
  645. import black
  646. config['black_version'] = black.__version__
  647. config['black_latest'] = latest('black', config['black_version'])
  648. except:
  649. config['black_version'] = None
  650. config['black_latest'] = latest('black')
  651. json.dump(config, sys.stdout)
  652. ")
  653. (defun elpy-config-error (&optional fmt &rest args)
  654. "Note a configuration problem.
  655. This will show a message in the minibuffer that tells the user to
  656. use \\[elpy-config]."
  657. (let ((msg (if fmt
  658. (apply #'format fmt args)
  659. "Elpy is not properly configured")))
  660. (error "%s; use M-x elpy-config to configure it" msg)))
  661. ;;;###autoload
  662. (defun elpy-config ()
  663. "Configure Elpy.
  664. This function will pop up a configuration buffer, which is mostly
  665. a customize buffer, but has some more options."
  666. (interactive)
  667. (let ((buf (custom-get-fresh-buffer "*Elpy Config*"))
  668. (config (elpy-config--get-config))
  669. (custom-search-field nil))
  670. (with-current-buffer buf
  671. (elpy-insert--header "Elpy Configuration")
  672. (elpy-config--insert-configuration-problems config)
  673. (elpy-insert--header "Options")
  674. (let ((custom-buffer-style 'tree))
  675. (Custom-mode)
  676. (elpy-config--insert-help)
  677. (dolist (cust elpy-config--related-custom-groups)
  678. (widget-create 'custom-group
  679. :custom-last t
  680. :custom-state 'hidden
  681. :tag (car cust)
  682. :value (cadr cust)))
  683. (widget-setup)
  684. (goto-char (point-min))))
  685. (pop-to-buffer-same-window buf)))
  686. ;;;###autoload
  687. (defun elpy-version ()
  688. "Display the version of Elpy."
  689. (interactive)
  690. (message "Elpy %s (use M-x elpy-config for details)" elpy-version))
  691. (defun elpy-config--insert-help ()
  692. (let ((start (point)))
  693. ;; Help display from `customize-browse'
  694. (widget-insert (format "\
  695. %s buttons; type RET or click mouse-1
  696. on a button to invoke its action.
  697. Invoke [+] to expand a group, and [-] to collapse an expanded group.\n"
  698. (if custom-raised-buttons
  699. "`Raised' text indicates"
  700. "Square brackets indicate")))
  701. (if custom-browse-only-groups
  702. (widget-insert "\
  703. Invoke the [Group] button below to edit that item in another window.\n\n")
  704. (widget-insert "Invoke the ")
  705. (widget-create 'item
  706. :format "%t"
  707. :tag "[Group]"
  708. :tag-glyph "folder")
  709. (widget-insert ", ")
  710. (widget-create 'item
  711. :format "%t"
  712. :tag "[Face]"
  713. :tag-glyph "face")
  714. (widget-insert ", and ")
  715. (widget-create 'item
  716. :format "%t"
  717. :tag "[Option]"
  718. :tag-glyph "option")
  719. (widget-insert " buttons below to edit that
  720. item in another window.\n\n")
  721. (fill-region start (point)))))
  722. (defun elpy-config--insert-configuration-problems (&optional config)
  723. "Insert help text and widgets for configuration problems."
  724. (when (not config)
  725. (setq config (elpy-config--get-config)))
  726. (let* ((python-version (gethash "python_version" config))
  727. (rope-pypi-package (if (and python-version
  728. (string-match "^3\\." python-version))
  729. "rope_py3k"
  730. "rope")))
  731. (elpy-config--insert-configuration-table config)
  732. (insert "\n")
  733. ;; Python not found
  734. (when (not (gethash "python_rpc_executable" config))
  735. (elpy-insert--para
  736. "Elpy can not find the configured Python interpreter. Please make "
  737. "sure that the variable `elpy-rpc-python-command' points to a "
  738. "command in your PATH. You can change the variable below.\n\n"))
  739. ;; No virtual env
  740. (when (and (gethash "python_rpc_executable" config)
  741. (not (gethash "virtual_env" config)))
  742. (elpy-insert--para
  743. "You have not activated a virtual env. While Elpy supports this, "
  744. "it is often a good idea to work inside a virtual env. You can use "
  745. "M-x pyvenv-activate or M-x pyvenv-workon to activate a virtual "
  746. "env.\n\n"))
  747. ;; No virtual env, but ~/.local/bin not in PATH
  748. (when (and (not (memq system-type '(ms-dos windows-nt)))
  749. (gethash "python_rpc_executable" config)
  750. (not pyvenv-virtual-env)
  751. (not (or (member (expand-file-name "~/.local/bin")
  752. exec-path)
  753. (member (expand-file-name "~/.local/bin/")
  754. exec-path))))
  755. (elpy-insert--para
  756. "The directory ~/.local/bin/ is not in your PATH. As there is "
  757. "no active virtualenv, installing Python packages locally will "
  758. "place executables in that directory, so Emacs won't find them. "
  759. "If you are missing some commands, do add this directory to your "
  760. "PATH -- and then do `elpy-rpc-restart'.\n\n"))
  761. ;; Python found, but can't find the elpy module
  762. (when (and (gethash "python_rpc_executable" config)
  763. (not (gethash "elpy_version" config)))
  764. (elpy-insert--para
  765. "The Python interpreter could not find the elpy module. "
  766. "Please report to: "
  767. "https://github.com/jorgenschaefer/elpy/issues/new."
  768. "\n")
  769. (insert "\n"))
  770. ;; Bad backend version
  771. (when (and (gethash "elpy_version" config)
  772. (not (equal (gethash "elpy_version" config)
  773. elpy-version)))
  774. (let ((elpy-python-version (gethash "elpy_version" config)))
  775. (elpy-insert--para
  776. "The Elpy backend is version " elpy-python-version " while "
  777. "the Emacs package is " elpy-version ". This is incompatible. "
  778. "Please report to: https://github.com/jorgenschaefer/elpy/issues/new."
  779. "\n")))
  780. ;; Otherwise unparseable output.
  781. (when (gethash "error_output" config)
  782. (elpy-insert--para
  783. "There was an unexpected problem starting the RPC process. Please "
  784. "check the following output to see if this makes sense to you. "
  785. "To me, it doesn't.\n")
  786. (insert "\n"
  787. (gethash "error_output" config) "\n"
  788. "\n"))
  789. ;; Interactive python interpreter not in the current virtual env
  790. (when (and pyvenv-virtual-env
  791. (not (string-prefix-p (expand-file-name pyvenv-virtual-env)
  792. (executable-find
  793. python-shell-interpreter))))
  794. (elpy-insert--para
  795. "The python interactive interpreter (" python-shell-interpreter
  796. ") is not installed on the current virtualenv ("
  797. pyvenv-virtual-env "). The system binary ("
  798. (executable-find python-shell-interpreter)
  799. ") will be used instead."
  800. "\n")
  801. (insert "\n")
  802. (widget-create 'elpy-insert--pip-button
  803. :package python-shell-interpreter)
  804. (insert "\n\n"))
  805. ;; Requested backend unavailable
  806. (when (and (gethash "python_rpc_executable" config)
  807. (not (gethash "jedi_version" config)))
  808. (elpy-insert--para
  809. "The jedi package is not available. Completion and code navigation will"
  810. " not work.\n")
  811. (insert "\n")
  812. (widget-create 'elpy-insert--pip-button
  813. :package "jedi")
  814. (insert "\n\n"))
  815. ;; Newer version of Rope available
  816. (when (and (gethash "rope_version" config)
  817. (gethash "rope_latest" config))
  818. (elpy-insert--para
  819. "There is a newer version of Rope available.\n")
  820. (insert "\n")
  821. (widget-create 'elpy-insert--pip-button
  822. :package rope-pypi-package :upgrade t)
  823. (insert "\n\n"))
  824. ;; Newer version of Jedi available
  825. (when (and (gethash "jedi_version" config)
  826. (gethash "jedi_latest" config))
  827. (elpy-insert--para
  828. "There is a newer version of Jedi available.\n")
  829. (insert "\n")
  830. (widget-create 'elpy-insert--pip-button
  831. :package "jedi" :upgrade t)
  832. (insert "\n\n"))
  833. ;; No autopep8 available
  834. (when (not (gethash "autopep8_version" config))
  835. (elpy-insert--para
  836. "The autopep8 package is not available. Commands using this will "
  837. "not work.\n")
  838. (insert "\n")
  839. (widget-create 'elpy-insert--pip-button
  840. :package "autopep8")
  841. (insert "\n\n"))
  842. ;; Newer version of autopep8 available
  843. (when (and (gethash "autopep8_version" config)
  844. (gethash "autopep8_latest" config))
  845. (elpy-insert--para
  846. "There is a newer version of the autopep8 package available.\n")
  847. (insert "\n")
  848. (widget-create 'elpy-insert--pip-button
  849. :package "autopep8" :upgrade t)
  850. (insert "\n\n"))
  851. ;; No yapf available
  852. (when (not (gethash "yapf_version" config))
  853. (elpy-insert--para
  854. "The yapf package is not available. Commands using this will "
  855. "not work.\n")
  856. (insert "\n")
  857. (widget-create 'elpy-insert--pip-button
  858. :package "yapf")
  859. (insert "\n\n"))
  860. ;; Newer version of yapf available
  861. (when (and (gethash "yapf_version" config)
  862. (gethash "yapf_latest" config))
  863. (elpy-insert--para
  864. "There is a newer version of the yapf package available.\n")
  865. (insert "\n")
  866. (widget-create 'elpy-insert--pip-button
  867. :package "yapf" :upgrade t)
  868. (insert "\n\n"))
  869. ;; No black available
  870. (when (not (gethash "black_version" config))
  871. (elpy-insert--para
  872. "The black package is not available. Commands using this will "
  873. "not work.\n")
  874. (insert "\n")
  875. (widget-create 'elpy-insert--pip-button
  876. :package "black")
  877. (insert "\n\n"))
  878. ;; Newer version of black available
  879. (when (and (gethash "black_version" config)
  880. (gethash "black_latest" config))
  881. (elpy-insert--para
  882. "There is a newer version of the black package available.\n")
  883. (insert "\n")
  884. (widget-create 'elpy-insert--pip-button
  885. :package "black" :upgrade t)
  886. (insert "\n\n"))
  887. ;; Syntax checker not available
  888. (when (not (executable-find (car (split-string elpy-syntax-check-command))))
  889. (elpy-insert--para
  890. "The configured syntax checker could not be found. Elpy uses this "
  891. "program to provide syntax checks of your programs, so you might "
  892. "want to install one. Elpy by default uses flake8.\n")
  893. (insert "\n")
  894. (widget-create 'elpy-insert--pip-button :package "flake8")
  895. (insert "\n\n"))
  896. ))
  897. (defun elpy-config--package-available-p (package)
  898. "Check if PACKAGE is installed in the rpc."
  899. (equal 0 (call-process elpy-rpc-python-command nil nil nil "-c"
  900. (format "import %s" package))))
  901. (defun elpy-config--get-config ()
  902. "Return the configuration from `elpy-rpc-python-command'.
  903. This returns a hash table with the following keys (all strings):
  904. emacs_version
  905. python_rpc
  906. python_rpc_executable
  907. python_interactive
  908. python_interactive_executable
  909. python_version (RPC)
  910. elpy_version
  911. jedi_version
  912. rope_version
  913. virtual_env
  914. virtual_env_short"
  915. (with-temp-buffer
  916. (let ((config (make-hash-table :test #'equal)))
  917. (puthash "emacs_version" emacs-version config)
  918. (puthash "python_rpc" elpy-rpc-python-command config)
  919. (puthash "python_rpc_executable"
  920. (executable-find elpy-rpc-python-command)
  921. config)
  922. (let ((interactive-python (if (boundp 'python-python-command)
  923. python-python-command
  924. python-shell-interpreter)))
  925. (puthash "python_interactive"
  926. interactive-python
  927. config)
  928. (puthash "python_interactive_executable"
  929. (executable-find interactive-python)
  930. config))
  931. (let ((venv (getenv "VIRTUAL_ENV")))
  932. (puthash "virtual_env" venv config)
  933. (if venv
  934. (puthash "virtual_env_short" (file-name-nondirectory venv) config)
  935. (puthash "virtual_env_short" nil config)))
  936. (let ((return-value (ignore-errors
  937. (let ((process-environment
  938. (elpy-rpc--environment))
  939. (default-directory "/"))
  940. (call-process elpy-rpc-python-command
  941. nil
  942. (current-buffer)
  943. nil
  944. "-c"
  945. elpy-config--get-config)))))
  946. (when return-value
  947. (let ((data (ignore-errors
  948. (let ((json-array-type 'list)
  949. (json-encoding-pretty-print nil)) ;; Link to bug https://github.com/jorgenschaefer/elpy/issues/1521
  950. (goto-char (point-min))
  951. (json-read)))))
  952. (if (not data)
  953. (puthash "error_output" (buffer-string) config)
  954. (dolist (pair data)
  955. (puthash (symbol-name (car pair)) (cdr pair) config))))))
  956. config)))
  957. (defun elpy-config--insert-configuration-table (&optional config)
  958. "Insert a table describing the current Elpy config."
  959. (when (not config)
  960. (setq config (elpy-config--get-config)))
  961. (let ((emacs-version (gethash "emacs_version" config))
  962. (python-version (gethash "python_version" config))
  963. (python-rpc (gethash "python_rpc" config))
  964. (python-rpc-executable (gethash "python_rpc_executable" config))
  965. (python-interactive (gethash "python_interactive" config))
  966. (python-interactive-executable (gethash "python_interactive_executable"
  967. config))
  968. (elpy-python-version (gethash "elpy_version" config))
  969. (jedi-version (gethash "jedi_version" config))
  970. (jedi-latest (gethash "jedi_latest" config))
  971. (rope-version (gethash "rope_version" config))
  972. (rope-latest (gethash "rope_latest" config))
  973. (autopep8-version (gethash "autopep8_version" config))
  974. (autopep8-latest (gethash "autopep8_latest" config))
  975. (yapf-version (gethash "yapf_version" config))
  976. (yapf-latest (gethash "yapf_latest" config))
  977. (black-version (gethash "black_version" config))
  978. (black-latest (gethash "black_latest" config))
  979. (virtual-env (gethash "virtual_env" config))
  980. (virtual-env-short (gethash "virtual_env_short" config))
  981. table maxwidth)
  982. (setq table
  983. `(("Virtualenv" . ,(if (gethash "virtual_env" config)
  984. (format "%s (%s)"
  985. virtual-env-short
  986. virtual-env)
  987. "None"))
  988. ("RPC Python" . ,(cond
  989. (python-version
  990. (format "%s (%s)"
  991. python-version
  992. python-rpc-executable))
  993. (python-rpc-executable
  994. python-rpc-executable)
  995. (python-rpc
  996. (format "%s (not found)" python-rpc))
  997. (t
  998. (format "Not configured"))))
  999. ("Interactive Python" . ,(cond
  1000. (python-interactive-executable
  1001. (format "%s (%s)"
  1002. python-interactive
  1003. python-interactive-executable))
  1004. (python-interactive
  1005. (format "%s (not found)"
  1006. python-interactive))
  1007. (t
  1008. "Not configured")))
  1009. ("Emacs" . ,emacs-version)
  1010. ("Elpy" . ,(cond
  1011. ((and elpy-python-version elpy-version
  1012. (equal elpy-python-version elpy-version))
  1013. elpy-version)
  1014. (elpy-python-version
  1015. (format "%s (Python), %s (Emacs Lisp)"
  1016. elpy-python-version
  1017. elpy-version))
  1018. (t
  1019. (format "Not found (Python), %s (Emacs Lisp)"
  1020. elpy-version))))
  1021. ("Jedi" . ,(elpy-config--package-link "jedi"
  1022. jedi-version
  1023. jedi-latest))
  1024. ("Rope" . ,(elpy-config--package-link "rope"
  1025. rope-version
  1026. rope-latest))
  1027. ("Autopep8" . ,(elpy-config--package-link "autopep8"
  1028. autopep8-version
  1029. autopep8-latest))
  1030. ("Yapf" . ,(elpy-config--package-link "yapf"
  1031. yapf-version
  1032. yapf-latest))
  1033. ("Black" . ,(elpy-config--package-link "black"
  1034. black-version
  1035. black-latest))
  1036. ("Syntax checker" . ,(let ((syntax-checker
  1037. (executable-find
  1038. (car (split-string
  1039. elpy-syntax-check-command)))))
  1040. (if syntax-checker
  1041. (format "%s (%s)"
  1042. (file-name-nondirectory
  1043. syntax-checker)
  1044. syntax-checker)
  1045. (format "Not found (%s)"
  1046. elpy-syntax-check-command))))))
  1047. (setq maxwidth 0)
  1048. (dolist (row table)
  1049. (when (> (length (car row))
  1050. maxwidth)
  1051. (setq maxwidth (length (car row)))))
  1052. (dolist (row table)
  1053. (insert (car row)
  1054. (make-string (- maxwidth (length (car row)))
  1055. ?.)
  1056. ": "
  1057. (cdr row)
  1058. "\n"))))
  1059. (defun elpy-config--package-link (_name version latest)
  1060. "Return a string detailing a Python package.
  1061. NAME is the PyPI name of the package. VERSION is the currently
  1062. installed version. LATEST is the latest-available version on
  1063. PyPI, or nil if that's VERSION."
  1064. (cond
  1065. ((and (not version) (not latest))
  1066. "Not found")
  1067. ((not latest)
  1068. version)
  1069. ((not version)
  1070. (format "Not found (%s available)" latest))
  1071. (t
  1072. (format "%s (%s available)" version latest))))
  1073. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1074. ;;; Elpy Formatted Insertion
  1075. (defmacro elpy-insert--popup (buffer-name &rest body)
  1076. "Pop up a help buffer named BUFFER-NAME and execute BODY in it."
  1077. (declare (indent 1))
  1078. `(with-help-window ,buffer-name
  1079. (with-current-buffer standard-output
  1080. ,@body)))
  1081. (defun elpy-insert--para (&rest messages)
  1082. "Insert a bunch of text and then fill it."
  1083. (let ((start (point)))
  1084. (mapc (lambda (obj)
  1085. (if (stringp obj)
  1086. (insert obj)
  1087. (insert (format "%s" obj))))
  1088. messages)
  1089. (fill-region start (point))))
  1090. (defun elpy-insert--header (&rest text)
  1091. "Insert TEXT has a header for a buffer."
  1092. (insert (propertize (mapconcat #'(lambda (x) x)
  1093. text
  1094. "")
  1095. 'face 'header-line)
  1096. "\n"
  1097. "\n"))
  1098. (define-widget 'elpy-insert--pip-button 'item
  1099. "A button that runs pip (or an alternative)."
  1100. :button-prefix "["
  1101. :button-suffix "]"
  1102. :format "%[run%] %v"
  1103. :value-create 'elpy-insert--pip-button-value-create
  1104. :action 'elpy-insert--pip-button-action)
  1105. (defun elpy-insert--pip-button-value-create (widget)
  1106. "The :value-create option for the pip button widget."
  1107. (let* ((python-package (widget-get widget :package))
  1108. (do-upgrade (widget-get widget :upgrade))
  1109. (upgrade-option (if do-upgrade
  1110. "--upgrade "
  1111. ""))
  1112. (do-user-install (not (or (getenv "VIRTUAL_ENV")
  1113. pyvenv-virtual-env)))
  1114. (user-option (if do-user-install
  1115. "--user "
  1116. ""))
  1117. (command (cond
  1118. ((= (call-process elpy-rpc-python-command
  1119. nil nil nil
  1120. "-m" "pip" "--help")
  1121. 0)
  1122. (format "%s -m pip install %s%s%s"
  1123. elpy-rpc-python-command
  1124. user-option
  1125. upgrade-option
  1126. python-package))
  1127. ((executable-find "easy_install")
  1128. (format "easy_install %s%s"
  1129. user-option python-package))
  1130. (t
  1131. (error "Neither easy_install nor pip found")))))
  1132. (widget-put widget :command command)
  1133. (insert command)))
  1134. (defun elpy-insert--pip-button-action (widget &optional _event)
  1135. "The :action option for the pip button widget."
  1136. (async-shell-command (widget-get widget :command)))
  1137. ;;;;;;;;;;;;
  1138. ;;; Projects
  1139. (defvar elpy-project--variable-name-history nil
  1140. "The history for `elpy-project--read-project-variable'")
  1141. (defun elpy-project-root ()
  1142. "Return the root of the current buffer's project.
  1143. This can very well be nil if the current file is not part of a
  1144. project.
  1145. See `elpy-project-root-finder-functions' for a way to configure
  1146. how the project root is found. You can also set the variable
  1147. `elpy-project-root' in, for example, .dir-locals.el to override
  1148. this."
  1149. (when (not elpy-project-root)
  1150. (setq elpy-project-root
  1151. (run-hook-with-args-until-success
  1152. 'elpy-project-root-finder-functions)))
  1153. elpy-project-root)
  1154. (defun elpy-set-project-root (new-root)
  1155. "Set the Elpy project root to NEW-ROOT."
  1156. (interactive "DNew project root: ")
  1157. (setq elpy-project-root new-root))
  1158. (defun elpy-project-find-python-root ()
  1159. "Return the current Python project root, if any.
  1160. This is marked with setup.py, setup.cfg or pyproject.toml."
  1161. (or (locate-dominating-file default-directory "setup.py")
  1162. (locate-dominating-file default-directory "setup.cfg")
  1163. (locate-dominating-file default-directory "pyproject.toml")))
  1164. (defun elpy-project-find-git-root ()
  1165. "Return the current git repository root, if any."
  1166. (locate-dominating-file default-directory ".git"))
  1167. (defun elpy-project-find-hg-root ()
  1168. "Return the current git repository root, if any."
  1169. (locate-dominating-file default-directory ".hg"))
  1170. (defun elpy-project-find-svn-root ()
  1171. "Return the current git repository root, if any."
  1172. (locate-dominating-file default-directory
  1173. (lambda (dir)
  1174. (and (file-directory-p (format "%s/.svn" dir))
  1175. (not (file-directory-p (format "%s/../.svn"
  1176. dir)))))))
  1177. (defun elpy-project-find-projectile-root ()
  1178. "Return the current project root according to projectile."
  1179. ;; `ignore-errors' both to avoid an unbound function error as well
  1180. ;; as ignore projectile saying there is no project root here.
  1181. (ignore-errors
  1182. (projectile-project-root)))
  1183. (defun elpy-library-root ()
  1184. "Return the root of the Python package chain of the current buffer.
  1185. That is, if you have /foo/package/module.py, it will return /foo,
  1186. so that import package.module will pick up module.py."
  1187. (locate-dominating-file default-directory
  1188. (lambda (dir)
  1189. (not (file-exists-p
  1190. (format "%s/__init__.py"
  1191. dir))))))
  1192. (defun elpy-project--read-project-variable (prompt)
  1193. "Prompt the user for a variable name to set project-wide."
  1194. (let* ((prefixes (mapcar (lambda (cust)
  1195. (nth 2 cust))
  1196. elpy-config--related-custom-groups))
  1197. (var-regex (format "^%s" (regexp-opt prefixes))))
  1198. (intern
  1199. (completing-read
  1200. prompt
  1201. obarray
  1202. (lambda (sym)
  1203. (and (get sym 'safe-local-variable)
  1204. (string-match var-regex (symbol-name sym))
  1205. (get sym 'custom-type)))
  1206. :require-match
  1207. nil
  1208. 'elpy-project--variable-name-history))))
  1209. (defun elpy-project--read-variable-value (prompt variable)
  1210. "Read the value for VARIABLE from the user."
  1211. (let ((custom-type (get variable 'custom-type)))
  1212. (if custom-type
  1213. (widget-prompt-value (if (listp custom-type)
  1214. custom-type
  1215. (list custom-type))
  1216. prompt
  1217. (if (boundp variable)
  1218. (funcall
  1219. (or (get variable 'custom-get)
  1220. 'symbol-value)
  1221. variable))
  1222. (not (boundp variable)))
  1223. (eval-minibuffer prompt))))
  1224. (defun elpy-set-project-variable (variable value)
  1225. "Set or remove a variable in the project-wide .dir-locals.el.
  1226. With prefix argument, remove the variable."
  1227. (interactive
  1228. (let* ((variable (elpy-project--read-project-variable
  1229. (if current-prefix-arg
  1230. "Remove project variable: "
  1231. "Set project variable: ")))
  1232. (value (if current-prefix-arg
  1233. nil
  1234. (elpy-project--read-variable-value (format "Value for %s: "
  1235. variable)
  1236. variable))))
  1237. (list variable value)))
  1238. (with-current-buffer (find-file-noselect (format "%s/%s"
  1239. (elpy-project-root)
  1240. dir-locals-file))
  1241. (modify-dir-local-variable nil
  1242. variable
  1243. value
  1244. (if current-prefix-arg
  1245. 'delete
  1246. 'add-or-replace))))
  1247. ;;;;;;;;;;;;;;;;;;;;;;;;
  1248. ;;; Search Project Files
  1249. (defun elpy-rgrep-symbol (regexp)
  1250. "Search for REGEXP in the current project.
  1251. REGEXP defaults to the symbol at point, or the current region if
  1252. active.
  1253. With a prefix argument, always prompt for a string to search for."
  1254. (interactive
  1255. (list
  1256. (let ((symbol
  1257. (if (use-region-p)
  1258. (buffer-substring-no-properties (region-beginning)
  1259. (region-end))
  1260. (thing-at-point 'symbol))))
  1261. (if (and symbol (not current-prefix-arg))
  1262. (concat "\\<" symbol "\\>")
  1263. (read-from-minibuffer "Search in project for regexp: " symbol)))))
  1264. (grep-compute-defaults)
  1265. (let ((grep-find-ignored-directories (elpy-project-ignored-directories)))
  1266. (rgrep regexp
  1267. elpy-rgrep-file-pattern
  1268. (or (elpy-project-root)
  1269. default-directory)))
  1270. (with-current-buffer next-error-last-buffer
  1271. (let ((inhibit-read-only t))
  1272. (save-excursion
  1273. (goto-char (point-min))
  1274. (when (re-search-forward "^find .*" nil t)
  1275. (replace-match (format "Searching for '%s'\n"
  1276. (regexp-quote regexp))))))))
  1277. ;;;;;;;;;;;;;;;;;;;;;;
  1278. ;;; Find Project Files
  1279. (defcustom elpy-ffip-prune-patterns '()
  1280. "Elpy-specific extension of `ffip-prune-patterns'.
  1281. This is in addition to `elpy-project-ignored-directories'
  1282. and `completion-ignored-extensions'.
  1283. The final value of `ffip-prune-patterns' used is computed
  1284. by the eponymous function `elpy-ffip-prune-patterns'."
  1285. :type '(repeat string)
  1286. :safe (lambda (val)
  1287. (cl-every #'stringp val))
  1288. :group 'elpy)
  1289. (defun elpy-ffip-prune-patterns ()
  1290. "Compute `ffip-prune-patterns' from other variables.
  1291. This combines
  1292. `elpy-ffip-prune-patterns'
  1293. `elpy-project-ignored-directories'
  1294. `completion-ignored-extensions'
  1295. `ffip-prune-patterns'."
  1296. (delete-dups
  1297. (nconc
  1298. (mapcar (lambda (dir) (concat "*/" dir "/*"))
  1299. elpy-project-ignored-directories)
  1300. (mapcar (lambda (ext) (if (s-ends-with? "/" ext)
  1301. (concat "*" ext "*")
  1302. (concat "*" ext)))
  1303. completion-ignored-extensions)
  1304. (cl-copy-list elpy-ffip-prune-patterns)
  1305. (cl-copy-list ffip-prune-patterns))))
  1306. (defun elpy-find-file (&optional dwim)
  1307. "Efficiently find a file in the current project.
  1308. With prefix argument, tries to guess what kind of file the user
  1309. wants to open.
  1310. On an import line, it opens the file of that module.
  1311. Otherwise, it opens a test file associated with the current file,
  1312. if one exists. A test file is named test_<name>.py if the current
  1313. file is <name>.py, and is either in the same directory or a
  1314. \"test\" or \"tests\" subdirectory."
  1315. (interactive "P")
  1316. (cond
  1317. ((and dwim
  1318. (buffer-file-name)
  1319. (save-excursion
  1320. (goto-char (line-beginning-position))
  1321. (or (looking-at "^ *import +\\([[:alnum:]._]+\\)")
  1322. (looking-at "^ *from +\\([[:alnum:]._]+\\) +import +\\([[:alnum:]._]+\\)"))))
  1323. (let* ((module (if (match-string 2)
  1324. (format "%s.%s" (match-string 1) (match-string 2))
  1325. (match-string 1)))
  1326. (path (elpy-find--resolve-module module)))
  1327. (if path
  1328. (find-file path)
  1329. (elpy-find-file nil))))
  1330. ((and dwim
  1331. (buffer-file-name))
  1332. (let ((test-file (elpy-find--test-file)))
  1333. (if test-file
  1334. (find-file test-file)
  1335. (elpy-find-file nil))))
  1336. (t
  1337. (let ((ffip-prune-patterns (elpy-ffip-prune-patterns))
  1338. (ffip-project-root (or (elpy-project-root)
  1339. default-directory))
  1340. ;; Set up ido to use vertical file lists.
  1341. (ido-decorations '("\n" "" "\n" "\n..."
  1342. "[" "]" " [No match]" " [Matched]"
  1343. " [Not readable]" " [Too big]"
  1344. " [Confirm]"))
  1345. (ido-setup-hook (cons (lambda ()
  1346. (define-key ido-completion-map (kbd "<down>")
  1347. 'ido-next-match)
  1348. (define-key ido-completion-map (kbd "<up>")
  1349. 'ido-prev-match))
  1350. ido-setup-hook)))
  1351. (find-file-in-project)))))
  1352. (defun elpy-find--test-file ()
  1353. "Return the test file for the current file, if any.
  1354. If this is a test file, return the non-test file.
  1355. A test file is named test_<name>.py if the current file is
  1356. <name>.py, and is either in the same directors or a \"test\" or
  1357. \"tests\" subdirectory."
  1358. (catch 'return
  1359. (let (full-name directory file)
  1360. (setq full-name (buffer-file-name))
  1361. (when (not full-name)
  1362. (throw 'return nil))
  1363. (setq full-name (expand-file-name full-name)
  1364. directory (file-name-directory full-name)
  1365. file (file-name-nondirectory full-name))
  1366. (if (string-match "^test_" file)
  1367. (let ((file (substring file 5)))
  1368. (dolist (implementation (list (format "%s/%s" directory file)
  1369. (format "%s/../%s" directory file)))
  1370. (when (file-exists-p implementation)
  1371. (throw 'return implementation))))
  1372. (dolist (test (list (format "%s/test_%s" directory file)
  1373. (format "%s/test/test_%s" directory file)
  1374. (format "%s/tests/test_%s" directory file)
  1375. (format "%s/../test/test_%s" directory file)
  1376. (format "%s/../tests/test_%s" directory file)))
  1377. (when (file-exists-p test)
  1378. (throw 'return test)))))))
  1379. (defun elpy-find--module-path (module)
  1380. "Return a directory path for MODULE.
  1381. The resulting path is not guaranteed to exist. This simply
  1382. resolves leading periods relative to the current directory and
  1383. replaces periods in the middle of the string with slashes.
  1384. Only works with absolute imports. Stop using implicit relative
  1385. imports. They're a bad idea."
  1386. (let* ((relative-depth (when(string-match "^\\.+" module)
  1387. (length (match-string 0 module))))
  1388. (base-directory (if relative-depth
  1389. (format "%s/%s"
  1390. (buffer-file-name)
  1391. (mapconcat (lambda (_)
  1392. "../")
  1393. (make-vector relative-depth
  1394. nil)
  1395. ""))
  1396. (elpy-library-root)))
  1397. (file-name (replace-regexp-in-string
  1398. "\\."
  1399. "/"
  1400. (if relative-depth
  1401. (substring module relative-depth)
  1402. module))))
  1403. (expand-file-name (format "%s/%s" base-directory file-name))))
  1404. (defun elpy-find--resolve-module (module)
  1405. "Resolve MODULE relative to the current file and project.
  1406. Returns a full path name for that module."
  1407. (catch 'return
  1408. (let ((path (elpy-find--module-path module)))
  1409. (while (string-prefix-p (expand-file-name (elpy-library-root))
  1410. path)
  1411. (dolist (name (list (format "%s.py" path)
  1412. (format "%s/__init__.py" path)))
  1413. (when (file-exists-p name)
  1414. (throw 'return name)))
  1415. (if (string-match "/$" path)
  1416. (setq path (substring path 0 -1))
  1417. (setq path (file-name-directory path)))))
  1418. nil))
  1419. ;;;;;;;;;;;;;;;;;
  1420. ;;; Syntax Checks
  1421. (defun elpy-check (&optional whole-project-p)
  1422. "Run `python-check-command' on the current buffer's file,
  1423. or the project root if WHOLE-PROJECT-P is non-nil (interactively,
  1424. with a prefix argument)."
  1425. (interactive "P")
  1426. (when (not (buffer-file-name))
  1427. (error "Can't check a buffer without a file."))
  1428. (save-some-buffers (not compilation-ask-about-save) nil)
  1429. (let ((process-environment (python-shell-calculate-process-environment))
  1430. (exec-path (python-shell-calculate-exec-path))
  1431. (file-name-or-directory (expand-file-name
  1432. (if whole-project-p
  1433. (or (elpy-project-root)
  1434. (buffer-file-name))
  1435. (buffer-file-name))))
  1436. (extra-args (if whole-project-p
  1437. (concat
  1438. (if (string-match "pylint$" python-check-command)
  1439. " --ignore="
  1440. " --exclude=")
  1441. (mapconcat #'identity
  1442. (elpy-project-ignored-directories)
  1443. ","))
  1444. "")))
  1445. (compilation-start (concat python-check-command
  1446. " "
  1447. (shell-quote-argument file-name-or-directory)
  1448. extra-args)
  1449. nil
  1450. (lambda (_mode-name)
  1451. "*Python Check*"))))
  1452. ;;;;;;;;;;;;;;
  1453. ;;; Navigation
  1454. (defvar elpy-nav-expand--initial-position nil
  1455. "Initial position before expanding to indentation.")
  1456. (make-variable-buffer-local 'elpy-nav-expand--initial-position)
  1457. (defun elpy-goto-definition ()
  1458. "Go to the definition of the symbol at point, if found."
  1459. (interactive)
  1460. (let ((location (elpy-rpc-get-definition)))
  1461. (if location
  1462. (elpy-goto-location (car location) (cadr location))
  1463. (error "No definition found"))))
  1464. (defun elpy-goto-assignment ()
  1465. "Go to the assignment of the symbol at point, if found."
  1466. (interactive)
  1467. (let ((location (elpy-rpc-get-assignment)))
  1468. (if location
  1469. (elpy-goto-location (car location) (cadr location))
  1470. (error "No assignment found"))))
  1471. (defun elpy-goto-definition-other-window ()
  1472. "Go to the definition of the symbol at point in other window, if found."
  1473. (interactive)
  1474. (let ((location (elpy-rpc-get-definition)))
  1475. (if location
  1476. (elpy-goto-location (car location) (cadr location) 'other-window)
  1477. (error "No definition found"))))
  1478. (defun elpy-goto-assignment-other-window ()
  1479. "Go to the assignment of the symbol at point in other window, if found."
  1480. (interactive)
  1481. (let ((location (elpy-rpc-get-assignment)))
  1482. (if location
  1483. (elpy-goto-location (car location) (cadr location) 'other-window)
  1484. (error "No assignment found"))))
  1485. (defun elpy-goto-location (filename offset &optional other-window-p)
  1486. "Show FILENAME at OFFSET to the user.
  1487. If other-window-p is non-nil, show the same in other window."
  1488. (ring-insert find-tag-marker-ring (point-marker))
  1489. (let ((buffer (find-file-noselect filename)))
  1490. (if other-window-p
  1491. (pop-to-buffer buffer t)
  1492. (switch-to-buffer buffer))
  1493. (goto-char (1+ offset))
  1494. (recenter 0)))
  1495. (defun elpy-nav-forward-block ()
  1496. "Move to the next line indented like point.
  1497. This will skip over lines and statements with different
  1498. indentation levels."
  1499. (interactive "^")
  1500. (let ((indent (current-column))
  1501. (start (point))
  1502. (cur nil))
  1503. (when (/= (% indent python-indent-offset)
  1504. 0)
  1505. (setq indent (* (1+ (/ indent python-indent-offset))
  1506. python-indent-offset)))
  1507. (python-nav-forward-statement)
  1508. (while (and (< indent (current-indentation))
  1509. (not (eobp)))
  1510. (when (equal (point) cur)
  1511. (error "Statement does not finish"))
  1512. (setq cur (point))
  1513. (python-nav-forward-statement))
  1514. (when (< (current-indentation)
  1515. indent)
  1516. (goto-char start))))
  1517. (defun elpy-nav-backward-block ()
  1518. "Move to the previous line indented like point.
  1519. This will skip over lines and statements with different
  1520. indentation levels."
  1521. (interactive "^")
  1522. (let ((indent (current-column))
  1523. (start (point))
  1524. (cur nil))
  1525. (when (/= (% indent python-indent-offset)
  1526. 0)
  1527. (setq indent (* (1+ (/ indent python-indent-offset))
  1528. python-indent-offset)))
  1529. (python-nav-backward-statement)
  1530. (while (and (< indent (current-indentation))
  1531. (not (bobp)))
  1532. (when (equal (point) cur)
  1533. (error "Statement does not start"))
  1534. (setq cur (point))
  1535. (python-nav-backward-statement))
  1536. (when (< (current-indentation)
  1537. indent)
  1538. (goto-char start))))
  1539. (defun elpy-nav-forward-indent ()
  1540. "Move forward to the next indent level, or over the next word."
  1541. (interactive "^")
  1542. (if (< (current-column) (current-indentation))
  1543. (let* ((current (current-column))
  1544. (next (* (1+ (/ current python-indent-offset))
  1545. python-indent-offset)))
  1546. (goto-char (+ (point-at-bol)
  1547. next)))
  1548. (let ((eol (point-at-eol)))
  1549. (forward-word)
  1550. (when (> (point) eol)
  1551. (goto-char (point-at-bol))))))
  1552. (defun elpy-nav-backward-indent ()
  1553. "Move backward to the previous indent level, or over the previous word."
  1554. (interactive "^")
  1555. (if (and (<= (current-column) (current-indentation))
  1556. (/= (current-column) 0))
  1557. (let* ((current (current-column))
  1558. (next (* (1- (/ current python-indent-offset))
  1559. python-indent-offset)))
  1560. (goto-char (+ (point-at-bol)
  1561. next)))
  1562. (backward-word)))
  1563. (defun elpy-nav-move-line-or-region-down (&optional beg end)
  1564. "Move the current line or active region down."
  1565. (interactive
  1566. (if (use-region-p)
  1567. (list (region-beginning) (region-end))
  1568. (list nil nil)))
  1569. (if beg
  1570. (elpy--nav-move-region-vertically beg end 1)
  1571. (elpy--nav-move-line-vertically 1)))
  1572. (defun elpy-nav-move-line-or-region-up (&optional beg end)
  1573. "Move the current line or active region down."
  1574. (interactive
  1575. (if (use-region-p)
  1576. (list (region-beginning) (region-end))
  1577. (list nil nil)))
  1578. (if beg
  1579. (elpy--nav-move-region-vertically beg end -1)
  1580. (elpy--nav-move-line-vertically -1)))
  1581. (defun elpy--nav-move-line-vertically (dir)
  1582. (let* ((beg (point-at-bol))
  1583. (end (point-at-bol 2))
  1584. (col (current-column))
  1585. (region (delete-and-extract-region beg end)))
  1586. (forward-line dir)
  1587. (save-excursion
  1588. (insert region))
  1589. (goto-char (+ (point) col))))
  1590. (defun elpy--nav-move-region-vertically (beg end dir)
  1591. (let* ((point-before-mark (< (point) (mark)))
  1592. (beg (save-excursion
  1593. (goto-char beg)
  1594. (point-at-bol)))
  1595. (end (save-excursion
  1596. (goto-char end)
  1597. (if (bolp)
  1598. (point)
  1599. (point-at-bol 2))))
  1600. (region (delete-and-extract-region beg end)))
  1601. (goto-char beg)
  1602. (forward-line dir)
  1603. (save-excursion
  1604. (insert region))
  1605. (if point-before-mark
  1606. (set-mark (+ (point)
  1607. (length region)))
  1608. (set-mark (point))
  1609. (goto-char (+ (point)
  1610. (length region))))
  1611. (setq deactivate-mark nil)))
  1612. (defun elpy-open-and-indent-line-below ()
  1613. "Open a line below the current one, move there, and indent."
  1614. (interactive)
  1615. (move-end-of-line 1)
  1616. (newline-and-indent))
  1617. (defun elpy-open-and-indent-line-above ()
  1618. "Open a line above the current one, move there, and indent."
  1619. (interactive)
  1620. (move-beginning-of-line 1)
  1621. (save-excursion
  1622. (insert "\n"))
  1623. (indent-according-to-mode))
  1624. (defun elpy-nav-expand-to-indentation ()
  1625. "Select surrounding lines with current indentation."
  1626. (interactive)
  1627. (setq elpy-nav-expand--initial-position (point))
  1628. (let ((indentation (current-indentation)))
  1629. (if (= indentation 0)
  1630. (progn
  1631. (push-mark (point))
  1632. (push-mark (point-max) nil t)
  1633. (goto-char (point-min)))
  1634. (while (<= indentation (current-indentation))
  1635. (forward-line -1))
  1636. (forward-line 1)
  1637. (push-mark (point) nil t)
  1638. (while (<= indentation (current-indentation))
  1639. (forward-line 1))
  1640. (backward-char))))
  1641. (defadvice keyboard-quit (before collapse-region activate)
  1642. (when (eq last-command 'elpy-nav-expand-to-indentation)
  1643. (goto-char elpy-nav-expand--initial-position)))
  1644. (defun elpy-nav-normalize-region ()
  1645. "If the first or last line are not fully selected, select them completely."
  1646. (let ((beg (region-beginning))
  1647. (end (region-end)))
  1648. (goto-char beg)
  1649. (beginning-of-line)
  1650. (push-mark (point) nil t)
  1651. (goto-char end)
  1652. (when (not (= (point) (line-beginning-position)))
  1653. (end-of-line))))
  1654. (defun elpy-nav-indent-shift-right (&optional _count)
  1655. "Shift current line by COUNT columns to the right.
  1656. COUNT defaults to `python-indent-offset'.
  1657. If region is active, normalize the region and shift."
  1658. (interactive)
  1659. (if (use-region-p)
  1660. (progn
  1661. (elpy-nav-normalize-region)
  1662. (python-indent-shift-right (region-beginning) (region-end) current-prefix-arg))
  1663. (python-indent-shift-right (line-beginning-position) (line-end-position) current-prefix-arg)))
  1664. (defun elpy-nav-indent-shift-left (&optional _count)
  1665. "Shift current line by COUNT columns to the left.
  1666. COUNT defaults to `python-indent-offset'.
  1667. If region is active, normalize the region and shift."
  1668. (interactive)
  1669. (if (use-region-p)
  1670. (progn
  1671. (elpy-nav-normalize-region)
  1672. (python-indent-shift-left (region-beginning) (region-end) current-prefix-arg))
  1673. (python-indent-shift-left (line-beginning-position) (line-end-position) current-prefix-arg)))
  1674. ;;;;;;;;;;;;;;;;
  1675. ;;; Test running
  1676. (defvar elpy-set-test-runner-history nil
  1677. "History variable for `elpy-set-test-runner'.")
  1678. (defun elpy-test (&optional test-whole-project)
  1679. "Run tests on the current test, or the whole project.
  1680. If there is a test at point, run that test. If not, or if a
  1681. prefix is given, run all tests in the current project."
  1682. (interactive "P")
  1683. (let ((current-test (elpy-test-at-point)))
  1684. (if test-whole-project
  1685. ;; With prefix arg, test the whole project.
  1686. (funcall elpy-test-runner
  1687. (car current-test)
  1688. nil nil nil)
  1689. ;; Else, run only this test
  1690. (apply elpy-test-runner current-test))))
  1691. (defun elpy-set-test-runner (test-runner)
  1692. "Tell Elpy to use TEST-RUNNER to run tests.
  1693. See `elpy-test' for how to invoke it."
  1694. (interactive
  1695. (list
  1696. (let* ((runners (mapcar (lambda (value)
  1697. (cons (nth 2 value)
  1698. (nth 3 value)))
  1699. (cdr (get 'elpy-test-runner 'custom-type))))
  1700. (current (cdr (assq elpy-test-runner
  1701. (mapcar (lambda (cell)
  1702. (cons (cdr cell) (car cell)))
  1703. runners))))
  1704. (choice (completing-read (if current
  1705. (format "Test runner (currently %s): "
  1706. current)
  1707. "Test runner: ")
  1708. runners
  1709. nil t nil 'elpy-set-test-runner-history)))
  1710. (if (equal choice "")
  1711. elpy-test-runner
  1712. (cdr (assoc choice runners))))))
  1713. (setq elpy-test-runner test-runner))
  1714. (defun elpy-test-at-point ()
  1715. "Return a list specifying the test at point, if any.
  1716. This is used as the interactive
  1717. This list has four elements.
  1718. - Top level directory:
  1719. All test files should be importable from here.
  1720. - Test file:
  1721. The current file name.
  1722. - Test module:
  1723. The module name, relative to the top level directory.
  1724. - Test name:
  1725. The full name of the current test within the module, for
  1726. example TestClass.test_method
  1727. If there is no test at point, test name is nil.
  1728. If the current buffer is not visiting a file, only the top level
  1729. directory is not nil."
  1730. (if (not buffer-file-name)
  1731. (progn
  1732. (save-some-buffers)
  1733. (list (elpy-library-root) nil nil nil))
  1734. (let* ((top (elpy-library-root))
  1735. (file buffer-file-name)
  1736. (module (elpy-test--module-name-for-file top file))
  1737. (test (elpy-test--current-test-name)))
  1738. (if (and file (string-match "test" (or module test "")))
  1739. (progn
  1740. (save-buffer)
  1741. (list top file module test))
  1742. (save-some-buffers)
  1743. (list top nil nil nil)))))
  1744. (defun elpy-test--current-test-name ()
  1745. (let ((name (python-info-current-defun)))
  1746. (if (and name
  1747. (string-match "\\`\\([^.]+\\.[^.]+\\)\\." name))
  1748. (match-string 1 name)
  1749. name)))
  1750. (defun elpy-test--module-name-for-file (top-level module-file)
  1751. "Return the module name relative to TOP-LEVEL for MODULE-FILE.
  1752. For example, for a top level of /project/root/ and a module file
  1753. of /project/root/package/module.py, this would return
  1754. \"package.module\"."
  1755. (let* ((relative-name (file-relative-name module-file top-level))
  1756. (no-extension (replace-regexp-in-string "\\.py\\'" "" relative-name))
  1757. (no-init (replace-regexp-in-string "/__init__\\'" "" no-extension))
  1758. (dotted (replace-regexp-in-string "/" "." no-init)))
  1759. (if (string-match "^\\." dotted)
  1760. (concat "." (replace-regexp-in-string (regexp-quote "...") "." dotted))
  1761. dotted)))
  1762. (defun elpy-test-runner-p (obj)
  1763. "Return t iff OBJ is a test runner.
  1764. This uses the `elpy-test-runner-p' symbol property."
  1765. (get obj 'elpy-test-runner-p))
  1766. (defun elpy-test-run (working-directory command &rest args)
  1767. "Run COMMAND with ARGS in WORKING-DIRECTORY as a test command."
  1768. (let ((default-directory working-directory))
  1769. (funcall elpy-test-compilation-function
  1770. (mapconcat #'shell-quote-argument
  1771. (cons command args)
  1772. " "))))
  1773. (defun elpy-test-discover-runner (top _file module test)
  1774. "Test the project using the python unittest discover runner.
  1775. This requires Python 2.7 or later."
  1776. (interactive (elpy-test-at-point))
  1777. (let ((test (cond
  1778. (test (format "%s.%s" module test))
  1779. (module module)
  1780. (t "discover"))))
  1781. (apply #'elpy-test-run
  1782. top
  1783. (append elpy-test-discover-runner-command
  1784. (list test)))))
  1785. (put 'elpy-test-discover-runner 'elpy-test-runner-p t)
  1786. (defun elpy-test-green-runner (top _file module test)
  1787. "Test the project using the green runner."
  1788. (interactive (elpy-test-at-point))
  1789. (let* ((test (cond
  1790. (test (format "%s.%s" module test))
  1791. (module module)))
  1792. (command (if test
  1793. (append elpy-test-green-runner-command (list test))
  1794. elpy-test-green-runner-command)))
  1795. (apply #'elpy-test-run top command)))
  1796. (put 'elpy-test-green-runner 'elpy-test-runner-p t)
  1797. (defun elpy-test-nose-runner (top _file module test)
  1798. "Test the project using the nose test runner.
  1799. This requires the nose package to be installed."
  1800. (interactive (elpy-test-at-point))
  1801. (if module
  1802. (apply #'elpy-test-run
  1803. top
  1804. (append elpy-test-nose-runner-command
  1805. (list (if test
  1806. (format "%s:%s" module test)
  1807. module))))
  1808. (apply #'elpy-test-run
  1809. top
  1810. elpy-test-nose-runner-command)))
  1811. (put 'elpy-test-nose-runner 'elpy-test-runner-p t)
  1812. (defun elpy-test-trial-runner (top _file module test)
  1813. "Test the project using Twisted's Trial test runner.
  1814. This requires the twisted-core package to be installed."
  1815. (interactive (elpy-test-at-point))
  1816. (if module
  1817. (apply #'elpy-test-run
  1818. top
  1819. (append elpy-test-trial-runner-command
  1820. (list (if test
  1821. (format "%s.%s" module test)
  1822. module))))
  1823. (apply #'elpy-test-run top elpy-test-trial-runner-command)))
  1824. (put 'elpy-test-trial-runner 'elpy-test-runner-p t)
  1825. (defun elpy-test-pytest-runner (top file module test)
  1826. "Test the project using the py.test test runner.
  1827. This requires the pytest package to be installed."
  1828. (interactive (elpy-test-at-point))
  1829. (cond
  1830. (test
  1831. (let ((test-list (split-string test "\\.")))
  1832. (apply #'elpy-test-run
  1833. top
  1834. (append elpy-test-pytest-runner-command
  1835. (list (mapconcat #'identity
  1836. (cons file test-list)
  1837. "::"))))))
  1838. (module
  1839. (apply #'elpy-test-run top (append elpy-test-pytest-runner-command
  1840. (list file))))
  1841. (t
  1842. (apply #'elpy-test-run top elpy-test-pytest-runner-command))))
  1843. (put 'elpy-test-pytest-runner 'elpy-test-runner-p t)
  1844. ;;;;;;;;;;;;;;;;;
  1845. ;;; Documentation
  1846. (defvar elpy-doc-history nil
  1847. "History for the `elpy-doc' command.")
  1848. (defun elpy-doc ()
  1849. "Show documentation for the symbol at point.
  1850. If there is no documentation for the symbol at point, or if a
  1851. prefix argument is given, prompt for a symbol from the user."
  1852. (interactive)
  1853. (let ((doc nil))
  1854. (when (not current-prefix-arg)
  1855. (setq doc (elpy-rpc-get-docstring))
  1856. (when (not doc)
  1857. (save-excursion
  1858. (python-nav-backward-up-list)
  1859. (setq doc (elpy-rpc-get-docstring))))
  1860. (when (not doc)
  1861. (setq doc (elpy-rpc-get-pydoc-documentation
  1862. (elpy-doc--symbol-at-point))))
  1863. (when (not doc)
  1864. (save-excursion
  1865. (python-nav-backward-up-list)
  1866. (setq doc (elpy-rpc-get-pydoc-documentation
  1867. (elpy-doc--symbol-at-point))))))
  1868. (when (not doc)
  1869. (setq doc (elpy-rpc-get-pydoc-documentation
  1870. (elpy-doc--read-identifier-from-minibuffer
  1871. (elpy-doc--symbol-at-point)))))
  1872. (if doc
  1873. (elpy-doc--show doc)
  1874. (error "No documentation found."))))
  1875. (defun elpy-doc--read-identifier-from-minibuffer (initial)
  1876. "Read a pydoc-able identifier from the minibuffer."
  1877. (completing-read "Pydoc for: "
  1878. (completion-table-dynamic #'elpy-rpc-get-pydoc-completions)
  1879. nil nil initial 'elpy-doc-history))
  1880. (defun elpy-doc--show (documentation)
  1881. "Show DOCUMENTATION to the user, replacing ^H with bold."
  1882. (with-help-window "*Python Doc*"
  1883. (with-current-buffer "*Python Doc*"
  1884. (erase-buffer)
  1885. (insert documentation)
  1886. (goto-char (point-min))
  1887. (while (re-search-forward "\\(.\\)\\1" nil t)
  1888. (replace-match (propertize (match-string 1)
  1889. 'face 'bold)
  1890. t t)))))
  1891. (defun elpy-doc--symbol-at-point ()
  1892. "Return the Python symbol at point, including dotted paths."
  1893. (with-syntax-table python-dotty-syntax-table
  1894. (let ((symbol (symbol-at-point)))
  1895. (if symbol
  1896. (symbol-name symbol)
  1897. nil))))
  1898. ;;;;;;;;;;;;;;
  1899. ;;; Buffer manipulation
  1900. (defun elpy-buffer--replace-block (spec)
  1901. "Replace a block. SPEC is (startline endline newblock)."
  1902. (let ((start-line (nth 0 spec))
  1903. (end-line (nth 1 spec))
  1904. (new-block (nth 2 spec)))
  1905. (save-excursion
  1906. (save-restriction
  1907. (widen)
  1908. (goto-char (point-min))
  1909. (forward-line start-line)
  1910. (let ((beg (point))
  1911. (end (progn (forward-line (- end-line start-line)) (point))))
  1912. ;; Avoid deleting and re-inserting when the blocks are equal.
  1913. (unless (string-equal (buffer-substring beg end) new-block)
  1914. (delete-region beg end)
  1915. (insert new-block)))))))
  1916. (defun elpy-buffer--replace-region (beg end rep)
  1917. "Replace text in BUFFER in region (BEG END) with REP."
  1918. (unless (string-equal (buffer-substring beg end) rep)
  1919. (save-excursion
  1920. (goto-char end)
  1921. (insert rep)
  1922. (delete-region beg end))))
  1923. ;;;;;;;;;;;;;;;;;;;;;
  1924. ;;; Importmagic - make obsolete
  1925. (defun elpy-importmagic-add-import ()
  1926. (interactive))
  1927. (defun elpy-importmagic-fixup ()
  1928. (interactive))
  1929. (make-obsolete 'elpy-importmagic-add-import "support for importmagic has been dropped." "1.17.0")
  1930. (make-obsolete 'elpy-importmagic-fixup "support for importmagic has been dropped." "1.17.0")
  1931. ;;;;;;;;;;;;;;;;;;;;;
  1932. ;;; Code reformatting
  1933. (defun elpy-format-code ()
  1934. "Format code using the available formatter."
  1935. (interactive)
  1936. (cond
  1937. ((elpy-config--package-available-p "yapf")
  1938. (elpy-yapf-fix-code))
  1939. ((elpy-config--package-available-p "autopep8")
  1940. (elpy-autopep8-fix-code))
  1941. ((elpy-config--package-available-p "black")
  1942. (elpy-black-fix-code))
  1943. (t
  1944. (message "Install yapf/autopep8 to format code."))))
  1945. (defun elpy-yapf-fix-code ()
  1946. "Automatically formats Python code with yapf.
  1947. Yapf can be configured with a style file placed in the project
  1948. root directory."
  1949. (interactive)
  1950. (elpy--fix-code-with-formatter "fix_code_with_yapf"))
  1951. (defun elpy-autopep8-fix-code ()
  1952. "Automatically formats Python code to conform to the PEP 8 style guide.
  1953. Autopep8 can be configured with a style file placed in the project
  1954. root directory."
  1955. (interactive)
  1956. (elpy--fix-code-with-formatter "fix_code"))
  1957. (defun elpy-black-fix-code ()
  1958. "Automatically formats Python code with black."
  1959. (interactive)
  1960. (elpy--fix-code-with-formatter "fix_code_with_black"))
  1961. (defun elpy--fix-code-with-formatter (method)
  1962. "Common routine for formatting python code."
  1963. (let ((line (line-number-at-pos))
  1964. (col (current-column))
  1965. (directory (if (elpy-project-root)
  1966. (expand-file-name (elpy-project-root))
  1967. default-directory)))
  1968. (if (use-region-p)
  1969. (let ((new-block (elpy-rpc method
  1970. (list (elpy-rpc--region-contents)
  1971. directory)))
  1972. (beg (region-beginning))
  1973. (end (region-end)))
  1974. (elpy-buffer--replace-region
  1975. beg end (string-trim-right new-block))
  1976. (goto-char end)
  1977. (deactivate-mark))
  1978. (let ((new-block (elpy-rpc method
  1979. (list (elpy-rpc--buffer-contents)
  1980. directory)))
  1981. (beg (point-min))
  1982. (end (point-max)))
  1983. (elpy-buffer--replace-region beg end new-block)
  1984. (when (bobp)
  1985. (forward-line (1- line))
  1986. (forward-char col))))))
  1987. ;;;;;;;;;;;;;;
  1988. ;;; Multi-Edit
  1989. (defvar elpy-multiedit-overlays nil
  1990. "List of overlays currently being edited.")
  1991. (defun elpy-multiedit-add-overlay (beg end)
  1992. "Add an editable overlay between BEG and END.
  1993. A modification in any of these overlays will modify all other
  1994. overlays, too."
  1995. (interactive "r")
  1996. (when (elpy-multiedit--overlays-in-p beg end)
  1997. (error "Overlapping multiedit overlays are not allowed"))
  1998. (let ((ov (make-overlay beg end nil nil :rear-advance)))
  1999. (overlay-put ov 'elpy-multiedit t)
  2000. (overlay-put ov 'face 'highlight)
  2001. (overlay-put ov 'modification-hooks '(elpy-multiedit--overlay-changed))
  2002. (overlay-put ov 'insert-in-front-hooks '(elpy-multiedit--overlay-changed))
  2003. (overlay-put ov 'insert-behind-hooks '(elpy-multiedit--overlay-changed))
  2004. (push ov elpy-multiedit-overlays)))
  2005. (defun elpy-multiedit--overlays-in-p (beg end)
  2006. "Return t iff there are multiedit overlays between beg and end."
  2007. (catch 'return
  2008. (dolist (ov (overlays-in beg end))
  2009. (when (overlay-get ov 'elpy-multiedit)
  2010. (throw 'return t)))
  2011. nil))
  2012. (defun elpy-multiedit-stop ()
  2013. "Stop editing multiple places at once."
  2014. (interactive)
  2015. (dolist (ov elpy-multiedit-overlays)
  2016. (delete-overlay ov))
  2017. (setq elpy-multiedit-overlays nil))
  2018. (defun elpy-multiedit--overlay-changed (ov after-change _beg _end
  2019. &optional _pre-change-length)
  2020. "Called for each overlay that changes.
  2021. This updates all other overlays."
  2022. (when (and after-change
  2023. (not undo-in-progress)
  2024. (overlay-buffer ov))
  2025. (let ((text (buffer-substring (overlay-start ov)
  2026. (overlay-end ov)))
  2027. (inhibit-modification-hooks t))
  2028. (dolist (other-ov elpy-multiedit-overlays)
  2029. (when (and (not (equal other-ov ov))
  2030. (buffer-live-p (overlay-buffer other-ov)))
  2031. (with-current-buffer (overlay-buffer other-ov)
  2032. (save-excursion
  2033. (goto-char (overlay-start other-ov))
  2034. (insert text)
  2035. (delete-region (point) (overlay-end other-ov)))))))))
  2036. (defun elpy-multiedit ()
  2037. "Edit all occurences of the symbol at point, or the active region.
  2038. If multiedit is active, stop it."
  2039. (interactive)
  2040. (if elpy-multiedit-overlays
  2041. (elpy-multiedit-stop)
  2042. (let ((regex (if (use-region-p)
  2043. (regexp-quote (buffer-substring (region-beginning)
  2044. (region-end)))
  2045. (format "\\_<%s\\_>" (regexp-quote
  2046. (symbol-name
  2047. (symbol-at-point))))))
  2048. (case-fold-search nil))
  2049. (save-excursion
  2050. (goto-char (point-min))
  2051. (while (re-search-forward regex nil t)
  2052. (elpy-multiedit-add-overlay (match-beginning 0)
  2053. (match-end 0)))))))
  2054. (defun elpy-multiedit-python-symbol-at-point (&optional use-symbol-p)
  2055. "Edit all usages of the the Python symbol at point.
  2056. With prefix arg, edit all syntactic usages of the symbol at
  2057. point. This might include unrelated symbols that just share the
  2058. name."
  2059. (interactive "P")
  2060. (if (or elpy-multiedit-overlays
  2061. use-symbol-p
  2062. (use-region-p))
  2063. ;; If we are already doing a multiedit, or are explicitly told
  2064. ;; to use the symbol at point, or if we are on an active region,
  2065. ;; call the multiedit function that does just that already.
  2066. (call-interactively 'elpy-multiedit)
  2067. ;; Otherwise, fetch usages from backend.
  2068. (save-some-buffers)
  2069. (let ((usages (condition-case err
  2070. (elpy-rpc-get-usages)
  2071. ;; This is quite the stunt, but elisp parses JSON
  2072. ;; null as nil, which is indistinguishable from
  2073. ;; the empty list, we stick to the error.
  2074. (error
  2075. (if (and (eq (car err) 'error)
  2076. (stringp (cadr err))
  2077. (string-match "not implemented" (cadr err)))
  2078. 'not-supported
  2079. (error (cadr err)))))))
  2080. (cond
  2081. ((eq usages 'not-supported)
  2082. (call-interactively 'elpy-multiedit)
  2083. (message (concat "Using syntactic editing "
  2084. "as current backend does not support get_usages.")))
  2085. ((null usages)
  2086. (call-interactively 'elpy-multiedit)
  2087. (if elpy-multiedit-overlays
  2088. (message (concat "Using syntactic editing as no usages of the "
  2089. "symbol at point were found by the backend."))
  2090. (message "No occurrences of the symbol at point found")))
  2091. (t
  2092. (save-restriction
  2093. (widen)
  2094. (elpy-multiedit--usages usages)))))))
  2095. (defun elpy-multiedit--usages (usages)
  2096. "Mark the usages in USAGES for editing."
  2097. (let ((name nil)
  2098. (locations (make-hash-table :test #'equal)))
  2099. (dolist (usage usages)
  2100. (let* ((filename (cdr (assq 'filename usage)))
  2101. (this-name (cdr (assq 'name usage)))
  2102. (offset (cdr (assq 'offset usage))))
  2103. (setq name this-name)
  2104. (with-current-buffer (if filename
  2105. (find-file-noselect filename)
  2106. (current-buffer))
  2107. (elpy-multiedit-add-overlay (+ offset 1)
  2108. (+ offset 1 (length this-name)))
  2109. (save-excursion
  2110. (goto-char (+ offset 1))
  2111. (puthash filename
  2112. (cons (list offset
  2113. (buffer-substring (line-beginning-position)
  2114. (line-end-position))
  2115. (- (point)
  2116. (line-beginning-position))
  2117. (- (+ (point) (length this-name))
  2118. (line-beginning-position)))
  2119. (gethash filename locations))
  2120. locations)))))
  2121. (if (<= (hash-table-count locations)
  2122. 1)
  2123. (message "Editing %s usages of '%s' in this buffer"
  2124. (length usages) name)
  2125. (with-current-buffer (get-buffer-create "*Elpy Edit Usages*")
  2126. (let ((inhibit-read-only t)
  2127. (filenames nil))
  2128. (erase-buffer)
  2129. (elpy-insert--para
  2130. "The symbol '" name "' was found in multiple files. Editing "
  2131. "all locations:\n\n")
  2132. (maphash (lambda (key _value)
  2133. (when (not (member key filenames))
  2134. (setq filenames (cons key filenames))))
  2135. locations)
  2136. (dolist (filename (sort filenames #'string<))
  2137. (elpy-insert--header filename)
  2138. (dolist (location (sort (gethash filename locations)
  2139. (lambda (loc1 loc2)
  2140. (< (car loc1)
  2141. (car loc2)))))
  2142. (let ((line (nth 1 location))
  2143. (start (+ (line-beginning-position)
  2144. (nth 2 location)))
  2145. (end (+ (line-end-position)
  2146. (nth 3 location))))
  2147. ;; Insert the \n first, else we extend the overlay.
  2148. (insert line "\n")
  2149. (elpy-multiedit-add-overlay start end)))
  2150. (insert "\n"))
  2151. (goto-char (point-min))
  2152. (display-buffer (current-buffer)
  2153. nil
  2154. 'visible))))))
  2155. ;;;;;;;;;;;;;;;;;;;;;
  2156. ;;; Occur Definitions
  2157. (defun elpy-occur-definitions ()
  2158. "Display an occur buffer of all definitions in the current buffer.
  2159. Also, switch to that buffer."
  2160. (interactive)
  2161. (let ((list-matching-lines-face nil))
  2162. (occur "^\s*\\(\\(async\s\\|\\)def\\|class\\)\s"))
  2163. (let ((window (get-buffer-window "*Occur*")))
  2164. (if window
  2165. (select-window window)
  2166. (switch-to-buffer "*Occur*"))))
  2167. ;;;;;;;;;;;;;;;;;;;
  2168. ;;; Promise objects
  2169. (defvar elpy-promise-marker (make-symbol "*elpy-promise*")
  2170. "An uninterned symbol marking an Elpy promise object.")
  2171. (defun elpy-promise (success &optional error)
  2172. "Return a new promise.
  2173. A promise is an object with a success and error callback. If the
  2174. promise is resolved using `elpy-promise-resolve', its success
  2175. callback is called with the given value. The current buffer is
  2176. restored, too.
  2177. If the promise is rejected using `elpy-promise-reject', its error
  2178. callback is called. For this function, the current buffer is not
  2179. necessarily restored, as it is also called when the buffer does
  2180. not exist anymore."
  2181. (vector elpy-promise-marker ; 0 id
  2182. success ; 1 success-callback
  2183. error ; 2 error-callback
  2184. (current-buffer) ; 3 current-buffer
  2185. nil ; 4 run
  2186. ))
  2187. (defun elpy-promise-p (obj)
  2188. "Return non-nil if the argument is a promise object."
  2189. (and (vectorp obj)
  2190. (= (length obj) 5)
  2191. (eq (aref obj 0) elpy-promise-marker)))
  2192. (defsubst elpy-promise-success-callback (promise)
  2193. "Return the success callback for PROMISE."
  2194. (aref promise 1))
  2195. (defsubst elpy-promise-error-callback (promise)
  2196. "Return the error callback for PROMISE."
  2197. (aref promise 2))
  2198. (defsubst elpy-promise-buffer (promise)
  2199. "Return the buffer for PROMISE."
  2200. (aref promise 3))
  2201. (defsubst elpy-promise-resolved-p (promise)
  2202. "Return non-nil if the PROMISE has been resolved or rejected."
  2203. (aref promise 4))
  2204. (defsubst elpy-promise-set-resolved (promise)
  2205. "Mark PROMISE as having been resolved."
  2206. (aset promise 4 t))
  2207. (defun elpy-promise-resolve (promise value)
  2208. "Resolve PROMISE with VALUE."
  2209. (when (not (elpy-promise-resolved-p promise))
  2210. (unwind-protect
  2211. (let ((success-callback (elpy-promise-success-callback promise)))
  2212. (when success-callback
  2213. (condition-case err
  2214. (with-current-buffer (elpy-promise-buffer promise)
  2215. (funcall success-callback value))
  2216. (error
  2217. (elpy-promise-reject promise err)))))
  2218. (elpy-promise-set-resolved promise))))
  2219. (defun elpy-promise-reject (promise reason)
  2220. "Reject PROMISE because of REASON."
  2221. (when (not (elpy-promise-resolved-p promise))
  2222. (unwind-protect
  2223. (let ((error-callback (elpy-promise-error-callback promise)))
  2224. (when error-callback
  2225. (if (buffer-live-p (elpy-promise-buffer promise))
  2226. (with-current-buffer (elpy-promise-buffer promise)
  2227. (funcall error-callback reason))
  2228. (with-temp-buffer
  2229. (funcall error-callback reason)))))
  2230. (elpy-promise-set-resolved promise))))
  2231. (defun elpy-promise-wait (promise &optional timeout)
  2232. "Wait for PROMISE to be resolved, for up to TIMEOUT seconds.
  2233. This will accept process output while waiting.
  2234. This will wait for the current Elpy RPC process specifically, as
  2235. Emacs currently has a bug where it can wait for the entire time
  2236. of the timeout, even if output arrives.
  2237. See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=17647"
  2238. (let ((end-time (when timeout
  2239. (time-add (current-time)
  2240. (seconds-to-time timeout))))
  2241. (process (get-buffer-process (elpy-rpc--get-rpc-buffer))))
  2242. (while (and (not (elpy-promise-resolved-p promise))
  2243. (or (not end-time)
  2244. (time-less-p (current-time)
  2245. end-time)))
  2246. (accept-process-output process timeout))))
  2247. ;;;;;;;
  2248. ;;; RPC
  2249. ;; elpy-rpc is a simple JSON-based RPC protocol. It's mostly JSON-RPC
  2250. ;; 1.0, except we do not implement the full protocol as we do not need
  2251. ;; all the features. Emacs starts a Python subprocess which runs a
  2252. ;; special module. The module reads JSON-RPC requests and responds
  2253. ;; with JSON-RPC responses.
  2254. (defvar elpy-rpc--call-id 0
  2255. "Call id of the last elpy-rpc call.
  2256. Used to associate responses to callbacks.")
  2257. (make-variable-buffer-local 'elpy-rpc--call-id)
  2258. (defvar elpy-rpc--buffer-p nil
  2259. "True iff the current buffer is an elpy-rpc buffer.")
  2260. (make-variable-buffer-local 'elpy-rpc--buffer-p)
  2261. (defvar elpy-rpc--buffer nil
  2262. "The elpy-rpc buffer associated with this buffer.")
  2263. (make-variable-buffer-local 'elpy-rpc--buffer)
  2264. (defvar elpy-rpc--backend-library-root nil
  2265. "The project root used by this backend.")
  2266. (make-variable-buffer-local 'elpy-rpc--backend-library-root)
  2267. (defvar elpy-rpc--backend-python-command nil
  2268. "The Python interpreter used by this backend.")
  2269. (make-variable-buffer-local 'elpy-rpc--backend-python-command)
  2270. (defvar elpy-rpc--backend-callbacks nil
  2271. "The callbacks registered for calls to the current backend.
  2272. This maps call IDs to functions.")
  2273. (make-variable-buffer-local 'elpy-rpc--backend-callbacks)
  2274. (defvar elpy-rpc--last-call nil
  2275. "The time of the last RPC call issued for this backend.")
  2276. (make-variable-buffer-local 'elpy-rpc--last-call)
  2277. (defvar elpy-rpc--last-error-popup nil
  2278. "The last time an error popup happened.")
  2279. (defvar elpy-rpc--jedi-available nil
  2280. "Whether jedi is available or not.")
  2281. (defun elpy-rpc (method params &optional success error)
  2282. "Call METHOD with PARAMS in the backend.
  2283. If SUCCESS and optionally ERROR is given, return immediately and
  2284. call those when a result is available. Otherwise, wait for a
  2285. result and return that."
  2286. (when (not error)
  2287. (setq error #'elpy-rpc--default-error-callback))
  2288. (if success
  2289. (elpy-rpc--call method params success error)
  2290. (elpy-rpc--call-blocking method params)))
  2291. (defun elpy-rpc--call-blocking (method-name params)
  2292. "Call METHOD-NAME with PARAMS in the current RPC backend.
  2293. Returns the result, blocking until this arrived."
  2294. (let* ((result-arrived nil)
  2295. (error-occured nil)
  2296. (result-value nil)
  2297. (error-object nil)
  2298. (promise (elpy-rpc--call method-name params
  2299. (lambda (result)
  2300. (setq result-value result
  2301. result-arrived t))
  2302. (lambda (err)
  2303. (setq error-object err
  2304. error-occured t)))))
  2305. (elpy-promise-wait promise elpy-rpc-timeout)
  2306. (cond
  2307. (error-occured
  2308. (elpy-rpc--default-error-callback error-object))
  2309. (result-arrived
  2310. result-value)
  2311. (t
  2312. (error "Timeout during RPC call %s from backend"
  2313. method-name)))))
  2314. (defun elpy-rpc--call (method-name params success error)
  2315. "Call METHOD-NAME with PARAMS in the current RPC backend.
  2316. When a result is available, SUCCESS will be called with that
  2317. value as its sole argument. If an error occurs, ERROR will be
  2318. called with the error list.
  2319. Returns a PROMISE object."
  2320. (let ((promise (elpy-promise success error)))
  2321. (with-current-buffer (elpy-rpc--get-rpc-buffer)
  2322. (setq elpy-rpc--call-id (1+ elpy-rpc--call-id)
  2323. elpy-rpc--last-call (float-time))
  2324. (elpy-rpc--register-callback elpy-rpc--call-id promise)
  2325. (process-send-string
  2326. (get-buffer-process (current-buffer))
  2327. (let ((json-encoding-pretty-print nil)) ;; Link to bug https://github.com/jorgenschaefer/elpy/issues/1521
  2328. (concat (json-encode `((id . ,elpy-rpc--call-id)
  2329. (method . ,method-name)
  2330. (params . ,params)))
  2331. "\n"))))
  2332. promise))
  2333. (defun elpy-rpc--register-callback (call-id promise)
  2334. "Register for PROMISE to be called when CALL-ID returns.
  2335. Must be called in an elpy-rpc buffer."
  2336. (when (not elpy-rpc--buffer-p)
  2337. (error "Must be called in RPC buffer"))
  2338. (when (not elpy-rpc--backend-callbacks)
  2339. (setq elpy-rpc--backend-callbacks (make-hash-table :test #'equal)))
  2340. (puthash call-id promise elpy-rpc--backend-callbacks))
  2341. (defun elpy-rpc--get-rpc-buffer ()
  2342. "Return the RPC buffer associated with the current buffer,
  2343. creating one if necessary."
  2344. (when (not (elpy-rpc--process-buffer-p elpy-rpc--buffer))
  2345. (setq elpy-rpc--buffer
  2346. (or (elpy-rpc--find-buffer (elpy-library-root)
  2347. elpy-rpc-python-command)
  2348. (elpy-rpc--open (elpy-library-root)
  2349. elpy-rpc-python-command))))
  2350. elpy-rpc--buffer)
  2351. (defun elpy-rpc--process-buffer-p (buffer)
  2352. "Return non-nil when BUFFER is a live elpy-rpc process buffer.
  2353. If BUFFER is a buffer for an elpy-rpc process, but the process
  2354. died, this will kill the process and buffer."
  2355. (cond
  2356. ((or (not buffer)
  2357. (not (buffer-live-p buffer)))
  2358. nil)
  2359. ((not (buffer-local-value 'elpy-rpc--buffer-p buffer))
  2360. nil)
  2361. ((and (get-buffer-process buffer)
  2362. (process-live-p (get-buffer-process buffer)))
  2363. t)
  2364. (t
  2365. (ignore-errors
  2366. (kill-process (get-buffer-process buffer)))
  2367. (ignore-errors
  2368. (kill-buffer buffer))
  2369. nil)))
  2370. (defun elpy-rpc--find-buffer (library-root python-command)
  2371. "Return an existing RPC buffer for this project root and command."
  2372. (catch 'return
  2373. (let ((full-python-command (executable-find python-command)))
  2374. (dolist (buf (buffer-list))
  2375. (when (and (elpy-rpc--process-buffer-p buf)
  2376. (equal (buffer-local-value 'elpy-rpc--backend-library-root
  2377. buf)
  2378. library-root)
  2379. (equal (buffer-local-value 'elpy-rpc--backend-python-command
  2380. buf)
  2381. full-python-command))
  2382. (throw 'return buf))))
  2383. nil))
  2384. (defun elpy-rpc--open (library-root python-command)
  2385. "Start a new RPC process and return the associated buffer."
  2386. (elpy-rpc--cleanup-buffers)
  2387. (let* ((full-python-command (executable-find python-command))
  2388. (name (format " *elpy-rpc [project:%s python:%s]*"
  2389. library-root
  2390. full-python-command))
  2391. (new-elpy-rpc-buffer (generate-new-buffer name))
  2392. (proc nil))
  2393. (when (not full-python-command)
  2394. (error "Can't find Python command, configure `elpy-rpc-python-command'"))
  2395. (with-current-buffer new-elpy-rpc-buffer
  2396. (setq elpy-rpc--buffer-p t
  2397. elpy-rpc--buffer (current-buffer)
  2398. elpy-rpc--backend-library-root library-root
  2399. elpy-rpc--backend-python-command full-python-command
  2400. default-directory "/"
  2401. proc (condition-case err
  2402. (let ((process-connection-type nil)
  2403. (process-environment (elpy-rpc--environment)))
  2404. (start-process name
  2405. (current-buffer)
  2406. full-python-command
  2407. "-W" "ignore"
  2408. "-m" "elpy.__main__"))
  2409. (error
  2410. (elpy-config-error
  2411. "Elpy can't start Python (%s: %s)"
  2412. (car err) (cadr err)))))
  2413. (set-process-query-on-exit-flag proc nil)
  2414. (set-process-sentinel proc #'elpy-rpc--sentinel)
  2415. (set-process-filter proc #'elpy-rpc--filter)
  2416. (elpy-rpc-init library-root
  2417. (lambda (result)
  2418. (setq elpy-rpc--jedi-available
  2419. (cdr (assq 'jedi_available result))))))
  2420. new-elpy-rpc-buffer))
  2421. (defun elpy-rpc--cleanup-buffers ()
  2422. "Close RPC buffers that have not been used in five minutes."
  2423. (when elpy-rpc-maximum-buffer-age
  2424. (let ((old (- (float-time)
  2425. elpy-rpc-maximum-buffer-age)))
  2426. (dolist (buffer (buffer-list))
  2427. (when (and (elpy-rpc--process-buffer-p buffer)
  2428. (< (or (buffer-local-value 'elpy-rpc--last-call buffer)
  2429. old)
  2430. old))
  2431. (ignore-errors
  2432. (kill-process (get-buffer-process buffer)))
  2433. (ignore-errors
  2434. (kill-buffer buffer)))))))
  2435. (defun elpy-rpc--sentinel (process event)
  2436. "The sentinel for the RPC process.
  2437. As process sentinels are only ever called when the process
  2438. terminates, this will call the error handler of all registered
  2439. RPC calls with the event."
  2440. (let ((buffer (process-buffer process))
  2441. (err (list 'process-sentinel (substring event 0 -1))))
  2442. (when (and buffer
  2443. (buffer-live-p buffer))
  2444. (with-current-buffer buffer
  2445. (when elpy-rpc--backend-callbacks
  2446. (maphash (lambda (_call-id promise)
  2447. (ignore-errors
  2448. (elpy-promise-reject promise err)))
  2449. elpy-rpc--backend-callbacks)
  2450. (setq elpy-rpc--backend-callbacks nil))))))
  2451. (defun elpy-rpc--filter (process output)
  2452. "The filter for the RPC process."
  2453. (let ((buffer (process-buffer process)))
  2454. (when (and buffer
  2455. (buffer-live-p buffer))
  2456. (with-current-buffer buffer
  2457. (goto-char (point-max))
  2458. (insert output)
  2459. (while (progn
  2460. (goto-char (point-min))
  2461. (search-forward "\n" nil t))
  2462. (let ((line-end (point))
  2463. (json nil)
  2464. (did-read-json nil))
  2465. (goto-char (point-min))
  2466. (condition-case _err
  2467. (progn
  2468. (setq json (let ((json-array-type 'list)
  2469. (json-encoding-pretty-print nil)) ;; Link to bug https://github.com/jorgenschaefer/elpy/issues/1521
  2470. (json-read)))
  2471. (if (listp json)
  2472. (setq line-end (1+ (point))
  2473. did-read-json t)
  2474. (goto-char (point-min))))
  2475. (error
  2476. (goto-char (point-min))))
  2477. (cond
  2478. (did-read-json
  2479. (delete-region (point-min) line-end)
  2480. (elpy-rpc--handle-json json))
  2481. ((looking-at "elpy-rpc ready\n")
  2482. (replace-match "")
  2483. (elpy-rpc--check-backend-version "1.1"))
  2484. ((looking-at "elpy-rpc ready (\\([^ ]*\\))\n")
  2485. (let ((rpc-version (match-string 1)))
  2486. (replace-match "")
  2487. (elpy-rpc--check-backend-version rpc-version)))
  2488. ((looking-at ".*No module named elpy\n")
  2489. (replace-match "")
  2490. (elpy-config-error "Elpy module not found"))
  2491. (t
  2492. (let ((line (buffer-substring (point-min)
  2493. line-end)))
  2494. (delete-region (point-min) line-end)
  2495. (elpy-rpc--handle-unexpected-line line))))))))))
  2496. (defun elpy-rpc--check-backend-version (rpc-version)
  2497. "Check that we are using the right version."
  2498. (when (not (equal rpc-version elpy-version))
  2499. (elpy-insert--popup "*Elpy Version Mismatch*"
  2500. (elpy-insert--header "Elpy Version Mismatch")
  2501. (elpy-insert--para
  2502. "You are not using the same version of Elpy in Emacs Lisp "
  2503. "compared to Python. This can cause random problems. Please "
  2504. "do make sure to use compatible versions.\n\n"
  2505. "This often happens because you have an obsolete elpy python "
  2506. "package installed on your system/virtualenv. This package "
  2507. "shadows the elpy python package shipped with elpy, leading "
  2508. "to this mismatch. If it is the case, uninstalling the elpy "
  2509. "python package (with pip for example) should resolve the issue.\n")
  2510. (insert
  2511. "\n"
  2512. "Elpy Emacs Lisp version: " elpy-version "\n"
  2513. "Elpy Python version....: " rpc-version "\n"))))
  2514. (defun elpy-rpc--handle-unexpected-line (line)
  2515. "Handle an unexpected line from the backend.
  2516. This is usually an error or backtrace."
  2517. (let ((buf (get-buffer "*Elpy Output*")))
  2518. (when (not buf)
  2519. (elpy-insert--popup "*Elpy Output*"
  2520. (elpy-insert--header "Output from Backend")
  2521. (elpy-insert--para
  2522. "There was some unexpected output from the Elpy backend. "
  2523. "This is usually not a problem and should usually not be "
  2524. "reported as a bug with Elpy. You can safely hide this "
  2525. "buffer and ignore it. You can also see the output below "
  2526. "in case there is an actual problem.\n\n")
  2527. (elpy-insert--header "Output")
  2528. (setq buf (current-buffer))))
  2529. (with-current-buffer buf
  2530. (goto-char (point-max))
  2531. (let ((inhibit-read-only t))
  2532. (insert line)))))
  2533. (defun elpy-rpc--handle-json (json)
  2534. "Handle a single JSON object from the RPC backend."
  2535. (let ((call-id (cdr (assq 'id json)))
  2536. (error-object (cdr (assq 'error json)))
  2537. (result (cdr (assq 'result json))))
  2538. (let ((promise (gethash call-id elpy-rpc--backend-callbacks)))
  2539. (when (not promise)
  2540. (error "Received a response for unknown call-id %s" call-id))
  2541. (remhash call-id elpy-rpc--backend-callbacks)
  2542. (if error-object
  2543. (elpy-promise-reject promise error-object)
  2544. (elpy-promise-resolve promise result)))))
  2545. (defun elpy-rpc--default-error-callback (error-object)
  2546. "Display an error from the RPC backend."
  2547. ;; We actually might get an (error "foo") thing here.
  2548. (if (and (consp error-object)
  2549. (not (consp (car error-object))))
  2550. (signal (car error-object) (cdr error-object))
  2551. (let ((message (cdr (assq 'message error-object)))
  2552. (code (cdr (assq 'code error-object)))
  2553. (data (cdr (assq 'data error-object))))
  2554. (cond
  2555. ((not (numberp code))
  2556. (error "Bad response from RPC: %S" error-object))
  2557. ((< code 300)
  2558. (message "Elpy warning: %s" message))
  2559. ((< code 500)
  2560. (error "Elpy error: %s" message))
  2561. ((and elpy-rpc-error-timeout
  2562. elpy-rpc--last-error-popup
  2563. (<= (float-time)
  2564. (+ elpy-rpc--last-error-popup
  2565. elpy-rpc-error-timeout)))
  2566. (message "Elpy error popup ignored, see `elpy-rpc-error-timeout': %s"
  2567. message))
  2568. ((not elpy-disable-backend-error-display)
  2569. (let ((config (elpy-config--get-config)))
  2570. (elpy-insert--popup "*Elpy Error*"
  2571. (elpy-insert--header "Elpy Error")
  2572. (elpy-insert--para
  2573. "The backend encountered an unexpected error. This indicates "
  2574. "a bug in Elpy. Please open a bug report with the data below "
  2575. "in the Elpy bug tracker:")
  2576. (insert "\n"
  2577. "\n")
  2578. (insert-button
  2579. "https://github.com/jorgenschaefer/elpy/issues/new"
  2580. 'action (lambda (button)
  2581. (browse-url (button-get button 'url)))
  2582. 'url "https://github.com/jorgenschaefer/elpy/issues/new")
  2583. (insert "\n"
  2584. "\n"
  2585. "```\n")
  2586. (elpy-insert--header "Error Message")
  2587. (insert message "\n\n")
  2588. (elpy-insert--header "Configuration")
  2589. (elpy-config--insert-configuration-table config)
  2590. (let ((traceback (cdr (assq 'traceback data))))
  2591. (when traceback
  2592. (insert "\n")
  2593. (elpy-insert--header "Traceback")
  2594. (insert traceback)))
  2595. (let ((jedi-info (cdr (assq 'jedi_debug_info data))))
  2596. (when jedi-info
  2597. (insert "\n")
  2598. (elpy-insert--header "Jedi Debug Information")
  2599. (pcase (cdr (assq 'debug_info jedi-info))
  2600. (`nil (insert "Jedi did not emit any debug info.\n"))
  2601. (infos
  2602. (dolist (outstr infos)
  2603. (insert outstr "\n"))))
  2604. (insert "\n"
  2605. "```\n"
  2606. "\n"
  2607. "Reproduction:\n"
  2608. "\n")
  2609. (let ((method (cdr (assq 'method jedi-info)))
  2610. (source (cdr (assq 'source jedi-info)))
  2611. (script-args (cdr (assq 'script_args jedi-info))))
  2612. (insert "```Python\n")
  2613. (insert "import jedi\n"
  2614. "\n"
  2615. "source = '''\\\n"
  2616. source
  2617. "'''\n"
  2618. "\n"
  2619. "script = jedi.Script(" script-args ")\n"
  2620. "script." method "()\n"))))
  2621. (let ((rope-info (cdr (assq 'rope_debug_info data))))
  2622. (when rope-info
  2623. (insert "\n")
  2624. (elpy-insert--header "Rope Debug Information")
  2625. (insert "```\n"
  2626. "\n"
  2627. "Reproduction:\n"
  2628. "\n")
  2629. (let ((project-root (cdr (assq 'project_root rope-info)))
  2630. (filename (cdr (assq 'filename rope-info)))
  2631. (source (cdr (assq 'source rope-info)))
  2632. (function-name (cdr (assq 'function_name rope-info)))
  2633. (function-args (cdr (assq 'function_args rope-info))))
  2634. (insert "```Python\n")
  2635. (insert "\n"
  2636. "source = '''\n"
  2637. source
  2638. "'''\n"
  2639. "\n")
  2640. (insert "project = rope.base.project.Project(\n"
  2641. (format " %S,\n" project-root)
  2642. " ropefolder=None\n"
  2643. ")\n")
  2644. (insert "resource = rope.base.libutils.path_to_resource(\n"
  2645. " project,\n"
  2646. (format " %S,\n" filename)
  2647. " 'file'\n"
  2648. ")\n")
  2649. (insert (format "%s(\n %s\n)\n"
  2650. function-name function-args)))))
  2651. (when (not (= 0 (current-column)))
  2652. (insert "\n"))
  2653. (insert "```"))
  2654. (setq elpy-rpc--last-error-popup (float-time))))))))
  2655. (defun elpy-rpc--environment ()
  2656. "Return a `process-environment' for the RPC process.
  2657. This includes `elpy-rpc-pythonpath' in the PYTHONPATH, if set."
  2658. (if (or (not elpy-rpc-pythonpath)
  2659. (not (file-exists-p (expand-file-name "elpy/__init__.py"
  2660. elpy-rpc-pythonpath))))
  2661. process-environment
  2662. (let* ((old-pythonpath (getenv "PYTHONPATH"))
  2663. (new-pythonpath (if old-pythonpath
  2664. (concat elpy-rpc-pythonpath
  2665. path-separator
  2666. old-pythonpath)
  2667. elpy-rpc-pythonpath)))
  2668. (cons (concat "PYTHONPATH=" new-pythonpath)
  2669. process-environment))))
  2670. (defun elpy-rpc--buffer-contents ()
  2671. "Return the contents of the current buffer.
  2672. This returns either a string, or a file object for the RPC
  2673. protocol if the buffer is larger than
  2674. `elpy-rpc-large-buffer-size'."
  2675. (if (< (buffer-size) elpy-rpc-large-buffer-size)
  2676. (buffer-string)
  2677. (let ((file-name (make-temp-file "elpy-rpc-"))
  2678. (coding-system-for-write 'utf-8))
  2679. (write-region nil nil file-name nil :nomessage)
  2680. `((filename . ,file-name)
  2681. (delete_after_use . t)))))
  2682. (defun elpy-rpc--region-contents ()
  2683. "Return the selected region as a string."
  2684. (if (use-region-p)
  2685. (buffer-substring (region-beginning) (region-end))))
  2686. (defun elpy-rpc--disconnect ()
  2687. "Disconnect rpc process from elpy buffers."
  2688. (dolist (buf (buffer-list))
  2689. (with-current-buffer buf
  2690. (when (memq 'elpy-mode minor-mode-list)
  2691. (setq elpy-rpc--buffer nil)))))
  2692. ;; RPC API functions
  2693. (defun elpy-rpc-restart ()
  2694. "Restart all RPC processes."
  2695. (interactive)
  2696. (dolist (buffer (buffer-list))
  2697. (when (elpy-rpc--process-buffer-p buffer)
  2698. (ignore-errors
  2699. (kill-process (get-buffer-process buffer)))
  2700. (ignore-errors
  2701. (kill-buffer buffer)))))
  2702. (defun elpy-rpc-init (library-root &optional success error)
  2703. "Initialize the backend.
  2704. This has to be called as the first method, else Elpy won't be
  2705. able to respond to other calls."
  2706. (elpy-rpc "init"
  2707. ;; This uses a vector because otherwise, json-encode in
  2708. ;; older Emacsen gets seriously confused, especially when
  2709. ;; backend is nil.
  2710. (vector `((project_root . ,(expand-file-name library-root))))
  2711. success error))
  2712. (defun elpy-rpc-get-calltip (&optional success error)
  2713. "Call the get_calltip API function.
  2714. Returns a calltip string for the function call at point."
  2715. (when (< (buffer-size) elpy-rpc-ignored-buffer-size)
  2716. (elpy-rpc "get_calltip"
  2717. (list buffer-file-name
  2718. (elpy-rpc--buffer-contents)
  2719. (- (point)
  2720. (point-min)))
  2721. success error)))
  2722. (defun elpy-rpc-get-oneline-docstring (&optional success error)
  2723. "Call the get_oneline_docstring API function.
  2724. Returns a oneline docstring string for the symbol at point."
  2725. (when (< (buffer-size) elpy-rpc-ignored-buffer-size)
  2726. (elpy-rpc "get_oneline_docstring"
  2727. (list buffer-file-name
  2728. (elpy-rpc--buffer-contents)
  2729. (- (point)
  2730. (point-min)))
  2731. success error)))
  2732. (defun elpy-rpc-get-completions (&optional success error)
  2733. "Call the get_completions API function.
  2734. Returns a list of possible completions for the Python symbol at
  2735. point."
  2736. (when (and (< (buffer-size) elpy-rpc-ignored-buffer-size)
  2737. (not (string-match "^[0-9]+$" (symbol-name (symbol-at-point)))))
  2738. (elpy-rpc "get_completions"
  2739. (list buffer-file-name
  2740. (elpy-rpc--buffer-contents)
  2741. (- (point)
  2742. (point-min)))
  2743. success error)))
  2744. (defun elpy-rpc-get-completion-docstring (completion &optional success error)
  2745. "Call the get_completion_docstring API function.
  2746. Returns a doc string or nil"
  2747. (elpy-rpc "get_completion_docstring" (list completion) success error))
  2748. (defun elpy-rpc-get-completion-location (completion &optional success error)
  2749. "Call the get_completion_location API function.
  2750. Returns a list of file name and line number, or nil"
  2751. (elpy-rpc "get_completion_location" (list completion) success error))
  2752. (defun elpy-rpc-get-definition (&optional success error)
  2753. "Call the find_definition API function.
  2754. Returns nil or a list of (filename, point)."
  2755. (elpy-rpc "get_definition"
  2756. (list buffer-file-name
  2757. (elpy-rpc--buffer-contents)
  2758. (- (point)
  2759. (point-min)))
  2760. success error))
  2761. (defun elpy-rpc-get-assignment (&optional success error)
  2762. "Call the find_assignment API function.
  2763. Returns nil or a list of (filename, point)."
  2764. (elpy-rpc "get_assignment"
  2765. (list buffer-file-name
  2766. (elpy-rpc--buffer-contents)
  2767. (- (point)
  2768. (point-min)))
  2769. success error))
  2770. (defun elpy-rpc-get-docstring (&optional success error)
  2771. "Call the get_docstring API function.
  2772. Returns a possible multi-line docstring for the symbol at point."
  2773. (elpy-rpc "get_docstring"
  2774. (list buffer-file-name
  2775. (elpy-rpc--buffer-contents)
  2776. (- (point)
  2777. (point-min)))
  2778. success error))
  2779. (defun elpy-rpc-get-pydoc-completions (prefix &optional success error)
  2780. "Return a list of modules available in pydoc starting with PREFIX."
  2781. (elpy-rpc "get_pydoc_completions" (list prefix)
  2782. success error))
  2783. (defun elpy-rpc-get-pydoc-documentation (symbol &optional success error)
  2784. "Get the Pydoc documentation for SYMBOL.
  2785. Returns a possible multi-line docstring."
  2786. (elpy-rpc "get_pydoc_documentation" (list symbol)
  2787. success error))
  2788. (defun elpy-rpc-get-usages (&optional success error)
  2789. "Return the symbol under point usages as a list"
  2790. (elpy-rpc "get_usages"
  2791. (list buffer-file-name
  2792. (elpy-rpc--buffer-contents)
  2793. (- (point)
  2794. (point-min)))
  2795. success error))
  2796. (defun elpy-rpc-get-names (&optional success error)
  2797. "Return all names (possible candidates for jumping to definition)."
  2798. (elpy-rpc "get_names"
  2799. (list buffer-file-name
  2800. (elpy-rpc--buffer-contents)
  2801. (- (point)
  2802. (point-min)))
  2803. success error))
  2804. ;;;;;;;;;;;;;;;;
  2805. ;;; Xref backend
  2806. (defun elpy--xref-backend ()
  2807. "Return the name of the elpy xref backend."
  2808. ;; If no rpc available, start one and assume jedi is available
  2809. (if (or (and (not (elpy-rpc--process-buffer-p elpy-rpc--buffer))
  2810. (elpy-rpc--get-rpc-buffer))
  2811. elpy-rpc--jedi-available)
  2812. 'elpy
  2813. nil))
  2814. (defvar elpy-xref--format-references
  2815. (let ((str "%s:\t%s"))
  2816. (put-text-property 0 4 'face 'font-lock-comment-face str)
  2817. str)
  2818. "String used to format references in xref buffers.")
  2819. ;; Elpy location structure
  2820. (when (featurep 'xref)
  2821. (cl-defstruct (xref-elpy-location
  2822. (:constructor xref-make-elpy-location (file pos)))
  2823. "Location of a python symbol definition."
  2824. file pos)
  2825. (defun xref-make-elpy-location (file pos)
  2826. "Return an elpy location structure.
  2827. Points to file FILE, at position POS."
  2828. (make-instance 'xref-etags-location
  2829. :file (expand-file-name file)
  2830. :pos pos))
  2831. (cl-defmethod xref-location-marker ((l xref-elpy-location))
  2832. (with-current-buffer (find-file-noselect (xref-elpy-location-file l))
  2833. (save-excursion
  2834. (goto-char (xref-elpy-location-pos l))
  2835. (point-marker))))
  2836. (cl-defmethod xref-location-group ((l xref-elpy-location))
  2837. (xref-elpy-location-file l))
  2838. ;; Identifiers
  2839. (cl-defmethod xref-backend-identifier-at-point ((_backend (eql elpy)))
  2840. (elpy-xref--identifier-at-point))
  2841. (defun elpy-xref--identifier-at-point ()
  2842. "Return identifier at point.
  2843. Is a string, formatted as \"LINE_NUMBER: VARIABLE_NAME\".
  2844. "
  2845. (let* ((symb (symbol-at-point))
  2846. (symb-str (substring-no-properties (symbol-name symb))))
  2847. (when symb
  2848. (format "%s: %s" (line-number-at-pos) symb-str))))
  2849. (defun elpy-xref--identifier-name (id)
  2850. "Return the identifier ID variable name."
  2851. (string-match ".*: \\([^:]*\\)" id)
  2852. (match-string 1 id))
  2853. (defun elpy-xref--identifier-line (id)
  2854. "Return the identifier ID line number."
  2855. (string-match "\\([^:]*\\):.*" id)
  2856. (string-to-number (match-string 1 id)))
  2857. (defun elpy-xref--goto-identifier (id)
  2858. "Goto the identifier ID in the current buffer.
  2859. This is needed to get information on the identifier with jedi
  2860. \(that work only on the symbol at point\)"
  2861. (let ((case-fold-search nil))
  2862. (goto-char (point-min))
  2863. (forward-line (1- (elpy-xref--identifier-line id)))
  2864. (search-forward (elpy-xref--identifier-name id) (line-end-position))
  2865. (goto-char (match-beginning 0))))
  2866. ;; Find definition
  2867. (cl-defmethod xref-backend-definitions ((_backend (eql elpy)) id)
  2868. (elpy-xref--definitions id))
  2869. (defun elpy-xref--definitions (id)
  2870. "Return SYMBOL definition position as a xref object."
  2871. (save-excursion
  2872. (elpy-xref--goto-identifier id)
  2873. (let* ((location (elpy-rpc-get-definition)))
  2874. (if (not location)
  2875. (error "No definition found")
  2876. (let* ((file (expand-file-name (car location)))
  2877. (pos (+ 1 (cadr location)))
  2878. (line (with-current-buffer (find-file-noselect file)
  2879. (goto-char (+ pos 1))
  2880. (buffer-substring (line-beginning-position) (line-end-position))))
  2881. (linenumber (with-current-buffer (find-file-noselect file)
  2882. (line-number-at-pos pos)))
  2883. (summary (format elpy-xref--format-references linenumber line))
  2884. (loc (xref-make-elpy-location file pos)))
  2885. (list (xref-make summary loc)))))))
  2886. ;; Find references
  2887. (cl-defmethod xref-backend-references ((_backend (eql elpy)) id)
  2888. (elpy-xref--references id))
  2889. (defun elpy-xref--references (id)
  2890. "Return SYMBOL references as a list of xref objects."
  2891. (save-excursion
  2892. (elpy-xref--goto-identifier id)
  2893. (let* ((references (elpy-rpc-get-usages)))
  2894. (cl-loop
  2895. for ref in references
  2896. for file = (alist-get 'filename ref)
  2897. for pos = (+ (alist-get 'offset ref) 1)
  2898. for line = (when file
  2899. (with-current-buffer (find-file-noselect file)
  2900. (save-excursion
  2901. (goto-char (+ pos 1))
  2902. (buffer-substring (line-beginning-position) (line-end-position)))))
  2903. for linenumber = (when file
  2904. (with-current-buffer (find-file-noselect file)
  2905. (line-number-at-pos pos)))
  2906. for summary = (format elpy-xref--format-references linenumber line)
  2907. for loc = (xref-make-elpy-location file pos)
  2908. if file
  2909. collect (xref-make summary loc)))))
  2910. ;; Completion table (used when calling `xref-find-references`)
  2911. (cl-defmethod xref-backend-identifier-completion-table ((_backend (eql elpy)))
  2912. (elpy-xref--get-completion-table))
  2913. (defun elpy-xref--get-completion-table ()
  2914. "Return the completion table for identifiers."
  2915. (cl-loop
  2916. for ref in (nreverse (elpy-rpc-get-names))
  2917. for offset = (+ (alist-get 'offset ref) 1)
  2918. for line = (line-number-at-pos offset)
  2919. for id = (format "%s: %s" line (alist-get 'name ref))
  2920. collect id))
  2921. ;; Apropos
  2922. (cl-defmethod xref-backend-apropos ((_backend (eql elpy)) regex)
  2923. (elpy-xref--apropos regex))
  2924. (defun elpy-xref--apropos (regex)
  2925. "Return identifiers matching REGEX."
  2926. (let ((ids (elpy-rpc-get-names))
  2927. (case-fold-search nil))
  2928. (cl-loop
  2929. for id in ids
  2930. for name = (alist-get 'name id)
  2931. for filename = (alist-get 'filename id)
  2932. for pos = (+ (alist-get 'offset id) 1)
  2933. if (string-match regex name)
  2934. collect (with-current-buffer (find-file-noselect filename)
  2935. (goto-char pos)
  2936. (save-excursion
  2937. (let* ((linenumber (line-number-at-pos))
  2938. (line (buffer-substring
  2939. (line-beginning-position)
  2940. (line-end-position)))
  2941. (summary (format elpy-xref--format-references linenumber line))
  2942. (loc (xref-make-elpy-location filename pos)))
  2943. (xref-make summary loc)))))))
  2944. )
  2945. ;;;;;;;;;;;
  2946. ;;; Modules
  2947. (defvar elpy-modules-initialized-p nil
  2948. "Boolean, set to true if modules were run with `global-init'.")
  2949. (defun elpy-modules-run (command &rest args)
  2950. "Run COMMAND with ARGS for all modules in `elpy-modules'."
  2951. (dolist (module elpy-modules)
  2952. (apply module command args)))
  2953. (defun elpy-modules-global-init ()
  2954. "Run the global-init method of Elpy modules.
  2955. Make sure this only happens once."
  2956. (when (not elpy-modules-initialized-p)
  2957. (elpy-modules-run 'global-init)
  2958. (setq elpy-modules-initialized-p t)))
  2959. (defun elpy-modules-global-stop ()
  2960. "Run the global-stop method of Elpy modules.
  2961. Make sure this only happens once per global-init call."
  2962. (when elpy-modules-initialized-p
  2963. (elpy-modules-run 'global-stop)
  2964. (setq elpy-modules-initialized-p nil)))
  2965. (defun elpy-modules-buffer-init ()
  2966. "Run the buffer-init method of Elpy modules.
  2967. Make sure global-init is called first."
  2968. (elpy-modules-global-init)
  2969. (elpy-modules-run 'buffer-init))
  2970. (defun elpy-modules-buffer-stop ()
  2971. "Run the buffer-stop method of Elpy modules."
  2972. (elpy-modules-run 'buffer-stop))
  2973. (defun elpy-modules-remove-modeline-lighter (modename)
  2974. "Remove the lighter for MODENAME.
  2975. It should not be necessary to see (Python Elpy yas company ElDoc) all the
  2976. time.
  2977. If you need your modeline, you can set the variable `elpy-remove-modeline-lighter' to nil
  2978. "
  2979. (interactive)
  2980. (when elpy-remove-modeline-lighter
  2981. (cond
  2982. ((eq modename 'eldoc-minor-mode)
  2983. (setq eldoc-minor-mode-string nil))
  2984. (t
  2985. (let ((cell (assq modename minor-mode-alist)))
  2986. (when cell
  2987. (setcdr cell
  2988. (list ""))))))))
  2989. ;;;;;;;;;;;;;;;;;;;;;;;;;
  2990. ;;; Module: Sane Defaults
  2991. (defun elpy-module-sane-defaults (command &rest _args)
  2992. (pcase command
  2993. (`buffer-init
  2994. ;; Set `forward-sexp-function' to nil in python-mode. See
  2995. ;; http://debbugs.gnu.org/db/13/13642.html
  2996. (set (make-local-variable 'forward-sexp-function) nil)
  2997. ;; PEP8 recommends two spaces in front of inline comments.
  2998. (set (make-local-variable 'comment-inline-offset) 2))
  2999. (`buffer-stop
  3000. (kill-local-variable 'forward-sexp-function)
  3001. (kill-local-variable 'comment-inline-offset))))
  3002. ;;;;;;;;;;;;;;;;;;;
  3003. ;;; Module: Company
  3004. (defun elpy-module-company (command &rest _args)
  3005. "Module to support company-mode completions."
  3006. (pcase command
  3007. (`global-init
  3008. (require 'company)
  3009. (require 'company-capf)
  3010. (elpy-modules-remove-modeline-lighter 'company-mode)
  3011. (define-key company-active-map (kbd "C-d")
  3012. 'company-show-doc-buffer)
  3013. (add-hook 'inferior-python-mode-hook
  3014. (lambda ()
  3015. ;; Workaround for company bug
  3016. ;; (https://github.com/company-mode/company-mode/issues/759)
  3017. (setq-local company-transformers
  3018. (remove 'company-sort-by-occurrence
  3019. company-transformers))
  3020. ;; Be sure to trigger completion for one character variable
  3021. ;; (i.e. `a.`)
  3022. (setq-local company-minimum-prefix-length 2))))
  3023. (`buffer-init
  3024. ;; We want immediate completions from company.
  3025. (set (make-local-variable 'company-idle-delay)
  3026. 0.1)
  3027. ;; And annotations should be right-aligned.
  3028. (set (make-local-variable 'company-tooltip-align-annotations)
  3029. t)
  3030. ;; Also, dabbrev in comments and strings is nice.
  3031. (set (make-local-variable 'company-dabbrev-code-everywhere)
  3032. t)
  3033. ;; Add our own backend and remove a bunch of backends that
  3034. ;; interfere in Python mode.
  3035. (set (make-local-variable 'company-backends)
  3036. (cons 'elpy-company-backend
  3037. (delq 'company-semantic
  3038. (delq 'company-ropemacs
  3039. (delq 'company-capf
  3040. (mapcar #'identity company-backends))))))
  3041. (company-mode 1)
  3042. (when (> (buffer-size) elpy-rpc-ignored-buffer-size)
  3043. (message
  3044. (concat "Buffer %s larger than elpy-rpc-ignored-buffer-size (%d)."
  3045. " Elpy will turn off completion.")
  3046. (buffer-name) elpy-rpc-ignored-buffer-size)))
  3047. (`buffer-stop
  3048. (company-mode -1)
  3049. (kill-local-variable 'company-idle-delay)
  3050. (kill-local-variable 'company-tooltip-align-annotations)
  3051. (kill-local-variable 'company-backends))
  3052. ))
  3053. (defvar elpy-company--cache nil
  3054. "Buffer-local cache for candidate information.")
  3055. (make-variable-buffer-local 'elpy-company--cache)
  3056. (defun elpy-company--cache-clear ()
  3057. "Clear and initialize the cache."
  3058. (if elpy-company--cache
  3059. (clrhash elpy-company--cache)
  3060. (setq elpy-company--cache
  3061. (make-hash-table :test #'equal))))
  3062. (defun elpy-company--cache-annotation (name)
  3063. "Return the cached annotation for NAME."
  3064. (when elpy-company--cache
  3065. (cdr (assq 'annotation (gethash name elpy-company--cache)))))
  3066. (defun elpy-company--cache-meta (name)
  3067. "Return the cached annotation for NAME."
  3068. (when elpy-company--cache
  3069. (cdr (assq 'meta (gethash name elpy-company--cache)))))
  3070. (defun elpy-company--cache-name (name)
  3071. "Return the cached name for NAME.
  3072. Confused yet? We pass \"our\" name, that is, prefix + suffix,
  3073. here, and return the \"name\" as used by the backend."
  3074. (when elpy-company--cache
  3075. (cdr (assq 'name (gethash name elpy-company--cache)))))
  3076. (defun elpy-company--cache-completions (prefix result)
  3077. "Store RESULT in the candidate cache and return candidates."
  3078. (elpy-company--cache-clear)
  3079. (mapcar (lambda (completion)
  3080. (let* ((suffix (cdr (assq 'name completion)))
  3081. (name (concat (s-chop-suffix (company-grab-symbol) prefix) suffix)))
  3082. (puthash name completion elpy-company--cache)
  3083. name))
  3084. result))
  3085. (defun elpy-company--python-exception-p (name)
  3086. "Check whether NAME is a Python exception."
  3087. (member name '("ArithmeticError"
  3088. "AssertionError"
  3089. "AttributeError"
  3090. "BlockingIOError"
  3091. "BrokenPipeError"
  3092. "BufferError"
  3093. "BytesWarning"
  3094. "ChildProcessError"
  3095. "ConnectionAbortedError"
  3096. "ConnectionError"
  3097. "ConnectionRefusedError"
  3098. "ConnectionResetError"
  3099. "DeprecationWarning"
  3100. "EOFError"
  3101. "EnvironmentError"
  3102. "Exception"
  3103. "FileExistsError"
  3104. "FileNotFoundError"
  3105. "FloatingPointError"
  3106. "FutureWarning"
  3107. "IOError"
  3108. "ImportError"
  3109. "ImportWarning"
  3110. "IndentationError"
  3111. "IndexError"
  3112. "InterruptedError"
  3113. "IsADirectoryError"
  3114. "KeyError"
  3115. "LookupError"
  3116. "MemoryError"
  3117. "NameError"
  3118. "NotADirectoryError"
  3119. "NotImplementedError"
  3120. "OSError"
  3121. "OverflowError"
  3122. "PendingDeprecationWarning"
  3123. "PermissionError"
  3124. "ProcessLookupError"
  3125. "RecursionError"
  3126. "ReferenceError"
  3127. "ResourceWarning"
  3128. "RuntimeError"
  3129. "RuntimeWarning"
  3130. "StandardError"
  3131. "StopAsyncIteration"
  3132. "StopIteration"
  3133. "SyntaxError"
  3134. "SyntaxWarning"
  3135. "SystemError"
  3136. "TabError"
  3137. "TimeoutError"
  3138. "TypeError"
  3139. "UnboundLocalError"
  3140. "UnicodeDecodeError"
  3141. "UnicodeEncodeError"
  3142. "UnicodeError"
  3143. "UnicodeTranslateError"
  3144. "UnicodeWarning"
  3145. "UserWarning"
  3146. "ValueError"
  3147. "Warning"
  3148. "ZeroDivisionError")))
  3149. (defun elpy-company-post-complete-parens (annotation name)
  3150. "Complete functions, classes, and callable instances with parentheses.
  3151. Add parentheses in case ANNOTATION is \"class\", \"function\", or \"instance\",
  3152. unless the completion is already looking at a left parenthesis,
  3153. or unless NAME is a Python exception outside a reasonably formed raise statement,
  3154. or unless NAME is no callable instance."
  3155. (when (not (looking-at-p "\("))
  3156. (cond ((string= annotation "function")
  3157. (insert "()")
  3158. (backward-char 1))
  3159. ((string= annotation "class")
  3160. (cond ((elpy-company--python-exception-p name)
  3161. (when (save-excursion
  3162. (backward-word 2)
  3163. (looking-at "\\_<raise\\_>"))
  3164. (insert "()")
  3165. (backward-char 1)))
  3166. (t
  3167. (insert "()")
  3168. (backward-char 1))))
  3169. ((string= annotation "instance")
  3170. ;; The jedi backend annotates some callables as instances (e.g. numpy
  3171. ;; and scipy) and `elpy-company--cache' does not allow to identify
  3172. ;; callable instances.
  3173. ;; It looks easy to modify `elpy-company--cache' cheaply for the jedi
  3174. ;; backend to eliminate the `elpy-rpc-get-calltip' call below.
  3175. (insert "()")
  3176. (backward-char 1)
  3177. (when (not (elpy-rpc-get-calltip))
  3178. (backward-char 1)
  3179. (delete-char 2))))))
  3180. (defun elpy-company--add-interpreter-completions-candidates (candidates)
  3181. "Add completions candidates from the shell to the list of candidates.
  3182. Get completions candidates at point from the shell, normalize them to look
  3183. like what elpy-company returns, merge them with the CANDIDATES list
  3184. and return the list."
  3185. ;; Check if prompt available
  3186. (if (not (and elpy-get-info-from-shell
  3187. (elpy-shell--check-if-shell-available)))
  3188. candidates
  3189. ;; Completion need the cursor to be at the end of the shell buffer
  3190. (save-excursion
  3191. (with-current-buffer (process-buffer (python-shell-get-process))
  3192. (goto-char (point-max)))
  3193. ;; Try to get the info with timeout
  3194. (let* ((new-candidates (with-timeout (elpy-get-info-from-shell-timeout
  3195. '(nil nil nil))
  3196. (python-completion-complete-at-point)))
  3197. (start (nth 0 new-candidates))
  3198. (end (nth 1 new-candidates))
  3199. (completion-list (nth 2 new-candidates)))
  3200. (if (not (and start end))
  3201. candidates
  3202. ;; Add the new candidates to the current ones
  3203. (let ((candidate-names (cl-map 'list
  3204. (lambda (el) (cdr (assoc 'name el)))
  3205. candidates))
  3206. (new-candidate-names (all-completions
  3207. (buffer-substring start end)
  3208. completion-list)))
  3209. (cl-loop
  3210. for pytel-cand in new-candidate-names
  3211. for pytel-cand = (replace-regexp-in-string "($" "" pytel-cand)
  3212. for pytel-cand = (replace-regexp-in-string "^.*\\." ""
  3213. pytel-cand)
  3214. if (not (member pytel-cand candidate-names))
  3215. do (push (list (cons 'name pytel-cand)) candidates)))
  3216. candidates)))))
  3217. (defun elpy-company-backend (command &optional arg &rest ignored)
  3218. "A company-mode backend for Elpy."
  3219. (interactive (list 'interactive))
  3220. (pcase command
  3221. (`interactive
  3222. (company-begin-backend 'elpy-company-backend))
  3223. ;; init => Called once per buffer
  3224. ;; prefix => return the prefix at point
  3225. (`prefix
  3226. (when (and elpy-mode
  3227. (not (company-in-string-or-comment)))
  3228. (company-grab-symbol-cons "\\." 1)))
  3229. ;; candidates <prefix> => return candidates for this prefix
  3230. (`candidates
  3231. (cons :async
  3232. (lambda (callback)
  3233. (elpy-rpc-get-completions
  3234. (lambda (result)
  3235. ;; add completion candidates from python.el
  3236. (setq result
  3237. (elpy-company--add-interpreter-completions-candidates
  3238. result))
  3239. (elpy-company--cache-clear)
  3240. (funcall
  3241. callback
  3242. (cond
  3243. ;; The backend returned something
  3244. (result
  3245. (elpy-company--cache-completions arg result))
  3246. ;; Nothing from the backend, try dabbrev-code.
  3247. ((> (length arg) company-minimum-prefix-length)
  3248. (elpy--sort-and-strip-duplicates
  3249. (company-dabbrev-code 'candidates arg)))
  3250. ;; Well, ok, let's go meh.
  3251. (t
  3252. nil))))))))
  3253. ;; sorted => t if the list is already sorted
  3254. (`sorted
  3255. t)
  3256. ;; duplicates => t if there could be duplicates
  3257. (`duplicates
  3258. nil)
  3259. ;; no-cache <prefix> => t if company shouldn't cache results
  3260. ;; meta <candidate> => short docstring for minibuffer
  3261. (`meta
  3262. (let ((meta (elpy-company--cache-meta arg)))
  3263. (when (and meta
  3264. (string-match "\\`\\(.*\n.*\\)\n.*" meta))
  3265. (setq meta (match-string 1 meta)))
  3266. meta))
  3267. ;; annotation <candidate> => short docstring for completion buffer
  3268. (`annotation
  3269. (elpy-company--cache-annotation arg))
  3270. ;; doc-buffer <candidate> => put doc buffer in `company-doc-buffer'
  3271. (`doc-buffer
  3272. (let* ((name (elpy-company--cache-name arg))
  3273. (doc (when name
  3274. (elpy-rpc-get-completion-docstring name))))
  3275. (when doc
  3276. (company-doc-buffer doc))))
  3277. ;; require-match => Never require a match, even if the user
  3278. ;; started to interact with company. See `company-require-match'.
  3279. (`require-match
  3280. 'never)
  3281. ;; location <candidate> => (buffer . point) or (file .
  3282. ;; line-number)
  3283. (`location
  3284. (let* ((name (elpy-company--cache-name arg))
  3285. (loc (when name
  3286. (elpy-rpc-get-completion-location name))))
  3287. (when loc
  3288. (cons (car loc)
  3289. (cadr loc)))))
  3290. ;; match <candidate> => for non-prefix based backends
  3291. ;; post-completion <candidate> => after insertion, for snippets
  3292. (`post-completion
  3293. (funcall elpy-company-post-completion-function
  3294. (elpy-company--cache-annotation arg)
  3295. (elpy-company--cache-name arg)))))
  3296. (defun elpy--sort-and-strip-duplicates (seq)
  3297. "Sort SEQ and remove any duplicates."
  3298. (sort (delete-dups seq)
  3299. (lambda (a b)
  3300. (string< a b))))
  3301. ;;;;;;;;;;;;;;;;;
  3302. ;;; Module: ElDoc
  3303. (defun elpy-module-eldoc (command &rest _args)
  3304. "Module to support ElDoc for Python files."
  3305. (pcase command
  3306. (`global-init
  3307. (require 'eldoc)
  3308. (setq eldoc-minor-mode-string nil))
  3309. (`buffer-init
  3310. ;; avoid eldoc message flickering when using eldoc and company modules jointly
  3311. (eldoc-add-command-completions "company-")
  3312. (eldoc-add-command-completions "python-indent-dedent-line-backspace")
  3313. (set (make-local-variable 'company-frontends)
  3314. (remq 'company-echo-metadata-frontend company-frontends))
  3315. (set (make-local-variable 'eldoc-documentation-function)
  3316. 'elpy-eldoc-documentation)
  3317. (eldoc-mode 1))
  3318. (`buffer-stop
  3319. (eldoc-mode -1)
  3320. (kill-local-variable 'eldoc-documentation-function))))
  3321. (defun elpy-eldoc-documentation ()
  3322. "Return some interesting information for the code at point.
  3323. This will return flymake errors for the line at point if there
  3324. are any. If not, this will do an asynchronous call to the RPC
  3325. backend to get a call tip, and display that using
  3326. `eldoc-message'. If the backend has no call tip, this will
  3327. display the current class and method instead."
  3328. (let ((flymake-error (elpy-flymake-error-at-point)))
  3329. (if flymake-error
  3330. flymake-error
  3331. ;; Try getting calltip
  3332. (elpy-rpc-get-calltip
  3333. (lambda (calltip)
  3334. (cond
  3335. ((stringp calltip)
  3336. (eldoc-message calltip))
  3337. (calltip
  3338. (let ((name (cdr (assq 'name calltip)))
  3339. (index (cdr (assq 'index calltip)))
  3340. (params (cdr (assq 'params calltip))))
  3341. (when index
  3342. (setf (nth index params)
  3343. (propertize (nth index params)
  3344. 'face
  3345. 'eldoc-highlight-function-argument)))
  3346. (let ((prefix (propertize name 'face
  3347. 'font-lock-function-name-face))
  3348. (args (format "(%s)" (mapconcat #'identity params ", "))))
  3349. (eldoc-message
  3350. (if (version<= emacs-version "25")
  3351. (format "%s%s" prefix args)
  3352. (eldoc-docstring-format-sym-doc prefix args nil))))))
  3353. (t
  3354. ;; Try getting oneline docstring
  3355. (elpy-rpc-get-oneline-docstring
  3356. (lambda (doc)
  3357. (cond
  3358. (doc
  3359. (let ((name (cdr (assq 'name doc)))
  3360. (doc (cdr (assq 'doc doc))))
  3361. (let ((prefix (propertize (format "%s: " name)
  3362. 'face
  3363. 'font-lock-function-name-face)))
  3364. (eldoc-message
  3365. (if (version<= emacs-version "25")
  3366. (format "%s%s" prefix doc)
  3367. (let ((eldoc-echo-area-use-multiline-p nil))
  3368. (eldoc-docstring-format-sym-doc
  3369. prefix doc nil)))
  3370. ))))
  3371. ;; Give the current definition
  3372. (elpy-eldoc-show-current-function
  3373. (let ((current-defun (python-info-current-defun)))
  3374. (when current-defun
  3375. (eldoc-message
  3376. (format "In: %s()" current-defun))))))))))))
  3377. ;; Return the last message until we're done
  3378. eldoc-last-message)))
  3379. ;;;;;;;;;;;;;;;;;;;
  3380. ;;; Module: Flymake
  3381. (defun elpy-module-flymake (command &rest _args)
  3382. "Enable Flymake support for Python."
  3383. (pcase command
  3384. (`global-init
  3385. (require 'flymake)
  3386. ;; flymake modeline is quite useful for emacs > 26.1
  3387. (when (version< emacs-version "26.1")
  3388. (elpy-modules-remove-modeline-lighter 'flymake-mode))
  3389. ;; Add our initializer function.
  3390. (when (not (version<= "26.1" emacs-version))
  3391. (add-to-list 'flymake-allowed-file-name-masks
  3392. '("\\.py\\'" elpy-flymake-python-init))))
  3393. (`buffer-init
  3394. ;; Set this for `elpy-check' command
  3395. (setq-local python-check-command elpy-syntax-check-command)
  3396. ;; For emacs > 26.1, python.el natively supports flymake,
  3397. ;; so we just tell python.el to use the wanted syntax checker
  3398. (when (version<= "26.1" emacs-version)
  3399. (setq-local python-flymake-command
  3400. (let ((command (split-string elpy-syntax-check-command)))
  3401. (if (string= (file-name-nondirectory (car command))
  3402. "flake8")
  3403. (append command '("-"))
  3404. command))))
  3405. ;; `flymake-no-changes-timeout': The original value of 0.5 is too
  3406. ;; short for Python code, as that will result in the current line
  3407. ;; to be highlighted most of the time, and that's annoying. This
  3408. ;; value might be on the long side, but at least it does not, in
  3409. ;; general, interfere with normal interaction.
  3410. (set (make-local-variable 'flymake-no-changes-timeout)
  3411. 60)
  3412. ;; `flymake-start-syntax-check-on-newline': This should be nil for
  3413. ;; Python, as;; most lines with a colon at the end will mean the
  3414. ;; next line is always highlighted as error, which is not helpful
  3415. ;; and mostly annoying.
  3416. (set (make-local-variable 'flymake-start-syntax-check-on-newline)
  3417. nil)
  3418. ;; Enable warning faces for flake8 output.
  3419. ;; Useless for emacs >= 26.1, as warning are handled fine
  3420. ;; COMPAT: Obsolete variable as of 24.4
  3421. (cond
  3422. ((version<= "26.1" emacs-version)
  3423. (setq-default python-flymake-msg-alist
  3424. '(("^W[0-9]+" . :warning)
  3425. ("^E[0-9]+" . :error))))
  3426. ((boundp 'flymake-warning-predicate)
  3427. (set (make-local-variable 'flymake-warning-predicate) "^W[0-9]"))
  3428. (t
  3429. (set (make-local-variable 'flymake-warning-re) "^W[0-9]")))
  3430. ;; for emacs >= 26.1, elpy relies on `python-flymake-command`, and
  3431. ;; doesn't need `python-check-command` anymore.
  3432. (when (and (buffer-file-name)
  3433. (or (version<= "26.1" emacs-version)
  3434. (executable-find python-check-command)))
  3435. (flymake-mode 1)))
  3436. (`buffer-stop
  3437. (flymake-mode -1)
  3438. (kill-local-variable 'flymake-no-changes-timeout)
  3439. (kill-local-variable 'flymake-start-syntax-check-on-newline)
  3440. ;; Disable warning faces for flake8 output.
  3441. ;; Useless for emacs >= 26.1, as warning are handled fine
  3442. ;; COMPAT: Obsolete variable as of 24.4
  3443. (cond
  3444. ((version<= "26.1" emacs-version) t)
  3445. ((boundp 'flymake-warning-predicate)
  3446. (kill-local-variable 'flymake-warning-predicate))
  3447. (t
  3448. (kill-local-variable 'flymake-warning-re))))))
  3449. (defun elpy-flymake-python-init ()
  3450. ;; Make sure it's not a remote buffer as flymake would not work
  3451. (when (not (file-remote-p buffer-file-name))
  3452. (let* ((temp-file (flymake-init-create-temp-buffer-copy
  3453. 'flymake-create-temp-inplace)))
  3454. (list python-check-command
  3455. (list temp-file)
  3456. ;; Run flake8 from / to avoid import problems (#169)
  3457. "/"))))
  3458. (defun elpy-flymake-next-error ()
  3459. "Move forward to the next Flymake error and show a
  3460. description."
  3461. (interactive)
  3462. (flymake-goto-next-error)
  3463. (elpy-flymake-show-error))
  3464. (defun elpy-flymake-previous-error ()
  3465. "Move backward to the previous Flymake error and show a
  3466. description."
  3467. (interactive)
  3468. (flymake-goto-prev-error)
  3469. (elpy-flymake-show-error))
  3470. (defun elpy-flymake-show-error ()
  3471. "Show the flymake error message at point."
  3472. (interactive)
  3473. (let ((error-message (elpy-flymake-error-at-point)))
  3474. (when error-message
  3475. (message "%s" error-message))))
  3476. (defun elpy-flymake-error-at-point ()
  3477. "Return the flymake error at point, or nil if there is none."
  3478. (cond ((boundp 'flymake-err-info) ; emacs < 26
  3479. (let* ((lineno (line-number-at-pos))
  3480. (err-info (car (flymake-find-err-info flymake-err-info
  3481. lineno))))
  3482. (when err-info
  3483. (mapconcat #'flymake-ler-text
  3484. err-info
  3485. ", "))))
  3486. ((and (fboundp 'flymake-diagnostic-text)
  3487. (fboundp 'flymake-diagnostics)) ; emacs >= 26
  3488. (let ((diag (flymake-diagnostics (point))))
  3489. (when diag
  3490. (mapconcat #'flymake-diagnostic-text diag ", "))))))
  3491. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3492. ;;; Module: Highlight Indentation
  3493. (defun elpy-module-highlight-indentation (command &rest _args)
  3494. "Module to highlight indentation in Python files."
  3495. (pcase command
  3496. (`global-init
  3497. (require 'highlight-indentation))
  3498. (`buffer-init
  3499. (highlight-indentation-mode 1))
  3500. (`buffer-stop
  3501. (highlight-indentation-mode -1))))
  3502. ;;;;;;;;;;;;;;;;;;
  3503. ;;; Module: pyvenv
  3504. (defun elpy-module-pyvenv (command &rest _args)
  3505. "Module to display the current virtualenv in the mode line."
  3506. (pcase command
  3507. (`global-init
  3508. (pyvenv-mode 1))
  3509. (`global-stop
  3510. (pyvenv-mode -1))))
  3511. ;;;;;;;;;;;;;;;;;;;;;
  3512. ;;; Module: Yasnippet
  3513. (defun elpy-module-yasnippet (command &rest _args)
  3514. "Module to enable YASnippet snippets."
  3515. (pcase command
  3516. (`global-init
  3517. (require 'yasnippet)
  3518. (elpy-modules-remove-modeline-lighter 'yas-minor-mode)
  3519. ;; We provide some YASnippet snippets. Add them.
  3520. ;; yas-snippet-dirs can be a string for a single directory. Make
  3521. ;; sure it's a list in that case so we can add our own entry.
  3522. (when (not (listp yas-snippet-dirs))
  3523. (setq yas-snippet-dirs (list yas-snippet-dirs)))
  3524. (add-to-list 'yas-snippet-dirs
  3525. (concat (file-name-directory (locate-library "elpy"))
  3526. "snippets/")
  3527. t)
  3528. ;; Now load yasnippets.
  3529. (yas-reload-all))
  3530. (`global-stop
  3531. (setq yas-snippet-dirs
  3532. (delete (concat (file-name-directory (locate-library "elpy"))
  3533. "snippets/")
  3534. yas-snippet-dirs)))
  3535. (`buffer-init
  3536. (yas-minor-mode 1))
  3537. (`buffer-stop
  3538. (yas-minor-mode -1))))
  3539. ;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3540. ;;; Module: Elpy-Django
  3541. (defun elpy-module-django (command &rest _args)
  3542. "Module to provide Django support."
  3543. (pcase command
  3544. (`buffer-init
  3545. (elpy-django-setup))
  3546. (`buffer-stop
  3547. (elpy-django -1))))
  3548. ;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3549. ;;; Module: Autodoc
  3550. (defun elpy-module-autodoc (command &rest _args)
  3551. "Module to automatically update documentation."
  3552. (pcase command
  3553. (`buffer-init
  3554. (add-hook 'pre-command-hook 'elpy-autodoc--pre-command nil t)
  3555. (add-hook 'post-command-hook 'elpy-autodoc--post-command nil t)
  3556. (make-local-variable 'company-frontends)
  3557. (add-to-list 'company-frontends 'elpy-autodoc--frontend :append))
  3558. (`buffer-stop
  3559. (remove-hook 'pre-command-hook 'elpy-autodoc--pre-command t)
  3560. (remove-hook 'post-command-hook 'elpy-autodoc--post-command t)
  3561. (setq company-frontends (remove 'elpy-autodoc--frontend company-frontends)))))
  3562. ;; Auto refresh documentation on cursor motion
  3563. (defvar elpy-autodoc--timer nil
  3564. "Timer to refresh documentation.")
  3565. (defcustom elpy-autodoc-delay .5
  3566. "The idle delay in seconds until documentation is refreshed automatically."
  3567. :type '(choice (const :tag "immediate (0)" 0)
  3568. (number :tag "seconds"))
  3569. :group 'elpy
  3570. :group 'elpy-autodoc)
  3571. (defun elpy-autodoc--pre-command ()
  3572. "Cancel autodoc timer on user action."
  3573. (when elpy-autodoc--timer
  3574. (cancel-timer elpy-autodoc--timer)
  3575. (setq elpy-autodoc--timer nil)))
  3576. (defun elpy-autodoc--post-command ()
  3577. "Set up autodoc timer after user action."
  3578. (when elpy-autodoc-delay
  3579. (setq elpy-autodoc--timer
  3580. (run-with-timer elpy-autodoc-delay nil
  3581. 'elpy-autodoc--refresh-doc))))
  3582. (defun elpy-autodoc--refresh-doc ()
  3583. "Refresh the doc asynchronously with the symbol at point."
  3584. (when (get-buffer-window "*Python Doc*")
  3585. (elpy-rpc-get-docstring 'elpy-autodoc--show-doc
  3586. (lambda (_reason) nil))))
  3587. (defun elpy-autodoc--show-doc (doc)
  3588. "Display DOC (if any) but only if the doc buffer is currently visible."
  3589. (when (and doc (get-buffer-window "*Python Doc*"))
  3590. (elpy-doc--show doc)))
  3591. ;; Auto refresh documentation in company candidate selection
  3592. (defun elpy-autodoc--frontend (command)
  3593. "Elpy autodoc front-end for refreshing documentation."
  3594. (pcase command
  3595. (`post-command
  3596. (when elpy-autodoc-delay
  3597. (when elpy-autodoc--timer
  3598. (cancel-timer elpy-autodoc--timer))
  3599. (setq elpy-autodoc--timer
  3600. (run-with-timer elpy-autodoc-delay
  3601. nil
  3602. 'elpy-autodoc--refresh-doc-from-company))))
  3603. (`hide
  3604. (when elpy-autodoc--timer
  3605. (cancel-timer elpy-autodoc--timer)))))
  3606. (defun elpy-autodoc--refresh-doc-from-company ()
  3607. "Refresh the doc asynchronously using the current company candidate."
  3608. (let* ((symbol (nth company-selection company-candidates))
  3609. (doc (elpy-rpc-get-completion-docstring symbol)))
  3610. (elpy-autodoc--show-doc doc)))
  3611. ;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3612. ;;; Backwards compatibility
  3613. ;; TODO Some/most of this compatibility code can now go, as minimum required
  3614. ;; Emacs version is 24.4.
  3615. ;; Functions for Emacs 24 before 24.3
  3616. (when (not (fboundp 'python-info-current-defun))
  3617. (defalias 'python-info-current-defun 'python-current-defun))
  3618. (when (not (fboundp 'python-nav-forward-statement))
  3619. (defun python-nav-forward-statement (&rest ignored)
  3620. "Function added in Emacs 24.3"
  3621. (error "Enhanced Python navigation only available in Emacs 24.3+")))
  3622. (when (not (fboundp 'python-nav-backward-up-list))
  3623. (defun python-nav-backward-up-list ()
  3624. "Compatibility function for older Emacsen"
  3625. (ignore-errors
  3626. (backward-up-list))))
  3627. (when (not (fboundp 'python-shell-calculate-exec-path))
  3628. (defun python-shell-calculate-exec-path ()
  3629. "Compatibility function for older Emacsen."
  3630. exec-path))
  3631. (when (not (fboundp 'python-shell-calculate-process-environment))
  3632. (defun python-shell-calculate-process-environment ()
  3633. "Compatibility function for older Emacsen."
  3634. process-environment))
  3635. (when (not (fboundp 'python-shell-get-process-name))
  3636. (defun python-shell-get-process-name (_dedicated)
  3637. "Compatibility function for older Emacsen."
  3638. "Python"))
  3639. (when (not (fboundp 'python-shell-parse-command))
  3640. (defun python-shell-parse-command ()
  3641. "Compatibility function for older Emacsen."
  3642. python-python-command))
  3643. (when (not (fboundp 'python-shell-send-buffer))
  3644. (defun python-shell-send-buffer (&optional _arg)
  3645. (python-send-buffer)))
  3646. (when (not (fboundp 'python-shell-send-string))
  3647. (defalias 'python-shell-send-string 'python-send-string))
  3648. (when (not (fboundp 'python-indent-shift-right))
  3649. (defalias 'python-indent-shift-right 'python-shift-right))
  3650. (when (not (fboundp 'python-indent-shift-left))
  3651. (defalias 'python-indent-shift-left 'python-shift-left))
  3652. ;; Emacs 24.2 made `locate-dominating-file' accept a predicate instead
  3653. ;; of a string. Simply overwrite the current one, it's
  3654. ;; backwards-compatible. The code below is taken from Emacs 24.3.
  3655. (when (or (< emacs-major-version 24)
  3656. (and (= emacs-major-version 24)
  3657. (<= emacs-minor-version 2)))
  3658. (defun locate-dominating-file (file name)
  3659. "Look up the directory hierarchy from FILE for a directory containing NAME.
  3660. Stop at the first parent directory containing a file NAME,
  3661. and return the directory. Return nil if not found.
  3662. Instead of a string, NAME can also be a predicate taking one argument
  3663. \(a directory) and returning a non-nil value if that directory is the one for
  3664. which we're looking."
  3665. ;; We used to use the above locate-dominating-files code, but the
  3666. ;; directory-files call is very costly, so we're much better off doing
  3667. ;; multiple calls using the code in here.
  3668. ;;
  3669. ;; Represent /home/luser/foo as ~/foo so that we don't try to look for
  3670. ;; `name' in /home or in /.
  3671. (setq file (abbreviate-file-name file))
  3672. (let ((root nil)
  3673. ;; `user' is not initialized outside the loop because
  3674. ;; `file' may not exist, so we may have to walk up part of the
  3675. ;; hierarchy before we find the "initial UID". Note: currently unused
  3676. ;; (user nil)
  3677. try)
  3678. (while (not (or root
  3679. (null file)
  3680. ;; FIXME: Disabled this heuristic because it is sometimes
  3681. ;; inappropriate.
  3682. ;; As a heuristic, we stop looking up the hierarchy of
  3683. ;; directories as soon as we find a directory belonging
  3684. ;; to another user. This should save us from looking in
  3685. ;; things like /net and /afs. This assumes that all the
  3686. ;; files inside a project belong to the same user.
  3687. ;; (let ((prev-user user))
  3688. ;; (setq user (nth 2 (file-attributes file)))
  3689. ;; (and prev-user (not (equal user prev-user))))
  3690. (string-match locate-dominating-stop-dir-regexp file)))
  3691. (setq try (if (stringp name)
  3692. (file-exists-p (expand-file-name name file))
  3693. (funcall name file)))
  3694. (cond (try (setq root file))
  3695. ((equal file (setq file (file-name-directory
  3696. (directory-file-name file))))
  3697. (setq file nil))))
  3698. (if root (file-name-as-directory root))))
  3699. )
  3700. ;; highlight-indentation 0.5 does not use modes yet
  3701. (when (not (fboundp 'highlight-indentation-mode))
  3702. (defun highlight-indentation-mode (on-or-off)
  3703. (cond
  3704. ((and (> on-or-off 0)
  3705. (not highlight-indent-active))
  3706. (highlight-indentation))
  3707. ((and (<= on-or-off 0)
  3708. highlight-indent-active)
  3709. (highlight-indentation)))))
  3710. ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=25753#44
  3711. (when (version< emacs-version "25.2")
  3712. (defun python-shell-completion-native-try ()
  3713. "Return non-nil if can trigger native completion."
  3714. (let ((python-shell-completion-native-enable t)
  3715. (python-shell-completion-native-output-timeout
  3716. python-shell-completion-native-try-output-timeout))
  3717. (python-shell-completion-native-get-completions
  3718. (get-buffer-process (current-buffer))
  3719. nil "_"))))
  3720. ;; python.el in Emacs 24 does not have functions to determine buffer encoding.
  3721. ;; In these versions, we fix the encoding to utf-8 (safe choice when no encoding
  3722. ;; is defined since Python 2 uses ASCII and Python 3 UTF-8).
  3723. (unless (fboundp 'python-info-encoding)
  3724. (defun python-info-encoding ()
  3725. 'utf-8))
  3726. ;; Added in Emacs 25
  3727. (unless (fboundp 'python-shell-comint-end-of-output-p)
  3728. (defun python-shell-comint-end-of-output-p (output)
  3729. "Return non-nil if OUTPUT is ends with input prompt."
  3730. (string-match
  3731. ;; XXX: It seems on macOS an extra carriage return is attached
  3732. ;; at the end of output, this handles that too.
  3733. (concat
  3734. "\r?\n?"
  3735. ;; Remove initial caret from calculated regexp
  3736. (replace-regexp-in-string
  3737. (rx string-start ?^) ""
  3738. python-shell--prompt-calculated-input-regexp)
  3739. (rx eos))
  3740. output)))
  3741. (provide 'elpy)
  3742. ;;; elpy.el ends here