aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/python.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/progmodes/python.el')
-rw-r--r--lisp/progmodes/python.el136
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.
3151When IMPORT is non-nil takes precedence over INPUT for 3151When IMPORT is non-nil takes precedence over INPUT for
3152completion." 3152completion."
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."
3253Optional argument PROCESS forces completions to be retrieved 3254Optional argument PROCESS forces completions to be retrieved
3254using that one instead of current buffer's process." 3255using 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))