f3fora / cmp-spell

spell source for nvim-cmp based on vim's spellsuggest.
191 stars 3 forks source link

cmp-spell source is always first selected #10

Closed shy-robin closed 11 months ago

shy-robin commented 11 months ago

This is my cmp sources:

      sources = cmp.config.sources({
        { name = "nvim_lsp" },
        { name = "luasnip" },
        { name = "buffer" },
        { name = "spell" },
        { name = "path" },
      }),

When I input text, lsp source should be on the top of popup menu, but I got spell source first:

image

Is there something wrong with priority of spell source? When I remove spell source, I got this:

image

It seems to be normal.

pimvh commented 11 months ago

Hi! This is probably not an issue with this plugin, you can set priority of your completions like the following:

         { name = "nvim_lua", priority = 10 }, 
         { name = "nvim_lsp_signature_help", priority = 10 }, 
         { name = "path", priority = 10 },
         -- Supplementary 
         { name = "dictionary", priority = 5, max_item_count = 4, keyword_length = 2 }, 
         { 
             name = "spell", 
             priority = 5,  --                  <<<< like this
             max_item_count = 2, 
             keyword_length = 2, 
             option = { keep_all_entries = true }, 
         },

By setting the priority of spell to a lower value, the ordering should change.

shy-robin commented 11 months ago

priority = 10

Thanks for your reply. I changed the priority of sources, but it does not work.

      sources = cmp.config.sources({
        { name = "nvim_lsp", priority = 10 },
        { name = "luasnip", priority = 8 },
        { name = "buffer", priority = 6 },
        { name = "spell", priority = 4 },
        { name = "path", priority = 2 },
      }),
image
pimvh commented 11 months ago

Let's see...

I remember having this issue a while ago too, and I think editing the sorting parameter(s) helped.

I have the following sorting defined:

    sorting = {
        priority_weight = 2,
        comparators = {
            cmp.config.compare.locality,
            cmp.config.compare.recently_used,
            cmp.config.compare.score, -- final_score = orig_score + ((#sources - (source_index - 1)) * sorting.priority_weight) (priority_weight = sources[n].priority
            cmp.config.compare.offset,
            cmp.config.compare.exact,
            -- cmp.config.compare.kind,
            cmp.config.compare.sort_text,
            -- cmp.config.compare.length,
            -- cmp.config.compare.order,
        },
    },

This might work. Aside, I have nothing in my config that would change this afaik.

Please report back, it might be useful to document this for other users.

shy-robin commented 11 months ago

Let's see...

I remember having this issue a while ago too, and I think editing the sorting parameter(s) helped.

I have the following sorting defined:

    sorting = {
        priority_weight = 2,
        comparators = {
            cmp.config.compare.locality,
            cmp.config.compare.recently_used,
            cmp.config.compare.score, -- final_score = orig_score + ((#sources - (source_index - 1)) * sorting.priority_weight) (priority_weight = sources[n].priority
            cmp.config.compare.offset,
            cmp.config.compare.exact,
            -- cmp.config.compare.kind,
            cmp.config.compare.sort_text,
            -- cmp.config.compare.length,
            -- cmp.config.compare.order,
        },
    },

This might work. Aside, I have nothing in my config that would change this afaik.

Please report back, it might be useful to document this for other users.

I use this config and it can change the order of sources. But there is another problem, when I input something, it will choose the cmp-spell source automatically, but not the first suggestion. image

pimvh commented 11 months ago

Let's see...

I remember having this issue a while ago too, and I think editing the sorting parameter(s) helped.

I have the following sorting defined:

    sorting = {
        priority_weight = 2,
        comparators = {
            cmp.config.compare.locality,
            cmp.config.compare.recently_used,
            cmp.config.compare.score, -- final_score = orig_score + ((#sources - (source_index - 1)) * sorting.priority_weight) (priority_weight = sources[n].priority
            cmp.config.compare.offset,
            cmp.config.compare.exact,
            -- cmp.config.compare.kind,
            cmp.config.compare.sort_text,
            -- cmp.config.compare.length,
            -- cmp.config.compare.order,
        },
    },

This might work. Aside, I have nothing in my config that would change this afaik.

Please report back, it might be useful to document this for other users.

I use this config and it can change the order of sources. But there is another problem, when I input something, it will choose the cmp-spell source automatically, but not the first suggestion. image

Have you set the options in the cmp completion source, for example the attribute where it keeps all entries? (see above)

shy-robin commented 11 months ago

@pimvh This is my nvim-cmp config (I use lazy.nvim):

return {
  "hrsh7th/nvim-cmp",
  dependencies = {
    "hrsh7th/cmp-nvim-lsp",
    "hrsh7th/cmp-buffer",
    "hrsh7th/cmp-path",
    "saadparwaiz1/cmp_luasnip",
    "hrsh7th/cmp-cmdline",
    "f3fora/cmp-spell"
  },
  opts = function()
    local defaults = require("cmp.config.default")()
    local cmp = require("cmp")

    -- `/` cmdline setup.
    ---@diagnostic disable-next-line: missing-fields
    cmp.setup.cmdline('/', {
      window = {
        completion = cmp.config.window.bordered(),
        documentation = cmp.config.window.bordered(),
      },
      mapping = cmp.mapping.preset.cmdline(),
      sources = {
        { name = 'buffer' }
      }
    })

    -- `:` cmdline setup.
    ---@diagnostic disable-next-line: missing-fields
    cmp.setup.cmdline(':', {
      window = {
        completion = cmp.config.window.bordered(),
        documentation = cmp.config.window.bordered(),
      },
      mapping = cmp.mapping.preset.cmdline(),
      sources = cmp.config.sources({
        { name = 'path' }
      }, {
        {
          name = 'cmdline',
          option = {
            ignore_cmds = { 'Man', '!' }
          }
        }
      })
    })

    return {
      window = {
        completion = cmp.config.window.bordered(),
        documentation = cmp.config.window.bordered(),
      },
      completion = {
        completeopt = "menu,menuone,noinsert",
      },
      snippet = {
        expand = function(args)
          require("luasnip").lsp_expand(args.body)
        end,
      },
      mapping = cmp.mapping.preset.insert({
        ["<C-j>"] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }),
        ["<C-k>"] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }),
        ["<C-u>"] = cmp.mapping.scroll_docs(-4),
        ["<C-d>"] = cmp.mapping.scroll_docs(4),
        ["<C-Space>"] = cmp.mapping.complete(),
        ["<C-e>"] = cmp.mapping.abort(),
        ["<Tab>"] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
        ["<CR>"] = cmp.mapping.confirm({ select = false }),
        ["<S-CR>"] = cmp.mapping.confirm({
          behavior = cmp.ConfirmBehavior.Replace,
          select = true,
        }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
      }),
      sources = cmp.config.sources({
        { name = "nvim_lsp", priority = 10 },
        { name = "luasnip",  priority = 8 },
        { name = "buffer",   priority = 6 },
        { name = "spell",    priority = 4 },
        { name = "path",     priority = 2 },
      }),
      formatting = {
        format = function(entry, item)
          local icons = require("lazyvim.config").icons.kinds
          if icons[item.kind] then
            item.kind = icons[item.kind] .. item.kind
            item.menu = ({
              nvim_lsp = "[LSP]",
              luasnip = "[Snippet]",
              buffer = "[Buffer]",
              spell = "[Spell]",
              path = "[Path]"
            })[entry.source.name]
          end
          return item
        end,
      },
      sorting = {
        priority_weight = 2,
        comparators = {
          cmp.config.compare.locality,
          cmp.config.compare.recently_used,
          cmp.config.compare.score,   -- final_score = orig_score + ((#sources - (source_index - 1)) * sorting.priority_weight) (priority_weight = sources[n].priority
          cmp.config.compare.offset,
          cmp.config.compare.exact,
          -- cmp.config.compare.kind,
          cmp.config.compare.sort_text,
          -- cmp.config.compare.length,
          -- cmp.config.compare.order,
        },
      },
    }
  end,
}

I have tried to remove cmp-spell source, and the problem is still exist. Maybe the sorting method is the main reason. image

f3fora commented 11 months ago

The current implementation selects an entry if the spell is correct.

The first "preselectable" item in the source with the highest priority get selected. You can disable preselect in nvim-cmp options: :h cmp-config.preselect, e.g.,


cmp.setup(
{
preselect = cmp.PreselectMode.None
}
)
shy-robin commented 11 months ago

@f3fora Thanks a lot. It works.