* lisp/minibuffer.el: Make minibuffer-complete call completion-in-region
[bpt/emacs.git] / lisp / emacs-lisp / crm.el
index b8e3276..750e070 100644 (file)
@@ -157,33 +157,32 @@ Functions'."
                                    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 ()
@@ -192,13 +191,18 @@ If no characters can be completed, display a list of possible completions.
 
 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.
@@ -211,16 +215,14 @@ This function is modeled after `minibuffer-complete-and-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)))