aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/python.el
diff options
context:
space:
mode:
authorRichard Stallman2015-04-05 08:36:56 -0400
committerRichard Stallman2015-04-05 08:42:43 -0400
commit4e23cd0ccde4ad1e14fe2870ccf140487af649b2 (patch)
treeb709ac1e92a892f6ec1faa85eb59a9e5960c25dd /lisp/progmodes/python.el
parentdca743f0941909a80e3f28c023977120b6203e20 (diff)
parent16eec6fc55dcc05d1d819f18998e84a9580b2521 (diff)
downloademacs-4e23cd0ccde4ad1e14fe2870ccf140487af649b2.tar.gz
emacs-4e23cd0ccde4ad1e14fe2870ccf140487af649b2.zip
* mail/rmail.el (rmail-show-message-1): When displaying a mime message,
indicate start and finish in the echo area. * mail/rmail.el (rmail-epa-decrypt): Disregard <pre> before armor. Ignore more kinds of whitespace in mime headers. Modify the decrypted mime part's mime type so it will be displayed by default when visiting this message again. * net/browse-url.el (browse-url-firefox-program): Prefer IceCat, doc. (browse-url-firefox-arguments) (browse-url-firefox-startup-arguments): Doc fix.
Diffstat (limited to 'lisp/progmodes/python.el')
-rw-r--r--lisp/progmodes/python.el392
1 files changed, 212 insertions, 180 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index d340550a017..67b44aa1bbe 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -4,7 +4,7 @@
4 4
5;; Author: Fabián E. Gallina <fabian@anue.biz> 5;; Author: Fabián E. Gallina <fabian@anue.biz>
6;; URL: https://github.com/fgallina/python.el 6;; URL: https://github.com/fgallina/python.el
7;; Version: 0.24.4 7;; Version: 0.24.5
8;; Maintainer: emacs-devel@gnu.org 8;; Maintainer: emacs-devel@gnu.org
9;; Created: Jul 2010 9;; Created: Jul 2010
10;; Keywords: languages 10;; Keywords: languages
@@ -696,6 +696,12 @@ It makes underscores and dots word constituent chars.")
696 :group 'python 696 :group 'python
697 :safe 'booleanp) 697 :safe 'booleanp)
698 698
699(defcustom python-indent-guess-indent-offset-verbose t
700 "Non-nil means to emit a warning when indentation guessing fails."
701 :type 'boolean
702 :group 'python
703 :safe' booleanp)
704
699(defcustom python-indent-trigger-commands 705(defcustom python-indent-trigger-commands
700 '(indent-for-tab-command yas-expand yas/expand) 706 '(indent-for-tab-command yas-expand yas/expand)
701 "Commands that might trigger a `python-indent-line' call." 707 "Commands that might trigger a `python-indent-line' call."
@@ -766,8 +772,9 @@ work on `python-indent-calculate-indentation' instead."
766 (current-indentation)))) 772 (current-indentation))))
767 (if (and indentation (not (zerop indentation))) 773 (if (and indentation (not (zerop indentation)))
768 (set (make-local-variable 'python-indent-offset) indentation) 774 (set (make-local-variable 'python-indent-offset) indentation)
769 (message "Can't guess python-indent-offset, using defaults: %s" 775 (when python-indent-guess-indent-offset-verbose
770 python-indent-offset))))))) 776 (message "Can't guess python-indent-offset, using defaults: %s"
777 python-indent-offset))))))))
771 778
772(defun python-indent-context () 779(defun python-indent-context ()
773 "Get information about the current indentation context. 780 "Get information about the current indentation context.
@@ -843,15 +850,6 @@ keyword
843 ;; Beginning of buffer. 850 ;; Beginning of buffer.
844 ((= (line-number-at-pos) 1) 851 ((= (line-number-at-pos) 1)
845 (cons :no-indent 0)) 852 (cons :no-indent 0))
846 ;; Comment continuation (maybe).
847 ((save-excursion
848 (when (and
849 (or
850 (python-info-current-line-comment-p)
851 (python-info-current-line-empty-p))
852 (forward-comment -1)
853 (python-info-current-line-comment-p))
854 (cons :after-comment (point)))))
855 ;; Inside a string. 853 ;; Inside a string.
856 ((let ((start (python-syntax-context 'string ppss))) 854 ((let ((start (python-syntax-context 'string ppss)))
857 (when start 855 (when start
@@ -963,28 +961,29 @@ keyword
963 ((let ((start (python-info-dedenter-statement-p))) 961 ((let ((start (python-info-dedenter-statement-p)))
964 (when start 962 (when start
965 (cons :at-dedenter-block-start start)))) 963 (cons :at-dedenter-block-start start))))
966 ;; After normal line. 964 ;; After normal line, comment or ender (default case).
967 ((let ((start (save-excursion 965 ((save-excursion
968 (back-to-indentation) 966 (back-to-indentation)
969 (skip-chars-backward " \t\n") 967 (skip-chars-backward " \t\n")
970 (python-nav-beginning-of-statement) 968 (python-nav-beginning-of-statement)
971 (point)))) 969 (cons
972 (when start 970 (cond ((python-info-current-line-comment-p)
973 (if (save-excursion 971 :after-comment)
974 (python-util-forward-comment -1) 972 ((save-excursion
975 (python-nav-beginning-of-statement) 973 (goto-char (line-end-position))
976 (looking-at (python-rx block-ender))) 974 (python-util-forward-comment -1)
977 (cons :after-block-end start) 975 (python-nav-beginning-of-statement)
978 (cons :after-line start))))) 976 (looking-at (python-rx block-ender)))
979 ;; Default case: do not indent. 977 :after-block-end)
980 (t (cons :no-indent 0)))))) 978 (t :after-line))
979 (point))))))))
981 980
982(defun python-indent--calculate-indentation () 981(defun python-indent--calculate-indentation ()
983 "Internal implementation of `python-indent-calculate-indentation'. 982 "Internal implementation of `python-indent-calculate-indentation'.
984May return an integer for the maximum possible indentation at 983May return an integer for the maximum possible indentation at
985current context or a list of integers. The latter case is only 984current context or a list of integers. The latter case is only
986happening for :at-dedenter-block-start context since the 985happening for :at-dedenter-block-start context since the
987possibilities can be narrowed to especific indentation points." 986possibilities can be narrowed to specific indentation points."
988 (save-restriction 987 (save-restriction
989 (widen) 988 (widen)
990 (save-excursion 989 (save-excursion
@@ -1068,12 +1067,14 @@ minimum."
1068 (levels (python-indent--calculate-levels indentation))) 1067 (levels (python-indent--calculate-levels indentation)))
1069 (if previous 1068 (if previous
1070 (python-indent--previous-level levels (current-indentation)) 1069 (python-indent--previous-level levels (current-indentation))
1071 (apply #'max levels)))) 1070 (if levels
1071 (apply #'max levels)
1072 0))))
1072 1073
1073(defun python-indent-line (&optional previous) 1074(defun python-indent-line (&optional previous)
1074 "Internal implementation of `python-indent-line-function'. 1075 "Internal implementation of `python-indent-line-function'.
1075Use the PREVIOUS level when argument is non-nil, otherwise indent 1076Use the PREVIOUS level when argument is non-nil, otherwise indent
1076to the maxium available level. When indentation is the minimum 1077to the maximum available level. When indentation is the minimum
1077possible and PREVIOUS is non-nil, cycle back to the maximum 1078possible and PREVIOUS is non-nil, cycle back to the maximum
1078level." 1079level."
1079 (let ((follow-indentation-p 1080 (let ((follow-indentation-p
@@ -1108,9 +1109,7 @@ indentation levels from right to left."
1108 (interactive "*") 1109 (interactive "*")
1109 (when (and (not (bolp)) 1110 (when (and (not (bolp))
1110 (not (python-syntax-comment-or-string-p)) 1111 (not (python-syntax-comment-or-string-p))
1111 (= (+ (line-beginning-position) 1112 (= (current-indentation) (current-column)))
1112 (current-indentation))
1113 (point)))
1114 (python-indent-line t) 1113 (python-indent-line t)
1115 t)) 1114 t))
1116 1115
@@ -2295,16 +2294,15 @@ Signals an error if no shell buffer is available for current buffer."
2295 (let ((process-name 2294 (let ((process-name
2296 (process-name (get-buffer-process (current-buffer))))) 2295 (process-name (get-buffer-process (current-buffer)))))
2297 (generate-new-buffer 2296 (generate-new-buffer
2298 (format "*%s-font-lock*" process-name)))))) 2297 (format " *%s-font-lock*" process-name))))))
2299 2298
2300(defun python-shell-font-lock-kill-buffer () 2299(defun python-shell-font-lock-kill-buffer ()
2301 "Kill the font-lock buffer safely." 2300 "Kill the font-lock buffer safely."
2302 (python-shell-with-shell-buffer 2301 (when (and python-shell--font-lock-buffer
2303 (when (and python-shell--font-lock-buffer 2302 (buffer-live-p python-shell--font-lock-buffer))
2304 (buffer-live-p python-shell--font-lock-buffer)) 2303 (kill-buffer python-shell--font-lock-buffer)
2305 (kill-buffer python-shell--font-lock-buffer) 2304 (when (derived-mode-p 'inferior-python-mode)
2306 (when (derived-mode-p 'inferior-python-mode) 2305 (setq python-shell--font-lock-buffer nil))))
2307 (setq python-shell--font-lock-buffer nil)))))
2308 2306
2309(defmacro python-shell-font-lock-with-font-lock-buffer (&rest body) 2307(defmacro python-shell-font-lock-with-font-lock-buffer (&rest body)
2310 "Execute the forms in BODY in the font-lock buffer. 2308 "Execute the forms in BODY in the font-lock buffer.
@@ -2318,6 +2316,8 @@ also `with-current-buffer'."
2318 (setq python-shell--font-lock-buffer 2316 (setq python-shell--font-lock-buffer
2319 (python-shell-font-lock-get-or-create-buffer))) 2317 (python-shell-font-lock-get-or-create-buffer)))
2320 (set-buffer python-shell--font-lock-buffer) 2318 (set-buffer python-shell--font-lock-buffer)
2319 (when (not font-lock-mode)
2320 (font-lock-mode 1))
2321 (set (make-local-variable 'delay-mode-hooks) t) 2321 (set (make-local-variable 'delay-mode-hooks) t)
2322 (let ((python-indent-guess-indent-offset nil)) 2322 (let ((python-indent-guess-indent-offset nil))
2323 (when (not (derived-mode-p 'python-mode)) 2323 (when (not (derived-mode-p 'python-mode))
@@ -2331,57 +2331,66 @@ goes wrong and syntax highlighting in the shell gets messed up."
2331 (interactive) 2331 (interactive)
2332 (python-shell-with-shell-buffer 2332 (python-shell-with-shell-buffer
2333 (python-shell-font-lock-with-font-lock-buffer 2333 (python-shell-font-lock-with-font-lock-buffer
2334 (delete-region (point-min) (point-max))))) 2334 (erase-buffer))))
2335 2335
2336(defun python-shell-font-lock-comint-output-filter-function (output) 2336(defun python-shell-font-lock-comint-output-filter-function (output)
2337 "Clean up the font-lock buffer after any OUTPUT." 2337 "Clean up the font-lock buffer after any OUTPUT."
2338 (when (and (not (string= "" output)) 2338 (if (and (not (string= "" output))
2339 ;; Is end of output and is not just a prompt. 2339 ;; Is end of output and is not just a prompt.
2340 (not (member 2340 (not (member
2341 (python-shell-comint-end-of-output-p 2341 (python-shell-comint-end-of-output-p
2342 (ansi-color-filter-apply output)) 2342 (ansi-color-filter-apply output))
2343 '(nil 0)))) 2343 '(nil 0))))
2344 ;; If output is other than an input prompt then "real" output has 2344 ;; If output is other than an input prompt then "real" output has
2345 ;; been received and the font-lock buffer must be cleaned up. 2345 ;; been received and the font-lock buffer must be cleaned up.
2346 (python-shell-font-lock-cleanup-buffer)) 2346 (python-shell-font-lock-cleanup-buffer)
2347 ;; Otherwise just add a newline.
2348 (python-shell-font-lock-with-font-lock-buffer
2349 (goto-char (point-max))
2350 (newline)))
2347 output) 2351 output)
2348 2352
2349(defun python-shell-font-lock-post-command-hook () 2353(defun python-shell-font-lock-post-command-hook ()
2350 "Fontifies current line in shell buffer." 2354 "Fontifies current line in shell buffer."
2351 (if (eq this-command 'comint-send-input) 2355 (let ((prompt-end (cdr (python-util-comint-last-prompt))))
2352 ;; Add a newline when user sends input as this may be a block. 2356 (when (and prompt-end (> (point) prompt-end)
2353 (python-shell-font-lock-with-font-lock-buffer 2357 (process-live-p (get-buffer-process (current-buffer))))
2354 (goto-char (line-end-position)) 2358 (let* ((input (buffer-substring-no-properties
2355 (newline)) 2359 prompt-end (point-max)))
2356 (when (and (python-util-comint-last-prompt) 2360 (deactivate-mark nil)
2357 (> (point) (cdr (python-util-comint-last-prompt)))) 2361 (start-pos prompt-end)
2358 (let ((input (buffer-substring-no-properties 2362 (buffer-undo-list t)
2359 (cdr (python-util-comint-last-prompt)) (point-max))) 2363 (font-lock-buffer-pos nil)
2360 (old-input (python-shell-font-lock-with-font-lock-buffer 2364 (replacement
2361 (buffer-substring-no-properties 2365 (python-shell-font-lock-with-font-lock-buffer
2362 (line-beginning-position) (point-max)))) 2366 (delete-region (line-beginning-position)
2363 (current-point (point)) 2367 (point-max))
2364 (buffer-undo-list t)) 2368 (setq font-lock-buffer-pos (point))
2365 ;; When input hasn't changed, do nothing. 2369 (insert input)
2366 (when (not (string= input old-input)) 2370 ;; Ensure buffer is fontified, keeping it
2367 (delete-region (cdr (python-util-comint-last-prompt)) (point-max)) 2371 ;; compatible with Emacs < 24.4.
2368 (insert 2372 (if (fboundp 'font-lock-ensure)
2369 (python-shell-font-lock-with-font-lock-buffer 2373 (funcall 'font-lock-ensure)
2370 (delete-region (line-beginning-position) 2374 (font-lock-default-fontify-buffer))
2371 (line-end-position)) 2375 (buffer-substring font-lock-buffer-pos
2372 (insert input) 2376 (point-max))))
2373 ;; Ensure buffer is fontified, keeping it 2377 (replacement-length (length replacement))
2374 ;; compatible with Emacs < 24.4. 2378 (i 0))
2375 (if (fboundp 'font-lock-ensure) 2379 ;; Inject text properties to get input fontified.
2376 (funcall 'font-lock-ensure) 2380 (while (not (= i replacement-length))
2377 (font-lock-default-fontify-buffer)) 2381 (let* ((plist (text-properties-at i replacement))
2378 ;; Replace FACE text properties with FONT-LOCK-FACE so 2382 (next-change (or (next-property-change i replacement)
2379 ;; they are not overwritten by comint buffer's font lock. 2383 replacement-length))
2380 (python-util-text-properties-replace-name 2384 (plist (let ((face (plist-get plist 'face)))
2381 'face 'font-lock-face) 2385 (if (not face)
2382 (buffer-substring (line-beginning-position) 2386 plist
2383 (line-end-position)))) 2387 ;; Replace FACE text properties with
2384 (goto-char current-point)))))) 2388 ;; FONT-LOCK-FACE so input is fontified.
2389 (plist-put plist 'face nil)
2390 (plist-put plist 'font-lock-face face)))))
2391 (set-text-properties
2392 (+ start-pos i) (+ start-pos next-change) plist)
2393 (setq i next-change)))))))
2385 2394
2386(defun python-shell-font-lock-turn-on (&optional msg) 2395(defun python-shell-font-lock-turn-on (&optional msg)
2387 "Turn on shell font-lock. 2396 "Turn on shell font-lock.
@@ -2414,7 +2423,7 @@ With argument MSG show deactivation message."
2414 '(face nil font-lock-face nil))) 2423 '(face nil font-lock-face nil)))
2415 (set (make-local-variable 'python-shell--font-lock-buffer) nil) 2424 (set (make-local-variable 'python-shell--font-lock-buffer) nil)
2416 (remove-hook 'post-command-hook 2425 (remove-hook 'post-command-hook
2417 #'python-shell-font-lock-post-command-hook'local) 2426 #'python-shell-font-lock-post-command-hook 'local)
2418 (remove-hook 'kill-buffer-hook 2427 (remove-hook 'kill-buffer-hook
2419 #'python-shell-font-lock-kill-buffer 'local) 2428 #'python-shell-font-lock-kill-buffer 'local)
2420 (remove-hook 'comint-output-filter-functions 2429 (remove-hook 'comint-output-filter-functions
@@ -3148,67 +3157,68 @@ With argument MSG show activation/deactivation message."
3148 "Get completions using native readline for PROCESS. 3157 "Get completions using native readline for PROCESS.
3149When IMPORT is non-nil takes precedence over INPUT for 3158When IMPORT is non-nil takes precedence over INPUT for
3150completion." 3159completion."
3151 (when (and python-shell-completion-native-enable 3160 (with-current-buffer (process-buffer process)
3152 (python-util-comint-last-prompt) 3161 (when (and python-shell-completion-native-enable
3153 (>= (point) (cdr (python-util-comint-last-prompt)))) 3162 (python-util-comint-last-prompt)
3154 (let* ((input (or import input)) 3163 (>= (point) (cdr (python-util-comint-last-prompt))))
3155 (original-filter-fn (process-filter process)) 3164 (let* ((input (or import input))
3156 (redirect-buffer (get-buffer-create 3165 (original-filter-fn (process-filter process))
3157 python-shell-completion-native-redirect-buffer)) 3166 (redirect-buffer (get-buffer-create
3158 (separators (python-rx 3167 python-shell-completion-native-redirect-buffer))
3159 (or whitespace open-paren close-paren))) 3168 (separators (python-rx
3160 (trigger "\t\t\t") 3169 (or whitespace open-paren close-paren)))
3161 (new-input (concat input trigger)) 3170 (trigger "\t\t\t")
3162 (input-length 3171 (new-input (concat input trigger))
3163 (save-excursion 3172 (input-length
3164 (+ (- (point-max) (comint-bol)) (length new-input)))) 3173 (save-excursion
3165 (delete-line-command (make-string input-length ?\b)) 3174 (+ (- (point-max) (comint-bol)) (length new-input))))
3166 (input-to-send (concat new-input delete-line-command))) 3175 (delete-line-command (make-string input-length ?\b))
3167 ;; Ensure restoring the process filter, even if the user quits 3176 (input-to-send (concat new-input delete-line-command)))
3168 ;; or there's some other error. 3177 ;; Ensure restoring the process filter, even if the user quits
3169 (unwind-protect 3178 ;; or there's some other error.
3170 (with-current-buffer redirect-buffer 3179 (unwind-protect
3171 ;; Cleanup the redirect buffer 3180 (with-current-buffer redirect-buffer
3172 (delete-region (point-min) (point-max)) 3181 ;; Cleanup the redirect buffer
3173 ;; Mimic `comint-redirect-send-command', unfortunately it 3182 (delete-region (point-min) (point-max))
3174 ;; can't be used here because it expects a newline in the 3183 ;; Mimic `comint-redirect-send-command', unfortunately it
3175 ;; command and that's exactly what we are trying to avoid. 3184 ;; can't be used here because it expects a newline in the
3176 (let ((comint-redirect-echo-input nil) 3185 ;; command and that's exactly what we are trying to avoid.
3177 (comint-redirect-verbose nil) 3186 (let ((comint-redirect-echo-input nil)
3178 (comint-redirect-perform-sanity-check nil) 3187 (comint-redirect-verbose nil)
3179 (comint-redirect-insert-matching-regexp nil) 3188 (comint-redirect-perform-sanity-check nil)
3180 ;; Feed it some regex that will never match. 3189 (comint-redirect-insert-matching-regexp nil)
3181 (comint-redirect-finished-regexp "^\\'$") 3190 ;; Feed it some regex that will never match.
3182 (comint-redirect-output-buffer redirect-buffer)) 3191 (comint-redirect-finished-regexp "^\\'$")
3183 ;; Compatibility with Emacs 24.x. Comint changed and 3192 (comint-redirect-output-buffer redirect-buffer))
3184 ;; now `comint-redirect-filter' gets 3 args. This 3193 ;; Compatibility with Emacs 24.x. Comint changed and
3185 ;; checks which version of `comint-redirect-filter' is 3194 ;; now `comint-redirect-filter' gets 3 args. This
3186 ;; in use based on its args and uses `apply-partially' 3195 ;; checks which version of `comint-redirect-filter' is
3187 ;; to make it up for the 3 args case. 3196 ;; in use based on its args and uses `apply-partially'
3188 (if (= (length 3197 ;; to make it up for the 3 args case.
3189 (help-function-arglist 'comint-redirect-filter)) 3) 3198 (if (= (length
3190 (set-process-filter 3199 (help-function-arglist 'comint-redirect-filter)) 3)
3191 process (apply-partially 3200 (set-process-filter
3192 #'comint-redirect-filter original-filter-fn)) 3201 process (apply-partially
3193 (set-process-filter process #'comint-redirect-filter)) 3202 #'comint-redirect-filter original-filter-fn))
3194 (process-send-string process input-to-send) 3203 (set-process-filter process #'comint-redirect-filter))
3195 (accept-process-output 3204 (process-send-string process input-to-send)
3196 process 3205 (accept-process-output
3197 python-shell-completion-native-output-timeout) 3206 process
3198 ;; XXX: can't use `python-shell-accept-process-output' 3207 python-shell-completion-native-output-timeout)
3199 ;; here because there are no guarantees on how output 3208 ;; XXX: can't use `python-shell-accept-process-output'
3200 ;; ends. The workaround here is to call 3209 ;; here because there are no guarantees on how output
3201 ;; `accept-process-output' until we don't find anything 3210 ;; ends. The workaround here is to call
3202 ;; else to accept. 3211 ;; `accept-process-output' until we don't find anything
3203 (while (accept-process-output 3212 ;; else to accept.
3204 process 3213 (while (accept-process-output
3205 python-shell-completion-native-output-timeout)) 3214 process
3206 (cl-remove-duplicates 3215 python-shell-completion-native-output-timeout))
3207 (split-string 3216 (cl-remove-duplicates
3208 (buffer-substring-no-properties 3217 (split-string
3209 (point-min) (point-max)) 3218 (buffer-substring-no-properties
3210 separators t)))) 3219 (point-min) (point-max))
3211 (set-process-filter process original-filter-fn))))) 3220 separators t))))
3221 (set-process-filter process original-filter-fn))))))
3212 3222
3213(defun python-shell-completion-get-completions (process import input) 3223(defun python-shell-completion-get-completions (process import input)
3214 "Do completion at point using PROCESS for IMPORT or INPUT. 3224 "Do completion at point using PROCESS for IMPORT or INPUT.
@@ -3251,20 +3261,23 @@ completion."
3251Optional argument PROCESS forces completions to be retrieved 3261Optional argument PROCESS forces completions to be retrieved
3252using that one instead of current buffer's process." 3262using that one instead of current buffer's process."
3253 (setq process (or process (get-buffer-process (current-buffer)))) 3263 (setq process (or process (get-buffer-process (current-buffer))))
3254 (let* ((last-prompt-end (cdr (python-util-comint-last-prompt))) 3264 (let* ((line-start (if (derived-mode-p 'inferior-python-mode)
3265 ;; Working on a shell buffer: use prompt end.
3266 (cdr (python-util-comint-last-prompt))
3267 (line-beginning-position)))
3255 (import-statement 3268 (import-statement
3256 (when (string-match-p 3269 (when (string-match-p
3257 (rx (* space) word-start (or "from" "import") word-end space) 3270 (rx (* space) word-start (or "from" "import") word-end space)
3258 (buffer-substring-no-properties last-prompt-end (point))) 3271 (buffer-substring-no-properties line-start (point)))
3259 (buffer-substring-no-properties last-prompt-end (point)))) 3272 (buffer-substring-no-properties line-start (point))))
3260 (start 3273 (start
3261 (save-excursion 3274 (save-excursion
3262 (if (not (re-search-backward 3275 (if (not (re-search-backward
3263 (python-rx 3276 (python-rx
3264 (or whitespace open-paren close-paren string-delimiter)) 3277 (or whitespace open-paren close-paren string-delimiter))
3265 last-prompt-end 3278 line-start
3266 t 1)) 3279 t 1))
3267 last-prompt-end 3280 line-start
3268 (forward-char (length (match-string-no-properties 0))) 3281 (forward-char (length (match-string-no-properties 0)))
3269 (point)))) 3282 (point))))
3270 (end (point)) 3283 (end (point))
@@ -3847,8 +3860,10 @@ The skeleton will be bound to python-skeleton-NAME."
3847 :type 'string 3860 :type 'string
3848 :group 'python) 3861 :group 'python)
3849 3862
3850(defvar-local python-check-custom-command nil 3863(defvar python-check-custom-command nil
3851 "Internal use.") 3864 "Internal use.")
3865;; XXX: Avoid `defvar-local' for compat with Emacs<24.3
3866(make-variable-buffer-local 'python-check-custom-command)
3852 3867
3853(defun python-check (command) 3868(defun python-check (command)
3854 "Check a Python file (default current buffer's file). 3869 "Check a Python file (default current buffer's file).
@@ -3917,15 +3932,29 @@ See `python-check-command' for the default."
3917 :type 'string 3932 :type 'string
3918 :group 'python) 3933 :group 'python)
3919 3934
3935(defun python-eldoc--get-symbol-at-point ()
3936 "Get the current symbol for eldoc.
3937Returns the current symbol handling point within arguments."
3938 (save-excursion
3939 (let ((start (python-syntax-context 'paren)))
3940 (when start
3941 (goto-char start))
3942 (when (or start
3943 (eobp)
3944 (memq (char-syntax (char-after)) '(?\ ?-)))
3945 ;; Try to adjust to closest symbol if not in one.
3946 (python-util-forward-comment -1)))
3947 (python-info-current-symbol t)))
3948
3920(defun python-eldoc--get-doc-at-point (&optional force-input force-process) 3949(defun python-eldoc--get-doc-at-point (&optional force-input force-process)
3921 "Internal implementation to get documentation at point. 3950 "Internal implementation to get documentation at point.
3922If not FORCE-INPUT is passed then what `python-info-current-symbol' 3951If not FORCE-INPUT is passed then what `python-eldoc--get-symbol-at-point'
3923returns will be used. If not FORCE-PROCESS is passed what 3952returns will be used. If not FORCE-PROCESS is passed what
3924`python-shell-get-process' returns is used." 3953`python-shell-get-process' returns is used."
3925 (let ((process (or force-process (python-shell-get-process)))) 3954 (let ((process (or force-process (python-shell-get-process))))
3926 (when process 3955 (when process
3927 (let ((input (or force-input 3956 (let ((input (or force-input
3928 (python-info-current-symbol t)))) 3957 (python-eldoc--get-symbol-at-point))))
3929 (and input 3958 (and input
3930 ;; Prevent resizing the echo area when iPython is 3959 ;; Prevent resizing the echo area when iPython is
3931 ;; enabled. Bug#18794. 3960 ;; enabled. Bug#18794.
@@ -3945,7 +3974,7 @@ inferior Python process is updated properly."
3945 "Get help on SYMBOL using `help'. 3974 "Get help on SYMBOL using `help'.
3946Interactively, prompt for symbol." 3975Interactively, prompt for symbol."
3947 (interactive 3976 (interactive
3948 (let ((symbol (python-info-current-symbol t)) 3977 (let ((symbol (python-eldoc--get-symbol-at-point))
3949 (enable-recursive-minibuffers t)) 3978 (enable-recursive-minibuffers t))
3950 (list (read-string (if symbol 3979 (list (read-string (if symbol
3951 (format "Describe symbol (default %s): " symbol) 3980 (format "Describe symbol (default %s): " symbol)
@@ -3954,6 +3983,17 @@ Interactively, prompt for symbol."
3954 (message (python-eldoc--get-doc-at-point symbol))) 3983 (message (python-eldoc--get-doc-at-point symbol)))
3955 3984
3956 3985
3986;;; Hideshow
3987
3988(defun python-hideshow-forward-sexp-function (arg)
3989 "Python specific `forward-sexp' function for `hs-minor-mode'.
3990Argument ARG is ignored."
3991 arg ; Shut up, byte compiler.
3992 (python-nav-end-of-defun)
3993 (unless (python-info-current-line-empty-p)
3994 (backward-char)))
3995
3996
3957;;; Imenu 3997;;; Imenu
3958 3998
3959(defvar python-imenu-format-item-label-function 3999(defvar python-imenu-format-item-label-function
@@ -4573,23 +4613,6 @@ returned as is."
4573 n (1- n))) 4613 n (1- n)))
4574 (reverse acc)))) 4614 (reverse acc))))
4575 4615
4576(defun python-util-text-properties-replace-name
4577 (from to &optional start end)
4578 "Replace properties named FROM to TO, keeping its value.
4579Arguments START and END narrow the buffer region to work on."
4580 (save-excursion
4581 (goto-char (or start (point-min)))
4582 (while (not (eobp))
4583 (let ((plist (text-properties-at (point)))
4584 (next-change (or (next-property-change (point) (current-buffer))
4585 (or end (point-max)))))
4586 (when (plist-get plist from)
4587 (let* ((face (plist-get plist from))
4588 (plist (plist-put plist from nil))
4589 (plist (plist-put plist to face)))
4590 (set-text-properties (point) next-change plist (current-buffer))))
4591 (goto-char next-change)))))
4592
4593(defun python-util-strip-string (string) 4616(defun python-util-strip-string (string)
4594 "Strip STRING whitespace and newlines from end and beginning." 4617 "Strip STRING whitespace and newlines from end and beginning."
4595 (replace-regexp-in-string 4618 (replace-regexp-in-string
@@ -4682,14 +4705,23 @@ Arguments START and END narrow the buffer region to work on."
4682 (current-column)))) 4705 (current-column))))
4683 (^ '(- (1+ (current-indentation)))))) 4706 (^ '(- (1+ (current-indentation))))))
4684 4707
4685 (add-function :before-until (local 'eldoc-documentation-function) 4708 (if (null eldoc-documentation-function)
4686 #'python-eldoc-function) 4709 ;; Emacs<25
4687 4710 (set (make-local-variable 'eldoc-documentation-function)
4688 (add-to-list 'hs-special-modes-alist 4711 #'python-eldoc-function)
4689 `(python-mode "^\\s-*\\(?:def\\|class\\)\\>" nil "#" 4712 (add-function :before-until (local 'eldoc-documentation-function)
4690 ,(lambda (_arg) 4713 #'python-eldoc-function))
4691 (python-nav-end-of-defun)) 4714
4692 nil)) 4715 (add-to-list
4716 'hs-special-modes-alist
4717 `(python-mode
4718 "\\s-*\\(?:def\\|class\\)\\>"
4719 ;; Use the empty string as end regexp so it doesn't default to
4720 ;; "\\s)". This way parens at end of defun are properly hidden.
4721 ""
4722 "#"
4723 python-hideshow-forward-sexp-function
4724 nil))
4693 4725
4694 (set (make-local-variable 'outline-regexp) 4726 (set (make-local-variable 'outline-regexp)
4695 (python-rx (* space) block-start)) 4727 (python-rx (* space) block-start))