branch: master
commit c6287a77c13747c0e6cb364a2be7342d08d24eb5
Author: Oleh Krehel <[email protected]>
Commit: Oleh Krehel <[email protected]>

    ivy.el (ivy-completion-in-region): Fix sole match case
    
    * ivy-test.el (ivy-with-r): New macro.
    (ivy-completion-in-region): Add test.
    
    Fixes #1252
---
 ivy-test.el | 41 ++++++++++++++++++----------
 ivy.el      | 90 ++++++++++++++++++++++++++++++++-----------------------------
 2 files changed, 74 insertions(+), 57 deletions(-)

diff --git a/ivy-test.el b/ivy-test.el
index 2102235..117fdca 100644
--- a/ivy-test.el
+++ b/ivy-test.el
@@ -573,21 +573,34 @@ will bring the behavior in line with the newer Emacsen."
             "bl C-p C-M-j")
            "bl")))
 
+(defmacro ivy-with-r (expr &rest keys)
+  `(let ((temp-buffer (generate-new-buffer " *temp*")))
+     (unwind-protect
+          (save-window-excursion
+            (switch-to-buffer temp-buffer)
+            ,expr
+            (ivy-mode)
+            (execute-kbd-macro
+             ,(apply 'vconcat (mapcar 'kbd keys)))
+            (buffer-string))
+       (and (buffer-name temp-buffer)
+            (kill-buffer temp-buffer)))))
+
 (ert-deftest ivy-completion-in-region ()
-  (should (string= (let ((temp-buffer (generate-new-buffer " *temp*")))
-                     (unwind-protect
-                          (save-window-excursion
-                            (switch-to-buffer temp-buffer)
-                            (emacs-lisp-mode)
-                            (ivy-mode)
-                            (insert " emacs-lisp-mode-h")
-                            (execute-kbd-macro
-                             (vconcat
-                              (kbd "C-M-i")))
-                            (buffer-string))
-                       (and (buffer-name temp-buffer)
-                            (kill-buffer temp-buffer))))
-                   " emacs-lisp-mode-hook")))
+  (should (string=
+           (ivy-with-r
+            (progn
+              (emacs-lisp-mode)
+              (insert " emacs-lisp-mode-h"))
+            "C-M-i")
+           " emacs-lisp-mode-hook"))
+  (should (string=
+           (ivy-with-r
+            (progn
+              (emacs-lisp-mode)
+              (insert "(nconc"))
+            "C-M-i")
+           "(nconc")))
 
 (ert-deftest ivy-completing-read-def-handling ()
   ;; DEF in COLLECTION
diff --git a/ivy.el b/ivy.el
index 44216e9..3dbd5bd 100644
--- a/ivy.el
+++ b/ivy.el
@@ -2005,49 +2005,53 @@ See `completion-in-region' for further information."
          (ivy--prompts-list (if (window-minibuffer-p)
                                 ivy--prompts-list
                               '(ivy-completion-in-region (lambda nil)))))
-    (if (null comps)
-        (message "No matches")
-      (let* ((len (ivy-completion-common-length (car comps)))
-             (str-len (length str))
-             (initial (cond ((= len 0)
-                             "")
-                            ((> len str-len)
-                             (setq len str-len)
-                             str)
-                            (t
-                             (substring str (- len))))))
-        (nconc comps nil)
-        (delete-region (- end len) end)
-        (setq ivy-completion-beg (- end len))
-        (setq ivy-completion-end ivy-completion-beg)
-        (if (null (cdr comps))
-            (if (string= str (car comps))
-                (message "Sole match")
-              (unless (minibuffer-window-active-p (selected-window))
-                (setf (ivy-state-window ivy-last) (selected-window)))
-              (ivy-completion-in-region-action
-               (substring-no-properties
-                (car comps))))
-          (let* ((w (1+ (floor (log (length comps) 10))))
-                 (ivy-count-format (if (string= ivy-count-format "")
-                                       ivy-count-format
-                                     (format "%%-%dd " w)))
-                 (prompt (format "(%s): " str)))
-            (and
-             (ivy-read (if (string= ivy-count-format "")
-                           prompt
-                         (replace-regexp-in-string "%" "%%" prompt))
-                       ;; remove 'completions-first-difference face
-                       (mapcar #'substring-no-properties comps)
-                       :predicate predicate
-                       :initial-input initial
-                       :action #'ivy-completion-in-region-action
-                       :unwind (lambda ()
-                                 (unless (eq ivy-exit 'done)
-                                   (goto-char ivy-completion-beg)
-                                   (insert initial)))
-                       :caller 'ivy-completion-in-region)
-             t)))))))
+    (cond ((null comps)
+           (message "No matches"))
+          ((progn
+             (nconc comps nil)
+             (and (null (cdr comps))
+                  (string= str (car comps))))
+           (message "Sole match"))
+          (t
+           (let* ((len (ivy-completion-common-length (car comps)))
+                  (str-len (length str))
+                  (initial (cond ((= len 0)
+                                  "")
+                                 ((> len str-len)
+                                  (setq len str-len)
+                                  str)
+                                 (t
+                                  (substring str (- len))))))
+             (delete-region (- end len) end)
+             (setq ivy-completion-beg (- end len))
+             (setq ivy-completion-end ivy-completion-beg)
+             (if (null (cdr comps))
+                 (progn
+                   (unless (minibuffer-window-active-p (selected-window))
+                     (setf (ivy-state-window ivy-last) (selected-window)))
+                   (ivy-completion-in-region-action
+                    (substring-no-properties
+                     (car comps))))
+               (let* ((w (1+ (floor (log (length comps) 10))))
+                      (ivy-count-format (if (string= ivy-count-format "")
+                                            ivy-count-format
+                                          (format "%%-%dd " w)))
+                      (prompt (format "(%s): " str)))
+                 (and
+                  (ivy-read (if (string= ivy-count-format "")
+                                prompt
+                              (replace-regexp-in-string "%" "%%" prompt))
+                            ;; remove 'completions-first-difference face
+                            (mapcar #'substring-no-properties comps)
+                            :predicate predicate
+                            :initial-input initial
+                            :action #'ivy-completion-in-region-action
+                            :unwind (lambda ()
+                                      (unless (eq ivy-exit 'done)
+                                        (goto-char ivy-completion-beg)
+                                        (insert initial)))
+                            :caller 'ivy-completion-in-region)
+                  t))))))))
 
 (defcustom ivy-do-completion-in-region t
   "When non-nil `ivy-mode' will set `completion-in-region-function'."

Reply via email to