(and (eq completion-auto-select t)
(eq t (frame-visible-p (window-frame minibuffer-scroll-window)))
;; When the completion list window was displayed, select it.
- (switch-to-completions))
- (completion-in-region-mode -1))))
+ (switch-to-completions)))))
(defun completion--metadata (string base md-at-point table pred)
;; Like completion-metadata, but for the specific case of getting the
;; completion is not finished.
(completion--done result
(if (eq (car bounds) (length result))
- 'exact 'finished))))))))))))
+ 'exact 'finished))))))))
+ (unless (minibufferp)
+ (set-transient-map completion-in-region-mode-map t #'minibuffer-hide-completions))))))
(defun completions-display (completions &rest plist)
"Display COMPLETIONS in the buffer specified by `standard-output'.
(throw 'exit (lambda () (minibuffer-quit-recursive-edit (1- levels))))
(throw 'exit (lambda () (signal 'minibuffer-quit nil)))))
-(defvar completion-in-region-functions nil
- "Wrapper hook around `completion--in-region'.
-\(See `with-wrapper-hook' for details about wrapper hooks.)")
-(make-obsolete-variable 'completion-in-region-functions
- 'completion-in-region-function "24.4")
-
(defvar completion-in-region-function #'completion--in-region
"Function to perform the job of `completion-in-region'.
The function is called with 4 arguments: START END COLLECTION PREDICATE.
The arguments and expected return value are as specified for
`completion-in-region'.")
-(defvar completion-in-region--data nil)
-
-(defvar completion-in-region-mode-predicate nil
- "Predicate to tell `completion-in-region-mode' when to exit.
-It is called with no argument and should return nil when
-`completion-in-region-mode' should exit (and hence pop down
-the *Completions* buffer).")
-
-(defvar completion-in-region-mode--predicate nil
- "Copy of the value of `completion-in-region-mode-predicate'.
-This holds the value `completion-in-region-mode-predicate' had when
-we entered `completion-in-region-mode'.")
-
(defun completion-in-region (start end collection &optional predicate)
"Complete the text between START and END using COLLECTION.
Point needs to be somewhere between START and END.
(defun completion--in-region (start end collection &optional predicate)
"Default function to use for `completion-in-region-function'.
-Its arguments and return value are as specified for `completion-in-region'.
-Also respects the obsolete wrapper hook `completion-in-region-functions'.
-\(See `with-wrapper-hook' for details about wrapper hooks.)"
- (subr--with-wrapper-hook-no-warnings
- ;; FIXME: Maybe we should use this hook to provide a "display
- ;; completions" operation as well.
- completion-in-region-functions (start end collection predicate)
- (let ((minibuffer-completion-table collection)
- (minibuffer-completion-predicate predicate))
- ;; HACK: if the text we are completing is already in a field, we
- ;; want the completion field to take priority (e.g. Bug#6830).
- (when completion-in-region-mode-predicate
- (setq completion-in-region--data
- `(,(if (markerp start) start (copy-marker start))
- ,(copy-marker end t) ,collection ,predicate))
- (completion-in-region-mode 1))
- (completion--in-region-1 start end))))
+Its arguments and return value are as specified for `completion-in-region'."
+ (let ((minibuffer-completion-table collection)
+ (minibuffer-completion-predicate predicate))
+ (completion--in-region-1 start end)))
(defvar-keymap completion-in-region-mode-map
:doc "Keymap activated during `completion-in-region'."
"M-<right>" #'minibuffer-next-completion
"M-RET" #'minibuffer-choose-completion)
-;; It is difficult to know when to exit completion-in-region-mode (i.e. hide
-;; the *Completions*). Here's how previous packages did it:
-;; - lisp-mode: never.
-;; - comint: only do it if you hit SPC at the right time.
-;; - pcomplete: pop it down on SPC or after some time-delay.
-;; - semantic: use a post-command-hook check similar to this one.
-(defun completion-in-region--postch ()
- (or unread-command-events ;Don't pop down the completions in the middle of
- ;mouse-drag-region/mouse-set-point.
- (and completion-in-region--data
- (and (eq (marker-buffer (nth 0 completion-in-region--data))
- (current-buffer))
- (>= (point) (nth 0 completion-in-region--data))
- (<= (point)
- (save-excursion
- (goto-char (nth 1 completion-in-region--data))
- (line-end-position)))
- (funcall completion-in-region-mode--predicate)))
- (completion-in-region-mode -1)))
-
-;; (defalias 'completion-in-region--prech 'completion-in-region--postch)
-
-(defvar completion-in-region-mode nil) ;Explicit defvar, i.s.o defcustom.
-
-(define-minor-mode completion-in-region-mode
- "Transient minor mode used during `completion-in-region'."
- :global t
- :group 'minibuffer
- ;; Prevent definition of a custom-variable since it makes no sense to
- ;; customize this variable.
- :variable completion-in-region-mode
- ;; (remove-hook 'pre-command-hook #'completion-in-region--prech)
- (remove-hook 'post-command-hook #'completion-in-region--postch)
- (setq minor-mode-overriding-map-alist
- (delq (assq 'completion-in-region-mode minor-mode-overriding-map-alist)
- minor-mode-overriding-map-alist))
- (if (null completion-in-region-mode)
- (progn
- (setq completion-in-region--data nil)
- (unless (equal completions-buffer-name (buffer-name (window-buffer)))
- (minibuffer-hide-completions)))
- ;; (add-hook 'pre-command-hook #'completion-in-region--prech)
- (cl-assert completion-in-region-mode-predicate)
- (setq completion-in-region-mode--predicate
- completion-in-region-mode-predicate)
- (setq-local minibuffer-completion-auto-choose nil)
- (add-hook 'post-command-hook #'completion-in-region--postch)
- (push `(completion-in-region-mode . ,completion-in-region-mode-map)
- minor-mode-overriding-map-alist)))
-
-;; Define-minor-mode added our keymap to minor-mode-map-alist, but we want it
-;; on minor-mode-overriding-map-alist instead.
-(setq minor-mode-map-alist
- (delq (assq 'completion-in-region-mode minor-mode-map-alist)
- minor-mode-map-alist))
-
(defvar completion-at-point-functions nil
"Special hook to find the completion table for the entity at point.
Each function on this hook is called in turn without any argument and
should return either nil, meaning it is not applicable at point,
-or a function of no arguments to perform completion (discouraged),
or a list of the form (START END COLLECTION . PROPS), where:
START and END delimit the entity to complete and should include point,
COLLECTION is the completion table to use to complete the entity, and
on the current text between START and END (e.g., they should not
obey `completion-styles').")
-(defvar completion--capf-misbehave-funs nil
- "List of functions found on `completion-at-point-functions' that misbehave.
-These are functions that neither return completion data nor a completion
-function but instead perform completion right away.")
-(defvar completion--capf-safe-funs nil
- "List of well-behaved functions found on `completion-at-point-functions'.
-These are functions which return proper completion data rather than
-a completion function or god knows what else.")
-
-(defun completion--capf-wrapper (fun which)
- ;; FIXME: The safe/misbehave handling assumes that a given function will
- ;; always return the same kind of data, but this breaks down with functions
- ;; like comint-completion-at-point or mh-letter-completion-at-point, which
- ;; could be sometimes safe and sometimes misbehaving (and sometimes neither).
- (if (pcase which
- ('all t)
- ('safe (member fun completion--capf-safe-funs))
- ('optimist (not (member fun completion--capf-misbehave-funs))))
- (let ((res (funcall fun)))
- (cond
- ((and (consp res) (not (functionp res)))
- (unless (member fun completion--capf-safe-funs)
- (push fun completion--capf-safe-funs))
- (and (eq 'no (plist-get (nthcdr 3 res) :exclusive))
- ;; FIXME: Here we'd need to decide whether there are
- ;; valid completions against the current text. But this depends
- ;; on the actual completion UI (e.g. with the default completion
- ;; it depends on completion-style) ;-(
- ;; We approximate this result by checking whether prefix
- ;; completion might work, which means that non-prefix completion
- ;; will not work (or not right) for completion functions that
- ;; are non-exclusive.
- (null (try-completion (buffer-substring-no-properties
- (car res) (point))
- (nth 2 res)
- (plist-get (nthcdr 3 res) :predicate)))
- (setq res nil)))
- ((not (or (listp res) (functionp res)))
- (unless (member fun completion--capf-misbehave-funs)
- (message
- "Completion function %S uses a deprecated calling convention" fun)
- (push fun completion--capf-misbehave-funs))))
- (if res (cons fun res)))))
+(defun completion--capf-wrapper (fun &optional _)
+ (let ((res (funcall fun)))
+ (cond
+ ((and (consp res) (not (functionp res)))
+ (and (eq 'no (plist-get (nthcdr 3 res) :exclusive))
+ (null (completion-try-completion (buffer-substring-no-properties
+ (car res) (point))
+ (nth 2 res)
+ (plist-get (nthcdr 3 res) :predicate)
+ (- (point) (car res))))
+ (setq res nil))))
+ res))
(defun completion-at-point ()
"Perform completion on the text around point.
The completion method is determined by `completion-at-point-functions'."
(interactive)
- (let ((res (run-hook-wrapped 'completion-at-point-functions
- #'completion--capf-wrapper 'all)))
- (pcase res
- (`(,_ . ,(and (pred functionp) f)) (funcall f))
- (`(,hookfun . (,start ,end ,collection . ,plist))
- (unless (markerp start) (setq start (copy-marker start)))
- (let* ((completion-extra-properties plist)
- (completion-in-region-mode-predicate
- (lambda ()
- ;; We're still in the same completion field.
- (let ((newstart (car-safe (funcall hookfun))))
- (and newstart (= newstart start))))))
- (completion-in-region start end collection
- (plist-get plist :predicate))))
- ;; Maybe completion already happened and the function returned t.
- (_
- (when (cdr res)
- (message "Warning: %S failed to return valid completion data!"
- (car res)))
- (cdr res)))))
+ (pcase (run-hook-wrapped 'completion-at-point-functions #'completion--capf-wrapper)
+ (`(,start ,end ,collection . ,plist)
+ (unless (markerp start) (setq start (copy-marker start)))
+ (let* ((completion-extra-properties plist))
+ (completion-in-region start end collection
+ (plist-get plist :predicate))))))
(defun completion-help-at-point ()
"Display the completions on the text around point.
The completion method is determined by `completion-at-point-functions'."
(interactive)
- (let ((res (run-hook-wrapped 'completion-at-point-functions
- ;; Ignore misbehaving functions.
- #'completion--capf-wrapper 'optimist)))
- (pcase res
- (`(,_ . ,(and (pred functionp) f))
- (message "Don't know how to show completions for %S" f))
- (`(,hookfun . (,start ,end ,collection . ,plist))
- (unless (markerp start) (setq start (copy-marker start)))
- (let* ((minibuffer-completion-table collection)
- (minibuffer-completion-predicate (plist-get plist :predicate))
- (completion-extra-properties plist)
- (completion-in-region-mode-predicate
- (lambda ()
- ;; We're still in the same completion field.
- (let ((newstart (car-safe (funcall hookfun))))
- (and newstart (= newstart start))))))
- ;; FIXME: We should somehow (ab)use completion-in-region-function or
- ;; introduce a corresponding hook (plus another for word-completion,
- ;; and another for force-completion, maybe?).
- (setq completion-in-region--data
- `(,start ,(copy-marker end t) ,collection
- ,(plist-get plist :predicate)))
- (completion-in-region-mode 1)
- (minibuffer-completion-help start end)))
- (`(,hookfun . ,_)
- ;; The hook function already performed completion :-(
- ;; Not much we can do at this point.
- (message "%s already performed completion!" hookfun)
- nil)
- (_ (message "Nothing to complete at point")))))
+ (pcase (run-hook-wrapped 'completion-at-point-functions #'completion--capf-wrapper)
+ (`(,start ,end ,collection . ,plist)
+ (unless (markerp start) (setq start (copy-marker start)))
+ (let* ((minibuffer-completion-table collection)
+ (minibuffer-completion-predicate (plist-get plist :predicate))
+ (completion-extra-properties plist))
+ (minibuffer-completion-help start end)))))
;;; Key bindings.
history)
(user-error "No history available"))))
;; FIXME: Can we make it work for CRM?
- (let ((completion-in-region-mode-predicate
- (lambda () (get-buffer-window completions-buffer-name 0))))
- (completion-in-region
- (minibuffer--completion-prompt-end) (point-max)
- (completion-table-with-metadata
- completions '((sort-function . identity)))))))
+ (completion-in-region
+ (minibuffer--completion-prompt-end) (point-max)
+ (completion-table-with-metadata
+ completions '((sort-function . identity))))))
(defun minibuffer-complete-defaults ()
"Complete minibuffer defaults as far as possible.
(functionp minibuffer-default-add-function))
(setq minibuffer-default-add-done t
minibuffer-default (funcall minibuffer-default-add-function)))
- (let ((completions (ensure-list minibuffer-default))
- (completion-in-region-mode-predicate
- (lambda () (get-buffer-window completions-buffer-name 0))))
+ (let ((completions (ensure-list minibuffer-default)))
(completion-in-region
(minibuffer--completion-prompt-end) (point-max)
(completion-table-with-metadata