:type 'integer
:group 'icomplete)
+(defvar icomplete-in-buffer nil
+ "If non-nil, also use Icomplete when completing in non-mini buffers.")
+
(defcustom icomplete-minibuffer-setup-hook nil
"Icomplete-specific customization of minibuffer setup.
(defvar icomplete-overlay (make-overlay (point-min) (point-min) nil t t)
"Overlay used to display the list of completions.")
-;;;_ = icomplete-pre-command-hook
-(defvar icomplete-pre-command-hook nil
- "Incremental-minibuffer-completion pre-command-hook.
-
-Is run in minibuffer before user input when `icomplete-mode' is non-nil.
-Use `icomplete-mode' function to set it up properly for incremental
-minibuffer completion.")
-(add-hook 'icomplete-pre-command-hook 'icomplete-tidy)
-;;;_ = icomplete-post-command-hook
-(defvar icomplete-post-command-hook nil
- "Incremental-minibuffer-completion post-command-hook.
+(defun icomplete-pre-command-hook ()
+ (let ((non-essential t))
+ (icomplete-tidy)))
-Is run in minibuffer after user input when `icomplete-mode' is non-nil.
-Use `icomplete-mode' function to set it up properly for incremental
-minibuffer completion.")
-(add-hook 'icomplete-post-command-hook 'icomplete-exhibit)
+(defun icomplete-post-command-hook ()
+ (let ((non-essential t)) ;E.g. don't prompt for password!
+ (icomplete-exhibit)))
;;;_ = icomplete-with-completion-tables
(defcustom icomplete-with-completion-tables t
Second entry becomes the first and can be selected with
`minibuffer-force-complete-and-exit'."
(interactive)
- (let* ((beg (minibuffer-prompt-end))
- (end (point-max))
+ (let* ((beg (icomplete--field-beg))
+ (end (icomplete--field-end))
(comps (completion-all-sorted-completions beg end))
(last (last comps)))
(when comps
Last entry becomes the first and can be selected with
`minibuffer-force-complete-and-exit'."
(interactive)
- (let* ((beg (minibuffer-prompt-end))
- (end (point-max))
+ (let* ((beg (icomplete--field-beg))
+ (end (icomplete--field-end))
(comps (completion-all-sorted-completions beg end))
(last-but-one (last comps 2))
(last (cdr last-but-one)))
positive, and disable it otherwise. If called from Lisp, enable
the mode if ARG is omitted or nil."
:global t :group 'icomplete
- (if icomplete-mode
- ;; The following is not really necessary after first time -
- ;; no great loss.
- (add-hook 'minibuffer-setup-hook 'icomplete-minibuffer-setup)
- (remove-hook 'minibuffer-setup-hook 'icomplete-minibuffer-setup)))
+ (remove-hook 'minibuffer-setup-hook #'icomplete-minibuffer-setup)
+ (remove-hook 'completion-in-region-mode-hook #'icomplete--in-region-setup)
+ (when icomplete-mode
+ (when icomplete-in-buffer
+ (add-hook 'completion-in-region-mode-hook #'icomplete--in-region-setup))
+ (add-hook 'minibuffer-setup-hook #'icomplete-minibuffer-setup)))
+
+(defun icomplete--completion-table ()
+ (if (window-minibuffer-p) minibuffer-completion-table
+ (or (nth 2 completion-in-region--data)
+ (message "In %S (w=%S): %S"
+ (current-buffer) (selected-window) (window-minibuffer-p)))))
+(defun icomplete--completion-predicate ()
+ (if (window-minibuffer-p) minibuffer-completion-predicate
+ (nth 3 completion-in-region--data)))
+(defun icomplete--field-string ()
+ (if (window-minibuffer-p) (minibuffer-contents)
+ (buffer-substring-no-properties
+ (nth 0 completion-in-region--data)
+ (nth 1 completion-in-region--data))))
+(defun icomplete--field-beg ()
+ (if (window-minibuffer-p) (minibuffer-prompt-end)
+ (nth 0 completion-in-region--data)))
+(defun icomplete--field-end ()
+ (if (window-minibuffer-p) (point-max)
+ (nth 1 completion-in-region--data)))
;;;_ > icomplete-simple-completing-p ()
(defun icomplete-simple-completing-p ()
Conditions are:
the selected window is a minibuffer,
and not in the middle of macro execution,
- and `minibuffer-completion-table' is not a symbol (which would
+ and the completion table is not a function (which would
indicate some non-standard, non-simple completion mechanism,
like file-name and other custom-func completions)."
- (and (window-minibuffer-p)
- (not executing-kbd-macro)
- minibuffer-completion-table
- (or (not (functionp minibuffer-completion-table))
- (eq icomplete-with-completion-tables t)
- (member minibuffer-completion-table
- icomplete-with-completion-tables))))
+ (unless executing-kbd-macro
+ (let ((table (icomplete--completion-table)))
+ (and table
+ (or (not (functionp table))
+ (eq icomplete-with-completion-tables t)
+ (member table icomplete-with-completion-tables))))))
;;;_ > icomplete-minibuffer-setup ()
(defun icomplete-minibuffer-setup ()
(set (make-local-variable 'completion-show-inline-help) nil)
(use-local-map (make-composed-keymap icomplete-minibuffer-map
(current-local-map)))
- (add-hook 'pre-command-hook
- (lambda () (let ((non-essential t))
- (run-hooks 'icomplete-pre-command-hook)))
- nil t)
- (add-hook 'post-command-hook
- (lambda () (let ((non-essential t)) ;E.g. don't prompt for password!
- (run-hooks 'icomplete-post-command-hook)))
- nil t)
+ (add-hook 'pre-command-hook #'icomplete-pre-command-hook nil t)
+ (add-hook 'post-command-hook #'icomplete-post-command-hook nil t)
(run-hooks 'icomplete-minibuffer-setup-hook)))
-;\f
+
+(defvar icomplete--in-region-buffer nil)
+
+(defun icomplete--in-region-setup ()
+ (when (or (not completion-in-region-mode)
+ (and icomplete--in-region-buffer
+ (not (eq icomplete--in-region-buffer (current-buffer)))))
+ (with-current-buffer (or icomplete--in-region-buffer (current-buffer))
+ (setq icomplete--in-region-buffer nil)
+ (delete-overlay icomplete-overlay)
+ (kill-local-variable 'completion-show-inline-help)
+ (remove-hook 'pre-command-hook 'icomplete-pre-command-hook t)
+ (remove-hook 'post-command-hook 'icomplete-post-command-hook t)
+ (message nil)))
+ (when (and completion-in-region-mode
+ icomplete-mode (icomplete-simple-completing-p))
+ (setq icomplete--in-region-buffer (current-buffer))
+ (set (make-local-variable 'completion-show-inline-help) nil)
+ (let ((tem (assq 'completion-in-region-mode
+ minor-mode-overriding-map-alist)))
+ (unless (memq icomplete-minibuffer-map (cdr tem))
+ (setcdr tem (make-composed-keymap icomplete-minibuffer-map
+ (cdr tem)))))
+ (add-hook 'pre-command-hook 'icomplete-pre-command-hook nil t)
+ (add-hook 'post-command-hook 'icomplete-post-command-hook nil t)))
+\f
;;;_* Completion
(save-excursion
(goto-char (point-max))
; Insert the match-status information:
- (if (and (> (point-max) (minibuffer-prompt-end))
+ (if (and (> (icomplete--field-end) (icomplete--field-beg))
buffer-undo-list ; Wait for some user input.
(or
;; Don't bother with delay after certain number of chars:
- (> (- (point) (field-beginning)) icomplete-max-delay-chars)
+ (> (- (point) (icomplete--field-beg))
+ icomplete-max-delay-chars)
;; Don't delay if the completions are known.
completion-all-sorted-completions
;; Don't delay if alternatives number is small enough:
- (and (sequencep minibuffer-completion-table)
- (< (length minibuffer-completion-table)
+ (and (sequencep (icomplete--completion-table))
+ (< (length (icomplete--completion-table))
icomplete-delay-completions-threshold))
;; Delay - give some grace time for next keystroke, before
;; embarking on computing completions:
(sit-for icomplete-compute-delay)))
- (let ((text (while-no-input
- (icomplete-completions
- (field-string)
- minibuffer-completion-table
- minibuffer-completion-predicate
- (not minibuffer-completion-confirm))))
- (buffer-undo-list t)
- deactivate-mark)
+ (let* ((field-string (icomplete--field-string))
+ (text (while-no-input
+ (icomplete-completions
+ field-string
+ (icomplete--completion-table)
+ (icomplete--completion-predicate)
+ (if (window-minibuffer-p)
+ (not minibuffer-completion-confirm)))))
+ (buffer-undo-list t)
+ deactivate-mark)
;; Do nothing if while-no-input was aborted.
(when (stringp text)
(move-overlay icomplete-overlay (point) (point) (current-buffer))
matches exist. \(Keybindings for uniquely matched commands
are exhibited within the square braces.)"
- (let* ((md (completion--field-metadata (field-beginning)))
+ (let* ((minibuffer-completion-table candidates)
+ (minibuffer-completion-predicate predicate)
+ (md (completion--field-metadata (icomplete--field-beg)))
(comps (completion-all-sorted-completions
- (minibuffer-prompt-end) (point-max)))
+ (icomplete--field-beg) (icomplete--field-end)))
(last (if (consp comps) (last comps)))
(base-size (cdr last))
(open-bracket (if require-match "(" "["))
(close-bracket (if require-match ")" "]")))
;; `concat'/`mapconcat' is the slow part.
(if (not (consp comps))
- (format " %sNo matches%s" open-bracket close-bracket)
+ (progn ;;(debug (format "Candidates=%S field=%S" candidates name))
+ (format " %sNo matches%s" open-bracket close-bracket))
(if last (setcdr last nil))
(let* ((most-try
(if (and base-size (> base-size 0))
;; Else, use try-completion.
(and (stringp prefix) (length prefix))) ;;)
prospects comp limit)
- (if (eq most-try t) ;; (or (null (cdr comps))
+ (if (or (eq most-try t) (not (consp (cdr comps))))
(setq prospects nil)
(when (member name comps)
;; NAME is complete but not unique. This scenario poses
;; 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
- (completion-in-region-mode 1)
(setq completion-in-region--data
- (list (if (markerp start) start (copy-marker start))
- (copy-marker end) collection)))
+ `(,(if (markerp start) start (copy-marker start))
+ ,(copy-marker end t) ,collection ,predicate))
+ (completion-in-region-mode 1))
(completion--in-region-1 start end))))
(defvar completion-in-region-mode-map
;; (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'.
-With a prefix argument ARG, enable the modemode if ARG is
-positive, and disable it otherwise. If called from Lisp, enable
-the mode if ARG is omitted or nil."
+ "Transient minor mode used during `completion-in-region'."
:global t
:group 'minibuffer
- (setq completion-in-region--data nil)
+ ;; 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)
- (unless (equal "*Completions*" (buffer-name (window-buffer)))
- (minibuffer-hide-completions))
+ (progn
+ (setq completion-in-region--data nil)
+ (unless (equal "*Completions*" (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
;; 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?).
- (completion-in-region-mode 1)
(setq completion-in-region--data
- (list start (copy-marker end) collection))
+ `(,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 :-(