Have anzu like #/total count be displayed in ivy [Feature request] #167

Closed
kaushalmodi opened this Issue Jul 1, 2015 · 17 comments

Projects

None yet

2 participants

@kaushalmodi
Contributor

The anzu package shows which search item you are on on the bottom left when you are using isearch; (1/2) as shown in the below screenshot.

clipboard01

swiper (and ivy in general) shown only the total search hits (total number of items in list); 2 in this example.

clipboard01

It will be nice to have a user option to show a #/total count instead of just total count to the left of pattern.

@abo-abo
Owner
abo-abo commented Jul 1, 2015

I have considered this, but I thought that it would be too annoying, since it's almost redundant information that updates with each scroll. I can add it as an option though, it's not hard.

@abo-abo abo-abo added a commit that closed this issue Jul 1, 2015
@abo-abo Allow to see the candidate index via ivy-count-format
* ivy.el (ivy--insert-prompt): Update.

To use this feature, use something like this:

    (setq ivy-count-format "(%d/%d)")

Basically two number specifiers instead of the usual one. The problem
with this approach is that the prompt length will change as you scroll
e.g. from 9 to 10, which is uncomfortable.

Fixes #167
f9974e8
@abo-abo abo-abo closed this in f9974e8 Jul 1, 2015
@abo-abo
Owner
abo-abo commented Jul 1, 2015

Try it out with:

(setq ivy-count-format "(%d/%d)")

Hopefully I didn't break the old behavior (when ivy-count-format has only one %d).

@kaushalmodi
Contributor

I was wondering how we can make this evaluation each time ivy--insert-prompt is called:

    (setq ivy-count-format (concat "%"
                                   (number-to-string
                                    (length `(number-to-string ,ivy--length)))
                                   "d/%d"))
@abo-abo
Owner
abo-abo commented Jul 2, 2015

I was wondering how we can make this evaluation each time ivy--insert-prompt is called:

I considered this, but I don't know if there's a way to make it look nice. Suppose the collection has size 9000. Then to keep the stuff aligned for all cases, since I find it extremely annoying when my input window is moving as I type:

(format "(%-4d/%-4d)" 1 9000)
;; => "(1   /9000)"
(format "(%-4d/%-4d)" 9000 9000)
;; => "(9000/9000)"

While the second one looks OK, the first one looks pretty ugly. Suggestions?

@kaushalmodi
Contributor

Currently I have set the format to

(setq ivy-count-format "%3d/%d")

and it looks nice. The count does not move around.

Instead of setting the index width to a static 3, it would be even better if I can evaluate the below each time ivy--insert-prompt is called.

 (setq ivy-count-format (concat "%"
                                   (number-to-string
                                    (length `(number-to-string ,ivy--length)))
                                   "d/%d"))

Things that make the index look good:

  • no brackets
  • right align the index (%Nd instead of %-Nd)

clipboard01

@abo-abo abo-abo added a commit that referenced this issue Jul 2, 2015
@abo-abo Update index formatting logic
* ivy.el (ivy--reset-state): Update.
(ivy--insert-prompt): Simplify.

If you want to see both the index and the length of the candidates,
instead of just the length, it can be done like this:

    (setq ivy-count-format "%d/%d ")

Each "%d" is replaced appropriately due to the total length of the
candidates. For instance, this one can result in "%4d/%-4d M-x ".

Re #167
e49d3cc
@abo-abo
Owner
abo-abo commented Jul 2, 2015

right align the index

OK, but the length needs to be left-aligned. Here's what I get for M-x: ___1/1___ ^vi li mo. Note the abundance of spaces: they are necessary, since it could be 8337/8337 ^ as well.

I guess it's bearable. Check out the last change with this setting:

(setq ivy-count-format "%d/%d ")
@abo-abo abo-abo added a commit that referenced this issue Jul 2, 2015
@abo-abo Update index formatting logic
* ivy.el (ivy--reset-state): Update.
(ivy--insert-prompt): Simplify.

If you want to see both the index and the length of the candidates,
instead of just the length, it can be done like this:

    (setq ivy-count-format "%d/%d ")

Each "%d" is replaced appropriately due to the total length of the
candidates. For instance, this one can result in "%4d/%-4d M-x ".

Re #167
783f7c5
@kaushalmodi
Contributor

Works for the few ivy powered functions I tested out, but not for swiper?
Sorry, forgot to update swiper.el..

@kaushalmodi
Contributor

I updated swiper.el but I notice that just for swiper, there is an extra offset on the left
clipboard01

As the total hits is 4, that 2 should have been flush to the left. On debugging, I noticed that swiper--width was being internally calculated as 3.

@abo-abo
Owner
abo-abo commented Jul 2, 2015

Looks correct to me: 239/239 Swiper. That one space should be there in case of max width.

@kaushalmodi
Contributor

It looks correct when there are 3 digits in the w in s/w. Try using swiper for something that has single digit hits (try swiping for the exact same thing as in the screenshot above).

@abo-abo
Owner
abo-abo commented Jul 2, 2015

try swiping for the exact same thing as in the screenshot above

OK, I got the same result as you:

__1/4___Swiper:
154 123_|||||||

That one extra space is there always: it's 3 chars, /, 3 chars, _.

@kaushalmodi
Contributor

Right.. the issue is that the swiper--width is calculated based on the number of lines in the file, not based on the number of hits.

  (let ((n-lines (count-lines (point-min) (point-max))))
    (unless (zerop n-lines)
      (setq swiper--width (1+ (floor (log n-lines 10))))
      (setq swiper--format-spec
            (format "%%-%dd %%s" swiper--width))

In the case of swiper.el, there are 363 lines ( 3 digit number) right now. So swiper--format-spec will always incorrectly be "%-3d %s".

It would be nice to have swiper--width update with the number of search hits.

@kaushalmodi
Contributor

The problem gets even more pronounced as the total number of lines in a file increase:

File with 1000+ lines
clipboard01

File with 10000+ lines
clipboard01

@abo-abo
Owner
abo-abo commented Jul 2, 2015

The problem gets even more pronounced as the total number of lines in a file increase:

It has to be done this way to prevent the input field from moving as you type. Just try it your way: replace head on line 1176 with "%d/%d". The result isn't great.

@kaushalmodi
Contributor

That one extra space is there always: it's 3 chars, /, 3 chars, _.

That extra space is not the problem. As shown in above screenshots, the issue is with how the number 3 is calculated; it should be

(1+ (floor (log NUM-SEARCH-HITS 10))) ; correct

not

(1+ (floor (log NUM-LINES-IN-FILE 10))) ; incorrect
@abo-abo
Owner
abo-abo commented Jul 2, 2015

(1+ (floor (log NUM-SEARCH-HITS 10))) ; correct

The input field will move with this approach.

@kaushalmodi
Contributor

The input field will move with this approach.

Thanks, I see your point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment