predicate
flag)))
-(defun crm--select-current-element ()
+(defun crm--current-element ()
"Parse the minibuffer to find the current element.
-Place an overlay on the element, with a `field' property, and return it."
- (let* ((bob (minibuffer-prompt-end))
- (start (save-excursion
+Return the element's boundaries as (START . END)."
+ (let ((bob (minibuffer-prompt-end)))
+ (cons (save-excursion
(if (re-search-backward crm-separator bob t)
(match-end 0)
- bob)))
- (end (save-excursion
+ bob))
+ (save-excursion
(if (re-search-forward crm-separator nil t)
(match-beginning 0)
- (point-max))))
- (ol (make-overlay start end nil nil t)))
- (overlay-put ol 'field (make-symbol "crm"))
- ol))
-
-(defmacro crm--completion-command (command)
- "Make COMMAND a completion command for `completing-read-multiple'."
- `(let ((ol (crm--select-current-element)))
- (unwind-protect
- ,command
- (delete-overlay ol))))
+ (point-max))))))
+
+(defmacro crm--completion-command (beg end &rest body)
+ "Run BODY with BEG and END bound to the current element's boundaries."
+ (declare (indent 2) (debug (sexp sexp &rest body)))
+ `(let* ((crm--boundaries (crm--current-element))
+ (,beg (car crm--boundaries))
+ (,end (cdr crm--boundaries)))
+ ,@body))
(defun crm-completion-help ()
"Display a list of possible completions of the current minibuffer element."
(interactive)
- (crm--completion-command (minibuffer-completion-help))
+ (crm--completion-command beg end
+ (minibuffer-completion-help beg end))
nil)
(defun crm-complete ()
Return t if the current element is now a valid match; otherwise return nil."
(interactive)
- (crm--completion-command (minibuffer-complete)))
+ (crm--completion-command beg end
+ (completion-in-region beg end
+ minibuffer-completion-table
+ minibuffer-completion-predicate)))
(defun crm-complete-word ()
"Complete the current element at most a single word.
Like `minibuffer-complete-word' but for `completing-read-multiple'."
(interactive)
- (crm--completion-command (minibuffer-complete-word)))
+ (crm--completion-command beg end
+ (completion-in-region--single-word
+ beg end minibuffer-completion-table minibuffer-completion-predicate)))
(defun crm-complete-and-exit ()
"If all of the minibuffer elements are valid completions then exit.
(goto-char (minibuffer-prompt-end))
(while
(and doexit
- (let ((ol (crm--select-current-element)))
- (goto-char (overlay-end ol))
- (unwind-protect
- (catch 'exit
- (minibuffer-complete-and-exit)
- ;; This did not throw `exit', so there was a problem.
- (setq doexit nil))
- (goto-char (overlay-end ol))
- (delete-overlay ol))
- (not (eobp)))
+ (crm--completion-command beg end
+ (let ((end (copy-marker end t)))
+ (goto-char end)
+ (setq doexit nil)
+ (completion-complete-and-exit beg end
+ (lambda () (setq doexit t)))
+ (goto-char end)
+ (not (eobp))))
(looking-at crm-separator))
;; Skip to the next element.
(goto-char (match-end 0)))