radian-software / prescient.el

☄️ Simple but effective sorting and filtering for Emacs.
MIT License
604 stars 25 forks source link

Support function as the value of prescient-filter-method #110

Closed peterstuart closed 3 years ago

peterstuart commented 3 years ago

Fixes #83. The use case is to be able to use different filter methods depending on the type of completions. I am testing this with the following config:

(defun ps/filter-method ()
  (let ((completion-category
         (completion-metadata-get
          (completion-metadata (minibuffer-contents)
                               minibuffer-completion-table
                               minibuffer-completion-predicate)
          'category)))
    (cond ((eql completion-category 'file)          '(fuzzy))
          ((eql completion-category 'command)       '(fuzzy))
          ((eql completion-category 'consult-multi) '(fuzzy))
          (t                                        '(literal regexp initialism)))))

(setq prescient-filter-method 'ps/filter-method)

I am an elisp beginner—hopefully I've done this correctly 😄

okamsn commented 3 years ago

Does this work with the toggling commands in the Selectrum-Prescient package?

peterstuart commented 3 years ago

@okamsn Whoops, no—I was not familiar with that feature. I just added a commit which makes it work with the selectrum-prescient-toggle-* functions.

okamsn commented 3 years ago

@okamsn Whoops, no—I was not familiar with that feature. I just added a commit which makes it work with the selectrum-prescient-toggle-* functions.

Thank you. This seems to work for me.

Maybe, in addition to allowing the function value and the flat list it is currently, it might also make sense to just allow prescient-filter-method to be an association list? What are your thoughts on this, @raxod502?

That way, instead of everyone needing to copy a function like that which @peterstuart has written, they could just do

(setq prescient-filter-method 
      '((file          . (fuzzy))
        (command       . (fuzzy))
        (consult-multi . (fuzzy))
        (t             . (literal regexp initialism))))

where the key is the completion category and the value is a symbol or list of symbols.

Or, if one wanted to mimic completion-category-overrides, then one could also do something like

(setq prescient-filter-method 
      '((file    . ((style     . (fuzzy))
                    (case-fold . nil)
                    (char-fold . t)))
        (command . ((full-matches-first . t)))
        (t       . ((style     . (literal regexp initialism))
                    (case-fold . smart)))))

which could also locally bind the variables prescient-use-char-folding, prescient-use-case-folding, and prescient-sort-full-matches-first.

raxod502 commented 3 years ago

Maybe, in addition to allowing the function value and the flat list it is currently, it might also make sense to just allow prescient-filter-method to be an association list?

I see the motivation for this, but I'd prefer not to do that at this time. I think that depending on the user's Emacs configuration there are quite a few potentially reasonable different ways to determine what the "current completion context" is, and I don't really want to tie prescient.el to one of them officially.

That said, I remember there was discussion about this in the Selectrum project where I took a similar position---did you end up finding a reasonable solution that was deemed not too fragile to endorse officially?

okamsn commented 3 years ago

That said, I remember there was discussion about this in the Selectrum project where I took a similar position---did you end up finding a reasonable solution that was deemed not too fragile to endorse officially?

Not that I recall. Re-reading the discussions, it doesn't look like any option was found to be the clear best.

My understanding of things is that packages like Consult, Embark, and Marginalia make good use of the "completion category" metadata, which might or might not encourage its use in other places. There's also the new variable current-minibuffer-command, which is similar to this-command.

I see the motivation for this, but I'd prefer not to do that at this time. I think that depending on the user's Emacs configuration there are quite a few potentially reasonable different ways to determine what the "current completion context" is, and I don't really want to tie prescient.el to one of them officially.

I understand. Hopefully a clear best approach arises in the future.

aspiers commented 1 year ago

That said, I remember there was discussion about this in the Selectrum project where I took a similar position---did you end up finding a reasonable solution that was deemed not too fragile to endorse officially?

Not that I recall. Re-reading the discussions, it doesn't look like any option was found to be the clear best.

The discussion (or at least some of it) was actually in this project:

https://github.com/radian-software/prescient.el/issues/83#issuecomment-749530731

My understanding of things is that packages like Consult, Embark, and Marginalia make good use of the "completion category" metadata, which might or might not encourage its use in other places. There's also the new variable current-minibuffer-command, which is similar to this-command.

I see the motivation for this, but I'd prefer not to do that at this time. I think that depending on the user's Emacs configuration there are quite a few potentially reasonable different ways to determine what the "current completion context" is, and I don't really want to tie prescient.el to one of them officially.

I understand. Hopefully a clear best approach arises in the future.

As reported in #146 just now, I haven't yet found any workable solution for my needs based on the above.