diff options
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 392 |
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'. |
| 984 | May return an integer for the maximum possible indentation at | 983 | May return an integer for the maximum possible indentation at |
| 985 | current context or a list of integers. The latter case is only | 984 | current context or a list of integers. The latter case is only |
| 986 | happening for :at-dedenter-block-start context since the | 985 | happening for :at-dedenter-block-start context since the |
| 987 | possibilities can be narrowed to especific indentation points." | 986 | possibilities 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'. |
| 1075 | Use the PREVIOUS level when argument is non-nil, otherwise indent | 1076 | Use the PREVIOUS level when argument is non-nil, otherwise indent |
| 1076 | to the maxium available level. When indentation is the minimum | 1077 | to the maximum available level. When indentation is the minimum |
| 1077 | possible and PREVIOUS is non-nil, cycle back to the maximum | 1078 | possible and PREVIOUS is non-nil, cycle back to the maximum |
| 1078 | level." | 1079 | level." |
| 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. |
| 3149 | When IMPORT is non-nil takes precedence over INPUT for | 3158 | When IMPORT is non-nil takes precedence over INPUT for |
| 3150 | completion." | 3159 | completion." |
| 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." | |||
| 3251 | Optional argument PROCESS forces completions to be retrieved | 3261 | Optional argument PROCESS forces completions to be retrieved |
| 3252 | using that one instead of current buffer's process." | 3262 | using 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. | ||
| 3937 | Returns 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. |
| 3922 | If not FORCE-INPUT is passed then what `python-info-current-symbol' | 3951 | If not FORCE-INPUT is passed then what `python-eldoc--get-symbol-at-point' |
| 3923 | returns will be used. If not FORCE-PROCESS is passed what | 3952 | returns 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'. |
| 3946 | Interactively, prompt for symbol." | 3975 | Interactively, 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'. | ||
| 3990 | Argument 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. | ||
| 4579 | Arguments 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)) |