branch: master
commit d587fa2ed93e0fb83adb97fc181178b1052f1e47
Author: Oleh Krehel <[email protected]>
Commit: Oleh Krehel <[email protected]>
ivy.el (ivy-read): Allow for format-style PROMPT
* ivy.el (ivy-read): When given a prompt of e.g. "%d pattern: ", update
the number of candidates in the prompt.
(ivy--prompt): New defvar.
(ivy--insert-prompt): New defun.
(ivy--exhibit): Call `ivy--insert-prompt'.
(ivy-completions): Fix a bug of `ivy--index' becoming -1 when the number
of matches becomes zero.
* swiper.el (swiper--format-spec): New defvar.
(swiper--candidates): Update.
(swiper--ivy): Use `swiper--format-spec' to make the prompt.
---
ivy.el | 31 +++++++++++++++++++++++++++++--
swiper.el | 27 ++++++++++++++++-----------
2 files changed, 45 insertions(+), 13 deletions(-)
diff --git a/ivy.el b/ivy.el
index 37c016d..10ee129 100644
--- a/ivy.el
+++ b/ivy.el
@@ -137,7 +137,9 @@ On error (read-only), quit without selecting."
(defun ivy-read (prompt collection &optional initial-input update-fn preselect)
"Read a string in the minibuffer, with completion.
-PROMPT is a string to prompt with; normally it ends in a colon and a space.
+PROMPT is a string to prompt with; normally it ends in a colon
+and a space. When PROMPT contains %d, it will be updated with
+the current number of matching candidates.
COLLECTION is a list of strings.
@@ -163,6 +165,10 @@ the ones that match INITIAL-INPUT."
(setq ivy--update-fn update-fn)
(setq ivy-exit nil)
(setq ivy--default (or (thing-at-point 'symbol) ""))
+ (setq ivy--prompt
+ (if (string-match "%.*d" prompt)
+ prompt
+ nil))
(unwind-protect
(minibuffer-with-setup-hook
#'ivy--minibuffer-setup
@@ -273,6 +279,26 @@ Otherwise, store nil.")
(goto-char (minibuffer-prompt-end))
(delete-region (line-end-position) (point-max))))
+(defvar ivy--prompt nil
+ "Store the format-style prompt.
+When non-nil, it should contain one %d.")
+
+(defun ivy--insert-prompt ()
+ "Update the prompt according to `ivy--prompt'."
+ (when ivy--prompt
+ (let ((inhibit-read-only t)
+ (n-str (format ivy--prompt ivy--length)))
+ (save-excursion
+ (goto-char (point-min))
+ (delete-region (point-min) (minibuffer-prompt-end))
+ (set-text-properties
+ 0 (length n-str)
+ '(front-sticky t rear-nonsticky t field t read-only t face
minibuffer-prompt)
+ n-str)
+ (insert n-str))
+ ;; get out of the prompt area
+ (constrain-to-field nil (point-max)))))
+
(defun ivy--exhibit ()
"Insert Ivy completions display.
Should be run via minibuffer `post-command-hook'."
@@ -286,6 +312,7 @@ Should be run via minibuffer `post-command-hook'."
deactivate-mark)
(when ivy--update-fn
(funcall ivy--update-fn))
+ (ivy--insert-prompt)
;; Do nothing if while-no-input was aborted.
(when (stringp text)
(save-excursion
@@ -333,7 +360,7 @@ CANDIDATES is a list of strings."
(setq ivy--index (or idx 0)))
(setq ivy--old-cands cands)
(when (>= ivy--index ivy--length)
- (setq ivy--index (1- ivy--length)))
+ (setq ivy--index (max (1- ivy--length) 0)))
(if (null cands)
""
(let ((index ivy--index))
diff --git a/swiper.el b/swiper.el
index 80c2339..906d1e4 100644
--- a/swiper.el
+++ b/swiper.el
@@ -85,19 +85,22 @@
(font-lock-ensure)
(font-lock-fontify-buffer))))
+(defvar swiper--format-spec ""
+ "Store the current candidates format spec.")
+
(defun swiper--candidates ()
"Return a list of this buffer lines."
(let ((n-lines (count-lines (point-min) (point-max))))
(unless (zerop n-lines)
- (let* ((line-width (1+ (floor (log n-lines 10))))
- (fspec (format "%%-%dd %%s" line-width))
- (line-number 0)
- candidates)
+ (setq swiper--format-spec
+ (format "%%-%dd %%s" (1+ (floor (log n-lines 10)))))
+ (let ((line-number 0)
+ candidates)
(save-excursion
(goto-char (point-min))
(swiper-font-lock-ensure)
(while (< (point) (point-max))
- (push (format fspec
+ (push (format swiper--format-spec
(cl-incf line-number)
(buffer-substring
(line-beginning-position)
@@ -142,7 +145,7 @@ When non-nil, INITIAL-INPUT is the initial search pattern."
(swiper--init)
(let ((candidates (swiper--candidates))
(preselect (format
- "%d *%s"
+ swiper--format-spec
(line-number-at-pos)
(regexp-quote
(buffer-substring-no-properties
@@ -150,11 +153,13 @@ When non-nil, INITIAL-INPUT is the initial search
pattern."
(line-end-position)))))
res)
(unwind-protect
- (setq res (ivy-read "pattern: "
- candidates
- initial-input
- #'swiper--update-input-ivy
- preselect))
+ (setq res (ivy-read
+ (replace-regexp-in-string
+ "%s" "pattern: " swiper--format-spec)
+ candidates
+ initial-input
+ #'swiper--update-input-ivy
+ preselect))
(ido-mode 1)
(swiper--cleanup)
(if (null ivy-exit)