diff options
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 115 |
1 files changed, 79 insertions, 36 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index ce727391ce8..7a90f0bb5ee 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -1968,8 +1968,8 @@ startup." | |||
| 1968 | (python-shell-parse-command) | 1968 | (python-shell-parse-command) |
| 1969 | (python-shell-internal-get-process-name) nil t)))) | 1969 | (python-shell-internal-get-process-name) nil t)))) |
| 1970 | 1970 | ||
| 1971 | (defun python-shell-get-process () | 1971 | (defun python-shell-get-buffer () |
| 1972 | "Get inferior Python process for current buffer and return it." | 1972 | "Get inferior Python buffer for current buffer and return it." |
| 1973 | (let* ((dedicated-proc-name (python-shell-get-process-name t)) | 1973 | (let* ((dedicated-proc-name (python-shell-get-process-name t)) |
| 1974 | (dedicated-proc-buffer-name (format "*%s*" dedicated-proc-name)) | 1974 | (dedicated-proc-buffer-name (format "*%s*" dedicated-proc-name)) |
| 1975 | (global-proc-name (python-shell-get-process-name nil)) | 1975 | (global-proc-name (python-shell-get-process-name nil)) |
| @@ -1977,8 +1977,12 @@ startup." | |||
| 1977 | (dedicated-running (comint-check-proc dedicated-proc-buffer-name)) | 1977 | (dedicated-running (comint-check-proc dedicated-proc-buffer-name)) |
| 1978 | (global-running (comint-check-proc global-proc-buffer-name))) | 1978 | (global-running (comint-check-proc global-proc-buffer-name))) |
| 1979 | ;; Always prefer dedicated | 1979 | ;; Always prefer dedicated |
| 1980 | (get-buffer-process (or (and dedicated-running dedicated-proc-buffer-name) | 1980 | (or (and dedicated-running dedicated-proc-buffer-name) |
| 1981 | (and global-running global-proc-buffer-name))))) | 1981 | (and global-running global-proc-buffer-name)))) |
| 1982 | |||
| 1983 | (defun python-shell-get-process () | ||
| 1984 | "Get inferior Python process for current buffer and return it." | ||
| 1985 | (get-buffer-process (python-shell-get-buffer))) | ||
| 1982 | 1986 | ||
| 1983 | (defun python-shell-get-or-create-process () | 1987 | (defun python-shell-get-or-create-process () |
| 1984 | "Get or create an inferior Python process for current buffer and return it." | 1988 | "Get or create an inferior Python process for current buffer and return it." |
| @@ -2032,27 +2036,30 @@ there for compatibility with CEDET.") | |||
| 2032 | (define-obsolete-variable-alias | 2036 | (define-obsolete-variable-alias |
| 2033 | 'python-preoutput-result 'python-shell-internal-last-output "24.3") | 2037 | 'python-preoutput-result 'python-shell-internal-last-output "24.3") |
| 2034 | 2038 | ||
| 2035 | (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) | ||
| 2036 | "Send STRING to inferior Python PROCESS. | 2053 | "Send STRING to inferior Python PROCESS. |
| 2037 | When MSG is non-nil messages the first line of STRING." | 2054 | When MSG is non-nil messages the first line of STRING." |
| 2038 | (interactive "sPython command: ") | 2055 | (interactive "sPython command: ") |
| 2039 | (let ((process (or process (python-shell-get-or-create-process))) | 2056 | (let ((process (or process (python-shell-get-or-create-process)))) |
| 2040 | (lines (split-string string "\n" t))) | 2057 | (if (string-match ".\n+." string) ;Multiline. |
| 2041 | (and msg (message "Sent: %s..." (nth 0 lines))) | 2058 | (let* ((temp-file-name (python-shell--save-temp-file string))) |
| 2042 | (if (> (length lines) 1) | 2059 | (python-shell-send-file temp-file-name process temp-file-name)) |
| 2043 | (let* ((temporary-file-directory | ||
| 2044 | (if (file-remote-p default-directory) | ||
| 2045 | (concat (file-remote-p default-directory) "/tmp") | ||
| 2046 | temporary-file-directory)) | ||
| 2047 | (temp-file-name (make-temp-file "py")) | ||
| 2048 | (file-name (or (buffer-file-name) temp-file-name))) | ||
| 2049 | (with-temp-file temp-file-name | ||
| 2050 | (insert string) | ||
| 2051 | (delete-trailing-whitespace)) | ||
| 2052 | (python-shell-send-file file-name process temp-file-name)) | ||
| 2053 | (comint-send-string process string) | 2060 | (comint-send-string process string) |
| 2054 | (when (or (not (string-match "\n$" string)) | 2061 | (when (or (not (string-match "\n\\'" string)) |
| 2055 | (string-match "\n[ \t].*\n?$" string)) | 2062 | (string-match "\n[ \t].*\n?\\'" string)) |
| 2056 | (comint-send-string process "\n"))))) | 2063 | (comint-send-string process "\n"))))) |
| 2057 | 2064 | ||
| 2058 | (defvar python-shell-output-filter-in-progress nil) | 2065 | (defvar python-shell-output-filter-in-progress nil) |
| @@ -2091,7 +2098,7 @@ detecting a prompt at the end of the buffer." | |||
| 2091 | (substring python-shell-output-filter-buffer (match-end 0))))) | 2098 | (substring python-shell-output-filter-buffer (match-end 0))))) |
| 2092 | "") | 2099 | "") |
| 2093 | 2100 | ||
| 2094 | (defun python-shell-send-string-no-output (string &optional process msg) | 2101 | (defun python-shell-send-string-no-output (string &optional process) |
| 2095 | "Send STRING to PROCESS and inhibit output. | 2102 | "Send STRING to PROCESS and inhibit output. |
| 2096 | 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 |
| 2097 | the output." | 2104 | the output." |
| @@ -2102,7 +2109,7 @@ the output." | |||
| 2102 | (inhibit-quit t)) | 2109 | (inhibit-quit t)) |
| 2103 | (or | 2110 | (or |
| 2104 | (with-local-quit | 2111 | (with-local-quit |
| 2105 | (python-shell-send-string string process msg) | 2112 | (python-shell-send-string string process) |
| 2106 | (while python-shell-output-filter-in-progress | 2113 | (while python-shell-output-filter-in-progress |
| 2107 | ;; `python-shell-output-filter' takes care of setting | 2114 | ;; `python-shell-output-filter' takes care of setting |
| 2108 | ;; `python-shell-output-filter-in-progress' to NIL after it | 2115 | ;; `python-shell-output-filter-in-progress' to NIL after it |
| @@ -2124,7 +2131,7 @@ Returns the output. See `python-shell-send-string-no-output'." | |||
| 2124 | ;; Makes this function compatible with the old | 2131 | ;; Makes this function compatible with the old |
| 2125 | ;; python-send-receive. (At least for CEDET). | 2132 | ;; python-send-receive. (At least for CEDET). |
| 2126 | (replace-regexp-in-string "_emacs_out +" "" string) | 2133 | (replace-regexp-in-string "_emacs_out +" "" string) |
| 2127 | (python-shell-internal-get-or-create-process) nil))) | 2134 | (python-shell-internal-get-or-create-process)))) |
| 2128 | 2135 | ||
| 2129 | (define-obsolete-function-alias | 2136 | (define-obsolete-function-alias |
| 2130 | 'python-send-receive 'python-shell-internal-send-string "24.3") | 2137 | 'python-send-receive 'python-shell-internal-send-string "24.3") |
| @@ -2132,6 +2139,12 @@ Returns the output. See `python-shell-send-string-no-output'." | |||
| 2132 | (define-obsolete-function-alias | 2139 | (define-obsolete-function-alias |
| 2133 | 'python-send-string 'python-shell-internal-send-string "24.3") | 2140 | 'python-send-string 'python-shell-internal-send-string "24.3") |
| 2134 | 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 | |||
| 2135 | (defun python-shell-buffer-substring (start end &optional nomain) | 2148 | (defun python-shell-buffer-substring (start end &optional nomain) |
| 2136 | "Send buffer substring from START to END formatted for shell. | 2149 | "Send buffer substring from START to END formatted for shell. |
| 2137 | This is a wrapper over `buffer-substring' that takes care of | 2150 | This is a wrapper over `buffer-substring' that takes care of |
| @@ -2144,7 +2157,8 @@ the python shell: | |||
| 2144 | 3. Wraps indented regions under an \"if True:\" block so the | 2157 | 3. Wraps indented regions under an \"if True:\" block so the |
| 2145 | interpreter evaluates them correctly." | 2158 | interpreter evaluates them correctly." |
| 2146 | (let ((substring (buffer-substring-no-properties start end)) | 2159 | (let ((substring (buffer-substring-no-properties start end)) |
| 2147 | (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))) | ||
| 2148 | (toplevel-block-p (save-excursion | 2162 | (toplevel-block-p (save-excursion |
| 2149 | (goto-char start) | 2163 | (goto-char start) |
| 2150 | (or (zerop (line-number-at-pos start)) | 2164 | (or (zerop (line-number-at-pos start)) |
| @@ -2153,9 +2167,14 @@ the python shell: | |||
| 2153 | (zerop (current-indentation))))))) | 2167 | (zerop (current-indentation))))))) |
| 2154 | (with-temp-buffer | 2168 | (with-temp-buffer |
| 2155 | (python-mode) | 2169 | (python-mode) |
| 2156 | (insert fillstr) | 2170 | (if fillstr (insert fillstr)) |
| 2157 | (insert substring) | 2171 | (insert substring) |
| 2158 | (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)))) | ||
| 2159 | (when (not toplevel-block-p) | 2178 | (when (not toplevel-block-p) |
| 2160 | (insert "if True:") | 2179 | (insert "if True:") |
| 2161 | (delete-region (point) (line-end-position))) | 2180 | (delete-region (point) (line-end-position))) |
| @@ -2179,11 +2198,26 @@ the python shell: | |||
| 2179 | (line-number-at-pos if-name-main-start)) ?\n))))) | 2198 | (line-number-at-pos if-name-main-start)) ?\n))))) |
| 2180 | (buffer-substring-no-properties (point-min) (point-max))))) | 2199 | (buffer-substring-no-properties (point-min) (point-max))))) |
| 2181 | 2200 | ||
| 2182 | (defun python-shell-send-region (start end) | 2201 | (declare-function compilation-fake-loc "compile" |
| 2202 | (marker file &optional line col)) | ||
| 2203 | |||
| 2204 | (defun python-shell-send-region (start end &optional nomain) | ||
| 2183 | "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." |
| 2184 | (interactive "r") | 2206 | (interactive "r") |
| 2185 | (python-shell-send-string | 2207 | (let* ((python--use-fake-loc |
| 2186 | (python-shell-buffer-substring start end) nil t)) | 2208 | (or python--use-fake-loc (not buffer-file-name))) |
| 2209 | (string (python-shell-buffer-substring start end nomain)) | ||
| 2210 | (process (python-shell-get-or-create-process)) | ||
| 2211 | (_ (string-match "\\`\n*\\(.*\\)" string))) | ||
| 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 | )))) | ||
| 2187 | 2221 | ||
| 2188 | (defun python-shell-send-buffer (&optional arg) | 2222 | (defun python-shell-send-buffer (&optional arg) |
| 2189 | "Send the entire buffer to inferior Python process. | 2223 | "Send the entire buffer to inferior Python process. |
| @@ -2192,9 +2226,7 @@ by \"if __name__== '__main__':\"" | |||
| 2192 | (interactive "P") | 2226 | (interactive "P") |
| 2193 | (save-restriction | 2227 | (save-restriction |
| 2194 | (widen) | 2228 | (widen) |
| 2195 | (python-shell-send-string | 2229 | (python-shell-send-region (point-min) (point-max) (not arg)))) |
| 2196 | (python-shell-buffer-substring | ||
| 2197 | (point-min) (point-max) (not arg))))) | ||
| 2198 | 2230 | ||
| 2199 | (defun python-shell-send-defun (arg) | 2231 | (defun python-shell-send-defun (arg) |
| 2200 | "Send the current defun to inferior Python process. | 2232 | "Send the current defun to inferior Python process. |
| @@ -3544,15 +3576,22 @@ list is returned as is." | |||
| 3544 | (reverse acc)))) | 3576 | (reverse acc)))) |
| 3545 | 3577 | ||
| 3546 | 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 | |||
| 3547 | (defvar electric-indent-inhibit) | 3588 | (defvar electric-indent-inhibit) |
| 3548 | 3589 | ||
| 3549 | ;;;###autoload | 3590 | ;;;###autoload |
| 3550 | (define-derived-mode python-mode prog-mode "Python" | 3591 | (define-derived-mode python-mode prog-mode "Python" |
| 3551 | "Major mode for editing Python files. | 3592 | "Major mode for editing Python files. |
| 3552 | 3593 | ||
| 3553 | \\{python-mode-map} | 3594 | \\{python-mode-map}" |
| 3554 | Entry to this mode calls the value of `python-mode-hook' | ||
| 3555 | if that value is non-nil." | ||
| 3556 | (set (make-local-variable 'tab-width) 8) | 3595 | (set (make-local-variable 'tab-width) 8) |
| 3557 | (set (make-local-variable 'indent-tabs-mode) nil) | 3596 | (set (make-local-variable 'indent-tabs-mode) nil) |
| 3558 | 3597 | ||
| @@ -3576,7 +3615,11 @@ if that value is non-nil." | |||
| 3576 | (set (make-local-variable 'indent-region-function) #'python-indent-region) | 3615 | (set (make-local-variable 'indent-region-function) #'python-indent-region) |
| 3577 | ;; Because indentation is not redundant, we cannot safely reindent code. | 3616 | ;; Because indentation is not redundant, we cannot safely reindent code. |
| 3578 | (setq-local electric-indent-inhibit t) | 3617 | (setq-local electric-indent-inhibit t) |
| 3579 | 3618 | ||
| 3619 | ;; Add """ ... """ pairing to electric-pair-mode. | ||
| 3620 | (add-hook 'post-self-insert-hook | ||
| 3621 | #'python-electric-pair-string-delimiter 'append t) | ||
| 3622 | |||
| 3580 | (set (make-local-variable 'paragraph-start) "\\s-*$") | 3623 | (set (make-local-variable 'paragraph-start) "\\s-*$") |
| 3581 | (set (make-local-variable 'fill-paragraph-function) | 3624 | (set (make-local-variable 'fill-paragraph-function) |
| 3582 | 'python-fill-paragraph) | 3625 | 'python-fill-paragraph) |