branch: externals/ivy
commit 36f68985dec5cb7a90518040efb85a91219a983c
Merge: 6cd8350655 6227843101
Author: Basil L. Contovounesios <ba...@contovou.net>
Commit: Basil L. Contovounesios <ba...@contovou.net>

    Merge branch 'master' into externals/ivy
---
 .mailmap         |   1 +
 CONTRIBUTING.org |   6 +--
 colir.el         |  46 ++++++++--------
 doc/ivy-ox.el    |   2 +-
 doc/ivy.org      |  14 ++---
 doc/ivy.texi     |   8 +--
 doc/scripts.el   |   2 +-
 ivy-faces.el     |   2 +-
 ivy-overlay.el   |   2 +-
 ivy-test.el      | 112 +++++++++++++++++++++++++++++++++------
 ivy.el           | 158 ++++++++++++++++++++++++++++++++++---------------------
 11 files changed, 237 insertions(+), 116 deletions(-)

diff --git a/.mailmap b/.mailmap
index fa38b3f201..eb78d6ffb0 100644
--- a/.mailmap
+++ b/.mailmap
@@ -19,6 +19,7 @@
 <ricouillet...@gmail.com> <eric.da...@u-cergy.fr>
 <syo...@gmail.com> <shohei.yosh...@dena.com>
 <ywwr...@gmail.com> <58066925+ywwr...@users.noreply.github.com>
+Christopher Floess <chris.flo...@mailbox.org>
 Daanturo <daant...@gmail.com> <dantle....@gmail.com>
 Diego A. Mundo <diegoamu...@gmail.com>
 Earl Hyatt <oka...@protonmail.com> <ej...@protonmail.com>
diff --git a/CONTRIBUTING.org b/CONTRIBUTING.org
index 6fcc7278ea..772e9ec4ca 100644
--- a/CONTRIBUTING.org
+++ b/CONTRIBUTING.org
@@ -14,9 +14,9 @@ init file.
 This shortcut will start =emacs -Q= for you with =ivy-mode= already
 loaded:
 #+begin_src sh
-git clone https://github.com/abo-abo/swiper/
-cd swiper
-make plain
+  git clone 'https://github.com/abo-abo/swiper.git'
+  cd swiper
+  make deps plain
 #+end_src
 
 * Contributing code
diff --git a/colir.el b/colir.el
index f371ef3839..a30046f0cc 100644
--- a/colir.el
+++ b/colir.el
@@ -1,6 +1,6 @@
 ;;; colir.el --- Color blending library -*- lexical-binding: t -*-
 
-;; Copyright (C) 2015-2024 Free Software Foundation, Inc.
+;; Copyright (C) 2015-2025 Free Software Foundation, Inc.
 
 ;; Author: Oleh Krehel <ohwoeo...@gmail.com>
 
@@ -35,7 +35,7 @@
 (require 'color)
 
 (defcustom colir-compose-method #'colir-compose-alpha
-  "Select a method to compose two color channels."
+  "The method `colir-blend' uses to compose two color channels."
   :group 'ivy
   :type '(radio
           (function-item colir-compose-alpha)
@@ -43,22 +43,25 @@
           (function-item colir-compose-soft-light)))
 
 (defun colir-compose-soft-light (a b)
-  "Compose A and B channels."
+  "Compose color channels A and B in Soft Light blend mode.
+See URL `https://en.wikipedia.org/wiki/Blend_modes#Soft_Light'."
   (if (< b 0.5)
       (+ (* 2 a b) (* a a (- 1 b b)))
-    (+ (* 2 a (- 1 b)) (* (sqrt a) (- (* 2 b) 1)))))
+    (+ (* 2 a (- 1 b)) (* (sqrt a) (+ b b -1)))))
 
 (defun colir-compose-overlay (a b)
-  "Compose A and B channels."
+  "Compose color channels A and B in Overlay blend mode.
+See URL `https://en.wikipedia.org/wiki/Blend_modes#Overlay'."
   (if (< a 0.5)
       (* 2 a b)
     (- 1 (* 2 (- 1 a) (- 1 b)))))
 
+;; Generalizes Emacs 31 `color-blend'.
 (defun colir-compose-alpha (a b &optional alpha gamma)
-  "Compose A and B channels.
-Optional argument ALPHA is a number between 0.0 and 1.0 which corresponds
-to the influence of A on the result.  Default value is 0.5.
-Optional argument GAMMA is used for gamma correction.  Default value is 2.2."
+  "Compose color channels A and B using alpha blending.
+Optional argument ALPHA controls the influence of A on the result.
+It is a number between 0.0 and 1.0, inclusive (default 0.5).
+Optional argument GAMMA controls gamma correction (default 2.2)."
   (setq alpha (or alpha 0.5))
   (setq gamma (or gamma 2.2))
   (+ (* (expt a gamma) alpha) (* (expt b gamma) (- 1 alpha))))
@@ -69,8 +72,8 @@ C1 and C2 are triples of floats in [0.0 1.0] range."
   (apply #'color-rgb-to-hex
          (cl-mapcar
           (if (eq (frame-parameter nil 'background-mode) 'dark)
-              ;; this method works nicely for dark themes
-              'colir-compose-soft-light
+              ;; This method works nicely for dark themes.
+              #'colir-compose-soft-light
             colir-compose-method)
           c1 c2)))
 
@@ -85,17 +88,16 @@ C1 and C2 are triples of floats in [0.0 1.0] range."
 
 (defun colir--blend-background (start next prevn face object)
   (let ((background-prev (face-background prevn)))
-    (progn
-      (put-text-property
-       start next 'face
-       (if background-prev
-           (cons `(background-color
-                   . ,(colir-blend
-                       (colir-color-parse background-prev)
-                       (colir-color-parse (face-background face nil t))))
-                 prevn)
-         (list face prevn))
-       object))))
+    (put-text-property
+     start next 'face
+     (if background-prev
+         (cons `(background-color
+                 . ,(colir-blend
+                     (colir-color-parse background-prev)
+                     (colir-color-parse (face-background face nil t))))
+               prevn)
+       (list face prevn))
+     object)))
 
 (defun colir-blend-face-background (start end face &optional object)
   "Append to the face property of the text from START to END the face FACE.
diff --git a/doc/ivy-ox.el b/doc/ivy-ox.el
index fd33b453fd..863e7dce92 100644
--- a/doc/ivy-ox.el
+++ b/doc/ivy-ox.el
@@ -1,6 +1,6 @@
 ;;; ivy-ox.el --- org-export settings for Ivy -*- lexical-binding: t -*-
 
-;; Copyright (C) 2015-2024 Free Software Foundation, Inc.
+;; Copyright (C) 2015-2025 Free Software Foundation, Inc.
 
 ;; Author: Oleh Krehel
 
diff --git a/doc/ivy.org b/doc/ivy.org
index cb1191d1d4..d54cdaf1f6 100644
--- a/doc/ivy.org
+++ b/doc/ivy.org
@@ -18,8 +18,8 @@
 #+STARTUP: indent
 * Setup                                                                        
       :noexport:
 #+BEGIN_SRC elisp :exports results :results silent
-(add-to-list 'load-path default-directory)
-(require 'ivy-ox)
+  (add-to-list 'load-path (directory-file-name default-directory))
+  (require 'ivy-ox)
 #+END_SRC
 * Writing this manual                                                          
       :noexport:
 To highlight a section without introducing a new subheading use
@@ -70,7 +70,7 @@ final candidate is either through simple keyboard character 
inputs or
 through powerful regular expressions.
 #+TEXINFO: @end ifnottex
 
-Copyright (C) 2015--2024 Free Software Foundation, Inc.
+Copyright (C) 2015--2025 Free Software Foundation, Inc.
 
 #+BEGIN_QUOTE
 Permission is granted to copy, distribute and/or modify this document
@@ -189,15 +189,15 @@ For package manager details, see [[info:emacs#Packages]].
      First clone the Swiper repository with:
 
      #+begin_src sh
-     cd ~/git && git clone https://github.com/abo-abo/swiper
-     cd swiper && make compile
+       cd ~/git && git clone 'https://github.com/abo-abo/swiper.git'
+       cd swiper && make deps compile
      #+end_src
 
      Second, add these lines to the Emacs init file:
 
      #+begin_src elisp
-     (add-to-list 'load-path "~/git/swiper/")
-     (require 'ivy)
+       (add-to-list 'load-path "~/git/swiper")
+       (require 'ivy)
      #+end_src
 
      Then, update the code with:
diff --git a/doc/ivy.texi b/doc/ivy.texi
index 90c5fa2e16..cb2a609127 100644
--- a/doc/ivy.texi
+++ b/doc/ivy.texi
@@ -20,7 +20,7 @@ final candidate is either through simple keyboard character 
inputs or
 through powerful regular expressions.
 @end ifnottex
 
-Copyright (C) 2015--2024 Free Software Foundation, Inc.
+Copyright (C) 2015--2025 Free Software Foundation, Inc.
 
 @quotation
 Permission is granted to copy, distribute and/or modify this document
@@ -261,14 +261,14 @@ Contribute to Ivy's development; send patches; pull 
requests
 First clone the Swiper repository with:
 
 @example
-cd ~/git && git clone https://github.com/abo-abo/swiper
-cd swiper && make compile
+cd ~/git && git clone 'https://github.com/abo-abo/swiper.git'
+cd swiper && make deps compile
 @end example
 
 Second, add these lines to the Emacs init file:
 
 @lisp
-(add-to-list 'load-path "~/git/swiper/")
+(add-to-list 'load-path "~/git/swiper")
 (require 'ivy)
 @end lisp
 
diff --git a/doc/scripts.el b/doc/scripts.el
index 6e00b162ff..97b1827af6 100644
--- a/doc/scripts.el
+++ b/doc/scripts.el
@@ -1,4 +1,4 @@
-;; Copyright (C) 2020-2024 Free Software Foundation, Inc.
+;; Copyright (C) 2020-2025 Free Software Foundation, Inc.
 (setq org-confirm-babel-evaluate nil)
 (defun org-to-texi (fname)
   (find-file fname)
diff --git a/ivy-faces.el b/ivy-faces.el
index c2195ed294..1a25cfc0a9 100644
--- a/ivy-faces.el
+++ b/ivy-faces.el
@@ -1,6 +1,6 @@
 ;;; ivy-faces.el --- Faces for Ivy -*- lexical-binding: t -*-
 
-;; Copyright (C) 2020-2024 Free Software Foundation, Inc.
+;; Copyright (C) 2020-2025 Free Software Foundation, Inc.
 
 ;; Author: Oleh Krehel <ohwoeo...@gmail.com>
 ;; Keywords: convenience
diff --git a/ivy-overlay.el b/ivy-overlay.el
index ad359fc83d..f52b5ecbee 100644
--- a/ivy-overlay.el
+++ b/ivy-overlay.el
@@ -1,6 +1,6 @@
 ;;; ivy-overlay.el --- Overlay display functions for Ivy  -*- lexical-binding: 
t -*-
 
-;; Copyright (C) 2016-2024 Free Software Foundation, Inc.
+;; Copyright (C) 2016-2025 Free Software Foundation, Inc.
 
 ;; Author: Oleh Krehel <ohwoeo...@gmail.com>
 ;; Keywords: convenience
diff --git a/ivy-test.el b/ivy-test.el
index 87dda1854b..f850bbe736 100644
--- a/ivy-test.el
+++ b/ivy-test.el
@@ -1,6 +1,6 @@
 ;;; ivy-test.el --- tests for ivy -*- lexical-binding: t -*-
 
-;; Copyright (C) 2015-2024 Free Software Foundation, Inc.
+;; Copyright (C) 2015-2025 Free Software Foundation, Inc.
 
 ;; Author: Oleh Krehel
 
@@ -1007,20 +1007,102 @@ Since `execute-kbd-macro' doesn't pick up a let-bound 
`default-directory'.")
       (ivy-mode ivy-mode-reset-arg))))
 
 (ert-deftest ivy-completion-common-length ()
-  (should (= 2
-             (ivy-completion-common-length
-              #("test/"
-                0 2 (face completions-common-part)
-                2 3 (face (completions-first-difference))))))
-  (should (= 5
-             (ivy-completion-common-length
-              #("Math/E"
-                0 5 (face (completions-common-part))
-                5 6 (face (completions-first-difference))))))
-  (should (= 3
-             (ivy-completion-common-length
-              #("vec"
-                0 3 (face (completions-common-part)))))))
+  (mapc (lambda (pair)
+          (dolist (str (cdr pair))
+            (ert-info ((format "%S" str) :prefix "String: ")
+              (should (= (ivy-completion-common-length str) (car pair))))))
+        '((0 ""
+             #("a"   0 1 (face completions-first-difference))
+             #("ab"  0 1 (face completions-first-difference))
+             #("abc" 0 1 (face completions-first-difference))
+             #("a"   0 1 (face (completions-first-difference)))
+             #("ab"  0 1 (face (completions-first-difference)))
+             #("abc" 0 1 (face (completions-first-difference)))
+             #("a"   0 1 (font-lock-face (completions-first-difference)))
+             #("ab"  0 1 (font-lock-face (completions-first-difference)))
+             #("abc" 0 1 (font-lock-face (completions-first-difference)))
+             #("abc"
+               0 1 (face completions-first-difference)
+               1 2 (face default))
+             #("abc"
+               0 1 (face completions-first-difference)
+               2 3 (face default))
+             #("abc"
+               0 1 (face (completions-first-difference))
+               1 2 (face default))
+             #("abc"
+               0 1 (face (completions-first-difference))
+               2 3 (face default)))
+          (1 "a"
+             #("a"   0 1 (face default))
+             #("ab"  1 2 (face completions-first-difference))
+             #("ab"  0 2 (face completions-first-difference))
+             #("abc" 1 2 (face completions-first-difference))
+             #("abc" 0 2 (face completions-first-difference))
+             #("ab"  1 2 (face (completions-first-difference)))
+             #("ab"  0 2 (face (completions-first-difference)))
+             #("abc" 1 2 (face (completions-first-difference)))
+             #("abc" 0 2 (face (completions-first-difference)))
+             #("ab"  1 2 (font-lock-face (completions-first-difference)))
+             #("ab"  0 2 (font-lock-face (completions-first-difference)))
+             #("abc" 1 2 (font-lock-face (completions-first-difference)))
+             #("abc" 0 2 (font-lock-face (completions-first-difference)))
+             #("abc"
+               0 1 (face default)
+               1 2 (face completions-first-difference))
+             #("abc"
+               1 2 (face completions-first-difference)
+               2 3 (face default))
+             #("abc"
+               0 1 (face default)
+               1 2 (face (completions-first-difference)))
+             #("abc"
+               1 2 (face (completions-first-difference))
+               2 3 (face default)))
+          (2 "ab"
+             #("ab"  0 1 (face default))
+             #("ab"  1 2 (face default))
+             #("ab"  0 2 (face default))
+             #("abc" 2 3 (face completions-first-difference))
+             #("abc" 1 3 (face completions-first-difference))
+             #("abc" 0 3 (face completions-first-difference))
+             #("abc" 2 3 (face (completions-first-difference)))
+             #("abc" 1 3 (face (completions-first-difference)))
+             #("abc" 0 3 (face (completions-first-difference)))
+             #("abc" 2 3 (font-lock-face (completions-first-difference)))
+             #("abc" 1 3 (font-lock-face (completions-first-difference)))
+             #("abc" 0 3 (font-lock-face (completions-first-difference)))
+             #("abc"
+               0 1 (face default)
+               2 3 (face completions-first-difference))
+             #("abc"
+               1 2 (face default)
+               2 3 (face completions-first-difference))
+             #("abc"
+               0 1 (face default)
+               2 3 (face (completions-first-difference)))
+             #("abc"
+               1 2 (face default)
+               2 3 (face (completions-first-difference)))
+             #("test/"
+               0 2 (face completions-common-part)
+               2 3 (face completions-first-difference))
+             #("test/"
+               0 2 (face completions-common-part)
+               2 3 (face (completions-first-difference))))
+          (3 "abc"
+             #("abc" 0 1 (face default))
+             #("abc" 1 2 (face default))
+             #("abc" 2 3 (face default))
+             #("abc" 0 2 (face default))
+             #("abc" 1 3 (face default))
+             #("abc" 0 3 (face default)))
+          (5 #("Math/E"
+               0 5 (face completions-common-part)
+               5 6 (face completions-first-difference))
+             #("Math/E"
+               0 5 (face completions-common-part)
+               5 6 (face (completions-first-difference)))))))
 
 (ert-deftest ivy--sort-function ()
   "Test `ivy--sort-function' behavior."
diff --git a/ivy.el b/ivy.el
index 15bf9bbe55..66e71ae32c 100644
--- a/ivy.el
+++ b/ivy.el
@@ -1,6 +1,6 @@
 ;;; ivy.el --- Incremental Vertical completYon -*- lexical-binding: t -*-
 
-;; Copyright (C) 2015-2024 Free Software Foundation, Inc.
+;; Copyright (C) 2015-2025 Free Software Foundation, Inc.
 
 ;; Author: Oleh Krehel <ohwoeo...@gmail.com>
 ;; Maintainer: Basil L. Contovounesios <ba...@contovou.net>
@@ -2037,6 +2037,8 @@ Directories come first."
          (seq (cl-mapcan
                (lambda (f)
                  (unless (member f '("./" "../"))
+                   ;; FIXME: Use `substitute-in-file-name'?
+                   ;; Re: #2012, #3060.
                    (setq f (ivy--string-replace "$$" "$" f))
                    (list (if (and dirs-first (ivy--dirname-p f))
                              (propertize f 'ivy--dir (directory-file-name f))
@@ -2620,10 +2622,11 @@ The previous string is between `ivy-completion-beg' and 
`ivy-completion-end'."
                                            (ivy-state-collection ivy-last)))
             (minibuffer-completion-predicate (if (boundp 'ivy--minibuffer-pred)
                                                  ivy--minibuffer-pred
-                                               (ivy-state-predicate 
ivy-last))))
-        (completion--done str (cond ((eq ivy--minibuffer-try t) 'finished)
-                                    ((eq ivy-exit 'done) 'unknown)
-                                    ('exact))))
+                                               (ivy-state-predicate ivy-last)))
+            (newstr (or (car-safe ivy--minibuffer-try) str)))
+        (completion--done newstr (cond ((eq ivy--minibuffer-try t) 'finished)
+                                       ((eq ivy-exit 'done) 'unknown)
+                                       ('exact))))
       (setq ivy-completion-end (point))
       (save-excursion
         (dolist (cursor fake-cursors)
@@ -2636,24 +2639,46 @@ The previous string is between `ivy-completion-beg' and 
`ivy-completion-end'."
           (set-marker (overlay-get cursor 'point) (point))
           (set-marker (overlay-get cursor 'mark) (point)))))))
 
+(defalias 'ivy--face-list-p
+  (if (fboundp 'face-list-p)
+      #'face-list-p
+    (lambda (face)
+      (and (listp face)
+           (listp (cdr face))
+           (not (keywordp (car face))))))
+  "Compatibility shim for Emacs 25 `face-list-p'.")
+
+;; FIXME: Should this return the smallest such index instead?
+;; Usually the two are equal, but perhaps there exist more
+;; exotic applications of `completions-first-difference'.
+;;
+;; Completing files under a directory foo/ can have a first difference at
+;; index 0 in some Emacs versions, and no such property in other versions.
+;; So perhaps this function should return 0 instead of (length str) when no
+;; property is found?  That still follows the 'largest index' definition.
 (defun ivy-completion-common-length (str)
-  "Return the amount of characters that match in  STR.
-
-`completion-all-completions' computes this and returns the result
-via text properties.
-
-The first non-matching part is propertized:
-- either with: (face (completions-first-difference))
-- or: (font-lock-face completions-first-difference)."
-  (let ((char-property-alias-alist '((face font-lock-face)))
-        (i (1- (length str))))
-    (catch 'done
-      (while (>= i 0)
-        (when (equal (get-text-property i 'face str)
-                     '(completions-first-difference))
-          (throw 'done i))
-        (cl-decf i))
-      (throw 'done (length str)))))
+  "Return the length of the completion-matching prefix of STR.
+
+That is, return the largest index into STR at which either the
+`face' or `font-lock-face' property value contains the face
+`completions-first-difference'.
+If no such index is found, return the length of STR.
+
+Typically the completion-matching parts of STR have previously been
+propertized by `completion-all-completions', but then the base-size
+returned by that function should be preferred over
+`ivy-completion-common-length'."
+  (let* ((char-property-alias-alist '((face font-lock-face)))
+         (cmn (length str))
+         (i cmn))
+    (when (> i 0)
+      (while (if (let ((face (get-text-property (1- i) 'face str)))
+                   (or (eq 'completions-first-difference face)
+                       (and (ivy--face-list-p face)
+                            (memq 'completions-first-difference face))))
+                 (ignore (setq cmn (1- i)))
+               (setq i (previous-single-property-change i 'face str)))))
+    cmn))
 
 (defun ivy-completion-in-region (start end collection &optional predicate)
   "An Ivy function suitable for `completion-in-region-function'.
@@ -2661,43 +2686,57 @@ The function completes the text between START and END 
using COLLECTION.
 PREDICATE (a function called with no arguments) says when to exit.
 See `completion-in-region' for further information."
   (let* ((enable-recursive-minibuffers t)
+         (reg (- end start))
          (str (buffer-substring-no-properties start end))
          (completion-ignore-case (ivy--case-fold-p str))
          (md (completion-metadata str collection predicate))
-         (reg (- end start))
-         (comps (completion-all-completions str collection predicate reg md))
          (try (completion-try-completion str collection predicate reg md))
+         (comps (completion-all-completions str collection predicate reg md))
+         (last (last comps))
+         (base-size (cdr last))
          (ivy--minibuffer-table collection)
          (ivy--minibuffer-pred predicate))
-    (cond ((null comps)
-           (message "No matches"))
-          ((progn
-             (nconc comps nil)
-             (and (null (cdr comps))
-                  (string= str (car comps))))
-           (message "Sole match"))
+    (when last (setcdr last ()))
+    (cond ((not try)
+           (and (not completion-fail-discreetly)
+                completion-show-inline-help
+                (minibuffer-message "No matches"))
+           nil)
+          ((eq try t)
+           (goto-char end)
+           (let ((minibuffer-completion-table collection)
+                 (minibuffer-completion-predicate predicate))
+             (completion--done str 'finished "Sole match"))
+           t)
           (t
            (when (eq collection 'crm--collection-fn)
              (setq comps (delete-dups comps)))
-           (let* ((len (ivy-completion-common-length (car comps)))
-                  (initial (cond ((= len 0)
+           (let* ((cmn (ivy-completion-common-length (car comps)))
+                  ;; Translate a 'not found' result to 0.  Do this here 
(instead
+                  ;; of fixing `ivy-completion-common-length') for backward
+                  ;; compatibility, since it's a potentially public function.
+                  (cmn (if (= cmn (length (car comps))) 0 cmn))
+                  (initial (cond (base-size (substring str base-size))
+                                 ;; The remaining clauses should hopefully 
never
+                                 ;; be taken, since they rely on
+                                 ;; `ivy-completion-common-length'.
+                                 ((= cmn 0)
                                   "")
-                                 ((let ((str-len (length str)))
-                                    (when (> len str-len)
-                                      (setq len str-len)
-                                      str)))
+                                 ((>= cmn reg)
+                                  (setq cmn reg)
+                                  str)
                                  (t
-                                  (substring str (- len))))))
-             (delete-region (- end len) end)
-             (setq ivy-completion-beg (- end len))
+                                  (substring str (- cmn)))))
+                  (base-pos (if base-size (+ start base-size) (- end cmn))))
+             (delete-region base-pos end)
+             (setq ivy-completion-beg base-pos)
              (setq ivy-completion-end ivy-completion-beg)
              (if (null (cdr comps))
-                 (progn
+                 (let ((ivy--minibuffer-try try))
                    (unless (minibuffer-window-active-p (selected-window))
                      (setf (ivy-state-window ivy-last) (selected-window)))
-                   (let ((ivy--minibuffer-try try))
-                     (ivy-completion-in-region-action
-                      (substring-no-properties (car comps)))))
+                   (ivy-completion-in-region-action
+                    (substring-no-properties (car comps))))
                (dolist (s comps)
                  ;; Remove face `completions-first-difference'.
                  (ivy--remove-props s 'face))
@@ -2711,6 +2750,9 @@ See `completion-in-region' for further information."
                  (setq predicate nil))
                (ivy-read (format "(%s): " str) collection
                          :predicate predicate
+                         ;; FIXME: The anchor is intrusive and not easily
+                         ;; configurable by `ivy-initial-inputs-alist' or
+                         ;; `ivy-hooks-alist'.
                          :initial-input (concat
                                          (and (derived-mode-p 
#'emacs-lisp-mode)
                                               "^")
@@ -2722,7 +2764,7 @@ See `completion-in-region' for further information."
                                      (when initial
                                        (insert initial))))
                          :caller 'ivy-completion-in-region)))
-           ;; Return value should be non-nil on valid completion;
+           ;; Return value should be t on valid completion;
            ;; see `completion-in-region'.
            t))))
 
@@ -3187,23 +3229,17 @@ parts beyond their respective faces `ivy-confirm-face' 
and
             (std-props '(front-sticky t rear-nonsticky t field t read-only t))
             (n-str
              (concat
-              (if (and (bound-and-true-p minibuffer-depth-indicate-mode)
-                       (> (minibuffer-depth) 1))
-                  (format "[%d] " (minibuffer-depth))
-                "")
-              (concat
-               (if (string-match "%d.*%d" ivy-count-format)
-                   (format head
-                           (1+ ivy--index)
-                           (or (and (ivy-state-dynamic-collection ivy-last)
+              (and (bound-and-true-p minibuffer-depth-indicate-mode)
+                   (> (minibuffer-depth) 1)
+                   (format "[%d] " (minibuffer-depth)))
+              (let ((count (or (and (ivy-state-dynamic-collection ivy-last)
                                     ivy--full-length)
-                               ivy--length))
-                 (format head
-                         (or (and (ivy-state-dynamic-collection ivy-last)
-                                  ivy--full-length)
-                             ivy--length)))
-               ivy--prompt-extra
-               tail)))
+                               ivy--length)))
+                (if (string-match-p "%d.*%d" ivy-count-format)
+                    (format head (min (1+ ivy--index) count) count)
+                  (format head count)))
+              ivy--prompt-extra
+              tail))
             (d-str (if ivy--directory
                        (abbreviate-file-name ivy--directory)
                      "")))

Reply via email to