diff options
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 136 |
1 files changed, 70 insertions, 66 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index c87b1f347a3..303c36c3932 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -3150,67 +3150,68 @@ With argument MSG show activation/deactivation message." | |||
| 3150 | "Get completions using native readline for PROCESS. | 3150 | "Get completions using native readline for PROCESS. |
| 3151 | When IMPORT is non-nil takes precedence over INPUT for | 3151 | When IMPORT is non-nil takes precedence over INPUT for |
| 3152 | completion." | 3152 | completion." |
| 3153 | (when (and python-shell-completion-native-enable | 3153 | (with-current-buffer (process-buffer process) |
| 3154 | (python-util-comint-last-prompt) | 3154 | (when (and python-shell-completion-native-enable |
| 3155 | (>= (point) (cdr (python-util-comint-last-prompt)))) | 3155 | (python-util-comint-last-prompt) |
| 3156 | (let* ((input (or import input)) | 3156 | (>= (point) (cdr (python-util-comint-last-prompt)))) |
| 3157 | (original-filter-fn (process-filter process)) | 3157 | (let* ((input (or import input)) |
| 3158 | (redirect-buffer (get-buffer-create | 3158 | (original-filter-fn (process-filter process)) |
| 3159 | python-shell-completion-native-redirect-buffer)) | 3159 | (redirect-buffer (get-buffer-create |
| 3160 | (separators (python-rx | 3160 | python-shell-completion-native-redirect-buffer)) |
| 3161 | (or whitespace open-paren close-paren))) | 3161 | (separators (python-rx |
| 3162 | (trigger "\t\t\t") | 3162 | (or whitespace open-paren close-paren))) |
| 3163 | (new-input (concat input trigger)) | 3163 | (trigger "\t\t\t") |
| 3164 | (input-length | 3164 | (new-input (concat input trigger)) |
| 3165 | (save-excursion | 3165 | (input-length |
| 3166 | (+ (- (point-max) (comint-bol)) (length new-input)))) | 3166 | (save-excursion |
| 3167 | (delete-line-command (make-string input-length ?\b)) | 3167 | (+ (- (point-max) (comint-bol)) (length new-input)))) |
| 3168 | (input-to-send (concat new-input delete-line-command))) | 3168 | (delete-line-command (make-string input-length ?\b)) |
| 3169 | ;; Ensure restoring the process filter, even if the user quits | 3169 | (input-to-send (concat new-input delete-line-command))) |
| 3170 | ;; or there's some other error. | 3170 | ;; Ensure restoring the process filter, even if the user quits |
| 3171 | (unwind-protect | 3171 | ;; or there's some other error. |
| 3172 | (with-current-buffer redirect-buffer | 3172 | (unwind-protect |
| 3173 | ;; Cleanup the redirect buffer | 3173 | (with-current-buffer redirect-buffer |
| 3174 | (delete-region (point-min) (point-max)) | 3174 | ;; Cleanup the redirect buffer |
| 3175 | ;; Mimic `comint-redirect-send-command', unfortunately it | 3175 | (delete-region (point-min) (point-max)) |
| 3176 | ;; can't be used here because it expects a newline in the | 3176 | ;; Mimic `comint-redirect-send-command', unfortunately it |
| 3177 | ;; command and that's exactly what we are trying to avoid. | 3177 | ;; can't be used here because it expects a newline in the |
| 3178 | (let ((comint-redirect-echo-input nil) | 3178 | ;; command and that's exactly what we are trying to avoid. |
| 3179 | (comint-redirect-verbose nil) | 3179 | (let ((comint-redirect-echo-input nil) |
| 3180 | (comint-redirect-perform-sanity-check nil) | 3180 | (comint-redirect-verbose nil) |
| 3181 | (comint-redirect-insert-matching-regexp nil) | 3181 | (comint-redirect-perform-sanity-check nil) |
| 3182 | ;; Feed it some regex that will never match. | 3182 | (comint-redirect-insert-matching-regexp nil) |
| 3183 | (comint-redirect-finished-regexp "^\\'$") | 3183 | ;; Feed it some regex that will never match. |
| 3184 | (comint-redirect-output-buffer redirect-buffer)) | 3184 | (comint-redirect-finished-regexp "^\\'$") |
| 3185 | ;; Compatibility with Emacs 24.x. Comint changed and | 3185 | (comint-redirect-output-buffer redirect-buffer)) |
| 3186 | ;; now `comint-redirect-filter' gets 3 args. This | 3186 | ;; Compatibility with Emacs 24.x. Comint changed and |
| 3187 | ;; checks which version of `comint-redirect-filter' is | 3187 | ;; now `comint-redirect-filter' gets 3 args. This |
| 3188 | ;; in use based on its args and uses `apply-partially' | 3188 | ;; checks which version of `comint-redirect-filter' is |
| 3189 | ;; to make it up for the 3 args case. | 3189 | ;; in use based on its args and uses `apply-partially' |
| 3190 | (if (= (length | 3190 | ;; to make it up for the 3 args case. |
| 3191 | (help-function-arglist 'comint-redirect-filter)) 3) | 3191 | (if (= (length |
| 3192 | (set-process-filter | 3192 | (help-function-arglist 'comint-redirect-filter)) 3) |
| 3193 | process (apply-partially | 3193 | (set-process-filter |
| 3194 | #'comint-redirect-filter original-filter-fn)) | 3194 | process (apply-partially |
| 3195 | (set-process-filter process #'comint-redirect-filter)) | 3195 | #'comint-redirect-filter original-filter-fn)) |
| 3196 | (process-send-string process input-to-send) | 3196 | (set-process-filter process #'comint-redirect-filter)) |
| 3197 | (accept-process-output | 3197 | (process-send-string process input-to-send) |
| 3198 | process | 3198 | (accept-process-output |
| 3199 | python-shell-completion-native-output-timeout) | 3199 | process |
| 3200 | ;; XXX: can't use `python-shell-accept-process-output' | 3200 | python-shell-completion-native-output-timeout) |
| 3201 | ;; here because there are no guarantees on how output | 3201 | ;; XXX: can't use `python-shell-accept-process-output' |
| 3202 | ;; ends. The workaround here is to call | 3202 | ;; here because there are no guarantees on how output |
| 3203 | ;; `accept-process-output' until we don't find anything | 3203 | ;; ends. The workaround here is to call |
| 3204 | ;; else to accept. | 3204 | ;; `accept-process-output' until we don't find anything |
| 3205 | (while (accept-process-output | 3205 | ;; else to accept. |
| 3206 | process | 3206 | (while (accept-process-output |
| 3207 | python-shell-completion-native-output-timeout)) | 3207 | process |
| 3208 | (cl-remove-duplicates | 3208 | python-shell-completion-native-output-timeout)) |
| 3209 | (split-string | 3209 | (cl-remove-duplicates |
| 3210 | (buffer-substring-no-properties | 3210 | (split-string |
| 3211 | (point-min) (point-max)) | 3211 | (buffer-substring-no-properties |
| 3212 | separators t)))) | 3212 | (point-min) (point-max)) |
| 3213 | (set-process-filter process original-filter-fn))))) | 3213 | separators t)))) |
| 3214 | (set-process-filter process original-filter-fn)))))) | ||
| 3214 | 3215 | ||
| 3215 | (defun python-shell-completion-get-completions (process import input) | 3216 | (defun python-shell-completion-get-completions (process import input) |
| 3216 | "Do completion at point using PROCESS for IMPORT or INPUT. | 3217 | "Do completion at point using PROCESS for IMPORT or INPUT. |
| @@ -3253,20 +3254,23 @@ completion." | |||
| 3253 | Optional argument PROCESS forces completions to be retrieved | 3254 | Optional argument PROCESS forces completions to be retrieved |
| 3254 | using that one instead of current buffer's process." | 3255 | using that one instead of current buffer's process." |
| 3255 | (setq process (or process (get-buffer-process (current-buffer)))) | 3256 | (setq process (or process (get-buffer-process (current-buffer)))) |
| 3256 | (let* ((last-prompt-end (cdr (python-util-comint-last-prompt))) | 3257 | (let* ((line-start (if (derived-mode-p 'inferior-python-mode) |
| 3258 | ;; Working on a shell buffer: use prompt end. | ||
| 3259 | (cdr (python-util-comint-last-prompt)) | ||
| 3260 | (line-beginning-position))) | ||
| 3257 | (import-statement | 3261 | (import-statement |
| 3258 | (when (string-match-p | 3262 | (when (string-match-p |
| 3259 | (rx (* space) word-start (or "from" "import") word-end space) | 3263 | (rx (* space) word-start (or "from" "import") word-end space) |
| 3260 | (buffer-substring-no-properties last-prompt-end (point))) | 3264 | (buffer-substring-no-properties line-start (point))) |
| 3261 | (buffer-substring-no-properties last-prompt-end (point)))) | 3265 | (buffer-substring-no-properties line-start (point)))) |
| 3262 | (start | 3266 | (start |
| 3263 | (save-excursion | 3267 | (save-excursion |
| 3264 | (if (not (re-search-backward | 3268 | (if (not (re-search-backward |
| 3265 | (python-rx | 3269 | (python-rx |
| 3266 | (or whitespace open-paren close-paren string-delimiter)) | 3270 | (or whitespace open-paren close-paren string-delimiter)) |
| 3267 | last-prompt-end | 3271 | line-start |
| 3268 | t 1)) | 3272 | t 1)) |
| 3269 | last-prompt-end | 3273 | line-start |
| 3270 | (forward-char (length (match-string-no-properties 0))) | 3274 | (forward-char (length (match-string-no-properties 0))) |
| 3271 | (point)))) | 3275 | (point)))) |
| 3272 | (end (point)) | 3276 | (end (point)) |