Autocompletion : rank Sections based on filter matches

Would it be possible to rank Sections based on filter matches in autocompletion ?

With fixed ranking of Sections, completions with fuzzy matches may be displayed before exact matches if their Section has a lower rank. This has a very negative impact on the relevance of completions.

To address this issue, I would like to sort Sections by relevance based on the filter results:

  • Sections with exact matches, sorted by :
    • number of exact matches
    • number of fuzzy matches
    • rank
  • Sections with fuzzy matches, sorted by
    • number of fuzzy matches
    • rank

We could compute sections ranks generating completions, but this would require access to CodeMirror fuzzy match.

What would be the best approach to achieve this result?

I won’t change the default behavior here, since that will impact people’s existing use. Does attached patch, which requires you to explicitly opt in to this behavior, work for you?

Of course, changing the default behaviour would not be right.
Adding this “dynamic” option to Section”s rank is a great way to enable this feature.

The sorting will be based on the best scores, not number of matches, but it may work as well.
I’ll test it and let you know.

Thank you very much for your support and quick answer.

After fixing the build of the module, the dynamic ranking of Sections work well.

I had a few errors if the dynamic option is not disabled when filtering is disabled. (I disable filtering when there is only 1 character of input)
But this was quickly fixed by disabling this option with filtering.

Many thanks for your help.

With this test program, if I type isv, I see Section 2 above Section 1 as expected. Are you sure you’re testing with the modified code?

import {EditorView, basicSetup} from "codemirror"
import {autocompletion} from "@codemirror/autocomplete"

new EditorView({
  doc: "is",
  extensions: [basicSetup, autocompletion({
    override: [cx => {
      let word = cx.matchBefore(/\w*$/)!
      return {
        from: word.from, to: word.to,
        options: [
          {label: "isEmptyValue", section: {name: "Section 1", rank: "dynamic"}},
          {label: "isValid", section: {name: "Section 2", rank: "dynamic"}},
        ]}
    }]
  })],
  parent: document.body
})

Sorry, indeed there was an issue with the build. I corrected my message earlier. The fix works great.

Wonderful. Want me to cut a release or do you need to evaluate this a bit further to make sure it solves your use case?

From my testing it works well and could be released this way.
But I’ll need to confirm when I have received end users feedback in 1 or 2 weeks. If they do ask for more specific ranking of sections, having seen how you implemented the dynamic ranking, I think that I can adjust it to meet their requests. In any case I’ll let you know.

User testing went well.
Could you cut a release? many thanks

Absolutely. See @codemirror/autocomplete 6.19.0

Awesome. Thanks