diff options
| author | Fabián Ezequiel Gallina | 2014-12-27 20:12:00 -0300 |
|---|---|---|
| committer | Fabián Ezequiel Gallina | 2014-12-27 20:12:00 -0300 |
| commit | 7d1e62d51b51be27b11a67d7828b77f2df9e1eb1 (patch) | |
| tree | 8404c3b50203c55b9cbffdbe0e0553311ff7df22 /lisp/progmodes/python.el | |
| parent | 996ad1b846a0865245df008bdb551093278b3c30 (diff) | |
| download | emacs-7d1e62d51b51be27b11a67d7828b77f2df9e1eb1.tar.gz emacs-7d1e62d51b51be27b11a67d7828b77f2df9e1eb1.zip | |
python.el: Enhance shell user interaction and deprecate python-shell-get-or-create-process.
* lisp/progmodes/python.el
(python-shell-get-process-or-error): New function.
(python-shell-with-shell-buffer): Use it.
(python-shell-send-string, python-shell-send-region)
(python-shell-send-buffer, python-shell-send-defun)
(python-shell-send-file, python-shell-switch-to-shell): Use it.
Add argument MSG to display user-friendly message when no process
is running.
(python-shell-switch-to-shell): Call pop-to-buffer with NORECORD.
(python-shell-make-comint): Rename argument SHOW from POP. Use
display-buffer instead of pop-to-buffer.
(run-python): Doc fix. Return process.
(python-shell-get-or-create-process): Make obsolete.
* test/automated/python-tests.el (python-shell-get-or-create-process-1)
(python-shell-get-or-create-process-2)
(python-shell-get-or-create-process-3): Remove tests.
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 127 |
1 files changed, 87 insertions, 40 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 0b7d9169e6a..8a85763f765 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -2255,11 +2255,9 @@ Avoids `recenter' calls until OUTPUT is completely sent." | |||
| 2255 | "Execute the forms in BODY with the shell buffer temporarily current. | 2255 | "Execute the forms in BODY with the shell buffer temporarily current. |
| 2256 | Signals an error if no shell buffer is available for current buffer." | 2256 | Signals an error if no shell buffer is available for current buffer." |
| 2257 | (declare (indent 0) (debug t)) | 2257 | (declare (indent 0) (debug t)) |
| 2258 | (let ((shell-buffer (make-symbol "shell-buffer"))) | 2258 | (let ((shell-process (make-symbol "shell-process"))) |
| 2259 | `(let ((,shell-buffer (python-shell-get-buffer))) | 2259 | `(let ((,shell-process (python-shell-get-process-or-error))) |
| 2260 | (when (not ,shell-buffer) | 2260 | (with-current-buffer (process-buffer ,shell-process) |
| 2261 | (error "No inferior Python buffer available.")) | ||
| 2262 | (with-current-buffer ,shell-buffer | ||
| 2263 | ,@body)))) | 2261 | ,@body)))) |
| 2264 | 2262 | ||
| 2265 | (defvar python-shell--font-lock-buffer nil) | 2263 | (defvar python-shell--font-lock-buffer nil) |
| @@ -2471,12 +2469,12 @@ variable. | |||
| 2471 | (python-shell-accept-process-output | 2469 | (python-shell-accept-process-output |
| 2472 | (get-buffer-process (current-buffer)))) | 2470 | (get-buffer-process (current-buffer)))) |
| 2473 | 2471 | ||
| 2474 | (defun python-shell-make-comint (cmd proc-name &optional pop internal) | 2472 | (defun python-shell-make-comint (cmd proc-name &optional show internal) |
| 2475 | "Create a Python shell comint buffer. | 2473 | "Create a Python shell comint buffer. |
| 2476 | CMD is the Python command to be executed and PROC-NAME is the | 2474 | CMD is the Python command to be executed and PROC-NAME is the |
| 2477 | process name the comint buffer will get. After the comint buffer | 2475 | process name the comint buffer will get. After the comint buffer |
| 2478 | is created the `inferior-python-mode' is activated. When | 2476 | is created the `inferior-python-mode' is activated. When |
| 2479 | optional argument POP is non-nil the buffer is shown. When | 2477 | optional argument SHOW is non-nil the buffer is shown. When |
| 2480 | optional argument INTERNAL is non-nil this process is run on a | 2478 | optional argument INTERNAL is non-nil this process is run on a |
| 2481 | buffer with a name that starts with a space, following the Emacs | 2479 | buffer with a name that starts with a space, following the Emacs |
| 2482 | convention for temporary/internal buffers, and also makes sure | 2480 | convention for temporary/internal buffers, and also makes sure |
| @@ -2505,16 +2503,13 @@ killed." | |||
| 2505 | (mapconcat #'identity args " "))) | 2503 | (mapconcat #'identity args " "))) |
| 2506 | (with-current-buffer buffer | 2504 | (with-current-buffer buffer |
| 2507 | (inferior-python-mode)) | 2505 | (inferior-python-mode)) |
| 2508 | (and pop (pop-to-buffer buffer t)) | 2506 | (when show (display-buffer buffer)) |
| 2509 | (and internal (set-process-query-on-exit-flag process nil)))) | 2507 | (and internal (set-process-query-on-exit-flag process nil)))) |
| 2510 | proc-buffer-name))) | 2508 | proc-buffer-name))) |
| 2511 | 2509 | ||
| 2512 | ;;;###autoload | 2510 | ;;;###autoload |
| 2513 | (defun run-python (&optional cmd dedicated show) | 2511 | (defun run-python (&optional cmd dedicated show) |
| 2514 | "Run an inferior Python process. | 2512 | "Run an inferior Python process. |
| 2515 | Input and output via buffer named after | ||
| 2516 | `python-shell-buffer-name'. If there is a process already | ||
| 2517 | running in that buffer, just switch to it. | ||
| 2518 | 2513 | ||
| 2519 | Argument CMD defaults to `python-shell-calculate-command' return | 2514 | Argument CMD defaults to `python-shell-calculate-command' return |
| 2520 | value. When called interactively with `prefix-arg', it allows | 2515 | value. When called interactively with `prefix-arg', it allows |
| @@ -2522,6 +2517,11 @@ the user to edit such value and choose whether the interpreter | |||
| 2522 | should be DEDICATED for the current buffer. When numeric prefix | 2517 | should be DEDICATED for the current buffer. When numeric prefix |
| 2523 | arg is other than 0 or 4 do not SHOW. | 2518 | arg is other than 0 or 4 do not SHOW. |
| 2524 | 2519 | ||
| 2520 | For a given buffer and same values of DEDICATED, if a process is | ||
| 2521 | already running for it, it will do nothing. This means that if | ||
| 2522 | the current buffer is using a global process, the user is still | ||
| 2523 | able to switch it to use a dedicated one. | ||
| 2524 | |||
| 2525 | Runs the hook `inferior-python-mode-hook' after | 2525 | Runs the hook `inferior-python-mode-hook' after |
| 2526 | `comint-mode-hook' is run. (Type \\[describe-mode] in the | 2526 | `comint-mode-hook' is run. (Type \\[describe-mode] in the |
| 2527 | process buffer for a list of commands.)" | 2527 | process buffer for a list of commands.)" |
| @@ -2532,10 +2532,10 @@ process buffer for a list of commands.)" | |||
| 2532 | (y-or-n-p "Make dedicated process? ") | 2532 | (y-or-n-p "Make dedicated process? ") |
| 2533 | (= (prefix-numeric-value current-prefix-arg) 4)) | 2533 | (= (prefix-numeric-value current-prefix-arg) 4)) |
| 2534 | (list (python-shell-calculate-command) nil t))) | 2534 | (list (python-shell-calculate-command) nil t))) |
| 2535 | (python-shell-make-comint | 2535 | (get-buffer-process |
| 2536 | (or cmd (python-shell-calculate-command)) | 2536 | (python-shell-make-comint |
| 2537 | (python-shell-get-process-name dedicated) show) | 2537 | (or cmd (python-shell-calculate-command)) |
| 2538 | dedicated) | 2538 | (python-shell-get-process-name dedicated) show))) |
| 2539 | 2539 | ||
| 2540 | (defun run-python-internal () | 2540 | (defun run-python-internal () |
| 2541 | "Run an inferior Internal Python process. | 2541 | "Run an inferior Internal Python process. |
| @@ -2578,6 +2578,21 @@ If current buffer is in `inferior-python-mode', return it." | |||
| 2578 | "Return inferior Python process for current buffer." | 2578 | "Return inferior Python process for current buffer." |
| 2579 | (get-buffer-process (python-shell-get-buffer))) | 2579 | (get-buffer-process (python-shell-get-buffer))) |
| 2580 | 2580 | ||
| 2581 | (defun python-shell-get-process-or-error (&optional interactivep) | ||
| 2582 | "Return inferior Python process for current buffer or signal error. | ||
| 2583 | When argument INTERACTIVEP is non-nil, use `user-error' instead | ||
| 2584 | of `error' with a user-friendly message." | ||
| 2585 | (or (python-shell-get-process) | ||
| 2586 | (if interactivep | ||
| 2587 | (user-error | ||
| 2588 | "Start a Python process first with `M-x run-python' or `%s'." | ||
| 2589 | ;; Get the binding. | ||
| 2590 | (key-description | ||
| 2591 | (where-is-internal | ||
| 2592 | #'run-python overriding-local-map t))) | ||
| 2593 | (error | ||
| 2594 | "No inferior Python process running.")))) | ||
| 2595 | |||
| 2581 | (defun python-shell-get-or-create-process (&optional cmd dedicated show) | 2596 | (defun python-shell-get-or-create-process (&optional cmd dedicated show) |
| 2582 | "Get or create an inferior Python process for current buffer and return it. | 2597 | "Get or create an inferior Python process for current buffer and return it. |
| 2583 | Arguments CMD, DEDICATED and SHOW are those of `run-python' and | 2598 | Arguments CMD, DEDICATED and SHOW are those of `run-python' and |
| @@ -2593,6 +2608,11 @@ be asked for their values." | |||
| 2593 | (run-python cmd dedicated show))) | 2608 | (run-python cmd dedicated show))) |
| 2594 | (or shell-process (python-shell-get-process)))) | 2609 | (or shell-process (python-shell-get-process)))) |
| 2595 | 2610 | ||
| 2611 | (make-obsolete | ||
| 2612 | #'python-shell-get-or-create-process | ||
| 2613 | "Instead call `python-shell-get-process' and create one if returns nil." | ||
| 2614 | "25.1") | ||
| 2615 | |||
| 2596 | (defvar python-shell-internal-buffer nil | 2616 | (defvar python-shell-internal-buffer nil |
| 2597 | "Current internal shell buffer for the current buffer. | 2617 | "Current internal shell buffer for the current buffer. |
| 2598 | This is really not necessary at all for the code to work but it's | 2618 | This is really not necessary at all for the code to work but it's |
| @@ -2631,10 +2651,14 @@ there for compatibility with CEDET.") | |||
| 2631 | (delete-trailing-whitespace)) | 2651 | (delete-trailing-whitespace)) |
| 2632 | temp-file-name)) | 2652 | temp-file-name)) |
| 2633 | 2653 | ||
| 2634 | (defun python-shell-send-string (string &optional process) | 2654 | (defun python-shell-send-string (string &optional process msg) |
| 2635 | "Send STRING to inferior Python PROCESS." | 2655 | "Send STRING to inferior Python PROCESS. |
| 2636 | (interactive "sPython command: ") | 2656 | When optional argument MSG is non-nil, forces display of a |
| 2637 | (let ((process (or process (python-shell-get-or-create-process)))) | 2657 | user-friendly message if there's no process running; defaults to |
| 2658 | t when called interactively." | ||
| 2659 | (interactive | ||
| 2660 | (list (read-string "Python command: ") nil t)) | ||
| 2661 | (let ((process (or process (python-shell-get-process-or-error msg)))) | ||
| 2638 | (if (string-match ".\n+." string) ;Multiline. | 2662 | (if (string-match ".\n+." string) ;Multiline. |
| 2639 | (let* ((temp-file-name (python-shell--save-temp-file string)) | 2663 | (let* ((temp-file-name (python-shell--save-temp-file string)) |
| 2640 | (file-name (or (buffer-file-name) temp-file-name))) | 2664 | (file-name (or (buffer-file-name) temp-file-name))) |
| @@ -2677,7 +2701,7 @@ detecting a prompt at the end of the buffer." | |||
| 2677 | (defun python-shell-send-string-no-output (string &optional process) | 2701 | (defun python-shell-send-string-no-output (string &optional process) |
| 2678 | "Send STRING to PROCESS and inhibit output. | 2702 | "Send STRING to PROCESS and inhibit output. |
| 2679 | Return the output." | 2703 | Return the output." |
| 2680 | (let ((process (or process (python-shell-get-or-create-process))) | 2704 | (let ((process (or process (python-shell-get-process-or-error))) |
| 2681 | (comint-preoutput-filter-functions | 2705 | (comint-preoutput-filter-functions |
| 2682 | '(python-shell-output-filter)) | 2706 | '(python-shell-output-filter)) |
| 2683 | (python-shell-output-filter-in-progress t) | 2707 | (python-shell-output-filter-in-progress t) |
| @@ -2781,35 +2805,43 @@ the python shell: | |||
| 2781 | (line-beginning-position) (line-end-position)))) | 2805 | (line-beginning-position) (line-end-position)))) |
| 2782 | (buffer-substring-no-properties (point-min) (point-max))))) | 2806 | (buffer-substring-no-properties (point-min) (point-max))))) |
| 2783 | 2807 | ||
| 2784 | (defun python-shell-send-region (start end &optional send-main) | 2808 | (defun python-shell-send-region (start end &optional send-main msg) |
| 2785 | "Send the region delimited by START and END to inferior Python process. | 2809 | "Send the region delimited by START and END to inferior Python process. |
| 2786 | When optional argument SEND-MAIN is non-nil, allow execution of | 2810 | When optional argument SEND-MAIN is non-nil, allow execution of |
| 2787 | code inside blocks delimited by \"if __name__== '__main__':\". | 2811 | code inside blocks delimited by \"if __name__== '__main__':\". |
| 2788 | When called interactively SEND-MAIN defaults to nil, unless it's | 2812 | When called interactively SEND-MAIN defaults to nil, unless it's |
| 2789 | called with prefix argument." | 2813 | called with prefix argument. When optional argument MSG is |
| 2790 | (interactive "r\nP") | 2814 | non-nil, forces display of a user-friendly message if there's no |
| 2815 | process running; defaults to t when called interactively." | ||
| 2816 | (interactive | ||
| 2817 | (list (region-beginning) (region-end) current-prefix-arg t)) | ||
| 2791 | (let* ((string (python-shell-buffer-substring start end (not send-main))) | 2818 | (let* ((string (python-shell-buffer-substring start end (not send-main))) |
| 2792 | (process (python-shell-get-or-create-process)) | 2819 | (process (python-shell-get-process-or-error msg)) |
| 2793 | (original-string (buffer-substring-no-properties start end)) | 2820 | (original-string (buffer-substring-no-properties start end)) |
| 2794 | (_ (string-match "\\`\n*\\(.*\\)" original-string))) | 2821 | (_ (string-match "\\`\n*\\(.*\\)" original-string))) |
| 2795 | (message "Sent: %s..." (match-string 1 original-string)) | 2822 | (message "Sent: %s..." (match-string 1 original-string)) |
| 2796 | (python-shell-send-string string process))) | 2823 | (python-shell-send-string string process))) |
| 2797 | 2824 | ||
| 2798 | (defun python-shell-send-buffer (&optional send-main) | 2825 | (defun python-shell-send-buffer (&optional send-main msg) |
| 2799 | "Send the entire buffer to inferior Python process. | 2826 | "Send the entire buffer to inferior Python process. |
| 2800 | When optional argument SEND-MAIN is non-nil, allow execution of | 2827 | When optional argument SEND-MAIN is non-nil, allow execution of |
| 2801 | code inside blocks delimited by \"if __name__== '__main__':\". | 2828 | code inside blocks delimited by \"if __name__== '__main__':\". |
| 2802 | When called interactively SEND-MAIN defaults to nil, unless it's | 2829 | When called interactively SEND-MAIN defaults to nil, unless it's |
| 2803 | called with prefix argument." | 2830 | called with prefix argument. When optional argument MSG is |
| 2804 | (interactive "P") | 2831 | non-nil, forces display of a user-friendly message if there's no |
| 2832 | process running; defaults to t when called interactively." | ||
| 2833 | (interactive (list current-prefix-arg t)) | ||
| 2805 | (save-restriction | 2834 | (save-restriction |
| 2806 | (widen) | 2835 | (widen) |
| 2807 | (python-shell-send-region (point-min) (point-max) send-main))) | 2836 | (python-shell-send-region (point-min) (point-max) send-main msg))) |
| 2808 | 2837 | ||
| 2809 | (defun python-shell-send-defun (arg) | 2838 | (defun python-shell-send-defun (&optional arg msg) |
| 2810 | "Send the current defun to inferior Python process. | 2839 | "Send the current defun to inferior Python process. |
| 2811 | When argument ARG is non-nil do not include decorators." | 2840 | When argument ARG is non-nil do not include decorators. When |
| 2812 | (interactive "P") | 2841 | optional argument MSG is non-nil, forces display of a |
| 2842 | user-friendly message if there's no process running; defaults to | ||
| 2843 | t when called interactively." | ||
| 2844 | (interactive (list current-prefix-arg t)) | ||
| 2813 | (save-excursion | 2845 | (save-excursion |
| 2814 | (python-shell-send-region | 2846 | (python-shell-send-region |
| 2815 | (progn | 2847 | (progn |
| @@ -2825,17 +2857,28 @@ When argument ARG is non-nil do not include decorators." | |||
| 2825 | (progn | 2857 | (progn |
| 2826 | (or (python-nav-end-of-defun) | 2858 | (or (python-nav-end-of-defun) |
| 2827 | (end-of-line 1)) | 2859 | (end-of-line 1)) |
| 2828 | (point-marker))))) | 2860 | (point-marker)) |
| 2861 | nil ;; noop | ||
| 2862 | msg))) | ||
| 2829 | 2863 | ||
| 2830 | (defun python-shell-send-file (file-name &optional process temp-file-name | 2864 | (defun python-shell-send-file (file-name &optional process temp-file-name |
| 2831 | delete) | 2865 | delete msg) |
| 2832 | "Send FILE-NAME to inferior Python PROCESS. | 2866 | "Send FILE-NAME to inferior Python PROCESS. |
| 2833 | If TEMP-FILE-NAME is passed then that file is used for processing | 2867 | If TEMP-FILE-NAME is passed then that file is used for processing |
| 2834 | instead, while internally the shell will continue to use | 2868 | instead, while internally the shell will continue to use |
| 2835 | FILE-NAME. If TEMP-FILE-NAME and DELETE are non-nil, then | 2869 | FILE-NAME. If TEMP-FILE-NAME and DELETE are non-nil, then |
| 2836 | TEMP-FILE-NAME is deleted after evaluation is performed." | 2870 | TEMP-FILE-NAME is deleted after evaluation is performed. When |
| 2837 | (interactive "fFile to send: ") | 2871 | optional argument MSG is non-nil, forces display of a |
| 2838 | (let* ((process (or process (python-shell-get-or-create-process))) | 2872 | user-friendly message if there's no process running; defaults to |
| 2873 | t when called interactively." | ||
| 2874 | (interactive | ||
| 2875 | (list | ||
| 2876 | (read-file-name "File to send: ") ; file-name | ||
| 2877 | nil ; process | ||
| 2878 | nil ; temp-file-name | ||
| 2879 | nil ; delete | ||
| 2880 | t)) ; msg | ||
| 2881 | (let* ((process (or process (python-shell-get-process-or-error msg))) | ||
| 2839 | (encoding (with-temp-buffer | 2882 | (encoding (with-temp-buffer |
| 2840 | (insert-file-contents | 2883 | (insert-file-contents |
| 2841 | (or temp-file-name file-name)) | 2884 | (or temp-file-name file-name)) |
| @@ -2860,10 +2903,14 @@ TEMP-FILE-NAME is deleted after evaluation is performed." | |||
| 2860 | (or temp-file-name file-name) encoding encoding file-name) | 2903 | (or temp-file-name file-name) encoding encoding file-name) |
| 2861 | process))) | 2904 | process))) |
| 2862 | 2905 | ||
| 2863 | (defun python-shell-switch-to-shell () | 2906 | (defun python-shell-switch-to-shell (&optional msg) |
| 2864 | "Switch to inferior Python process buffer." | 2907 | "Switch to inferior Python process buffer. |
| 2865 | (interactive) | 2908 | When optional argument MSG is non-nil, forces display of a |
| 2866 | (pop-to-buffer (process-buffer (python-shell-get-or-create-process)) t)) | 2909 | user-friendly message if there's no process running; defaults to |
| 2910 | t when called interactively." | ||
| 2911 | (interactive "p") | ||
| 2912 | (pop-to-buffer | ||
| 2913 | (process-buffer (python-shell-get-process-or-error msg)) nil t)) | ||
| 2867 | 2914 | ||
| 2868 | (defun python-shell-send-setup-code () | 2915 | (defun python-shell-send-setup-code () |
| 2869 | "Send all setup code for shell. | 2916 | "Send all setup code for shell. |