minad / cape

🦸cape.el - Completion At Point Extensions
GNU General Public License v3.0
584 stars 20 forks source link

Cape-super-capf doesn't have a normal ordering #41

Closed e190 closed 2 years ago

e190 commented 2 years ago

my config is :

  (defun kb/cape-capf-setup-c ()
      (let (result)
        (dolist (element (list
                          (cape-super-capf #'cape-keyword #'cape-dabbrev))
                        result)
          (add-to-list 'completion-at-point-functions element)))))
  :hook
  (c-mode . kb/cape-capf-setup-c)

Result of auto-completion: 图片

Manual execution of cape-Dabbrev results: 图片

I prefer the latter sort

minad commented 2 years ago

Yes, cape-super-capf affects the candidate ordering, such that the results of the different sub-capfs are not mixed. cape-super-capf is experimental as noted in the README. Anyway, if you have a patch or an idea to improve the behavior, it is welcome.

For more details, look at the code.

  1. cape-super-capf disables sorting:

https://github.com/minad/cape/blob/0a490abfbf89a24ceb148bdb8afbbd8823a2a201/cape.el#L536-L538

  1. cape-super-capf obtains the sort function of the sub tables and sorts the candidates early on:

https://github.com/minad/cape/blob/0a490abfbf89a24ceb148bdb8afbbd8823a2a201/cape.el#L547-L549

jdtsmith commented 2 years ago

The issue I suppose is how to "chain" the sort functions of the underlying tables. One idea is to create a super-sort function that allows all the underlying sort functions to have a "vote" as to sort order, and in the case of no clear majority opinion, those appearing earliest on the super-capf wins. The issue with this is that the metadata-specified sort function simply returns a sorted list, instead of specifying a pairwise sort comparison function.

If you use corfu, you can set corfu-sort-override-function to (e.g.) corfu-sort-length-alpha, to re-mix candidates from your various sources. I actually find I prefer that.

jdtsmith commented 2 years ago

One other thought: rather than hard-code #'identity (which overrides any final sort function the UI might apply), it would be helpful if cape-super-capf asked for the metadata from each of its tables, and set its sort-functions to nil if none of its underlying table specifies a sort function. Then you wouldn't need to override if the pre-sorting was a no-op.

minad commented 2 years ago

On 5/18/22 21:36, JD Smith wrote:

One other thought: rather than hard-code #'identity (which overrides any final sort function the UI might apply), it would be helpful if cape-super-capf asked for the metadata from each of its tables, and set its sort-functions to nil if none of its underlying table specifies a sort function. Then you wouldn't need to override if the pre-sorting was a no-op.

No, then we would get mixing of the tables, which I find undesirable. But we could make this configurable, such that we don't specify an identity as overall sorting function. But then we would also render the sort function of the individual tables ineffective. This needs more thought. If you come up with a good proposal and a patch, please do so. But for now I don't see a need to change anything.