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

Source priority customization per each source #156

Closed
fenuks opened this issue Sep 5, 2021 · 9 comments
Closed

Source priority customization per each source #156

fenuks opened this issue Sep 5, 2021 · 9 comments

Comments

@fenuks
Copy link

fenuks commented Sep 5, 2021

Hello, I'm switching from nvim-compe, and got most things working, really great work, with exception for sorting that would behave the way I would like.

I've browsed default configuration and comparers, and I have few suggestions.

Score is documented to be computed as score = score + ((#sources - (source_index - 1)) * sorting.priority_weight). This is fine, but I think it would be nice if one could override ((#sources - (source_index - 1)) by providing value in sources, like so:

    sources = {
      { name = 'nvim_lsp' , score = 3},
      { name = 'path' , score = 3},
      { name = 'spell' , score = 0},

That would allow assigning same base score for different sources.

completion-nvim allows specifying which kinds within LSP should have the highest priority, e.g.:

vim.g.completion_items_priority = {
  Field = 11,
  Method = 10,
  Property = 9,
  Function = 7,
  Variables = 6,
  Struct = 6,
  Interfaces = 6,
  Constant = 6,
  Class = 6,
  Keyword = 5,
  Treesitter = 4,
  File = 2,
  Buffers = 0,

That also allows disabling items that are not wanted (e.g. snippets) from showing in completion menu.

Currently, compare.kind hardcodes which kind is considered most important (snippets). Personally, I would prefer suggestions to be first sorted on source (LSP suggestion always first), then on kinds (fields from LSP always on top), and then alphabetically (fields should be ordered in ascending order). That would be possible if comparers worked like stable sorting. In such case comparators = [compare.sort_text, compare.kind, compare.score]. I suppose that with current method of ordering, composing functions the best I can do is writing something like sort_combined, and set comparators = [sort_combined]?

@hrsh7th
Copy link
Owner

hrsh7th commented Sep 6, 2021

Yes. If you want to full customize sorting aloghrithm, You should specify sorting.comparators = [function(entry1, entry2) return ... end].

Hm... assigning the same priority (to the part of source) is impossible in current nvim-cmp.
This can have worth considering, I think.

@fenuks
Copy link
Author

fenuks commented Sep 6, 2021

And do you think about adding priority to the kinds as well akin to what is possible in completion-nvim? I think it could be useful for those wanting to change order of kinds without having to write own 'compare_kind` function, especially if you want to have different kind order for different buffers/languages.

@hrsh7th
Copy link
Owner

hrsh7th commented Sep 6, 2021

I have no plan to implement the kind's priority.
I think it should be realized by the comparators.

@fenuks
Copy link
Author

fenuks commented Sep 6, 2021

I also think it should be done with comparators. I will write it for myself (with option to configure it with global variable or partial function application). In case that would be useful for others, I could make MR later.

@hrsh7th
Copy link
Owner

hrsh7th commented Sep 6, 2021

I dislike modifying global variables for configuration. the partial function application can be acceptable but it might be depending on the API.

I am confused.
The user wants to customize in detail but theirs doesn't want to write a function...

I think your can create a new custom plugin like cmp-sorting-vscode.

require'cmp'.setup {
  sorting = {
    comparators = require'cmp-sorting-vscode'
  }
}

@fenuks
Copy link
Author

fenuks commented Sep 6, 2021

I am confused.
The user wants to customize in detail but theirs doesn't want to write a function...

I have nothing against writing own functions, but obviously it's best if relatively common things could be achieved as simple as possible. Writing functions requires some understanding how things work under the hood. I might be wrong, but I believe that adjusting sorting by kind is what many people will attempt to do.

I think the users can provides custom plugin like cmp-sorting-vscode.

Thank you, I will try to write something like that.

I think the issue can be closed if you don't want to keep it as reminder of assigning same score to completion sources.

@hrsh7th hrsh7th changed the title Feedback on configuration Source priority customization per each source Sep 8, 2021
@nikklassen
Copy link

nikklassen commented Sep 8, 2021

First of all, love the new plugin, I'm finding much better completion behaviour vs nvim-compe (and of course better than the other plugins ;) )

I've been customizing a bit and I just finished customizing my language server's comparators, so I thought I'd add a note here.

The main language server I use is proprietary, and does its own prioritization. The first result coming back is what the server says is "best", basically I just need comparators = {compare.order} for this server. But I assume other language servers aren't this good. I would like to see the ability to set different comparators for different servers.

Sorry if this is a bit off topic, I can open another feature request.

@fenuks
Copy link
Author

fenuks commented Sep 9, 2021

The main language server I use is proprietary, and does its own prioritization. The first result coming back is what the server says is "best", basically I just need comparators = {compare.order} for this server. But I assume other language servers aren't this good. I would like to see the ability to set different comparators for different servers.

It is possible to configure cmp per language with autocommands, and I guess you could write comparator that behaves differently depending on the server, though I'm not sure if you get the server name in the entry.

Just in case everybody wanted to achieve something similar to what I was discussing here, I wrote comparators that seem to do the trick (I can make a pull request if they are deemed generally useful).

  local lspkind_comparator = function(conf)
    local lsp_types = require('cmp.types').lsp
    return function(entry1, entry2)
      if entry1.source.name ~= 'nvim_lsp' then
        if entry2.source.name == 'nvim_lsp' then
          return false
        else
          return nil
        end
      end
      local kind1 = lsp_types.CompletionItemKind[entry1:get_kind()]
      local kind2 = lsp_types.CompletionItemKind[entry2:get_kind()]

      local priority1 = conf.kind_priority[kind1] or 0
      local priority2 = conf.kind_priority[kind2] or 0
      if priority1 == priority2 then
        return nil
      end
      return priority2 < priority1
    end
  end

  local label_comparator = function(entry1, entry2)
    return entry1.completion_item.label < entry2.completion_item.label
  end

You can use them in your setup like so:

      comparators = {
        lspkind_comparator({
          kind_priority = {
            Field = 11,
            Property = 11,
            Constant = 10,
            Enum = 10,
            EnumMember = 10,
            Event = 10,
            Function = 10,
            Method = 10,
            Operator = 10,
            Reference = 10,
            Struct = 10,
            Variable = 9,
            File = 8,
            Folder = 8,
            Class = 5,
            Color = 5,
            Module = 5,
            Keyword = 2,
            Constructor = 1,
            Interface = 1,
            Snippet = 0,
            Text = 1,
            TypeParameter = 1,
            Unit = 1,
            Value = 1,
          },
        }),
        label_comparator,
      },

@hrsh7th
Copy link
Owner

hrsh7th commented Sep 16, 2021

Implemented the manually specified source priority.

@hrsh7th hrsh7th closed this as completed Sep 16, 2021
Freeman-Peng pushed a commit to Freeman-Peng/workspace that referenced this issue Jul 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants