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

It's not possible to filter candidates that contain a similar string more than once #88

Open
gexplorer opened this issue Jan 13, 2021 · 3 comments

Comments

@gexplorer
Copy link

When using selectrum with prescient I'm unable to find the command projectile-switch-project with the query pro pr.

My reasoning is:

  • Searching pro I expect to get all the candidates that contain pro
  • Searching pro pr I expecto to get all the candidates that contain pro and pr but in different matches

The issue seems to bee in the prescient-filter method:
https://github.com/raxod502/prescient.el/blob/42adc802d3ba6c747bed7ea1f6e3ffbbdfc7192d/prescient.el#L536

Here all the regex are matched independently so there is no way to do this.
I've created some tests to explain it better:

(require 'ert)
(require 'prescient)

(ert-deftest prescient-filter-pro ()
  (should (equal (prescient-filter "pro" '("projectile-switch-project" "projectile-ag"))
                 '("projectile-switch-project" "projectile-ag"))))

(ert-deftest prescient-filter-pro-swi ()
  (should (equal (prescient-filter "pro swi" '("projectile-switch-project" "projectile-ag")) 
                 '("projectile-switch-project"))))

(ert-deftest prescient-filter-swi-pro ()
  (should (equal (prescient-filter "swi pro" '("projectile-switch-project" "projectile-ag")) 
                 '("projectile-switch-project"))))

(ert-deftest prescient-filter-pro-swi-pro ()
  (should (equal (prescient-filter "pro swi pro" '("projectile-switch-project" "projectile-ag")) 
                 '("projectile-switch-project"))))

(ert-deftest prescient-filter-pro-pr ()
  (should (equal (prescient-filter "pro pr" '("projectile-switch-project" "projectile-ag")) 
                 '("projectile-switch-project"))))

(ert-deftest prescient-filter-crazy-query ()
  (should (equal (prescient-filter "pro swi pr sw" '("projectile-switch-project" "projectile-ag")) 
                 nil)))
@raxod502
Copy link
Member

Thanks for the detailed report. Yes, everything you said is exactly right. The reason for the current behavior is that prescient.el supports out-of-order matching by default, and with out-of-order matching it's difficult to impose the constraint that you are suggesting. I can see why you would want the behavior you describe, however, and I don't see any reason that we couldn't add a new filter method that would implement it (disabling out-of-order matching at the same time).

I think we would need to revise the interface for prescient-filter-alist functions to be more general, so that behavior like this could be implemented. We previously generalized it in #86, and need to do so again. Ideally in a way that means we don't have to change the interface a third time. I am happy to spend some time thinking about the best way to do this, if desired.

@gexplorer
Copy link
Author

Yeah, that's what I thought. that out of order matching was the reason for this behavior. I've been thinking about a solution so I'd be happy to lend a hand. Have you thought about adding testing?

@raxod502
Copy link
Member

I of course have no objection to adding testing, but have not so far simply because the package in the past was not very complex. It seems to be growing in complexity, and might therefore warrant some tests being added.

I will admit, embarrassingly enough, that almost all the tests in my packages have been added by other people thus far. You could look at radian-software/straight.el#603 and radian-software/apheleia#26 for some examples.

In terms of the approach, I am thinking it would make sense for a filter function to get all of the information that could be needed, in a simple format without preprocessing or postprocessing. There would then be some duplicated code between all the filter functions, which could be eliminated by providing a utility function that would "do the normal thing" (with out of order matching and such) given a regexp generator like we have in our current filter functions.

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

No branches or pull requests

2 participants