copilot-cmp icon indicating copy to clipboard operation
copilot-cmp copied to clipboard

nvim-cmp crash, error "'start' is higher than 'end' " on selecting copilot item

Open Rhymond opened this issue 2 years ago • 11 comments

When I select a Copilot generated item, I encounter an error and nvim-cmp crashes with the error mentioned below. It looks like cmp tries to replace the entire line. However, I think that when my cursor is at the end of the line, it causes the cmp to crash and returns an error (this is just my wild guess).

Here is a video demonstrating the issue being replicated: https://cln.sh/t6z8MwwN4YXHVDcMyTYr

cmp error:

E5108: Error executing lua ...lauskas/.local/share/nvim/lazy/nvim-cmp/lua/cmp/core.lua:396: 'start' is higher than 'end'                                                                     
stack traceback:                                                                                                                                                                             
        [C]: in function 'nvim_buf_set_text'                                                                                                                                                 
        ...lauskas/.local/share/nvim/lazy/nvim-cmp/lua/cmp/core.lua:396: in function <...lauskas/.local/share/nvim/lazy/nvim-cmp/lua/cmp/core.lua:384>                                       
        ...ocal/share/nvim/lazy/nvim-cmp/lua/cmp/utils/feedkeys.lua:47: in function <...ocal/share/nvim/lazy/nvim-cmp/lua/cmp/utils/feedkeys.lua:45> 

cmp configuration

local luasnip = require("luasnip")
local cmp = require("cmp")

local has_words_before = function()
    if vim.api.nvim_buf_get_option(0, "buftype") == "prompt" then return false end
    local line, col = unpack(vim.api.nvim_win_get_cursor(0))
    return col ~= 0 and vim.api.nvim_buf_get_text(0, line - 1, 0, line - 1, col, {})[1]:match("^%s*$") == nil
end

cmp.setup({
    snippet = {
        expand = function(args)
            require('luasnip').lsp_expand(args.body) -- For `luasnip` users.
        end,
    },
    window = {
        documentation = cmp.config.window.bordered()
    },
    mapping = cmp.mapping.preset.insert({
        ['<C-b>'] = cmp.mapping.scroll_docs(-4),
        ['<C-f>'] = cmp.mapping.scroll_docs(4),
        ['<C-Space>'] = cmp.mapping.complete(),
        ['<C-e>'] = cmp.mapping.abort(),
        ['<CR>'] = cmp.mapping.confirm({
            behavior = cmp.ConfirmBehavior.Replace,
            select = false,
        }),
        ["<Tab>"] = vim.schedule_wrap(function(fallback)
            if cmp.visible() and has_words_before() then
                cmp.select_next_item({ behavior = cmp.SelectBehavior.Select })
            else
                fallback()
            end
            -- if cmp.visible() then
            --     cmp.select_next_item()
            -- elseif luasnip.expand_or_jumpable() then
            --     luasnip.expand_or_jump()
            -- elseif has_words_before() then
            --     cmp.complete()
            -- else
            --     fallback()
            -- end
        end, { "i", "s" }),

        ["<S-Tab>"] = vim.schedule_wrap(function(fallback)
            if cmp.visible() and has_words_before() then
                cmp.select_prev_item({ behavior = cmp.SelectBehavior.Select })
            else
                fallback()
            end
        end, { "i", "s" }),
    }),
    sources = cmp.config.sources({
        { name = "copilot", group_index = 2 },
        { name = 'nvim_lsp' },
        { name = 'luasnip' },
        -- { name = 'buffer' },
        { name = 'path' },
        -- { name = 'cmdline' },
    }),
    formatting = {
        format = function(entry, item)
            local menu_icon = {
                nvim_lsp = 'L',
                luasnip = 'S',
                buffer = 'B',
                path = 'P',
            }

            item.menu = menu_icon[entry.source.name]
            return item
        end,
    }
})

copilot settings

    require("copilot").setup({
        suggestion = { enabled = false },
        panel = { enabled = false },
    })

    require("copilot_cmp").setup()

I'm not sure if the issue lies with nvim-cmp or copilot-cmp package. However, I cannot reproduce the same error with other cmp selections.

Rhymond avatar Jul 05 '23 09:07 Rhymond

Running into this as well.

rsarv3006 avatar Jul 11 '23 17:07 rsarv3006

I'm having the same issue, however, it's always on the third time I select something.

sommerper avatar Jul 16 '23 10:07 sommerper

I haven't run into this, but I would guess it has to do with completion insert and replace ranges since I've seen similar errors when experimenting with those. Try out #92

zbirenbaum avatar Sep 07 '23 11:09 zbirenbaum

Still encounter same issue It happens every time when I try to edit fields of golang structs

ivanlee1999 avatar Nov 07 '23 20:11 ivanlee1999

Same here, with golang structs.

palcalde avatar Dec 14 '23 22:12 palcalde

Running into this same problem.

mahmoudk1000 avatar Mar 07 '24 13:03 mahmoudk1000

This crashes the nvim-cmp completely. It's a huge bummer in my workflow and I have no idea how to fix it (tried various options).

Same problem with golang structs.

fira42073 avatar Jun 21 '24 11:06 fira42073

I have the same problem.

Mostly happens in Golang.

k1ng440 avatar Jun 26 '24 02:06 k1ng440

I wonder how it can be fixed. Any advice on where to look? I'd fix it myself, but I don't have a lot of experience with lua, except doing minor fixes in my own config. Thanks in advance!

fira42073 avatar Jun 27 '24 12:06 fira42073

As a fairly reproducible example for me, create a file with the following Go code

package main

type Test struct {
	Name string `json:"name,omitempty"`
	Age  int    `json:"age"`
}

Go to Age field, and delete the backtick, there will be a suggestion to add the omitempty to the json definition.

Cmp will crash, and some wierdness goes on where the code is collapsed into one line

tris203 avatar Jul 09 '24 22:07 tris203

PR to CMP above that seems to fix this issue for me

tris203 avatar Jul 11 '24 16:07 tris203