update elpy
[emacs.git] / .emacs.d / elisp / elpy / elpy.el
1 ;;; elpy.el --- Emacs Lisp Python Environment -*- lexical-binding: t -*-
2
3 ;; Copyright (C) 2012, 2013 Jorgen Schaefer
4
5 ;; Author: Jorgen Schaefer <contact@jorgenschaefer.de>
6 ;; URL: https://github.com/jorgenschaefer/elpy
7 ;; Version: 1.4.1
8
9 ;; This program is free software; you can redistribute it and/or
10 ;; modify it under the terms of the GNU General Public License
11 ;; as published by the Free Software Foundation; either version 3
12 ;; of the License, or (at your option) any later version.
13
14 ;; This program is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
21
22 ;;; Commentary:
23
24 ;; The Emacs Lisp Python Environment in Emacs
25
26 ;; Elpy is an Emacs package to bring powerful Python editing to Emacs.
27 ;; It combines a number of existing Emacs packages, and uses one of a
28 ;; selection of Python packages for code introspection.
29
30 ;; To use, you need to install not only this package, but a few Python
31 ;; packages as well. See the installation instructions on the wiki.
32
33 ;; Documentation is available there as well.
34
35 ;; https://github.com/jorgenschaefer/elpy/wiki
36
37 ;;; Code:
38
39 ;; Bad hack. nose.el from MELPA uses defvar-local, which breaks with
40 ;; older Emacsen. Of course, users use MELPA, so elpy gets blamed.
41 (when (not (fboundp 'defvar-local))
42 (defmacro defvar-local (var val &optional docstring)
43 "Compatibility declaration, backported from Emacs 24.4."
44 (list 'progn (list 'defvar var val docstring)
45 (list 'make-variable-buffer-local (list 'quote var)))))
46
47 (require 'auto-complete-config)
48 (require 'elpy-refactor)
49 (require 'etags)
50 (require 'find-file-in-project)
51 (require 'flymake)
52 (require 'highlight-indentation)
53 (require 'idomenu)
54 (require 'json)
55 (require 'nose)
56 (require 'python)
57 (require 'grep)
58 (require 'thingatpt)
59 (require 'pyvenv)
60 (require 'yasnippet)
61
62
63 ;;;;;;;;;;;;;;;
64 ;;; Elpy itself
65
66 (defgroup elpy nil
67 "The Emacs Lisp Python Environment."
68 :prefix "elpy-"
69 :group 'languages)
70
71 (defcustom elpy-rpc-python-command (if (eq window-system 'w32)
72 "pythonw"
73 "python")
74 "The command to be used for the RPC backend."
75 :type 'string
76 :group 'elpy)
77
78 (defcustom elpy-show-installation-instructions t
79 "Whether Elpy should display installation instructions in a
80 help buffer. If nil, displays a message in the echo area
81 instead."
82 :type 'boolean
83 :group 'elpy)
84
85 (defcustom elpy-rpc-project-specific nil
86 "Whether Elpy should use a separate process for each project."
87 :type 'boolean
88 :group 'elpy)
89
90 (defcustom elpy-rpc-backend nil
91 "Your preferred backend.
92
93 Either nil, or a string.
94
95 nil - Select a backend automatically.
96 rope - Use the Rope refactoring library. This will create
97 .ropeproject directories in your project roots.
98 jedi - Use the Jedi completion library.
99 native - Do not use any backend, use native Python methods only."
100 :type '(choice (const "rope")
101 (const "jedi")
102 (const "native")
103 (const nil))
104 :group 'elpy)
105
106 (defcustom elpy-default-minor-modes '(eldoc-mode
107 flymake-mode
108 highlight-indentation-mode
109 yas-minor-mode
110 auto-complete-mode)
111 "Minor modes enabled when `elpy-mode' is enabled."
112 :group 'elpy)
113
114 (defcustom elpy-rgrep-ignored-directories '(".tox" "build" "dist")
115 "Directories ignored by `elpy-rgrep-symbol'.
116
117 These are prepended to `grep-find-ignored-directories'."
118 :group 'elpy)
119
120 (defcustom elpy-mode-hook nil
121 "Hook run when `elpy-mode' is enabled."
122 :group 'elpy)
123
124 (defconst elpy-version "1.4.1"
125 "The version of the Elpy lisp code.")
126
127 (defun elpy-version ()
128 "Echo the version of Elpy."
129 (interactive)
130 (let ((version elpy-version)
131 (rpc-version (when elpy-rpc--buffer
132 (or (ignore-errors
133 (elpy-rpc "version" nil))
134 "1.1"))))
135 (if (equal version "devel")
136 (setq version "development version")
137 (setq version (format "version %s" version)))
138 (when rpc-version
139 (if (equal rpc-version "devel")
140 (setq rpc-version "development version")
141 (setq rpc-version (format "version %s" rpc-version))))
142 (if rpc-version
143 (message "Elpy %s using the Python backend %s"
144 version rpc-version)
145 (message "Elpy %s" version))))
146
147 (defvar elpy-mode-map
148 (let ((map (make-sparse-keymap)))
149 ;; Alphabetical order to make it easier to find free C-c C-X
150 ;; bindings in the future. Heh.
151
152 ;; (define-key map (kbd "<backspace>") 'python-indent-dedent-line-backspace)
153 ;; (define-key map (kbd "<backtab>") 'python-indent-dedent-line)
154 ;; (define-key map (kbd "<tab>") 'ac-trigger-key)
155
156 ;; (define-key map (kbd "C-M-x") 'python-shell-send-defun)
157 ;; (define-key map (kbd "C-c <") 'python-indent-shift-left)
158 ;; (define-key map (kbd "C-c >") 'python-indent-shift-right)
159 (define-key map (kbd "C-c C-c") 'elpy-shell-send-region-or-buffer)
160 (define-key map (kbd "C-c C-z") 'elpy-shell-switch-to-shell)
161 (define-key map (kbd "C-c C-d") 'elpy-doc)
162 (define-key map (kbd "C-c C-f") 'find-file-in-project)
163 ;; (define-key map (kbd "C-c C-i") 'yasnippet-expand)
164 (define-key map (kbd "C-c C-j") 'idomenu)
165 (define-key map (kbd "C-c C-n") 'elpy-flymake-forward-error)
166 (define-key map (kbd "C-c C-o") 'elpy-occur-definitions)
167 (define-key map (kbd "C-c C-p") 'elpy-flymake-backward-error)
168 (define-key map (kbd "C-c C-q") 'elpy-show-defun)
169 (define-key map (kbd "C-c C-r") 'elpy-refactor)
170 (define-key map (kbd "C-c C-s") 'elpy-rgrep-symbol)
171 (define-key map (kbd "C-c C-t") 'elpy-test)
172 (define-key map (kbd "C-c C-v") 'elpy-check)
173 (define-key map (kbd "C-c C-w") 'elpy-doc-websearch)
174 ;; (define-key map (kbd "C-c C-z") 'python-shell-switch-to-shell)
175
176 (define-key map (kbd "<C-down>") 'elpy-nav-forward-definition)
177 (define-key map (kbd "<C-up>") 'elpy-nav-backward-definition)
178 ;; (define-key map (kbd "M-,") 'iedit-mode
179 (define-key map (kbd "M-.") 'elpy-goto-definition)
180 (define-key map (kbd "M-a") 'elpy-nav-backward-statement)
181 (define-key map (kbd "M-e") 'elpy-nav-forward-statement)
182 (define-key map (kbd "M-n") 'elpy-nav-forward-definition)
183 (define-key map (kbd "M-p") 'elpy-nav-backward-definition)
184
185 map)
186 "Key map for the Emacs Lisp Python Environment.")
187
188 ;;;###autoload
189 (defun elpy-enable (&optional skip-initialize-variables)
190 "Enable Elpy in all future Python buffers.
191
192 When SKIP-INITIALIZE-VARIABLES is non-nil, this will NOT call
193 `elpy-initialize-variables' to configure various modes in a way
194 that the Elpy author considers sensible. If you'd rather
195 configure those modes yourself, pass t here."
196 (interactive)
197 (when (< emacs-major-version 24)
198 (error "Elpy requires Emacs 24 or newer"))
199 (let ((filename (find-lisp-object-file-name 'python-mode
200 'symbol-function)))
201 (when (and filename
202 (string-match "/python-mode\\.el\\'"
203 filename))
204 (error (concat "You are using python-mode.el. "
205 "Elpy only works with python.el from "
206 "Emacs 24 and above"))))
207 (add-hook 'python-mode-hook 'elpy-mode)
208 (when (not skip-initialize-variables)
209 (elpy-initialize-variables)))
210
211 ;;;###autoload
212 (defun elpy-disable ()
213 "Disable Elpy in all future Python buffers."
214 (interactive)
215 (remove-hook 'python-mode-hook 'elpy-mode))
216
217 ;;;###autoload
218 (define-minor-mode elpy-mode
219 "Minor mode in Python buffers for the Emacs Lisp Python Environment.
220
221 This mode fully supports virtualenvs. Once you switch a
222 virtualenv using \\[pyvenv-workon], you can use
223 \\[elpy-rpc-restart] to make the elpy Python process use your
224 virtualenv.
225
226 See https://github.com/jorgenschaefer/elpy/wiki/Keybindings for a
227 more structured list.
228
229 \\{elpy-mode-map}"
230 :lighter " Elpy"
231 (when (not (eq major-mode 'python-mode))
232 (error "Elpy only works with `python-mode'"))
233 (cond
234 (elpy-mode
235 (when buffer-file-name
236 (set (make-local-variable 'ffip-project-root) (elpy-project-root)))
237 (set (make-local-variable 'eldoc-documentation-function)
238 'elpy-eldoc-documentation)
239 (add-to-list 'ac-sources 'ac-source-elpy)
240 (add-to-list 'ac-sources 'ac-source-elpy-dot)
241 ;; Enable modes, hence the 1.
242 (run-hook-with-args 'elpy-default-minor-modes 1))
243 (t
244 (kill-local-variable 'ffip-project-root)
245 (kill-local-variable 'eldoc-documentation-function)
246 (setq ac-sources
247 (delq 'ac-source-elpy
248 (delq 'ac-source-elpy-dot
249 ac-sources))))))
250
251 (defun elpy-installation-instructions (message &optional show-elpy-module)
252 "Display a window with installation instructions for the Python
253 side of elpy.
254
255 MESSAGE is shown as the first paragraph.
256
257 If SHOW-ELPY-MODULE is non-nil, the help buffer will first
258 explain how to install the elpy module."
259 (if elpy-show-installation-instructions
260 (with-help-window "*Elpy Installation*"
261 (with-current-buffer "*Elpy Installation*"
262 (let ((inhibit-read-only t))
263 (erase-buffer)
264 (insert "Elpy Installation Instructions\n")
265 (insert "\n")
266 (insert message)
267 (when (not (bolp))
268 (insert "\n"))
269 (insert "\n")
270 (when show-elpy-module
271 (insert "Elpy requires the Python module \"elpy\". The module "
272 "is available from pypi, so you can install it using "
273 "the following command:\n")
274 (insert "\n")
275 (elpy-installation-command "elpy")
276 (insert "\n"))
277 (insert "To find possible completions, Elpy uses one of two "
278 "Python modules. Either \"rope\" or \"jedi\". To use "
279 "Elpy to its fullest potential, you should install "
280 "either one of them. Which one is a matter of taste. "
281 "You can try both and even switch at runtime using "
282 "M-x elpy-set-backend.\n")
283 (insert "\n")
284 (insert "Elpy also uses the Rope module for refactoring options, "
285 "so you likely want to install it even if you use jedi "
286 "for completion.\n")
287 (insert "\n")
288 (if (string-match "Python 3" (shell-command-to-string
289 "python --version"))
290 (elpy-installation-command "rope_py3k")
291 (elpy-installation-command "rope"))
292 (insert "\n")
293 (elpy-installation-command "jedi")
294 (insert "\n")
295 (insert "If you are using virtualenvs, you can use the "
296 "M-x pyvenv-workon command to switch to a virtualenv "
297 "of your choice. Afterwards, running the command "
298 "M-x elpy-rpc-restart will use the packages in "
299 "that virtualenv.")
300 (fill-region (point-min) (point-max)))))
301 (message "%s" (substitute-command-keys "You don't have elpy properly installed. Set `elpy-show-installation-instructions' to t to see the help buffer."))))
302
303 (defun elpy-installation-command (python-module)
304 "Insert an installation command description for PYTHON-MODULE."
305 (let* ((do-user-install (not (or (getenv "VIRTUAL_ENV")
306 pyvenv-virtual-env)))
307 (user-option (if do-user-install
308 "--user "
309 ""))
310 (command (cond
311 ((executable-find "pip")
312 (format "pip install %s%s" user-option python-module))
313 ((executable-find "easy_install")
314 (format "easy_install %s%s" user-option python-module))
315 (t
316 nil))))
317 (if (not command)
318 (insert "... hm. It appears you have neither pip nor easy_install "
319 "available. You might want to get the python-pip or "
320 "or python-setuptools package.\n")
321 (insert-text-button "[run]"
322 'action (lambda (button)
323 (async-shell-command
324 (button-get button 'command)))
325 'command command)
326 (insert " " command "\n"))))
327
328 (defun elpy-initialize-variables ()
329 "This sets some variables in other modes we like to set.
330
331 If you want to configure your own keys, do so after this function
332 is called (usually from `elpy-enable'), or override this function
333 using (defalias 'elpy-initialize-variables 'identity)"
334 ;; Local variables in `python-mode'. This is not removed when Elpy
335 ;; is disabled, which can cause some confusion.
336 (add-hook 'python-mode-hook 'elpy-initialize-local-variables)
337
338 ;; Flymake support using flake8, including warning faces.
339 (when (and (executable-find "flake8")
340 (not (executable-find python-check-command)))
341 (setq python-check-command "flake8"))
342
343 ;; `flymake-no-changes-timeout': The original value of 0.5 is too
344 ;; short for Python code, as that will result in the current line to
345 ;; be highlighted most of the time, and that's annoying. This value
346 ;; might be on the long side, but at least it does not, in general,
347 ;; interfere with normal interaction.
348 (setq flymake-no-changes-timeout 60)
349
350 ;; `flymake-start-syntax-check-on-newline': This should be nil for
351 ;; Python, as;; most lines with a colon at the end will mean the next
352 ;; line is always highlighted as error, which is not helpful and
353 ;; mostly annoying.
354 (setq flymake-start-syntax-check-on-newline nil)
355
356 ;; `ac-trigger-key': TAB is a great trigger key. We also need to
357 ;; tell auto-complete about the new trigger key. This is a bad
358 ;; interface to set the trigger key. Don't do this. Just let the
359 ;; user set the key in the keymap. Stop second-guessing the user, or
360 ;; Emacs.
361 (setq ac-trigger-key "TAB")
362 (when (fboundp 'ac-set-trigger-key)
363 (ac-set-trigger-key ac-trigger-key))
364
365 ;; `ac-auto-show-menu': Short timeout because the menu is great.
366 (setq ac-auto-show-menu 0.4)
367
368 ;; `ac-quick-help-delay': I'd like to show the menu right with the
369 ;; completions, but this value should be greater than
370 ;; `ac-auto-show-menu' to show help for the first entry as well.
371 (setq ac-quick-help-delay 0.5)
372
373 ;; Fix some key bindings in ac completions. Using RET when a
374 ;; completion is offered is not usually intended to complete (use
375 ;; TAB for that), but done while typing and the inputer is considere
376 ;; complete, with the intent to simply leave it as is and go to the
377 ;; next line. Much like space will not complete, but leave it as is
378 ;; and insert a space.
379 (define-key ac-completing-map (kbd "RET") nil)
380 (define-key ac-completing-map (kbd "<return>") nil)
381
382 ;; `yas-trigger-key': TAB, as is the default, conflicts with the
383 ;; autocompletion. We also need to tell yasnippet about the new
384 ;; binding. This is a bad interface to set the trigger key. Stop
385 ;; doing this.
386 (let ((old (when (boundp 'yas-trigger-key)
387 yas-trigger-key)))
388 (setq yas-trigger-key "C-c C-i")
389 (when (fboundp 'yas--trigger-key-reload)
390 (yas--trigger-key-reload old)))
391
392 ;; We provide some YASnippet snippets. Add them.
393
394 ;; yas-snippet-dirs can be a string for a single directory. Make
395 ;; sure it's a list in that case so we can add our own entry.
396 (when (not (listp yas-snippet-dirs))
397 (setq yas-snippet-dirs (list yas-snippet-dirs)))
398 (add-to-list 'yas-snippet-dirs
399 (concat (file-name-directory (locate-library "elpy"))
400 "snippets/")
401 t)
402
403 ;; Now load yasnippets.
404 (yas-reload-all))
405
406 (defun elpy-initialize-local-variables ()
407 "Initialize local variables in python-mode.
408
409 This should be run from `python-mode-hook'."
410 ;; Set `forward-sexp-function' to nil in python-mode. See
411 ;; http://debbugs.gnu.org/db/13/13642.html
412 (setq forward-sexp-function nil)
413 ;; Enable warning faces for flake8 output.
414 (when (string-match "flake8" python-check-command)
415 ;; COMPAT: Obsolete variable as of 24.4
416 (if (boundp 'flymake-warning-predicate)
417 (set (make-local-variable 'flymake-warning-predicate) "^W[0-9]")
418 (set (make-local-variable 'flymake-warning-re) "^W[0-9]"))))
419
420 (defvar elpy-project-root nil
421 "The root of the project the current buffer is in.")
422 (make-variable-buffer-local 'elpy-project-root)
423 (put 'elpy-project-root 'safe-local-variable 'file-directory-p)
424
425 (defun elpy-project-root ()
426 "Return the root of the current buffer's project.
427
428 You can set the variable `elpy-project-root' in, for example,
429 .dir-locals.el to configure this."
430 (when (not elpy-project-root)
431 (setq elpy-project-root (elpy-project--find-root))
432 (when (equal (directory-file-name (expand-file-name default-directory))
433 (directory-file-name (expand-file-name "~")))
434 (display-warning 'elpy
435 (concat "Project root set to your home directory; "
436 "this can slow down operation considerably")
437 :warning)))
438 elpy-project-root)
439
440 (defun elpy-project--find-root ()
441 "Find the first directory in the tree not containing an __init__.py
442
443 If there is no __init__.py in the current directory, return the
444 current directory."
445 (cond
446 ((and (functionp 'projectile-project-root)
447 (projectile-project-root))
448 (projectile-project-root))
449 ((file-exists-p (format "%s/__init__.py" default-directory))
450 (locate-dominating-file default-directory
451 (lambda (dir)
452 (not (file-exists-p
453 (format "%s/__init__.py" dir))))))
454 (t
455 default-directory)))
456
457 (defun elpy-set-project-root (new-root)
458 "Set the Elpy project root to NEW-ROOT."
459 (interactive "DNew project root: ")
460 (setq elpy-project-root new-root))
461
462 (defun elpy-use-ipython (&optional ipython)
463 "Set defaults to use IPython instead of the standard interpreter.
464
465 With prefix arg, prompt for the command to use."
466 (interactive (list (when current-prefix-arg
467 (read-file-name "IPython command: "))))
468 (when (not ipython)
469 (setq ipython "ipython"))
470 (if (boundp 'python-python-command)
471 ;; Emacs 24 until 24.3
472 (setq python-python-command ipython)
473 ;; Emacs 24.3 and onwards.
474
475 ;; This is from the python.el commentary.
476 ;; Settings for IPython 0.11:
477 (setq python-shell-interpreter ipython
478 python-shell-interpreter-args ""
479 python-shell-prompt-regexp "In \\[[0-9]+\\]: "
480 python-shell-prompt-output-regexp "Out\\[[0-9]+\\]: "
481 python-shell-completion-setup-code
482 "from IPython.core.completerlib import module_completion"
483 python-shell-completion-module-string-code
484 "';'.join(module_completion('''%s'''))\n"
485 python-shell-completion-string-code
486 "';'.join(get_ipython().Completer.all_completions('''%s'''))\n")))
487
488 (defun elpy-use-cpython (&optional cpython)
489 "Set defaults to use the standard interpreter instead of IPython.
490
491 With prefix arg, prompt for the command to use."
492 (interactive (list (when current-prefix-arg
493 (read-file-name "Python command: "))))
494 (when (not cpython)
495 (setq cpython "python"))
496 (if (boundp 'python-python-command)
497 ;; Emacs 24 until 24.3
498 (setq python-python-command cpython)
499 ;; Emacs 24.3 and onwards.
500 (setq python-shell-interpreter cpython
501 python-shell-interpreter-args "-i"
502 python-shell-prompt-regexp ">>> "
503 python-shell-prompt-output-regexp ""
504 python-shell-completion-setup-code
505 "try:
506 import readline
507 except ImportError:
508 def __COMPLETER_all_completions(text): []
509 else:
510 import rlcompleter
511 readline.set_completer(rlcompleter.Completer().complete)
512 def __COMPLETER_all_completions(text):
513 import sys
514 completions = []
515 try:
516 i = 0
517 while True:
518 res = readline.get_completer()(text, i)
519 if not res: break
520 i += 1
521 completions.append(res)
522 except NameError:
523 pass
524 return completions"
525 python-shell-completion-module-string-code ""
526 python-shell-completion-string-code
527 "';'.join(__COMPLETER_all_completions('''%s'''))\n")))
528
529 (defun elpy-clean-modeline ()
530 "Clean up the mode line by removing some lighters.
531
532 It's not necessary to see (Python Elpy yas AC ElDoc) all the
533 time. Honestly."
534 (interactive)
535 (setq eldoc-minor-mode-string nil)
536 (dolist (mode '(elpy-mode yas-minor-mode auto-complete-mode
537 flymake-mode))
538 (setcdr (assq mode minor-mode-alist)
539 (list ""))))
540
541 (defun elpy-shell-send-region-or-buffer (&optional arg)
542 "Send the active region or the buffer to the Python shell.
543
544 If there is an active region, send that. Otherwise, send the
545 whole buffer.
546
547 In Emacs 24.3 and later, without prefix argument, this will
548 escape the Python idiom of if __name__ == '__main__' to be false
549 to avoid accidental execution of code. With prefix argument, this
550 code is executed."
551 (interactive "P")
552 ;; Ensure process exists
553 (elpy-shell-get-or-create-process)
554 (if (region-active-p)
555 (python-shell-send-string (elpy--region-without-indentation
556 (region-beginning) (region-end)))
557 (python-shell-send-buffer arg))
558 (elpy-shell-switch-to-shell))
559
560 (defun elpy--region-without-indentation (beg end)
561 "Return the current region as a string, but without indentation."
562 (let ((region (buffer-substring beg end))
563 (indent-level nil))
564 (catch 'return
565 (with-temp-buffer
566 (insert region)
567 (goto-char (point-min))
568 (while (< (point) (point-max))
569 (cond
570 ((and (not indent-level)
571 (not (looking-at "[ \t]*$")))
572 (setq indent-level (current-indentation)))
573 ((and indent-level
574 (not (looking-at "[ \t]*$"))
575 (< (current-indentation)
576 indent-level))
577 (error "Can't adjust indentation, consecutive lines indented less than starting line")))
578 (forward-line))
579 (indent-rigidly (point-min)
580 (point-max)
581 (- indent-level))
582 (buffer-string)))))
583
584 (defun elpy-shell-switch-to-shell ()
585 "Switch to inferior Python process buffer."
586 (interactive)
587 (pop-to-buffer (process-buffer (elpy-shell-get-or-create-process)) t))
588
589 (defun elpy-shell-get-or-create-process ()
590 "Get or create an inferior Python process for current buffer and return it."
591 (let* ((bufname (format "*%s*" (python-shell-get-process-name nil)))
592 (proc (get-buffer-process bufname)))
593 (if proc
594 proc
595 (run-python (python-shell-parse-command))
596 (get-buffer-process bufname))))
597
598 (defun elpy-check (&optional whole-project-p)
599 "Run `python-check-command' on the current buffer's file,
600
601 or the project root if WHOLE-PROJECT-P is non-nil (interactively,
602 with a prefix argument)."
603 (interactive "P")
604 (when (not (buffer-file-name))
605 (error "Can't check a buffer without a file."))
606 (save-some-buffers (not compilation-ask-about-save) nil)
607 (let ((process-environment (python-shell-calculate-process-environment))
608 (exec-path (python-shell-calculate-exec-path))
609 (file-name-or-directory (expand-file-name
610 (if whole-project-p
611 (elpy-project-root)
612 (buffer-file-name))))
613 (extra-args (if whole-project-p
614 " --exclude=.svn,CVS,.bzr,.hg,.git,.tox,build,dist"
615 "")))
616 (compilation-start (concat python-check-command
617 " "
618 (shell-quote-argument file-name-or-directory)
619 extra-args)
620 nil
621 (lambda (mode-name)
622 "*Python Check*"))))
623
624 (defun elpy-show-defun ()
625 "Show the current class and method, in case they are not on
626 screen."
627 (interactive)
628 (let ((function (python-info-current-defun)))
629 (if function
630 (message "%s()" function)
631 (message "Not in a function"))))
632
633 (defun elpy-goto-definition ()
634 "Go to the definition of the symbol at point, if found."
635 (interactive)
636 (let ((location (elpy-rpc-get-definition)))
637 (if location
638 (elpy-goto-location (car location) (cadr location))
639 (error "No definition found"))))
640
641 (defun elpy-goto-location (filename offset)
642 "Show FILENAME at OFFSET to the user."
643 (ring-insert find-tag-marker-ring (point-marker))
644 (let ((buffer (find-file filename)))
645 (with-current-buffer buffer
646 (with-selected-window (get-buffer-window buffer)
647 (goto-char (1+ offset))))))
648
649 (defun elpy-nav-forward-statement ()
650 "Move forward one statement.
651
652 This will go to the end of the current statement, or the end of
653 the next one if already at the end."
654 (interactive)
655 (let ((old (point)))
656 (python-nav-end-of-statement)
657 (when (= old (point))
658 (python-nav-forward-statement)
659 (python-nav-end-of-statement))))
660
661 (defun elpy-nav-backward-statement ()
662 "Move backward one statement.
663
664 This will go to the beginning of the current statement, or the
665 beginning of the previous one if already at the beginning."
666 (interactive)
667 (let ((old (point)))
668 (python-nav-beginning-of-statement)
669 (when (= old (point))
670 (python-nav-backward-statement))))
671
672 (defun elpy-nav-forward-definition ()
673 "Move forward to the next definition (class or function)."
674 (interactive)
675 (if (save-excursion
676 (forward-char 1)
677 (re-search-forward "^ *\\(def\\|class\\) " nil t))
678 (goto-char (match-beginning 1))
679 (goto-char (point-max))))
680
681 (defun elpy-nav-backward-definition ()
682 "Move backward to the previous definition (class or function)."
683 (interactive)
684 (if (save-excursion
685 (forward-char -1)
686 (re-search-backward "^ *\\(def\\|class\\) " nil t))
687 (goto-char (match-beginning 1))
688 (goto-char (point-min))))
689
690 (defun elpy-occur-definitions ()
691 "Display an occur buffer of all definitions in the current buffer.
692
693 Also, switch to that buffer."
694 (interactive)
695 (let ((list-matching-lines-face nil))
696 (occur "^ *\\(def\\|class\\) "))
697 (let ((window (get-buffer-window "*Occur*")))
698 (if window
699 (select-window window)
700 (switch-to-buffer "*Occur*"))))
701
702 (defun elpy-rgrep-symbol (symbol)
703 "Search for SYMBOL in the current project.
704
705 SYMBOL defaults to the symbol at point, or the current region if
706 active.
707
708 With a prefix argument, prompt for a string to search for."
709 (interactive
710 (list
711 (cond
712 (current-prefix-arg
713 (read-from-minibuffer "Search for symbol: "))
714 ((use-region-p)
715 (buffer-substring-no-properties (region-beginning)
716 (region-end)))
717 (t
718 (or (thing-at-point 'symbol)
719 (read-from-minibuffer "Search for symbol: "))))))
720 (grep-compute-defaults)
721 (let ((grep-find-ignored-directories (append elpy-rgrep-ignored-directories
722 grep-find-ignored-directories)))
723 (rgrep (format "\\b%s\\b" symbol)
724 "*.py"
725 (elpy-project-root)))
726 (with-current-buffer next-error-last-buffer
727 (let ((inhibit-read-only t))
728 (save-excursion
729 (goto-char (point-min))
730 (when (re-search-forward "^find .*" nil t)
731 (replace-match (format "\\1\nSearching for symbol %s\n"
732 symbol)))))))
733
734 (defun elpy-test (&optional arg)
735 "Run nosetests on the current project.
736
737 With no prefix arg, all tests are run.
738 With one prefix arg, only the current test is run.
739 With two prefix args, only the current module is run."
740 (interactive "p")
741 (save-some-buffers)
742 (cond
743 ((>= arg 16) (nosetests-module))
744 ((>= arg 4) (nosetests-one))
745 (t (nosetests-all))))
746
747
748 ;;;;;;;;;;;;;;;;;
749 ;;; Documentation
750
751 (defvar elpy-doc-history nil
752 "History for the `elpy-doc' command.")
753
754 (defun elpy-doc-websearch (what)
755 "Search the Python web documentation for the string WHAT."
756 (interactive
757 (list (read-from-minibuffer "Search Python.org for: "
758 (symbol-name (symbol-at-point)))))
759 (browse-url
760 (format "https://www.google.com/search?q=site:docs.python.org%%20%s"
761 what)))
762
763 (defun elpy-doc (&optional use-pydoc-p symbol)
764 "Show documentation on the thing at point.
765
766 If USE-PYDOC is non-nil (interactively, when a prefix argument is
767 given), use pydoc on the symbol SYMBOL (interactively, the symbol
768 at point). With a single prefix argument, the user gets a
769 completion interface for possible symbols. With two prefix
770 arguments, the interface simply asks for a string."
771 (interactive
772 (list current-prefix-arg
773 (let ((initial (with-syntax-table python-dotty-syntax-table
774 (let ((symbol (symbol-at-point)))
775 (if symbol
776 (symbol-name symbol)
777 nil)))))
778 (cond
779 ((and initial (not current-prefix-arg))
780 initial)
781 ((equal current-prefix-arg '(16))
782 ;; C-u C-u
783 (read-from-minibuffer "Pydoc: " initial nil nil
784 'elpy-doc-history))
785 (t
786 (elpy-ido-recursive-completing-read "Pydoc: "
787 'elpy-pydoc--completions
788 "."
789 t
790 initial
791 'elpy-doc-history))))))
792 (let ((doc (if use-pydoc-p
793 (elpy-rpc-get-pydoc-documentation symbol)
794 (or (elpy-rpc-get-docstring)
795 ;; This will get the right position for
796 ;; multiprocessing.Queue(quxqux_|_)
797 (ignore-errors
798 (save-excursion
799 (elpy-nav-backward-statement)
800 (with-syntax-table python-dotty-syntax-table
801 (forward-symbol 1)
802 (backward-char 1))
803 (elpy-rpc-get-docstring)))))))
804 (if doc
805 (with-help-window "*Python Doc*"
806 (with-current-buffer "*Python Doc*"
807 (erase-buffer)
808 (insert doc)
809 (goto-char (point-min))
810 (while (re-search-forward "\\(.\\)\b\\1" nil t)
811 (replace-match (propertize (match-string 1)
812 'face 'bold)
813 t t))))
814 (message "No documentation available."))))
815
816 (defun elpy-pydoc--completions (rcr-prefix)
817 "Return a list of modules available in pydoc starting with RCR-PREFIX."
818 (sort (if (or (not rcr-prefix)
819 (equal rcr-prefix ""))
820 (elpy-rpc "get_pydoc_completions" nil)
821 (elpy-rpc "get_pydoc_completions" (list rcr-prefix)))
822 (lambda (a b)
823 (if (and (string-prefix-p "_" b)
824 (not (string-prefix-p "_" a)))
825 t
826 (string< (downcase a)
827 (downcase b))))))
828
829
830 ;;;;;;;;;;;;
831 ;;; elpy-ido
832
833 ;; This is a wrapper around ido-completing-read, which does not
834 ;; provide for recursive reads by default.
835
836 (defvar elpy-ido-rcr-choice-function nil
837 "Internal variable for `elpy-ido-recursive-completing-read'.
838
839 Don't touch. Won't help.")
840
841 (defvar elpy-ido-rcr-selection nil
842 "Internal variable for `elpy-ido-recursive-completing-read'.
843
844 Don't touch. Won't help.")
845
846 (defvar elpy-ido-rcr-separator nil
847 "Internal variable for `elpy-ido-recursive-completing-read'.
848
849 Don't touch. Won't help.")
850
851 (defvar elpy-ido-rcr-choices nil
852 "Internal variable for `elpy-ido-recursive-completing-read'.
853
854 Don't touch. Won't help.")
855
856 (defun elpy-ido--rcr-selected ()
857 "Return the currently selected compound."
858 (mapconcat #'identity
859 (reverse elpy-ido-rcr-selection)
860 elpy-ido-rcr-separator))
861
862 (defun elpy-ido--rcr-setup-keymap ()
863 "Set up the ido keymap for `elpy-ido-recursive-completing-read'."
864 (define-key ido-completion-map (read-kbd-macro elpy-ido-rcr-separator)
865 'elpy-ido-rcr-complete)
866 (define-key ido-completion-map (kbd "DEL") 'elpy-ido-rcr-backspace))
867
868 (defun elpy-ido-rcr-complete ()
869 "Complete the current ido completion and attempt an extension."
870 (interactive)
871 (let* ((new (car ido-matches))
872 (full (concat (elpy-ido--rcr-selected)
873 elpy-ido-rcr-separator
874 new))
875 (choices (funcall elpy-ido-rcr-choice-function full)))
876 (when choices
877 (setq elpy-ido-rcr-choices choices
878 elpy-ido-rcr-selection (cons new elpy-ido-rcr-selection))
879 (throw 'continue t))))
880
881 (defun elpy-ido-rcr-backspace (&optional n)
882 "Delete the last character in the minibuffer.
883
884 If the minibuffer is empty, recurse to the last completion."
885 (interactive "p")
886 (if (= (minibuffer-prompt-end) (point))
887 (progn
888 (setq elpy-ido-rcr-selection (cdr elpy-ido-rcr-selection)
889 elpy-ido-rcr-choices (funcall elpy-ido-rcr-choice-function
890 (elpy-ido--rcr-selected)))
891 (throw 'continue t))
892 (delete-char (- n))))
893
894 (defun elpy-ido-recursive-completing-read (prompt choice-function
895 separator
896 &optional
897 require-match
898 initial-input
899 hist def)
900 "An alternative to `ido-completing-read' supporting recursive selection.
901
902 The CHOICE-FUNCTION is called with a prefix string and should
903 find all possible selections with this prefix. The user is then
904 prompted with those options. When the user hits RET, the
905 currently selected option is returned. When the user hits the
906 SEPARATOR key, though, the currently selected option is appended,
907 with the separator, to the selected prefix, and the user is
908 prompted for further completions returned by CHOICE-FUNCTION.
909
910 For REQUIRE-MATCH, INITIAL-INPUT, HIST and DEF, see
911 `completing-read'."
912 (let ((ido-setup-hook (cons 'elpy-ido--rcr-setup-keymap
913 ido-setup-hook))
914 (elpy-ido-rcr-choice-function choice-function)
915 (elpy-ido-rcr-separator separator)
916 elpy-ido-rcr-choices
917 elpy-ido-rcr-selection)
918 (when initial-input
919 (let ((parts (reverse (split-string initial-input
920 (regexp-quote separator)))))
921 (setq initial-input (car parts)
922 elpy-ido-rcr-selection (cdr parts))))
923 (setq elpy-ido-rcr-choices (funcall choice-function
924 (elpy-ido--rcr-selected)))
925 (catch 'return
926 (while t
927 (catch 'continue
928 (throw 'return
929 (let ((completion (ido-completing-read
930 (concat prompt
931 (elpy-ido--rcr-selected)
932 (if elpy-ido-rcr-selection
933 elpy-ido-rcr-separator
934 ""))
935 elpy-ido-rcr-choices
936 nil require-match
937 initial-input hist def)))
938 (concat
939 (mapconcat (lambda (element)
940 (concat element elpy-ido-rcr-separator))
941 (reverse elpy-ido-rcr-selection)
942 "")
943 completion))))
944 ;; after the first run, we don't want initial and default
945 ;; anymore.
946 (setq initial-input nil
947 def nil)))))
948
949
950 ;;;;;;;;;;;;;;;;;;;;;
951 ;;; elpy-rpc backends
952
953 ;; elpy-rpc is a simple JSON-based RPC protocol. It's mostly JSON-RPC
954 ;; 1.0, except we do not implement the full protocol as we do not need
955 ;; all the features. Emacs starts a Python subprocess which runs a
956 ;; special module. The module reads JSON-RPC requests and responds
957 ;; with JSON-RPC responses.
958
959 (defvar elpy-rpc--call-id 0
960 "Call id of the last elpy-rpc call.
961
962 Used to associate responses to callbacks.")
963 (make-variable-buffer-local 'elpy-rpc--call-id)
964
965 (defvar elpy-rpc--buffer-p nil
966 "True iff the current buffer is an elpy-rpc buffer.")
967 (make-variable-buffer-local 'elpy-rpc--buffer-p)
968
969 (defvar elpy-rpc--buffer nil
970 "The elpy-rpc buffer associated with this buffer.")
971 (make-variable-buffer-local 'elpy-rpc--buffer)
972
973 (defvar elpy-rpc--backend-project-root nil
974 "The project root used by this backend.")
975 (make-variable-buffer-local 'elpy-rpc--backend-project-root)
976
977 (defvar elpy-rpc--backend-python-command nil
978 "The Python interpreter used by this backend.")
979 (make-variable-buffer-local 'elpy-rpc--backend-python-command)
980
981 (defvar elpy-rpc--backend-callbacks nil
982 "The callbacks registered for calls to the current backend.
983
984 This maps call IDs to functions.")
985 (make-variable-buffer-local 'elpy-rpc--backend-callbacks)
986
987 (defvar elpy-rpc--timeout 1
988 "Number of seconds to wait for a response.
989
990 You can dynamically bind this to a higher value if you want to
991 wait longer.")
992
993 (defun elpy-rpc--process-buffer-p (buffer)
994 "Return non-nil when BUFFER is an elpy-rpc buffer."
995 (buffer-local-value 'elpy-rpc--buffer-p buffer))
996
997 (defun elpy-rpc--live-p (buffer)
998 "Return non-nil when BUFFER is a live elpy-rpc process."
999 (and buffer
1000 (get-buffer-process buffer)
1001 (process-live-p (get-buffer-process buffer))))
1002
1003 (defun elpy-rpc--get-rpc-buffer ()
1004 "Return the RPC buffer associated with the current buffer,
1005 creating one if necessary."
1006 (cond
1007 (elpy-rpc--buffer-p
1008 (current-buffer))
1009 ((not elpy-mode)
1010 (error "Not an Elpy buffer"))
1011 ((elpy-rpc--live-p elpy-rpc--buffer)
1012 elpy-rpc--buffer)
1013 (t
1014 (when elpy-rpc--buffer
1015 (kill-buffer elpy-rpc--buffer))
1016 (setq elpy-rpc--buffer
1017 (or (elpy-rpc--find-buffer (elpy-project-root)
1018 elpy-rpc-python-command)
1019 (elpy-rpc--open (elpy-project-root)
1020 elpy-rpc-python-command)))
1021 elpy-rpc--buffer)))
1022
1023 (defun elpy-rpc--get-rpc-process ()
1024 "Return the RPC process associated with the current buffer,
1025 creating one if necessary."
1026 (get-buffer-process (elpy-rpc--get-rpc-buffer)))
1027
1028 (defun elpy-rpc--find-buffer (project-root python-command)
1029 "Return an existing RPC buffer for this project root and command."
1030 (let ((result nil))
1031 (dolist (buf (buffer-list))
1032 (when (elpy-rpc--process-buffer-p buf)
1033 (if (not (elpy-rpc--live-p buf))
1034 (kill-buffer buf)
1035 (with-current-buffer buf
1036 (when (and (equal elpy-rpc--backend-project-root
1037 project-root)
1038 (equal elpy-rpc--backend-python-command
1039 python-command))
1040 (when result
1041 (kill-buffer result))
1042 (setq result buf))))))
1043 result))
1044
1045 (defun elpy-rpc--open (project-root python-command)
1046 "Start a new RPC process and return the associated buffer."
1047 (when (and elpy-rpc-backend
1048 (not (stringp elpy-rpc-backend)))
1049 (error "`elpy-rpc-backend' should be nil or a string."))
1050 (let ((new-elpy-rpc-buffer (generate-new-buffer "*elpy-rpc*")))
1051 (with-current-buffer new-elpy-rpc-buffer
1052 (setq elpy-rpc--buffer-p t
1053 elpy-rpc--backend-project-root project-root
1054 elpy-rpc--backend-python-command python-command
1055 default-directory project-root))
1056 (let ((proc (condition-case err
1057 (let ((process-connection-type nil))
1058 (start-process "elpy-rpc"
1059 new-elpy-rpc-buffer
1060 python-command
1061 "-W" "ignore"
1062 "-m" "elpy.__main__"))
1063 (error
1064 (elpy-installation-instructions
1065 (format "Could not start the Python subprocess: %s"
1066 (cadr err))
1067 t)
1068 (error (cadr err))))))
1069 (set-process-query-on-exit-flag proc nil)
1070 (set-process-sentinel proc #'elpy-rpc--sentinel)
1071 (set-process-filter proc #'elpy-rpc--filter))
1072 (cond
1073 ;; User requested a specific backend
1074 (elpy-rpc-backend
1075 (elpy-rpc-set-backend
1076 elpy-rpc-backend
1077 (lambda (result)
1078 ;; Requested backend successfully set
1079 t)
1080 (lambda (err)
1081 (elpy-installation-instructions
1082 (format (concat "The %s backend is unavailable. "
1083 "Please install appropriate Python library,\n"
1084 "or change the value of `elpy-rpc-backend'")
1085 elpy-rpc-backend)))))
1086 ;; User did not specify a backend, make sure we are not using the
1087 ;; native one.
1088 (t
1089 (elpy-rpc-get-backend
1090 (lambda (current-backend)
1091 (when (equal current-backend "native")
1092 (elpy-installation-instructions
1093 (concat "Only the basic native backend is available. "
1094 "You might want to install an appropriate "
1095 "Python library. If you are happy with the native "
1096 "backend, please add the following to your .emacs:"
1097 "\n\n(setq elpy-rpc-backend \"native\")")))))))
1098 new-elpy-rpc-buffer))
1099
1100 (defun elpy-rpc--sentinel (process event)
1101 "The sentinel for the RPC process."
1102 (when event
1103 ;; Process sentinels are only ever called when the process
1104 ;; finishes.
1105 (when elpy-rpc--backend-callbacks
1106 (maphash (lambda (call-id callbacks)
1107 (ignore-errors
1108 (funcall (nth 1 callbacks)
1109 (substring event 0 -1))))
1110 elpy-rpc--backend-callbacks)
1111 (setq elpy-rpc--backend-callbacks nil))))
1112
1113 (defun elpy-rpc--filter (process output)
1114 "The filter for the RPC process."
1115 (with-current-buffer (process-buffer process)
1116 (goto-char (point-max))
1117 (insert output)
1118 (catch 'return
1119 (while (progn
1120 (goto-char (point-min))
1121 (search-forward "\n" nil t))
1122 (goto-char (point-min))
1123 (let (json did-read-json)
1124 (condition-case err
1125 (setq json (let ((json-array-type 'list))
1126 (json-read))
1127 did-read-json t)
1128 (error
1129 (goto-char (point-min))
1130 (cond
1131 ((looking-at "elpy-rpc ready\n")
1132 (replace-match "")
1133 (elpy-rpc--backend-version "1.1"))
1134 ((looking-at "elpy-rpc ready (\\([^ ]*\\))\n")
1135 (let ((rpc-version (match-string 1)))
1136 (replace-match "")
1137 (elpy-rpc--backend-version rpc-version)))
1138 (t
1139 (elpy-rpc--handle-unexpected-line)
1140 (throw 'return nil)))))
1141 (when did-read-json
1142 (delete-region (point-min) (1+ (point)))
1143 (elpy-rpc--handle-json json)))))))
1144
1145 (defun elpy-rpc--backend-version (rpc-version)
1146 "Check that we are using the right version."
1147 (when (not (equal rpc-version elpy-version))
1148 (with-help-window "*Elpy Version Mismatch*"
1149 (with-current-buffer "*Elpy Version Mismatch*"
1150 (insert
1151 "You are not using the same version of Elpy in Emacs Lisp\n"
1152 "compared to Python. This can cause random problems. Please\n"
1153 "do make sure to use compatible versions.\n"
1154 "\n"
1155 "Elpy Emacs Lisp version: " elpy-version "\n"
1156 "Elpy Python version....: " rpc-version "\n")))))
1157
1158 (defun elpy-rpc--handle-json (json)
1159 "Handle a single JSON object from the RPC backend."
1160 (let ((call-id (cdr (assq 'id json)))
1161 (error-string (cdr (assq 'error json)))
1162 (result (cdr (assq 'result json)))
1163 success-callback error-callback)
1164 (let ((callbacks (gethash call-id elpy-rpc--backend-callbacks)))
1165 (when (not callbacks)
1166 (error "Received a response for unknown call-id %s" call-id))
1167 (setq success-callback (nth 0 callbacks)
1168 error-callback (nth 1 callbacks)
1169 orig-buf (nth 2 callbacks))
1170 (remhash call-id elpy-rpc--backend-callbacks)
1171 (with-current-buffer orig-buf
1172 (if error-string
1173 (if error-callback
1174 (funcall error-callback error-string)
1175 (error "Error from RPC: %S" error-string))
1176 (funcall success-callback result))))))
1177
1178 (defun elpy-rpc--handle-unexpected-line ()
1179 "Handle an unexpected line from the backend.
1180
1181 This is usually an error or backtrace."
1182 (let ((missing-module (when (re-search-forward "No module named \\(.*\\)"
1183 nil t)
1184 (match-string 1))))
1185 (cond
1186 ((member missing-module '("elpy" "rope" "jedi"))
1187 (elpy-installation-instructions
1188 (format "The %s Python module was not found." missing-module)
1189 (equal missing-module "elpy")))
1190 (missing-module
1191 (with-help-window "*Elpy Error*"
1192 (with-current-buffer "*Elpy Error*"
1193 (view-mode 1)
1194 (let ((inhibit-read-only t))
1195 (erase-buffer)
1196 (insert "There was an error initializing the Elpy backend,\n"
1197 "as the " missing-module " Python module was not found.\n"
1198 "\n"
1199 "Please install this module to use elpy.\n"))
1200 (pop-to-buffer (current-buffer)))))
1201 (t
1202 (let ((data (buffer-string)))
1203 (with-help-window "*Elpy Error*"
1204 (with-current-buffer "*Elpy Error*"
1205 (view-mode 1)
1206 (let ((inhibit-read-only t))
1207 (erase-buffer)
1208 (insert "There was an error in the Elpy backend.\n"
1209 "The following lines were received from Python, and "
1210 "might help identifying\n"
1211 "the problem.\n"
1212 "\n"
1213 data))
1214 (pop-to-buffer (current-buffer)))))))))
1215
1216 (defun elpy-rpc--call (method-name params success &optional error)
1217 "Call METHOD-NAME with PARAMS in the current RPC backend.
1218
1219 Returns immediately. When a result is available, SUCCESS will be
1220 called with that value as its sole argument. If an error occurs,
1221 ERROR is called, if set."
1222 (let ((orig-buf (current-buffer)))
1223 (with-current-buffer (elpy-rpc--get-rpc-buffer)
1224 (setq elpy-rpc--call-id (1+ elpy-rpc--call-id))
1225 (elpy-rpc--register-callback elpy-rpc--call-id success error orig-buf)
1226 (process-send-string
1227 (get-buffer-process (current-buffer))
1228 (concat (json-encode `((id . ,elpy-rpc--call-id)
1229 (method . ,method-name)
1230 (params . ,params)))
1231 "\n")))))
1232
1233 (defun elpy-rpc--register-callback (call-id success error buffer)
1234 "Register for SUCCESS and ERROR to be called when CALL-ID returns.
1235
1236 Must be called in an elpy-rpc buffer."
1237 (assert elpy-rpc--buffer-p)
1238 (when (not elpy-rpc--backend-callbacks)
1239 (setq elpy-rpc--backend-callbacks (make-hash-table :test #'equal)))
1240 (puthash call-id (list success error buffer) elpy-rpc--backend-callbacks))
1241
1242 (defun elpy-rpc--call-blocking (method-name params)
1243 "Call METHOD-NAME with PARAMS in the current RPC backend.
1244
1245 Returns the result, blocking until this arrived."
1246 (let ((result-arrived nil)
1247 (error-occured nil)
1248 (result-value nil)
1249 (error-string nil))
1250 (elpy-rpc--call method-name params
1251 (lambda (result)
1252 (setq result-value result
1253 result-arrived t))
1254 (lambda (err)
1255 (setq error-string err
1256 error-occured t)))
1257 (let ((end-time (time-add (current-time)
1258 (seconds-to-time elpy-rpc--timeout))))
1259 (while (and (time-less-p (current-time)
1260 end-time)
1261 (not (or result-arrived
1262 error-occured)))
1263 (accept-process-output (elpy-rpc--get-rpc-process)
1264 elpy-rpc--timeout)))
1265 (cond
1266 (error-occured
1267 (error error-string))
1268 (result-arrived
1269 result-value)
1270 (t
1271 (error "Timeout in RPC call from backend")))))
1272
1273 (defun elpy-rpc (method params &optional success error)
1274 "Call METHOD with PARAMS in the backend.
1275
1276 If SUCCESS and optionally ERROR is given, return immediately and
1277 call those when a result is available. Otherwise, wait for a
1278 result and return that."
1279 (if success
1280 (elpy-rpc--call method params success error)
1281 (elpy-rpc--call-blocking method params)))
1282
1283 (defun elpy-rpc-restart ()
1284 "Restart the current RPC process."
1285 (interactive)
1286 (dolist (b (buffer-list))
1287 (when (buffer-local-value 'elpy-rpc--buffer-p b)
1288 (kill-buffer b))))
1289
1290 (defun elpy-rpc-traceback ()
1291 "Print the last traceback from the backend."
1292 (interactive)
1293 (let ((traceback (elpy-rpc "get_traceback" nil)))
1294 (with-current-buffer (get-buffer-create "*Elpy Traceback*")
1295 (with-help-window "*Elpy Traceback*"
1296 (let ((inhibit-read-only t))
1297 (erase-buffer)
1298 (if traceback
1299 (insert traceback)
1300 (insert "No traceback")))))))
1301
1302 (defun elpy-rpc-get-completions (&optional success error)
1303 "Call the find_completions API function.
1304
1305 Returns a list of possible completions for the Python symbol at
1306 point."
1307 (elpy-rpc "get_completions"
1308 (list (expand-file-name (elpy-project-root))
1309 buffer-file-name
1310 (buffer-string)
1311 (- (point)
1312 (point-min)))
1313 success error))
1314
1315 (defun elpy-rpc-get-calltip (&optional success error)
1316 "Call the get_calltip API function.
1317
1318 Returns a calltip string for the function call at point."
1319 (elpy-rpc "get_calltip"
1320 (list (expand-file-name (elpy-project-root))
1321 buffer-file-name
1322 (buffer-string)
1323 (- (point)
1324 (point-min)))
1325 success error))
1326
1327 (defun elpy-rpc-get-docstring (&optional success error)
1328 "Call the get_docstring API function.
1329
1330 Returns a possible multi-line docstring for the symbol at point."
1331 (elpy-rpc "get_docstring"
1332 (list (expand-file-name (elpy-project-root))
1333 buffer-file-name
1334 (buffer-string)
1335 (- (point)
1336 (point-min)))
1337 success error))
1338
1339 (defun elpy-rpc-get-pydoc-documentation (symbol &optional success error)
1340 "Get the Pydoc documentation for SYMBOL.
1341
1342 Returns a possible multi-line docstring."
1343 (elpy-rpc "get_pydoc_documentation" (list symbol)
1344 success error))
1345
1346 (defun elpy-rpc-get-definition (&optional success error)
1347 "Call the find_definition API function.
1348
1349 Returns nil or a list of (filename, point)."
1350 (elpy-rpc "get_definition"
1351 (list (expand-file-name (elpy-project-root))
1352 buffer-file-name
1353 (buffer-string)
1354 (- (point)
1355 (point-min)))
1356 success error))
1357
1358 (defun elpy-rpc-get-backend (&optional success error)
1359 "Call the get_backend API function.
1360
1361 Returns the name of the backend currently in use."
1362 (elpy-rpc "get_backend" nil success error))
1363
1364 (defun elpy-rpc-get-available-backends (&optional success error)
1365 "Call the get_available_backends API function.
1366
1367 Returns a list of names of available backends, depending on which
1368 Python libraries are installed."
1369 (elpy-rpc "get_available_backends" nil success error))
1370
1371 (defun elpy-rpc-set-backend (backend &optional success error)
1372 "Call the set_backend API function.
1373
1374 This changes the current backend to the named backend. Raises an
1375 error if the backend is not supported."
1376 (interactive
1377 (list (completing-read
1378 (format "Switch elpy backend (currently %s): "
1379 (elpy-rpc-get-backend))
1380 (elpy-rpc-get-available-backends)
1381 nil t)))
1382 (elpy-rpc "set_backend" (list backend) success error))
1383
1384 (defalias 'elpy-set-backend 'elpy-rpc-set-backend)
1385
1386
1387 ;;;;;;;;;
1388 ;;; Eldoc
1389
1390 (defun elpy-eldoc-documentation ()
1391 "Return a call tip for the python call at point."
1392 (elpy-rpc-get-calltip
1393 (lambda (calltip)
1394 (eldoc-message
1395 (when calltip
1396 (with-temp-buffer
1397 ;; multiprocessing.queues.Queue.cancel_join_thread(self)
1398 (insert calltip)
1399 (goto-char (point-min))
1400 ;; First, remove the whole path up to the second-to-last dot. We
1401 ;; retain the class just to make it nicer.
1402 (while (search-forward "." nil t)
1403 nil)
1404 (when (search-backward "." nil t 2)
1405 (delete-region (point-min) (1+ (point))))
1406 ;; Then remove the occurrence of "self", that's not passed by
1407 ;; the user.
1408 (when (re-search-forward "(self\\(, \\)?" nil t)
1409 (replace-match "("))
1410 (goto-char (point-min))
1411 ;; Lastly, we'd like to highlight the argument are on.
1412
1413 ;; This is tricky with keyword vs. positions arguments, and
1414 ;; possibly quite complex argument values.
1415
1416 ;; Hence, we don't do anything for now.
1417 (buffer-string))))))
1418 ;; Return the last message until we're done
1419 eldoc-last-message)
1420
1421
1422 ;;;;;;;;;;;
1423 ;;; Flymake
1424
1425 (eval-after-load "flymake"
1426 '(add-to-list 'flymake-allowed-file-name-masks
1427 '("\\.py\\'" elpy-flymake-python-init)))
1428
1429 (defun elpy-flymake-python-init ()
1430 ;; Make sure it's not a remote buffer as flymake would not work
1431 (when (not (file-remote-p buffer-file-name))
1432 (let* ((temp-file (flymake-init-create-temp-buffer-copy
1433 'flymake-create-temp-inplace)))
1434 (list python-check-command
1435 (list temp-file)
1436 ;; Run flake8 from / to avoid import problems (#169)
1437 "/"))))
1438
1439 (defun elpy-flymake-forward-error ()
1440 "Move forward to the next Flymake error and show a
1441 description."
1442 (interactive)
1443 (flymake-goto-next-error)
1444 (elpy-flymake-show-error))
1445
1446 (defun elpy-flymake-backward-error ()
1447 "Move backward to the previous Flymake error and show a
1448 description."
1449 (interactive)
1450 (flymake-goto-prev-error)
1451 (elpy-flymake-show-error))
1452
1453 (defun elpy-flymake-show-error ()
1454 "Show the flymake error message at point."
1455 (let* ((lineno (line-number-at-pos))
1456 (err-info (car (flymake-find-err-info flymake-err-info
1457 lineno)))
1458 (text (mapconcat #'flymake-ler-text
1459 err-info
1460 ", ")))
1461 (message "%s" text)))
1462
1463
1464 ;;;;;;;;;;;;;
1465 ;;; Yasnippet
1466
1467 ;; No added configuration needed. Nice mode. :o)
1468
1469
1470 ;;;;;;;;;;;;;;;;;
1471 ;;; Auto-Complete
1472
1473 (defvar elpy--ac-cache nil
1474 "List of current expansions and docstrings.")
1475
1476 (defun elpy--ac-init ()
1477 "Initialize a completion.
1478
1479 This will call Python in the background and initialize
1480 `elpy--ac-cache' when it returns."
1481 (when (not (eq (python-syntax-context-type)
1482 'comment))
1483 (elpy-rpc-get-completions
1484 (lambda (result)
1485 (setq elpy--ac-cache nil)
1486 (dolist (completion result)
1487 (let ((name (car completion))
1488 (doc (cadr completion)))
1489 (when (not (string-prefix-p "_" name))
1490 (push (cons (concat ac-prefix name)
1491 doc)
1492 elpy--ac-cache))))
1493 (ac-start))
1494 (lambda (err)
1495 (message "Can't get completions: %s" err)))))
1496
1497 (defun elpy--ac-candidates ()
1498 "Return a list of possible expansions at points.
1499
1500 This uses `elpy--ac-cache'."
1501 (mapcar (lambda (info)
1502 (popup-make-item
1503 (car info)
1504 :symbol "p"
1505 :summary (when (and (cdr info)
1506 (not (equal (cdr info) "")))
1507 "->")))
1508 elpy--ac-cache))
1509
1510 (defun elpy--ac-document (name)
1511 "Return the documentation for the symbol NAME."
1512 (let ((doc (assoc-default name elpy--ac-cache)))
1513 ;; popup.el has a bug when the docstring is the empty string. See
1514 ;; elpy tickets #182 and #154 as well as pull request #183 for
1515 ;; details.
1516 (if (equal doc "")
1517 nil
1518 doc)))
1519
1520 (ac-define-source elpy
1521 '((init . elpy--ac-init)
1522 (candidates . elpy--ac-candidates)
1523 (document . elpy--ac-document)
1524 (symbol . "p")))
1525
1526 (ac-define-source elpy-dot
1527 '((init . elpy--ac-init)
1528 (candidates . elpy--ac-candidates)
1529 (document . elpy--ac-document)
1530 (symbol . "p")
1531 (prefix . c-dot)
1532 (requires . 0)))
1533
1534
1535 ;;;;;;;;;;;;;;;;;;;;;;;;;;;
1536 ;;; Backwards compatibility
1537
1538 ;; Functions for Emacs 24 before 24.3
1539 (when (not (fboundp 'python-shell-send-string))
1540 (defalias 'python-shell-send-string 'python-send-string))
1541 (when (not (fboundp 'python-shell-send-buffer))
1542 (defun python-shell-send-buffer (&optional arg)
1543 (python-send-buffer)))
1544 (when (not (fboundp 'python-info-current-defun))
1545 (defalias 'python-info-current-defun 'python-current-defun))
1546 (when (not (fboundp 'python-nav-end-of-statement))
1547 (defalias 'python-nav-end-of-statement 'python-end-of-statement))
1548 (when (not (fboundp 'python-nav-beginning-of-statement))
1549 (require 'thingatpt)
1550 (defalias 'python-nav-beginning-of-statement 'beginning-of-sexp))
1551 (when (not (fboundp 'python-nav-forward-statement))
1552 (defalias 'python-nav-forward-statement 'forward-sexp))
1553 (when (not (fboundp 'python-nav-backward-statement))
1554 (defalias 'python-nav-backward-statement 'backward-sexp))
1555
1556 (when (not (fboundp 'python-shell-get-process-name))
1557 (defun python-shell-get-process-name (dedicated)
1558 "Compatibility function for older Emacsen."
1559 "Python"))
1560 (when (not (fboundp 'python-shell-parse-command))
1561 (defun python-shell-parse-command ()
1562 "Compatibility function for older Emacsen."
1563 python-python-command))
1564 (when (not (fboundp 'python-shell-calculate-process-environment))
1565 (defun python-shell-calculate-process-environment ()
1566 "Compatibility function for older Emacsen."
1567 process-environment))
1568 (when (not (fboundp 'python-shell-calculate-exec-path))
1569 (defun python-shell-calculate-exec-path ()
1570 "Compatibility function for older Emacsen."
1571 exec-path))
1572
1573 ;; Emacs 24.2 made `locate-dominating-file' accept a predicate instead
1574 ;; of a string. Simply overwrite the current one, it's
1575 ;; backwards-compatible. The code below is taken from Emacs 24.3.
1576 (when (or (< emacs-major-version 24)
1577 (and (= emacs-major-version 24)
1578 (<= emacs-minor-version 2)))
1579 (defun locate-dominating-file (file name)
1580 "Look up the directory hierarchy from FILE for a directory containing NAME.
1581 Stop at the first parent directory containing a file NAME,
1582 and return the directory. Return nil if not found.
1583 Instead of a string, NAME can also be a predicate taking one argument
1584 \(a directory) and returning a non-nil value if that directory is the one for
1585 which we're looking."
1586 ;; We used to use the above locate-dominating-files code, but the
1587 ;; directory-files call is very costly, so we're much better off doing
1588 ;; multiple calls using the code in here.
1589 ;;
1590 ;; Represent /home/luser/foo as ~/foo so that we don't try to look for
1591 ;; `name' in /home or in /.
1592 (setq file (abbreviate-file-name file))
1593 (let ((root nil)
1594 ;; `user' is not initialized outside the loop because
1595 ;; `file' may not exist, so we may have to walk up part of the
1596 ;; hierarchy before we find the "initial UID". Note: currently unused
1597 ;; (user nil)
1598 try)
1599 (while (not (or root
1600 (null file)
1601 ;; FIXME: Disabled this heuristic because it is sometimes
1602 ;; inappropriate.
1603 ;; As a heuristic, we stop looking up the hierarchy of
1604 ;; directories as soon as we find a directory belonging
1605 ;; to another user. This should save us from looking in
1606 ;; things like /net and /afs. This assumes that all the
1607 ;; files inside a project belong to the same user.
1608 ;; (let ((prev-user user))
1609 ;; (setq user (nth 2 (file-attributes file)))
1610 ;; (and prev-user (not (equal user prev-user))))
1611 (string-match locate-dominating-stop-dir-regexp file)))
1612 (setq try (if (stringp name)
1613 (file-exists-p (expand-file-name name file))
1614 (funcall name file)))
1615 (cond (try (setq root file))
1616 ((equal file (setq file (file-name-directory
1617 (directory-file-name file))))
1618 (setq file nil))))
1619 (if root (file-name-as-directory root))))
1620 )
1621
1622 ;; highlight-indentation 0.5 does not use modes yet
1623 (when (not (fboundp 'highlight-indentation-mode))
1624 (defun highlight-indentation-mode (on-or-off)
1625 (cond
1626 ((and (= on-or-off 1)
1627 (not highlight-indent-active))
1628 (highlight-indentation))
1629 ((and (= on-or-off 0)
1630 highlight-indent-active)
1631 (highlight-indentation)))))
1632
1633 (provide 'elpy)
1634 ;;; elpy.el ends here