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

Add customization to prevent swiper from displaying the whole file when initial input is empty #1908

Closed
Alexander-Shukaev opened this issue Jan 29, 2019 · 8 comments

Comments

@Alexander-Shukaev
Copy link

@Alexander-Shukaev Alexander-Shukaev commented Jan 29, 2019

swiper is a narrowing utility, there is no point in displaying the whole file when the input is empty. This is very slow on huge files and stutters Emacs. I believe a general approach would be to allow swiper to display anything (do actual search) only after a configurable/customizable number of input characters (this practice was already applied elsewhere in ivy probably and is usual for company too).

@abo-abo
Copy link
Owner

@abo-abo abo-abo commented Jan 29, 2019

very slow on huge files and stutters Emacs

You should use counsel-grep-or-swiper which circumvents this issue. It doesn't handle file-less buffers, but usually they aren't too big to freeze Emacs.

I think there's value in the current swiper UX:

  • use case 1: swiper, the thing you're looking for is close to the point, so it's displayed in the minibuffer. You can look in the minibuffer as you type.
  • use case 2: swiper with no input, then C-v, or M-< or M->.

@Alexander-Shukaev
Copy link
Author

@Alexander-Shukaev Alexander-Shukaev commented Jan 29, 2019

You should use counsel-grep-or-swiper which circumvents this issue. It doesn't handle file-less buffers, but usually they aren't too big to freeze Emacs.

I already use counsel-grep-or-swiper and it looks like the threshold is too high still. It's difficult to find the right value. The speed will also still depend on length of the lines as well.

  • use case 1: swiper, the thing you're looking for is close to the point, so it's displayed in the minibuffer. You can look in the minibuffer as you type.
  • use case 2: swiper with no input, then C-v, or M-< or M->.
  • use case 1: better only display the same portion of buffer that is already displayed in the window where swiper was invoked, until there is some input. And even better, don't display anything, just let the navigation work. That is moving to next candidate should simply move to the next line in the original window (as there is no input). Why do double rendering of what is already in the window anyway?
  • use case 2: Again navigation can still work within the window; just no need to render something that I already see anyway.

@Alexander-Shukaev
Copy link
Author

@Alexander-Shukaev Alexander-Shukaev commented Jan 29, 2019

If minibuffer could be populated asynchronously, I'm also fine with that. All I want to avoid is the rendering stutter that prevents me from immediately doing input and forces me to wait. On the side note, if grep behaves in the same way as swiper does and is more efficient (and could also be potentially invoked in a way that it would asynchronously populate minibuffer even with zero input), then why do we need the pure Emacs Lisp implementation of it (i.e. swiper) at all?

@abo-abo
Copy link
Owner

@abo-abo abo-abo commented Jan 29, 2019

You can't use grep for file-less buffers.

Pure Elisp implementation takes longer to start up, but is usually faster for filtering.

When dealing with external processes, you always have to keep track of how much process input you accept into Emacs, since that can cause lag.

For now, I prefer to keep things the way they are. I realize that something can be optimized, but we need to go about this in a smart way. I don't want to introduce new APIs/hacks/workarounds only to obsolete/rewrite them in a few months. I wouldn't mind a well thought through PR that solves this.

@Alexander-Shukaev
Copy link
Author

@Alexander-Shukaev Alexander-Shukaev commented Jan 29, 2019

Sure, I'm not proposing to do any hacks.

While talking about external processes, for example, I have the counsel-rg implementation in the first place, which works perfectly in the asynchronous mode. I can type like three spaces in the root directory / and while thousands of matches start flooding minibuffer, I can still both navigate and type freely.

Speaking about file-less buffers, this could for example be the trigger for falling back to swiper but in all other cases use grep instead. How about such customization for a quick solution? Furthermore, even for file-less buffers, we could just pipe the content to grep as well.

I think two customization options with backward compatible defaults: one for beginning the search after certain amount of input and the other one to use swiper only for file-less buffers and prefer grep otherwise should be a good compromise before we have an asynchronous implementation (if ever).

@abo-abo abo-abo closed this in 596461e Jan 29, 2019
@abo-abo
Copy link
Owner

@abo-abo abo-abo commented Jan 29, 2019

Thanks, I think the new defcustom should address your issue.

@Alexander-Shukaev
Copy link
Author

@Alexander-Shukaev Alexander-Shukaev commented Jan 29, 2019

Thanks, that's a nice generalization of that customization point. Using grep also solves the problem of having initial input limit as it requires at least 2 characters by default, which is nice, otherwise, I believe there would be the same stutter problem upon initial rendering (since it is synchronously invoked).

@abo-abo
Copy link
Owner

@abo-abo abo-abo commented Jan 29, 2019

And there's ivy-more-chars-alist already available for more customization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants