Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ivy-switch-buffer: filtering does not preserve virtual buffer ordering #706

Closed
Wilfred opened this Issue Oct 13, 2016 · 13 comments

Comments

Projects
None yet
2 participants
@Wilfred
Copy link
Contributor

Wilfred commented Oct 13, 2016

I use ivy-switch-buffer with ivy-use-virtual-buffers and it generally does exactly what I want.

However, if I kill a buffer, then try to switch to buffer with the same name, I accidentally reopen the previous file:

lib_rs_counsel

In this picture, I've just killed a lib.rs buffer. I have two other files called lib.rs open. However, typing C-x b lib.rs RET reopens the lib.rs file I just closed.

Is it possible to reorder the results to prevent this?

@abo-abo

This comment has been minimized.

Copy link
Owner

abo-abo commented Oct 13, 2016

It looks like the case here is the perfect match logic: when you type in the exact candidate name, it will be selected no matter where in the list it is.

I think if you type in only lib, the virtual one will be lower in the list.

@Wilfred

This comment has been minimized.

Copy link
Contributor Author

Wilfred commented Oct 13, 2016

This doesn't seem to be the case:

package_json

What would you expect to happen in this case?

@abo-abo

This comment has been minimized.

Copy link
Owner

abo-abo commented Oct 13, 2016

What would you expect to happen in this case?

The virtual buffers are always below for me. What settings are you using?

@Wilfred

This comment has been minimized.

Copy link
Contributor Author

Wilfred commented Oct 15, 2016

I think my only relevant setting is this one:

(setq ivy-re-builders-alist '((t . ivy--regex-ignore-order)))

I have set four other ivy related settings: https://github.com/Wilfred/.emacs.d/blob/40cc6ebc474f04d14762f3898677589f17781373/user-lisp/minibuffer-completion-customisations.el#L47-L70

I'm not seeing virtual buffers at the bottom. In one case (note the case difference), I am even seeing the virtual buffers in the middle:

cask_ordering

Is there code to ensure that virtual buffers are last? Could you point me at it?

@abo-abo

This comment has been minimized.

Copy link
Owner

abo-abo commented Oct 15, 2016

See ivy--buffer-list. It has an append of current buffers and virtual buffers.

@Wilfred

This comment has been minimized.

Copy link
Contributor Author

Wilfred commented Oct 18, 2016

OK, so ivy--buffer-list is only called once, and ordering is correct at that point. It's only when I start typing characters to narrow down the options that the order is not preserved.

This seems odd because my understanding of ivy-sort-functions-alist is that we shouldn't change the ordering for buffers.

Edit: strike that, ivy-sort-functions-alist seems to be for the initial sort. I think the function I'm interested in is ivy--filter.

@Wilfred

This comment has been minimized.

Copy link
Contributor Author

Wilfred commented Oct 18, 2016

I think the problem might be this line in ivy--filter:

(setq ivy--old-cands (ivy--sort name cands))

This seems to be putting package.json first in the list of candidates, even though it's a virtual buffer. Changing this line to:

(setq ivy--old-cands cands)

Fixes the issue. Is this a reasonable patch? Assuming the data is sorted anyway, sorting when filtering seems redundant.

@abo-abo

This comment has been minimized.

Copy link
Owner

abo-abo commented Oct 18, 2016

Likely the issue with ivy--regex-fuzzy and flx: flx doesn't care if a buffer is virtual or not when sorting.

@Wilfred

This comment has been minimized.

Copy link
Contributor Author

Wilfred commented Oct 19, 2016

I have a stupid question: why does ivy--filter sort at all?

Edit: oh, I see. ivy-sort-function-buffer prefers prefix matches first.

For what it's worth, I don't have flx installed, so I don't end up using ivy--flx-sort. It's ivy-sort-function-buffer that seems to not be preserving virtual buffer ordering.

@Wilfred Wilfred changed the title ivy-switch-buffer: consider putting virtual buffers *after* open buffers ivy-switch-buffer: filtering does not preserve virtual buffer ordering Oct 19, 2016

@Wilfred

This comment has been minimized.

Copy link
Contributor Author

Wilfred commented Oct 19, 2016

Aha, I think I see the problem. I have the following in my init.el:

(setq uniquify-buffer-name-style 'post-forward-angle-brackets)

This means that the virtual buffer name is just package.json, whereas the existing buffers have prefixes: eslint/package.json and so on. Since ivy-sort-function-buffer prefers a prefix match, it is prioritising the virtual buffer name over the uniquified buffer name.

@abo-abo

This comment has been minimized.

Copy link
Owner

abo-abo commented Oct 20, 2016

Can you make a generic fix for uniquify? Patches welcome.
Otherwise, you can adjust your ivy-sort-matches-functions-alist setting.

@Wilfred

This comment has been minimized.

Copy link
Contributor Author

Wilfred commented Oct 21, 2016

I'm not sure what the ideal behaviour is, really. Uniquify appending text seems to be in conflict with preferring prefix matches.

How would you feel about a patch to ivy-sort-function-buffer that ensures virtual buffers are always last?

Alternatively, I'm very happy just to set ivy-sort-matches-functions-alist if you think this is all too much of a corner case to be worth handling.

@abo-abo

This comment has been minimized.

Copy link
Owner

abo-abo commented Oct 21, 2016

How would you feel about a patch to ivy-sort-function-buffer that ensures virtual buffers are always last?

Sounds good.

Wilfred added a commit to Wilfred/swiper that referenced this issue Oct 29, 2016

@abo-abo abo-abo closed this in 74d83ab Oct 29, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.