Personal emacs config
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.

1177 lines
47 KiB

  1. ;;; elpy-rpc.el --- RPC protocol for elpy -*- lexical-binding: t -*-
  2. ;;
  3. ;; Copyright (C) 2012-2019 Jorgen Schaefer
  4. ;;
  5. ;; Author: Jorgen Schaefer <contact@jorgenschaefer.de>, Rainer Gemulla <rgemulla@gmx.de>, Gaby Launay <gaby.launay@protonmail.com>
  6. ;; URL: https://github.com/jorgenschaefer/elpy
  7. ;;
  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. ;;
  13. ;; This program is distributed in the hope that it will be useful,
  14. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. ;; GNU General Public License for more details.
  17. ;;
  18. ;; You should have received a copy of the GNU General Public License
  19. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. ;;
  21. ;;; Commentary:
  22. ;;
  23. ;; elpy-rpc is a simple JSON-based RPC protocol. It's mostly JSON-RPC
  24. ;; 1.0, except we do not implement the full protocol as we do not need
  25. ;; all the features. Emacs starts a Python subprocess which runs a
  26. ;; special module. The module reads JSON-RPC requests and responds
  27. ;; with JSON-RPC responses.
  28. ;;
  29. ;;; Code:
  30. (require 'json)
  31. (require 'pyvenv)
  32. (defcustom elpy-rpc-maximum-buffer-age (* 5 60)
  33. "Seconds after which Elpy automatically closes an unused RPC buffer.
  34. Elpy creates RPC buffers over time, depending on python interpreters
  35. and the project root. When there are many projects being worked on,
  36. these can accumulate. Setting this variable to an integer will close
  37. buffers and processes when they have not been used for this amount of
  38. seconds.
  39. Setting this variable to nil will disable the behavior."
  40. :type '(choice (const :tag "Never" nil)
  41. integer)
  42. :group 'elpy)
  43. (defcustom elpy-rpc-large-buffer-size 4096
  44. "Size for a source buffer up to which it will be sent directly.
  45. The Elpy RPC protocol uses JSON as the serialization format.
  46. Large buffers take a long time to encode, so Elpy can transmit
  47. them via temporary files. If a buffer is larger than this value,
  48. it is sent via a temporary file."
  49. :type 'integer
  50. :safe #'integerp
  51. :group 'elpy)
  52. (defcustom elpy-rpc-ignored-buffer-size 102400
  53. "Size for a source buffer over which Elpy completion will not work.
  54. To provide completion, Elpy's backends have to parse the whole
  55. file every time. For very large files, this is slow, and can make
  56. Emacs laggy. Elpy will simply not work on buffers larger than
  57. this to prevent this from happening."
  58. :type 'integer
  59. :safe #'integerp
  60. :group 'elpy)
  61. (defcustom elpy-rpc-python-command (if (equal system-type 'windows-nt)
  62. (or (executable-find "py")
  63. (executable-find "pythonw")
  64. "python")
  65. "python")
  66. "The Python interpreter for the RPC backend.
  67. This should NOT be an interactive shell like ipython or jupyter.
  68. As the RPC should be independent of any virtual environment, Elpy
  69. will try to use the system interpreter if it exists. If you wish
  70. to use a specific python interpreter (from a virtual environment
  71. for example), set this to the full interpreter path."
  72. :type '(choice (const :tag "python" "python")
  73. (const :tag "python2" "python2")
  74. (const :tag "python3" "python3")
  75. (const :tag "pythonw (Python on Windows)" "pythonw")
  76. (const :tag "py (other Python on Windows)" "py")
  77. (string :tag "Other"))
  78. :safe (lambda (val)
  79. (member val '("python" "python2" "python3" "pythonw")))
  80. ;; Make sure there is no obsolete rpc running
  81. :set (lambda (var val) ;
  82. (set-default var val)
  83. (when (and (fboundp 'elpy-rpc-restart)
  84. (not (autoloadp #'elpy-rpc-restart)))
  85. (elpy-rpc-restart)))
  86. :group 'elpy)
  87. (defcustom elpy-rpc-pythonpath (file-name-directory (locate-library "elpy"))
  88. "A directory to add to the PYTHONPATH for the RPC process.
  89. This should be a directory where the elpy module can be found. If
  90. this is nil, it's assumed elpy can be found in the standard path.
  91. Usually, there is no need to change this."
  92. :type 'directory
  93. :safe #'file-directory-p
  94. :group 'elpy)
  95. (defcustom elpy-rpc-timeout 1
  96. "Number of seconds to wait for a response when blocking.
  97. When Elpy blocks Emacs to wait for a response from the RPC
  98. process, it will assume it won't come or wait too long after this
  99. many seconds. On a slow computer, or if you have a large project,
  100. you might want to increase this.
  101. A setting of nil means to block indefinitely."
  102. :type '(choice (const :tag "Block indefinitely" nil)
  103. integer)
  104. :safe (lambda (val)
  105. (or (integerp val)
  106. (null val)))
  107. :group 'elpy)
  108. (defcustom elpy-rpc-error-timeout 30
  109. "Minimum number of seconds between error popups.
  110. When Elpy encounters an error in the backend, it will display a
  111. lengthy description of the problem for a bug report. This hangs
  112. Emacs for a moment, and can be rather annoying if it happens
  113. repeatedly while editing a source file.
  114. If this variabl is non-nil, Elpy will not display the error
  115. message again within this amount of seconds."
  116. :type 'integer
  117. :group 'elpy)
  118. (defvar elpy-rpc--call-id 0
  119. "Call id of the last call to `elpy-rpc`.
  120. Used to associate responses to callbacks.")
  121. (make-variable-buffer-local 'elpy-rpc--call-id)
  122. (defvar elpy-rpc--buffer-p nil
  123. "Non-nil if the current buffer is an elpy-rpc buffer.")
  124. (make-variable-buffer-local 'elpy-rpc--buffer-p)
  125. (defvar elpy-rpc--buffer nil
  126. "The elpy-rpc buffer associated with this buffer.")
  127. (make-variable-buffer-local 'elpy-rpc--buffer)
  128. (defvar elpy-rpc--backend-library-root nil
  129. "The project root used by this backend.")
  130. (make-variable-buffer-local 'elpy-rpc--backend-library-root)
  131. (defvar elpy-rpc--backend-python-command nil
  132. "The Python interpreter used by this backend.")
  133. (make-variable-buffer-local 'elpy-rpc--backend-python-command)
  134. (defvar elpy-rpc--backend-callbacks nil
  135. "The callbacks registered for calls to the current backend.
  136. This maps call IDs to functions.")
  137. (make-variable-buffer-local 'elpy-rpc--backend-callbacks)
  138. (defvar elpy-rpc--last-call nil
  139. "The time of the last RPC call issued for this backend.")
  140. (make-variable-buffer-local 'elpy-rpc--last-call)
  141. (defvar elpy-rpc--last-error-popup nil
  142. "The last time an error popup happened.")
  143. (defvar elpy-rpc--jedi-available nil
  144. "Whether jedi is available or not.")
  145. ;;;;;;;;;;;;;;;;;;;
  146. ;;; RPC virualenv
  147. (defcustom elpy-rpc-virtualenv-path 'default
  148. "Path to the virtualenv used by the RPC.
  149. Can be `default' (create a dedicated virtualenv in
  150. \".emacs.d/elpy\"), `system' (use the system environment),
  151. `current' (use the currently active environment), a virtualenv
  152. path or a function returning a virtualenv path.
  153. If the default virtual environment does not exist, it will be
  154. created using `elpy-rpc-python-command' and populated with the
  155. needed packages from `elpy-rpc--get-package-list'."
  156. :type '(choice (const :tag "Dedicated environment" default)
  157. (const :tag "Global environment" system)
  158. (const :tag "Current environment" current)
  159. (string :tag "Virtualenv path")
  160. (function :tag "Function returning the virtualenv path"))
  161. :group 'elpy)
  162. (defun elpy-rpc-default-virtualenv-path ()
  163. "Return the default virtualenv path."
  164. (expand-file-name (locate-user-emacs-file "elpy/rpc-venv")))
  165. (defun elpy-rpc-get-virtualenv-path ()
  166. "Return the RPC virutalenv path to use."
  167. (cond
  168. ((eq elpy-rpc-virtualenv-path 'default)
  169. (elpy-rpc-default-virtualenv-path))
  170. ((or (eq elpy-rpc-virtualenv-path 'system)
  171. (eq elpy-rpc-virtualenv-path 'global)) ;; for backward compatibility
  172. (let ((exec-path (reverse exec-path)))
  173. (directory-file-name
  174. (file-name-directory
  175. (directory-file-name
  176. (file-name-directory
  177. (executable-find elpy-rpc-python-command)))))))
  178. ((eq elpy-rpc-virtualenv-path 'current)
  179. (directory-file-name
  180. (file-name-directory
  181. (directory-file-name
  182. (file-name-directory
  183. (executable-find elpy-rpc-python-command))))))
  184. ((stringp elpy-rpc-virtualenv-path)
  185. (expand-file-name elpy-rpc-virtualenv-path))
  186. ((functionp elpy-rpc-virtualenv-path)
  187. (expand-file-name (funcall elpy-rpc-virtualenv-path)))
  188. (t
  189. (error "Invalid value for `elpy-rpc-virtualenv-path', please set it to a proper value using customize"))))
  190. (defun elpy-rpc--get-package-list ()
  191. "Return the list of packages to be installed in the RPC virtualenv."
  192. (let ((rpc-python-version (elpy-rpc--get-python-version)))
  193. (if (version< rpc-python-version "3.6.0")
  194. '("jedi" "flake8" "autopep8" "yapf" "rope")
  195. '("jedi" "flake8" "autopep8" "yapf" "black" "rope"))))
  196. (defun elpy-rpc--get-python-version ()
  197. "Return the RPC python version."
  198. (with-temp-buffer
  199. (call-process elpy-rpc-python-command nil t nil "--version")
  200. (goto-char (point-min))
  201. (re-search-forward "Python \\([0-9.]+\\)")
  202. (match-string 1)))
  203. (defmacro with-elpy-rpc-virtualenv-activated (&rest body)
  204. "Run BODY with Elpy's RPC virtualenv activated.
  205. During the execution of BODY the following variables are available:
  206. - `current-environment': current environment path.
  207. - `current-environment-binaries': current environment python binaries path.
  208. - `current-environment-is-deactivated': non-nil if the current
  209. environment has been deactivated (it is not if the RPC environment and
  210. the current environment are the same)."
  211. `(if (not (executable-find elpy-rpc-python-command))
  212. (error "Cannot find executable '%s', please set 'elpy-rpc-python-command' to an existing executable." elpy-rpc-python-command)
  213. (let* ((pyvenv-post-activate-hooks (remq 'elpy-rpc--disconnect
  214. pyvenv-post-activate-hooks))
  215. (pyvenv-post-deactivate-hooks (remq 'elpy-rpc--disconnect
  216. pyvenv-post-deactivate-hooks))
  217. (venv-was-activated pyvenv-virtual-env)
  218. (current-environment-binaries (executable-find
  219. elpy-rpc-python-command))
  220. (current-environment (directory-file-name (file-name-directory (directory-file-name (file-name-directory current-environment-binaries)))))
  221. ;; No need to change of venv if they are the same
  222. (same-venv (or (string= current-environment
  223. (elpy-rpc-get-virtualenv-path))
  224. (file-equal-p current-environment
  225. (elpy-rpc-get-virtualenv-path))))
  226. current-environment-is-deactivated)
  227. ;; If different than the current one, try to activate the RPC virtualenv
  228. (unless same-venv
  229. (condition-case err
  230. (pyvenv-activate (elpy-rpc-get-or-create-virtualenv))
  231. ((error quit) (if venv-was-activated
  232. (pyvenv-activate venv-was-activated)
  233. (pyvenv-deactivate))))
  234. (setq current-environment-is-deactivated t))
  235. (let (venv-err result)
  236. ;; Run BODY and catch errors and quit to avoid keeping the RPC
  237. ;; virtualenv activated
  238. (condition-case err
  239. (setq result (progn ,@body))
  240. (error (setq venv-err
  241. (if (stringp err)
  242. err
  243. (car (cdr err)))))
  244. (quit nil))
  245. ;; Reactivate the previous environment if necessary
  246. (unless same-venv
  247. (if venv-was-activated
  248. (pyvenv-activate venv-was-activated)
  249. (pyvenv-deactivate)))
  250. ;; Raise errors that could have happened in BODY
  251. (when venv-err
  252. (error venv-err))
  253. result))))
  254. (defun elpy-rpc-get-or-create-virtualenv ()
  255. "Return Elpy's RPC virtualenv.
  256. Create the virtualenv if it does not exist yet.
  257. Update the virtualenv if the variable `elpy-rpc-python-command' has
  258. changed since the virtualenv creation.
  259. An additional file `elpy-rpc-python-path-command' is added in the
  260. virtualenv directory in order to keep track of the python
  261. binaries used to create the virtualenv."
  262. (let* ((rpc-venv-path (elpy-rpc-get-virtualenv-path))
  263. (is-venv-exist (file-exists-p rpc-venv-path))
  264. (is-default-rpc-venv
  265. (and rpc-venv-path
  266. (string= rpc-venv-path
  267. (elpy-rpc-default-virtualenv-path))))
  268. (venv-python-path-command-file
  269. (concat (file-name-as-directory rpc-venv-path)
  270. "elpy-rpc-python-path-command"))
  271. (venv-python-path-command
  272. (when (file-exists-p venv-python-path-command-file)
  273. (with-temp-buffer
  274. (insert-file-contents venv-python-path-command-file)
  275. (buffer-string))))
  276. (venv-need-update
  277. (and is-venv-exist
  278. is-default-rpc-venv
  279. (not (string= venv-python-path-command
  280. elpy-rpc-python-command))))
  281. (venv-creation-allowed
  282. (and (or (not is-venv-exist) venv-need-update)
  283. (or is-default-rpc-venv
  284. (y-or-n-p
  285. (format "`elpy-rpc-virtualenv-path' was set to '%s', but this virtualenv does not exist, create it ? " rpc-venv-path))))))
  286. ;; Delete the rpc virtualenv if obsolete
  287. (when venv-need-update
  288. (delete-directory rpc-venv-path t)
  289. (setq is-venv-exist nil))
  290. ;; Create a new rpc venv if necessary
  291. (unless is-venv-exist
  292. (if (not venv-creation-allowed)
  293. (message "Please indicate the virtualenv you wish to use with `elpy-rpc-virtualenv-path'.")
  294. (let ((deact-venv pyvenv-virtual-env))
  295. (message "Elpy is %s the RPC virtualenv ('%s')"
  296. (if venv-need-update "updating" "creating")
  297. rpc-venv-path)
  298. (elpy-rpc--create-virtualenv rpc-venv-path)
  299. ;; Make sure the rpc venv is deacivated on quit
  300. (condition-case nil
  301. (progn
  302. (pyvenv-activate rpc-venv-path)
  303. ;; Add file to keep track of the `elpy-rpc-python-command` used
  304. (with-temp-file venv-python-path-command-file
  305. (insert elpy-rpc-python-command))
  306. ;; safeguard to be sure we don't install stuff in the wrong venv
  307. (when (file-equal-p pyvenv-virtual-env rpc-venv-path)
  308. (elpy-rpc--install-dependencies))
  309. (elpy-rpc-restart))
  310. (quit nil))
  311. ;; Deactivate the rpc venv
  312. (if deact-venv
  313. (pyvenv-activate (directory-file-name deact-venv))
  314. (pyvenv-deactivate))
  315. (message "Done"))))
  316. rpc-venv-path))
  317. (defun elpy-rpc--create-virtualenv (rpc-venv-path)
  318. "Create a virtualenv for the RPC in RPC-VENV-PATH."
  319. ;; venv cannot create a proper virtualenv from inside another virtualenv
  320. (let* ((elpy-rpc-virtualenv-path 'system)
  321. success
  322. (elpy-venv-buffname-visible "*elpy-virtualenv*")
  323. (elpy-venv-buffname (concat " " elpy-venv-buffname-visible)))
  324. (when (get-buffer elpy-venv-buffname)
  325. (kill-buffer elpy-venv-buffname))
  326. (when (get-buffer elpy-venv-buffname-visible)
  327. (kill-buffer elpy-venv-buffname-visible))
  328. (with-elpy-rpc-virtualenv-activated
  329. (cond
  330. ((and (= 0 (call-process elpy-rpc-python-command nil nil nil
  331. "-m" "venv" "-h"))
  332. ;; see https://github.com/jorgenschaefer/elpy/issues/1756
  333. (= 0 (call-process elpy-rpc-python-command nil nil nil
  334. "-m" "ensurepip" "-h")))
  335. (with-current-buffer (get-buffer-create elpy-venv-buffname)
  336. (insert (concat "Running '" elpy-rpc-python-command " -m venv "
  337. rpc-venv-path "':\n\n"))
  338. (setq success (call-process elpy-rpc-python-command nil t t
  339. "-m" "venv" rpc-venv-path))))
  340. ((executable-find "virtualenv")
  341. (with-current-buffer (get-buffer-create elpy-venv-buffname)
  342. (insert (concat "Running 'virtualenv -p "
  343. elpy-rpc-python-command " " rpc-venv-path
  344. "':\n\n"))
  345. (setq success (call-process "virtualenv" nil t t "-p"
  346. elpy-rpc-python-command rpc-venv-path))))
  347. (t
  348. (error "Elpy needs the 'virtualenv' or 'venv' python packages to create its virtualenv. Please install one of them or disable the dedicated virtualenv with `(setq elpy-rpc-virtualenv-path 'current)`"))))
  349. ;; warn us if something wrong happened
  350. (unless (= 0 success)
  351. (with-current-buffer elpy-venv-buffname
  352. (rename-buffer elpy-venv-buffname-visible)
  353. (goto-char (point-max))
  354. (insert
  355. (concat
  356. "\n\n"
  357. "Elpy failed to install its dedicated virtualenv due to the above\n"
  358. "error. If the error details does not help you fixing it, You can\n"
  359. "report this problem on Elpy repository on github.\n"
  360. "In the meantime, setting the `elpy-rpc-virtualenv-path' option to\n"
  361. "either `system' or `current' should temporarily fix the issue.")))
  362. (error (concat "Elpy failed to create its dedicated virtualenv. "
  363. "Please check the `" elpy-venv-buffname-visible
  364. "' buffer.")))))
  365. (defun elpy-rpc--install-dependencies ()
  366. "Install the RPC dependencies in the current virtualenv."
  367. (if (y-or-n-p "Automatically install the RPC dependencies from PyPI (needed for completion, autoformatting and documentation) ? ")
  368. (with-temp-buffer
  369. (message "Elpy is installing the RPC dependencies...")
  370. (when (/= (apply 'call-process elpy-rpc-python-command
  371. nil t nil
  372. "-m" "pip" "install" "--upgrade"
  373. (elpy-rpc--get-package-list))
  374. 0)
  375. (message "Elpy failed to install some of the RPC dependencies, please use `elpy-config' to install them.")))
  376. (message "Some of Elpy's functionnalities will not work, please use `elpy-config' to install the needed python dependencies.")))
  377. (defun elpy-rpc-reinstall-virtualenv ()
  378. "Re-install the RPC virtualenv."
  379. (interactive)
  380. (let ((rpc-venv-path (elpy-rpc-get-virtualenv-path)))
  381. (when
  382. (cond
  383. ((or (eq elpy-rpc-virtualenv-path 'system)
  384. (eq elpy-rpc-virtualenv-path 'global)) ;; backward compatibility
  385. (error "Cannot reinstall the system environment, please reinstall the necessary packages manually"))
  386. ((string= (elpy-rpc-default-virtualenv-path) rpc-venv-path)
  387. t)
  388. (t
  389. (y-or-n-p (format "Are you sure you want to reinstall the virtualenv in '%s' (every manual modifications will be lost) ? " rpc-venv-path))))
  390. (delete-directory rpc-venv-path t)
  391. (elpy-rpc-get-or-create-virtualenv))))
  392. (defun elpy-rpc--pip-missing ()
  393. "Return t if pip is not installed in the RPC virtualenv."
  394. (let* ((rpc-venv-path (file-name-as-directory
  395. (elpy-rpc-get-virtualenv-path)))
  396. (base-pip-scripts (concat rpc-venv-path
  397. (file-name-as-directory "Scripts")
  398. "pip"))
  399. (base-pip-bin (concat rpc-venv-path
  400. (file-name-as-directory "bin")
  401. "pip")))
  402. (not (or
  403. (file-exists-p base-pip-scripts)
  404. (file-exists-p base-pip-bin)
  405. (file-exists-p (concat base-pip-scripts ".exe"))
  406. (file-exists-p (concat base-pip-bin ".exe"))))))
  407. ;;;;;;;;;;;;;;;;;;;
  408. ;;; Promise objects
  409. (defvar elpy-promise-marker (make-symbol "*elpy-promise*")
  410. "An uninterned symbol marking an Elpy promise object.")
  411. (defun elpy-promise (success &optional error)
  412. "Return a new promise.
  413. A promise is an object with a success and error callback. If the
  414. promise is resolved using `elpy-promise-resolve', the SUCCESS
  415. callback is called with the given value. The current buffer is
  416. restored, too.
  417. If the promise is rejected using `elpy-promise-reject', the ERROR
  418. callback is called. For this function, the current buffer is not
  419. necessarily restored, as it is also called when the buffer does
  420. not exist anymore."
  421. (vector elpy-promise-marker ; 0 id
  422. success ; 1 success-callback
  423. error ; 2 error-callback
  424. (current-buffer) ; 3 current-buffer
  425. nil ; 4 run
  426. ))
  427. (defun elpy-promise-p (obj)
  428. "Return non-nil if OBJ is a promise object."
  429. (and (vectorp obj)
  430. (= (length obj) 5)
  431. (eq (aref obj 0) elpy-promise-marker)))
  432. (defsubst elpy-promise-success-callback (promise)
  433. "Return the success callback for PROMISE."
  434. (aref promise 1))
  435. (defsubst elpy-promise-error-callback (promise)
  436. "Return the error callback for PROMISE."
  437. (aref promise 2))
  438. (defsubst elpy-promise-buffer (promise)
  439. "Return the buffer for PROMISE."
  440. (aref promise 3))
  441. (defsubst elpy-promise-resolved-p (promise)
  442. "Return non-nil if the PROMISE has been resolved or rejected."
  443. (aref promise 4))
  444. (defsubst elpy-promise-set-resolved (promise)
  445. "Mark PROMISE as having been resolved."
  446. (aset promise 4 t))
  447. (defun elpy-promise-resolve (promise value)
  448. "Resolve PROMISE with VALUE."
  449. (unless (elpy-promise-resolved-p promise)
  450. (unwind-protect
  451. (let ((success-callback (elpy-promise-success-callback promise)))
  452. (when success-callback
  453. (condition-case err
  454. (with-current-buffer (elpy-promise-buffer promise)
  455. (funcall success-callback value))
  456. (error
  457. (elpy-promise-reject promise err)))))
  458. (elpy-promise-set-resolved promise))))
  459. (defun elpy-promise-reject (promise reason)
  460. "Reject PROMISE because of REASON."
  461. (unless (elpy-promise-resolved-p promise)
  462. (unwind-protect
  463. (let ((error-callback (elpy-promise-error-callback promise)))
  464. (when error-callback
  465. (if (buffer-live-p (elpy-promise-buffer promise))
  466. (with-current-buffer (elpy-promise-buffer promise)
  467. (funcall error-callback reason))
  468. (with-temp-buffer
  469. (funcall error-callback reason)))))
  470. (elpy-promise-set-resolved promise))))
  471. (defun elpy-promise-wait (promise &optional timeout)
  472. "Wait for PROMISE to be resolved, for up to TIMEOUT seconds.
  473. This will accept process output while waiting.
  474. This will wait for the current Elpy RPC process specifically, as
  475. Emacs currently has a bug where it can wait for the entire time
  476. of the timeout, even if output arrives.
  477. See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=17647"
  478. (let ((end-time (when timeout
  479. (time-add (current-time)
  480. (seconds-to-time timeout))))
  481. (process (get-buffer-process (elpy-rpc--get-rpc-buffer))))
  482. (while (and (not (elpy-promise-resolved-p promise))
  483. (or (not end-time)
  484. (time-less-p (current-time)
  485. end-time)))
  486. (accept-process-output process timeout))))
  487. ;;;;;;;;;;;;;;;;;
  488. ;;; Elpy RPC
  489. (defun elpy-rpc (method params &optional success error)
  490. "Call METHOD with PARAMS in the backend.
  491. If SUCCESS and optionally ERROR is given, return immediately and
  492. call those when a result is available. Otherwise, wait for a
  493. result and return that."
  494. (unless error
  495. (setq error #'elpy-rpc--default-error-callback))
  496. (if success
  497. (elpy-rpc--call method params success error)
  498. (elpy-rpc--call-blocking method params)))
  499. (defun elpy-rpc--call-blocking (method-name params)
  500. "Call METHOD-NAME with PARAMS in the current RPC backend.
  501. Returns the result, blocking until this arrived."
  502. (let* ((result-arrived nil)
  503. (error-occured nil)
  504. (result-value nil)
  505. (error-object nil)
  506. (promise (elpy-rpc--call method-name params
  507. (lambda (result)
  508. (setq result-value result
  509. result-arrived t))
  510. (lambda (err)
  511. (setq error-object err
  512. error-occured t)))))
  513. (elpy-promise-wait promise elpy-rpc-timeout)
  514. (cond
  515. (error-occured
  516. (elpy-rpc--default-error-callback error-object))
  517. (result-arrived
  518. result-value)
  519. (t
  520. (error "Timeout during RPC call %s from backend"
  521. method-name)))))
  522. (defun elpy-rpc--call (method-name params success error)
  523. "Call METHOD-NAME with PARAMS in the current RPC backend.
  524. When a result is available, SUCCESS will be called with that
  525. value as its sole argument. If an error occurs, ERROR will be
  526. called with the error list.
  527. Returns a PROMISE object."
  528. (let ((promise (elpy-promise success error)))
  529. (with-current-buffer (elpy-rpc--get-rpc-buffer)
  530. (setq elpy-rpc--call-id (1+ elpy-rpc--call-id)
  531. elpy-rpc--last-call (float-time))
  532. (elpy-rpc--register-callback elpy-rpc--call-id promise)
  533. (process-send-string
  534. (get-buffer-process (current-buffer))
  535. (let ((json-encoding-pretty-print nil)) ;; Link to bug https://github.com/jorgenschaefer/elpy/issues/1521
  536. (concat (json-encode `((id . ,elpy-rpc--call-id)
  537. (method . ,method-name)
  538. (params . ,params)))
  539. "\n"))))
  540. promise))
  541. (defun elpy-rpc--register-callback (call-id promise)
  542. "Register for PROMISE to be called when CALL-ID returns.
  543. Must be called in an elpy-rpc buffer."
  544. (unless elpy-rpc--buffer-p
  545. (error "Must be called in RPC buffer"))
  546. (unless elpy-rpc--backend-callbacks
  547. (setq elpy-rpc--backend-callbacks (make-hash-table :test #'equal)))
  548. (puthash call-id promise elpy-rpc--backend-callbacks))
  549. (defun elpy-rpc--get-rpc-buffer ()
  550. "Return the RPC buffer associated with the current buffer,
  551. creating one if necessary."
  552. (unless (elpy-rpc--process-buffer-p elpy-rpc--buffer)
  553. (setq elpy-rpc--buffer
  554. (or (elpy-rpc--find-buffer (elpy-library-root)
  555. elpy-rpc-python-command)
  556. (elpy-rpc--open (elpy-library-root)
  557. elpy-rpc-python-command))))
  558. elpy-rpc--buffer)
  559. (defun elpy-rpc--process-buffer-p (buffer)
  560. "Return non-nil when BUFFER is a live elpy-rpc process buffer.
  561. If BUFFER is a buffer for an elpy-rpc process, but the process
  562. died, this will kill the process and buffer."
  563. (cond
  564. ((or (not buffer)
  565. (not (buffer-live-p buffer)))
  566. nil)
  567. ((not (buffer-local-value 'elpy-rpc--buffer-p buffer))
  568. nil)
  569. ((and (get-buffer-process buffer)
  570. (process-live-p (get-buffer-process buffer)))
  571. t)
  572. (t
  573. (ignore-errors
  574. (kill-process (get-buffer-process buffer)))
  575. (ignore-errors
  576. (kill-buffer buffer))
  577. nil)))
  578. (defun elpy-rpc--find-buffer (library-root python-command)
  579. "Return an existing RPC buffer for this project root and command."
  580. (catch 'return
  581. (let ((full-python-command (executable-find python-command)))
  582. (dolist (buf (buffer-list))
  583. (when (and (elpy-rpc--process-buffer-p buf)
  584. (equal (buffer-local-value 'elpy-rpc--backend-library-root
  585. buf)
  586. library-root)
  587. (equal (buffer-local-value 'elpy-rpc--backend-python-command
  588. buf)
  589. full-python-command))
  590. (throw 'return buf))))
  591. nil))
  592. (defun elpy-rpc--open (library-root python-command)
  593. "Start a new RPC process and return the associated buffer."
  594. (elpy-rpc--cleanup-buffers)
  595. (with-elpy-rpc-virtualenv-activated
  596. (let* ((full-python-command (executable-find python-command))
  597. (name (format " *elpy-rpc [project:%s environment:%s]*"
  598. library-root
  599. current-environment))
  600. (new-elpy-rpc-buffer (generate-new-buffer name))
  601. (proc nil))
  602. (unless full-python-command
  603. (error "Can't find Python command, configure `elpy-rpc-python-command'"))
  604. (with-current-buffer new-elpy-rpc-buffer
  605. (setq elpy-rpc--buffer-p t
  606. elpy-rpc--buffer (current-buffer)
  607. elpy-rpc--backend-library-root library-root
  608. elpy-rpc--backend-python-command full-python-command
  609. default-directory "/"
  610. proc (condition-case err
  611. (let ((process-connection-type nil)
  612. (process-environment (elpy-rpc--environment)))
  613. (start-process name
  614. (current-buffer)
  615. full-python-command
  616. "-W" "ignore"
  617. "-m" "elpy.__main__"))
  618. (error
  619. (elpy-config-error
  620. "Elpy can't start Python (%s: %s)"
  621. (car err) (cadr err)))))
  622. (set-process-query-on-exit-flag proc nil)
  623. (set-process-sentinel proc #'elpy-rpc--sentinel)
  624. (set-process-filter proc #'elpy-rpc--filter)
  625. (elpy-rpc-init library-root
  626. (when current-environment-is-deactivated
  627. current-environment-binaries)
  628. (lambda (result)
  629. (setq elpy-rpc--jedi-available
  630. (cdr (assq 'jedi_available result))))))
  631. new-elpy-rpc-buffer)))
  632. (defun elpy-rpc--cleanup-buffers ()
  633. "Close RPC buffers that have not been used in five minutes."
  634. (when elpy-rpc-maximum-buffer-age
  635. (let ((old (- (float-time)
  636. elpy-rpc-maximum-buffer-age)))
  637. (dolist (buffer (buffer-list))
  638. (when (and (elpy-rpc--process-buffer-p buffer)
  639. (< (or (buffer-local-value 'elpy-rpc--last-call buffer)
  640. old)
  641. old))
  642. (ignore-errors
  643. (kill-process (get-buffer-process buffer)))
  644. (ignore-errors
  645. (kill-buffer buffer)))))))
  646. (defun elpy-rpc--sentinel (process event)
  647. "The sentinel for the RPC process.
  648. As process sentinels are only ever called when the process
  649. terminates, this will call the error handler of all registered
  650. RPC calls with the event."
  651. (let ((buffer (process-buffer process))
  652. (err (list 'process-sentinel (substring event 0 -1))))
  653. (when (and buffer
  654. (buffer-live-p buffer))
  655. (with-current-buffer buffer
  656. (when elpy-rpc--backend-callbacks
  657. (maphash (lambda (_call-id promise)
  658. (ignore-errors
  659. (elpy-promise-reject promise err)))
  660. elpy-rpc--backend-callbacks)
  661. (setq elpy-rpc--backend-callbacks nil))))))
  662. (defun elpy-rpc--filter (process output)
  663. "The filter for the RPC process."
  664. (let ((buffer (process-buffer process)))
  665. (when (and buffer
  666. (buffer-live-p buffer))
  667. (with-current-buffer buffer
  668. (goto-char (point-max))
  669. (insert output)
  670. (while (progn
  671. (goto-char (point-min))
  672. (search-forward "\n" nil t))
  673. (let ((line-end (point))
  674. (json nil)
  675. (did-read-json nil))
  676. (goto-char (point-min))
  677. (condition-case _err
  678. (progn
  679. (setq json (let ((json-array-type 'list)
  680. (json-false nil)
  681. (json-encoding-pretty-print nil)) ;; Link to bug https://github.com/jorgenschaefer/elpy/issues/1521
  682. (json-read)))
  683. (if (listp json)
  684. (setq line-end (1+ (point))
  685. did-read-json t)
  686. (goto-char (point-min))))
  687. (error
  688. (goto-char (point-min))))
  689. (cond
  690. (did-read-json
  691. (delete-region (point-min) line-end)
  692. (elpy-rpc--handle-json json))
  693. ((looking-at "elpy-rpc ready\n")
  694. (replace-match "")
  695. (elpy-rpc--check-backend-version "1.1"))
  696. ((looking-at "elpy-rpc ready (\\([^ ]*\\))\n")
  697. (let ((rpc-version (match-string 1)))
  698. (replace-match "")
  699. (elpy-rpc--check-backend-version rpc-version)))
  700. ((looking-at ".*No module named elpy\n")
  701. (replace-match "")
  702. (elpy-config-error "Elpy module not found"))
  703. (t
  704. (let ((line (buffer-substring (point-min)
  705. line-end)))
  706. (delete-region (point-min) line-end)
  707. (elpy-rpc--handle-unexpected-line line))))))))))
  708. (defmacro elpy-insert--popup (buffer-name &rest body)
  709. "Pop up a help buffer named BUFFER-NAME and execute BODY in it."
  710. (declare (indent 1))
  711. `(with-help-window ,buffer-name
  712. (with-current-buffer standard-output
  713. ,@body)))
  714. (defun elpy-rpc--check-backend-version (rpc-version)
  715. "Check that we are using the right version."
  716. (unless (equal rpc-version elpy-version)
  717. (elpy-insert--popup "*Elpy Version Mismatch*"
  718. (elpy-insert--header "Elpy Version Mismatch")
  719. (elpy-insert--para
  720. "You are not using the same version of Elpy in Emacs Lisp "
  721. "compared to Python. This can cause random problems. Please "
  722. "do make sure to use compatible versions.\n\n"
  723. "This often happens because you have an obsolete elpy python "
  724. "package installed on your system/virtualenv. This package "
  725. "shadows the elpy python package shipped with elpy, leading "
  726. "to this mismatch. If it is the case, uninstalling the elpy "
  727. "python package (with pip for example) should resolve the issue.\n")
  728. (insert
  729. "\n"
  730. "Elpy Emacs Lisp version: " elpy-version "\n"
  731. "Elpy Python version....: " rpc-version "\n"))))
  732. (defun elpy-rpc--handle-unexpected-line (line)
  733. "Handle an unexpected line from the backend.
  734. This is usually an error or backtrace."
  735. (let ((buf (get-buffer "*Elpy Output*")))
  736. (unless buf
  737. (elpy-insert--popup "*Elpy Output*"
  738. (elpy-insert--header "Output from Backend")
  739. (elpy-insert--para
  740. "There was some unexpected output from the Elpy backend. "
  741. "This is usually not a problem and should usually not be "
  742. "reported as a bug with Elpy. You can safely hide this "
  743. "buffer and ignore it. You can also see the output below "
  744. "in case there is an actual problem.\n\n")
  745. (elpy-insert--header "Output")
  746. (setq buf (current-buffer))))
  747. (with-current-buffer buf
  748. (goto-char (point-max))
  749. (let ((inhibit-read-only t))
  750. (insert line)))))
  751. (defun elpy-rpc--handle-json (json)
  752. "Handle a single JSON object from the RPC backend."
  753. (let ((call-id (cdr (assq 'id json)))
  754. (error-object (cdr (assq 'error json)))
  755. (result (cdr (assq 'result json))))
  756. (let ((promise (gethash call-id elpy-rpc--backend-callbacks)))
  757. (unless promise
  758. (error "Received a response for unknown call-id %s" call-id))
  759. (remhash call-id elpy-rpc--backend-callbacks)
  760. (if error-object
  761. (elpy-promise-reject promise error-object)
  762. (elpy-promise-resolve promise result)))))
  763. (defun elpy-rpc--default-error-callback (error-object)
  764. "Display an error from the RPC backend."
  765. ;; We actually might get an (error "foo") thing here.
  766. (if (and (consp error-object)
  767. (not (consp (car error-object))))
  768. (signal (car error-object) (cdr error-object))
  769. (let ((message (cdr (assq 'message error-object)))
  770. (code (cdr (assq 'code error-object)))
  771. (data (cdr (assq 'data error-object))))
  772. (cond
  773. ((not (numberp code))
  774. (error "Bad response from RPC: %S" error-object))
  775. ((< code 300)
  776. (message "Elpy warning: %s" message))
  777. ((< code 500)
  778. (error "Elpy error: %s" message))
  779. ((and elpy-rpc-error-timeout
  780. elpy-rpc--last-error-popup
  781. (<= (float-time)
  782. (+ elpy-rpc--last-error-popup
  783. elpy-rpc-error-timeout)))
  784. (message "Elpy error popup ignored, see `elpy-rpc-error-timeout': %s"
  785. message))
  786. ((not elpy-disable-backend-error-display)
  787. (let ((config (elpy-config--get-config)))
  788. (elpy-insert--popup "*Elpy Error*"
  789. (elpy-insert--header "Elpy Error")
  790. (elpy-insert--para
  791. "The backend encountered an unexpected error. This indicates "
  792. "a bug in Elpy. Please open a bug report with the data below "
  793. "in the Elpy bug tracker:")
  794. (insert "\n"
  795. "\n")
  796. (insert-button
  797. "https://github.com/jorgenschaefer/elpy/issues/new"
  798. 'action (lambda (button)
  799. (browse-url (button-get button 'url)))
  800. 'url "https://github.com/jorgenschaefer/elpy/issues/new")
  801. (insert "\n"
  802. "\n"
  803. "```\n")
  804. (elpy-insert--header "Error Message")
  805. (insert message "\n\n")
  806. (elpy-insert--header "Configuration")
  807. (elpy-config--insert-configuration-table config)
  808. (let ((traceback (cdr (assq 'traceback data))))
  809. (when traceback
  810. (insert "\n")
  811. (elpy-insert--header "Traceback")
  812. (insert traceback)))
  813. (let ((jedi-info (cdr (assq 'jedi_debug_info data))))
  814. (when jedi-info
  815. (insert "\n")
  816. (elpy-insert--header "Jedi Debug Information")
  817. (pcase (cdr (assq 'debug_info jedi-info))
  818. (`nil (insert "Jedi did not emit any debug info.\n"))
  819. (infos
  820. (dolist (outstr infos)
  821. (insert outstr "\n"))))
  822. (insert "\n"
  823. "```\n"
  824. "\n"
  825. "Reproduction:\n"
  826. "\n")
  827. (let ((method (cdr (assq 'method jedi-info)))
  828. (source (cdr (assq 'source jedi-info)))
  829. (script-args (cdr (assq 'script_args jedi-info))))
  830. (insert "```Python\n")
  831. (insert "import jedi\n"
  832. "\n"
  833. "source = '''\\\n"
  834. source
  835. "'''\n"
  836. "\n"
  837. "script = jedi.Script(" script-args ")\n"
  838. "script." method "()\n"))))
  839. (let ((rope-info (cdr (assq 'rope_debug_info data))))
  840. (when rope-info
  841. (insert "\n")
  842. (elpy-insert--header "Rope Debug Information")
  843. (insert "```\n"
  844. "\n"
  845. "Reproduction:\n"
  846. "\n")
  847. (let ((project-root (cdr (assq 'project_root rope-info)))
  848. (filename (cdr (assq 'filename rope-info)))
  849. (source (cdr (assq 'source rope-info)))
  850. (function-name (cdr (assq 'function_name rope-info)))
  851. (function-args (cdr (assq 'function_args rope-info))))
  852. (insert "```Python\n")
  853. (insert "\n"
  854. "source = '''\n"
  855. source
  856. "'''\n"
  857. "\n")
  858. (insert "project = rope.base.project.Project(\n"
  859. (format " %S,\n" project-root)
  860. " ropefolder=None\n"
  861. ")\n")
  862. (insert "resource = rope.base.libutils.path_to_resource(\n"
  863. " project,\n"
  864. (format " %S,\n" filename)
  865. " 'file'\n"
  866. ")\n")
  867. (insert (format "%s(\n %s\n)\n"
  868. function-name function-args)))))
  869. (unless (= 0 (current-column))
  870. (insert "\n"))
  871. (insert "```"))
  872. (setq elpy-rpc--last-error-popup (float-time))))))))
  873. (defun elpy-rpc--environment ()
  874. "Return a `process-environment' for the RPC process.
  875. This includes `elpy-rpc-pythonpath' in the PYTHONPATH, if set."
  876. (if (or (not elpy-rpc-pythonpath)
  877. (not (file-exists-p (expand-file-name "elpy/__init__.py"
  878. elpy-rpc-pythonpath))))
  879. process-environment
  880. (let* ((old-pythonpath (getenv "PYTHONPATH"))
  881. (new-pythonpath (if old-pythonpath
  882. (concat elpy-rpc-pythonpath
  883. path-separator
  884. old-pythonpath)
  885. elpy-rpc-pythonpath)))
  886. (cons (concat "PYTHONPATH=" new-pythonpath)
  887. (append process-environment
  888. (when (and (string-equal system-type "windows-nt")
  889. (>= (string-match-p
  890. (regexp-quote "utf-8")
  891. (format "%s" buffer-file-coding-system))) 0)
  892. (list
  893. "PYTHONIOENCODING=utf-8"
  894. "PYTHONLEGACYWINDOWSSTDIO=1")))))))
  895. (defun elpy-rpc--buffer-contents ()
  896. "Return the contents of the current buffer.
  897. This returns either a string, or a file object for the RPC
  898. protocol if the buffer is larger than
  899. `elpy-rpc-large-buffer-size'."
  900. (if (< (buffer-size) elpy-rpc-large-buffer-size)
  901. (buffer-string)
  902. (let ((file-name (make-temp-file "elpy-rpc-"))
  903. (coding-system-for-write 'utf-8))
  904. (write-region nil nil file-name nil :nomessage)
  905. `((filename . ,file-name)
  906. (delete_after_use . t)))))
  907. (defun elpy-rpc--region-contents ()
  908. "Return the selected region as a string."
  909. (if (use-region-p)
  910. (buffer-substring (region-beginning) (region-end))))
  911. (defun elpy-rpc--disconnect ()
  912. "Disconnect rpc process from elpy buffers."
  913. (dolist (buf (buffer-list))
  914. (with-current-buffer buf
  915. (when elpy-mode
  916. (setq elpy-rpc--buffer nil)))))
  917. ;; RPC API functions
  918. (defun elpy-rpc-restart ()
  919. "Restart all RPC processes."
  920. (interactive)
  921. (dolist (buffer (buffer-list))
  922. (when (elpy-rpc--process-buffer-p buffer)
  923. (ignore-errors
  924. (kill-process (get-buffer-process buffer)))
  925. (ignore-errors
  926. (kill-buffer buffer)))))
  927. (defun elpy-rpc-init (library-root environment-binaries &optional success error)
  928. "Initialize the backend.
  929. This has to be called as the first method, else Elpy won't be
  930. able to respond to other calls.
  931. +LIBRARY-ROOT is the current project root,
  932. +ENVIRONMENT-BINARIES is the path to the python binaries of the environment to work in."
  933. (elpy-rpc "init"
  934. ;; This uses a vector because otherwise, json-encode in
  935. ;; older Emacsen gets seriously confused, especially when
  936. ;; backend is nil.
  937. (vector `((project_root . ,(expand-file-name library-root))
  938. (environment . ,(when environment-binaries
  939. (expand-file-name
  940. environment-binaries)))))
  941. success error))
  942. ;;;;;;;;;;;;;;
  943. ;;; RPC API
  944. (defun elpy-rpc-get-calltip (&optional success error)
  945. "Call the get_calltip API function.
  946. Returns a calltip string for the function call at point."
  947. (when (< (buffer-size) elpy-rpc-ignored-buffer-size)
  948. (elpy-rpc "get_calltip"
  949. (list buffer-file-name
  950. (elpy-rpc--buffer-contents)
  951. (- (point)
  952. (point-min)))
  953. success error)))
  954. (defun elpy-rpc-get-calltip-or-oneline-docstring (&optional success error)
  955. "Call the get_calltip_or_oneline_doc API function.
  956. Returns a calltip string or a oneline docstring for the function call at point."
  957. (when (< (buffer-size) elpy-rpc-ignored-buffer-size)
  958. (elpy-rpc "get_calltip_or_oneline_docstring"
  959. (list buffer-file-name
  960. (elpy-rpc--buffer-contents)
  961. (- (point)
  962. (point-min)))
  963. success error)))
  964. (defun elpy-rpc-get-oneline-docstring (&optional success error)
  965. "Call the get_oneline_docstring API function.
  966. Returns a oneline docstring string for the symbol at point."
  967. (when (< (buffer-size) elpy-rpc-ignored-buffer-size)
  968. (elpy-rpc "get_oneline_docstring"
  969. (list buffer-file-name
  970. (elpy-rpc--buffer-contents)
  971. (- (point)
  972. (point-min)))
  973. success error)))
  974. (defun elpy-rpc-get-completions (&optional success error)
  975. "Call the get_completions API function.
  976. Returns a list of possible completions for the Python symbol at
  977. point."
  978. (when (and (< (buffer-size) elpy-rpc-ignored-buffer-size)
  979. (not (string-match "^[0-9]+$" (symbol-name (symbol-at-point)))))
  980. (elpy-rpc "get_completions"
  981. (list buffer-file-name
  982. (elpy-rpc--buffer-contents)
  983. (- (point)
  984. (point-min)))
  985. success error)))
  986. (defun elpy-rpc-get-completion-docstring (completion &optional success error)
  987. "Call the get_completion_docstring API function.
  988. Returns a doc string or nil"
  989. (elpy-rpc "get_completion_docstring" (list completion) success error))
  990. (defun elpy-rpc-get-completion-location (completion &optional success error)
  991. "Call the get_completion_location API function.
  992. Returns a list of file name and line number, or nil"
  993. (elpy-rpc "get_completion_location" (list completion) success error))
  994. (defun elpy-rpc-get-definition (&optional success error)
  995. "Call the find_definition API function.
  996. Returns nil or a list of (filename, point)."
  997. (elpy-rpc "get_definition"
  998. (list buffer-file-name
  999. (elpy-rpc--buffer-contents)
  1000. (- (point)
  1001. (point-min)))
  1002. success error))
  1003. (defun elpy-rpc-get-assignment (&optional success error)
  1004. "Call the find_assignment API function.
  1005. Returns nil or a list of (filename, point)."
  1006. (elpy-rpc "get_assignment"
  1007. (list buffer-file-name
  1008. (elpy-rpc--buffer-contents)
  1009. (- (point)
  1010. (point-min)))
  1011. success error))
  1012. (defun elpy-rpc-get-docstring (&optional success error)
  1013. "Call the get_docstring API function.
  1014. Returns a possible multi-line docstring for the symbol at point."
  1015. (elpy-rpc "get_docstring"
  1016. (list buffer-file-name
  1017. (elpy-rpc--buffer-contents)
  1018. (- (point)
  1019. (point-min)))
  1020. success error))
  1021. (defun elpy-rpc-get-pydoc-completions (prefix &optional success error)
  1022. "Return a list of modules available in pydoc starting with PREFIX."
  1023. (elpy-rpc "get_pydoc_completions" (list prefix)
  1024. success error))
  1025. (defun elpy-rpc-get-pydoc-documentation (symbol &optional success error)
  1026. "Get the Pydoc documentation for SYMBOL.
  1027. Returns a possible multi-line docstring."
  1028. (elpy-rpc "get_pydoc_documentation" (list symbol)
  1029. success error))
  1030. (defun elpy-rpc-get-usages (&optional success error)
  1031. "Return the symbol under point usages as a list."
  1032. (elpy-rpc "get_usages"
  1033. (list buffer-file-name
  1034. (elpy-rpc--buffer-contents)
  1035. (- (point)
  1036. (point-min)))
  1037. success error))
  1038. (defun elpy-rpc-get-names (&optional success error)
  1039. "Return all names (possible candidates for jumping to definition)."
  1040. (elpy-rpc "get_names"
  1041. (list buffer-file-name
  1042. (elpy-rpc--buffer-contents)
  1043. (- (point)
  1044. (point-min)))
  1045. success error))
  1046. (provide 'elpy-rpc)
  1047. ;;; elpy-rpc.el ends here