Function: python-shell-completion-at-point
python-shell-completion-at-point is a byte-compiled function defined
in python.el.gz.
Signature
(python-shell-completion-at-point &optional PROCESS)
Documentation
Function for completion-at-point-functions in inferior-python-mode.
Optional argument PROCESS forces completions to be retrieved using that one instead of current buffer's process.
Aliases
python-shell-completion-complete-at-point (obsolete since 25.1)
Source Code
;; Defined in /usr/src/emacs/lisp/progmodes/python.el.gz
(defun python-shell-completion-at-point (&optional process)
"Function for `completion-at-point-functions' in `inferior-python-mode'.
Optional argument PROCESS forces completions to be retrieved
using that one instead of current buffer's process."
(setq process (or process (get-buffer-process (current-buffer))))
(unless process
(user-error "No active python inferior process"))
(let* ((is-shell-buffer (derived-mode-p 'inferior-python-mode))
(line-start (if is-shell-buffer
;; Working on a shell buffer: use prompt end.
(cdr (python-util-comint-last-prompt))
(line-beginning-position)))
(no-delims
(and (not (if is-shell-buffer
(eq 'font-lock-comment-face
(get-text-property (1- (point)) 'face))
(python-syntax-context 'comment)))
(with-current-buffer (process-buffer process)
(if python-shell-completion-native-enable
(string= python-shell-readline-completer-delims "")
(or (string-match-p "ipython[23]?\\'" python-shell-interpreter)
(equal python-shell-readline-completer-delims ""))))))
(start
(if (< (point) line-start)
(point)
(save-excursion
(if (or no-delims
(not (re-search-backward
(python-rx
(or whitespace open-paren close-paren
string-delimiter simple-operator))
line-start
t 1)))
line-start
(forward-char (length (match-string-no-properties 0)))
(point)))))
(end (point))
(prompt-boundaries
(with-current-buffer (process-buffer process)
(python-util-comint-last-prompt)))
(prompt
(with-current-buffer (process-buffer process)
(when prompt-boundaries
(buffer-substring-no-properties
(car prompt-boundaries) (cdr prompt-boundaries)))))
(completion-fn
(with-current-buffer (process-buffer process)
(cond ((or (null prompt)
(and is-shell-buffer
(< (point) (cdr prompt-boundaries)))
(and (not is-shell-buffer)
(string-match-p
python-shell-prompt-pdb-regexp prompt)))
#'ignore)
((or (not python-shell-completion-native-enable)
;; Even if native completion is enabled, for
;; pdb interaction always use the fallback
;; mechanism since the completer is changed.
;; Also, since pdb interaction is single-line
;; based, this is enough.
(string-match-p python-shell-prompt-pdb-regexp prompt))
(if (or (equal python-shell--block-prompt prompt)
(string-match-p
python-shell-prompt-block-regexp prompt))
;; The non-native completion mechanism sends
;; newlines to the interpreter, so we can't use
;; it during a multiline statement (Bug#28051).
#'ignore
#'python-shell-completion-get-completions))
(t #'python-shell-completion-native-get-completions))))
(prev-prompt (car python-shell--capf-cache))
(re (or (cadr python-shell--capf-cache) regexp-unmatchable))
(prefix (buffer-substring-no-properties start end))
(prefix-offset 0)
(extra-context (when no-delims
(if is-shell-buffer
(python-shell--extra-completion-context)
(python-shell-completion-extra-context))))
(extra-offset (length extra-context)))
(unless (zerop extra-offset)
(setq prefix (concat extra-context prefix)))
;; To invalidate the cache, we check if the prompt position or the
;; completion prefix changed.
(unless (and (equal prev-prompt (car prompt-boundaries))
(string-match re prefix)
(setq prefix-offset (- (length prefix) (match-end 1))))
(setq python-shell--capf-cache
`(,(car prompt-boundaries)
,(if (string-empty-p prefix)
regexp-unmatchable
(concat "\\`\\(" (regexp-quote prefix) "\\)\\(?:\\sw\\|\\s_\\)*\\'"))
,@(funcall completion-fn process prefix))))
(let ((cands (cddr python-shell--capf-cache)))
(cond
((stringp (car cands))
(if no-delims
;; Reduce completion candidates due to long prefix.
(if-let* ((Lp (length prefix))
((string-match "\\(\\sw\\|\\s_\\)+\\'" prefix))
(L (match-beginning 0)))
;; If extra-offset is not zero:
;; start end
;; o------------------o---------o-------o
;; |<- extra-offset ->|
;; |<----------- L ------------>|
;; new-start
(list (+ start L (- extra-offset)) end
(mapcar (lambda (s) (substring s L)) cands))
(list end end (mapcar (lambda (s) (substring s Lp)) cands)))
(list start end cands)))
;; python-shell-completion(-native)-get-completions may produce a
;; list of (text start end type signature) for completion.
((consp (car cands))
(list (+ start (nth 1 (car cands)) (- extra-offset))
;; Candidates may be cached, so the end position should
;; be adjusted according to current completion prefix.
(+ start (nth 2 (car cands)) (- extra-offset) prefix-offset)
cands
:annotation-function
(lambda (c) (concat " " (nth 3 (assoc c cands))))
:company-docsig
(lambda (c) (nth 4 (assoc c cands)))))))))