diff options
| author | Stefan Monnier | 2013-11-04 14:14:58 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2013-11-04 14:14:58 -0500 |
| commit | e5afbcacfab50bb3cceb95bb778a1a4cbb90eda0 (patch) | |
| tree | daf06aab2617a57a43f292be40f91bdecb77eb2d /lisp/progmodes/python.el | |
| parent | c8b09927b5ae87b19e8880614ac2b23e3c0df6e6 (diff) | |
| download | emacs-e5afbcacfab50bb3cceb95bb778a1a4cbb90eda0.tar.gz emacs-e5afbcacfab50bb3cceb95bb778a1a4cbb90eda0.zip | |
* lisp/progmodes/python.el: Fix up last change.
(python-shell--save-temp-file): New function.
(python-shell-send-string): Use it. Remove `msg' arg. Don't assume
`string' comes from the current buffer.
(python-shell-send-string-no-output): Remove `msg' arg.
(python--use-fake-loc): New var.
(python-shell-buffer-substring): Obey it. Try to compensate for the
extra coding line added by python-shell--save-temp-file.
(python-shell-send-region): Use python-shell--save-temp-file and
python-shell-send-file directly. Add `nomain' argument.
(python-shell-send-buffer): Use python-shell-send-region.
(python-electric-pair-string-delimiter): New function.
(python-mode): Use it.
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 110 |
1 files changed, 69 insertions, 41 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index e0a7feb3a72..ca9c3c6e6ef 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -2036,34 +2036,31 @@ there for compatibility with CEDET.") | |||
| 2036 | (define-obsolete-variable-alias | 2036 | (define-obsolete-variable-alias |
| 2037 | 'python-preoutput-result 'python-shell-internal-last-output "24.3") | 2037 | 'python-preoutput-result 'python-shell-internal-last-output "24.3") |
| 2038 | 2038 | ||
| 2039 | (defun python-shell-send-string (string &optional process msg) | 2039 | (defun python-shell--save-temp-file (string) |
| 2040 | (let* ((temporary-file-directory | ||
| 2041 | (if (file-remote-p default-directory) | ||
| 2042 | (concat (file-remote-p default-directory) "/tmp") | ||
| 2043 | temporary-file-directory)) | ||
| 2044 | (temp-file-name (make-temp-file "py")) | ||
| 2045 | (coding-system-for-write 'utf-8)) | ||
| 2046 | (with-temp-file temp-file-name | ||
| 2047 | (insert "# -*- coding: utf-8 -*-\n") ;Not needed for Python-3. | ||
| 2048 | (insert string) | ||
| 2049 | (delete-trailing-whitespace)) | ||
| 2050 | temp-file-name)) | ||
| 2051 | |||
| 2052 | (defun python-shell-send-string (string &optional process) | ||
| 2040 | "Send STRING to inferior Python PROCESS. | 2053 | "Send STRING to inferior Python PROCESS. |
| 2041 | When MSG is non-nil messages the first line of STRING. | 2054 | When MSG is non-nil messages the first line of STRING." |
| 2042 | If a temp file is used, return its name, otherwise return nil." | ||
| 2043 | (interactive "sPython command: ") | 2055 | (interactive "sPython command: ") |
| 2044 | (let ((process (or process (python-shell-get-or-create-process))) | 2056 | (let ((process (or process (python-shell-get-or-create-process)))) |
| 2045 | (_ (string-match "\\`\n*\\(.*\\)\\(\n.\\)?" string)) | 2057 | (if (string-match ".\n+." string) ;Multiline. |
| 2046 | (multiline (match-beginning 2))) | 2058 | (let* ((temp-file-name (python-shell--save-temp-file string))) |
| 2047 | (and msg (message "Sent: %s..." (match-string 1 string))) | 2059 | (python-shell-send-file temp-file-name process temp-file-name)) |
| 2048 | (if multiline | ||
| 2049 | (let* ((temporary-file-directory | ||
| 2050 | (if (file-remote-p default-directory) | ||
| 2051 | (concat (file-remote-p default-directory) "/tmp") | ||
| 2052 | temporary-file-directory)) | ||
| 2053 | (temp-file-name (make-temp-file "py")) | ||
| 2054 | (coding-system-for-write 'utf-8) | ||
| 2055 | (file-name (or (buffer-file-name) temp-file-name))) | ||
| 2056 | (with-temp-file temp-file-name | ||
| 2057 | (insert "# -*- coding: utf-8 -*-\n") | ||
| 2058 | (insert string) | ||
| 2059 | (delete-trailing-whitespace)) | ||
| 2060 | (python-shell-send-file file-name process temp-file-name) | ||
| 2061 | temp-file-name) | ||
| 2062 | (comint-send-string process string) | 2060 | (comint-send-string process string) |
| 2063 | (when (or (not (string-match "\n$" string)) | 2061 | (when (or (not (string-match "\n\\'" string)) |
| 2064 | (string-match "\n[ \t].*\n?$" string)) | 2062 | (string-match "\n[ \t].*\n?\\'" string)) |
| 2065 | (comint-send-string process "\n")) | 2063 | (comint-send-string process "\n"))))) |
| 2066 | nil))) | ||
| 2067 | 2064 | ||
| 2068 | (defvar python-shell-output-filter-in-progress nil) | 2065 | (defvar python-shell-output-filter-in-progress nil) |
| 2069 | (defvar python-shell-output-filter-buffer nil) | 2066 | (defvar python-shell-output-filter-buffer nil) |
| @@ -2101,7 +2098,7 @@ detecting a prompt at the end of the buffer." | |||
| 2101 | (substring python-shell-output-filter-buffer (match-end 0))))) | 2098 | (substring python-shell-output-filter-buffer (match-end 0))))) |
| 2102 | "") | 2099 | "") |
| 2103 | 2100 | ||
| 2104 | (defun python-shell-send-string-no-output (string &optional process msg) | 2101 | (defun python-shell-send-string-no-output (string &optional process) |
| 2105 | "Send STRING to PROCESS and inhibit output. | 2102 | "Send STRING to PROCESS and inhibit output. |
| 2106 | When MSG is non-nil messages the first line of STRING. Return | 2103 | When MSG is non-nil messages the first line of STRING. Return |
| 2107 | the output." | 2104 | the output." |
| @@ -2112,7 +2109,7 @@ the output." | |||
| 2112 | (inhibit-quit t)) | 2109 | (inhibit-quit t)) |
| 2113 | (or | 2110 | (or |
| 2114 | (with-local-quit | 2111 | (with-local-quit |
| 2115 | (python-shell-send-string string process msg) | 2112 | (python-shell-send-string string process) |
| 2116 | (while python-shell-output-filter-in-progress | 2113 | (while python-shell-output-filter-in-progress |
| 2117 | ;; `python-shell-output-filter' takes care of setting | 2114 | ;; `python-shell-output-filter' takes care of setting |
| 2118 | ;; `python-shell-output-filter-in-progress' to NIL after it | 2115 | ;; `python-shell-output-filter-in-progress' to NIL after it |
| @@ -2134,7 +2131,7 @@ Returns the output. See `python-shell-send-string-no-output'." | |||
| 2134 | ;; Makes this function compatible with the old | 2131 | ;; Makes this function compatible with the old |
| 2135 | ;; python-send-receive. (At least for CEDET). | 2132 | ;; python-send-receive. (At least for CEDET). |
| 2136 | (replace-regexp-in-string "_emacs_out +" "" string) | 2133 | (replace-regexp-in-string "_emacs_out +" "" string) |
| 2137 | (python-shell-internal-get-or-create-process) nil))) | 2134 | (python-shell-internal-get-or-create-process)))) |
| 2138 | 2135 | ||
| 2139 | (define-obsolete-function-alias | 2136 | (define-obsolete-function-alias |
| 2140 | 'python-send-receive 'python-shell-internal-send-string "24.3") | 2137 | 'python-send-receive 'python-shell-internal-send-string "24.3") |
| @@ -2142,6 +2139,12 @@ Returns the output. See `python-shell-send-string-no-output'." | |||
| 2142 | (define-obsolete-function-alias | 2139 | (define-obsolete-function-alias |
| 2143 | 'python-send-string 'python-shell-internal-send-string "24.3") | 2140 | 'python-send-string 'python-shell-internal-send-string "24.3") |
| 2144 | 2141 | ||
| 2142 | (defvar python--use-fake-loc nil | ||
| 2143 | "If non-nil, use `compilation-fake-loc' to trace errors back to the buffer. | ||
| 2144 | If nil, regions of text are prepended by the corresponding number of empty | ||
| 2145 | lines and Python is told to output error messages referring to the whole | ||
| 2146 | source file.") | ||
| 2147 | |||
| 2145 | (defun python-shell-buffer-substring (start end &optional nomain) | 2148 | (defun python-shell-buffer-substring (start end &optional nomain) |
| 2146 | "Send buffer substring from START to END formatted for shell. | 2149 | "Send buffer substring from START to END formatted for shell. |
| 2147 | This is a wrapper over `buffer-substring' that takes care of | 2150 | This is a wrapper over `buffer-substring' that takes care of |
| @@ -2154,7 +2157,8 @@ the python shell: | |||
| 2154 | 3. Wraps indented regions under an \"if True:\" block so the | 2157 | 3. Wraps indented regions under an \"if True:\" block so the |
| 2155 | interpreter evaluates them correctly." | 2158 | interpreter evaluates them correctly." |
| 2156 | (let ((substring (buffer-substring-no-properties start end)) | 2159 | (let ((substring (buffer-substring-no-properties start end)) |
| 2157 | (fillstr (make-string (1- (line-number-at-pos start)) ?\n)) | 2160 | (fillstr (unless python--use-fake-loc |
| 2161 | (make-string (1- (line-number-at-pos start)) ?\n))) | ||
| 2158 | (toplevel-block-p (save-excursion | 2162 | (toplevel-block-p (save-excursion |
| 2159 | (goto-char start) | 2163 | (goto-char start) |
| 2160 | (or (zerop (line-number-at-pos start)) | 2164 | (or (zerop (line-number-at-pos start)) |
| @@ -2163,9 +2167,14 @@ the python shell: | |||
| 2163 | (zerop (current-indentation))))))) | 2167 | (zerop (current-indentation))))))) |
| 2164 | (with-temp-buffer | 2168 | (with-temp-buffer |
| 2165 | (python-mode) | 2169 | (python-mode) |
| 2166 | (insert fillstr) | 2170 | (if fillstr (insert fillstr)) |
| 2167 | (insert substring) | 2171 | (insert substring) |
| 2168 | (goto-char (point-min)) | 2172 | (goto-char (point-min)) |
| 2173 | (unless python--use-fake-loc | ||
| 2174 | ;; python-shell--save-temp-file adds an extra coding line, which would | ||
| 2175 | ;; throw off the line-counts, so let's try to compensate here. | ||
| 2176 | (if (looking-at "[ \t]*[#\n]") | ||
| 2177 | (delete-region (point) (line-beginning-position 2)))) | ||
| 2169 | (when (not toplevel-block-p) | 2178 | (when (not toplevel-block-p) |
| 2170 | (insert "if True:") | 2179 | (insert "if True:") |
| 2171 | (delete-region (point) (line-end-position))) | 2180 | (delete-region (point) (line-end-position))) |
| @@ -2192,15 +2201,23 @@ the python shell: | |||
| 2192 | (declare-function compilation-fake-loc "compile" | 2201 | (declare-function compilation-fake-loc "compile" |
| 2193 | (marker file &optional line col)) | 2202 | (marker file &optional line col)) |
| 2194 | 2203 | ||
| 2195 | (defun python-shell-send-region (start end) | 2204 | (defun python-shell-send-region (start end &optional nomain) |
| 2196 | "Send the region delimited by START and END to inferior Python process." | 2205 | "Send the region delimited by START and END to inferior Python process." |
| 2197 | (interactive "r") | 2206 | (interactive "r") |
| 2198 | (let ((temp-file-name | 2207 | (let* ((python--use-fake-loc |
| 2199 | (python-shell-send-string | 2208 | (or python--use-fake-loc (not buffer-file-name))) |
| 2200 | (python-shell-buffer-substring start end) nil t))) | 2209 | (string (python-shell-buffer-substring start end nomain)) |
| 2201 | (when temp-file-name | 2210 | (process (python-shell-get-or-create-process)) |
| 2202 | (with-current-buffer (python-shell-get-buffer) | 2211 | (_ (string-match "\\`\n*\\(.*\\)" string))) |
| 2203 | (compilation-fake-loc (copy-marker start) temp-file-name))))) | 2212 | (message "Sent: %s..." (match-string 1 string)) |
| 2213 | (let* ((temp-file-name (python-shell--save-temp-file string)) | ||
| 2214 | (file-name (or (buffer-file-name) temp-file-name))) | ||
| 2215 | (python-shell-send-file file-name process temp-file-name) | ||
| 2216 | (unless python--use-fake-loc | ||
| 2217 | (with-current-buffer (process-buffer process) | ||
| 2218 | (compilation-fake-loc (copy-marker start) temp-file-name | ||
| 2219 | 2)) ;; Not 1, because of the added coding line. | ||
| 2220 | )))) | ||
| 2204 | 2221 | ||
| 2205 | (defun python-shell-send-buffer (&optional arg) | 2222 | (defun python-shell-send-buffer (&optional arg) |
| 2206 | "Send the entire buffer to inferior Python process. | 2223 | "Send the entire buffer to inferior Python process. |
| @@ -2209,9 +2226,7 @@ by \"if __name__== '__main__':\"" | |||
| 2209 | (interactive "P") | 2226 | (interactive "P") |
| 2210 | (save-restriction | 2227 | (save-restriction |
| 2211 | (widen) | 2228 | (widen) |
| 2212 | (python-shell-send-string | 2229 | (python-shell-send-region (point-min) (point-max) (not arg)))) |
| 2213 | (python-shell-buffer-substring | ||
| 2214 | (point-min) (point-max) (not arg))))) | ||
| 2215 | 2230 | ||
| 2216 | (defun python-shell-send-defun (arg) | 2231 | (defun python-shell-send-defun (arg) |
| 2217 | "Send the current defun to inferior Python process. | 2232 | "Send the current defun to inferior Python process. |
| @@ -3561,6 +3576,15 @@ list is returned as is." | |||
| 3561 | (reverse acc)))) | 3576 | (reverse acc)))) |
| 3562 | 3577 | ||
| 3563 | 3578 | ||
| 3579 | (defun python-electric-pair-string-delimiter () | ||
| 3580 | (when (and electric-pair-mode | ||
| 3581 | (memq last-command-event '(?\" ?\')) | ||
| 3582 | (let ((count 0)) | ||
| 3583 | (while (eq (char-before (- (point) count)) last-command-event) | ||
| 3584 | (cl-incf count)) | ||
| 3585 | (= count 3))) | ||
| 3586 | (save-excursion (insert (make-string 3 last-command-event))))) | ||
| 3587 | |||
| 3564 | (defvar electric-indent-inhibit) | 3588 | (defvar electric-indent-inhibit) |
| 3565 | 3589 | ||
| 3566 | ;;;###autoload | 3590 | ;;;###autoload |
| @@ -3593,7 +3617,11 @@ if that value is non-nil." | |||
| 3593 | (set (make-local-variable 'indent-region-function) #'python-indent-region) | 3617 | (set (make-local-variable 'indent-region-function) #'python-indent-region) |
| 3594 | ;; Because indentation is not redundant, we cannot safely reindent code. | 3618 | ;; Because indentation is not redundant, we cannot safely reindent code. |
| 3595 | (setq-local electric-indent-inhibit t) | 3619 | (setq-local electric-indent-inhibit t) |
| 3596 | 3620 | ||
| 3621 | ;; Add """ ... """ pairing to electric-pair-mode. | ||
| 3622 | (add-hook 'post-self-insert-hook | ||
| 3623 | #'python-electric-pair-string-delimiter 'append t) | ||
| 3624 | |||
| 3597 | (set (make-local-variable 'paragraph-start) "\\s-*$") | 3625 | (set (make-local-variable 'paragraph-start) "\\s-*$") |
| 3598 | (set (make-local-variable 'fill-paragraph-function) | 3626 | (set (make-local-variable 'fill-paragraph-function) |
| 3599 | 'python-fill-paragraph) | 3627 | 'python-fill-paragraph) |