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