Exafunction / codeium.nvim

A native neovim extension for Codeium
MIT License
658 stars 50 forks source link

This doesn't show multiline suggestions #40

Closed TroySigX closed 1 year ago

TroySigX commented 1 year ago

It need it to suggest the whole function (Codeium can do it), but this plugin only suggests 1 line at a time.

jcdickinson commented 1 year ago

I will look into this when I have time.

zettlrobert commented 1 year ago

@TroySigX

The plugin already provides completion suggestions, but you need to select one of them, to preview more than one line.

To enable this functionality, completion source has to be setup, as described in the readme.

In addition, you need to configure Neovim's completopt option accordingly. Assuming you have an options table that you iterate over, you can simply add the completeopt setting to it:

completeopt = {"menuone", "noselect", "preview"}

The preview option is what you need to accomplish your goal.

For more information on the completopt option, consult Neovim documentation

:h 'completeopt'

image

TroySigX commented 1 year ago

@zettlrobert I have set the preview option, but the issue still persists.

TroySigX commented 1 year ago

FYI, here's my config:

vim.cmd([[set completeopt=menu,menuone,noselect,preview]])
require('codeium').setup({})
local has_words_before = function()
    unpack = unpack or table.unpack
    local line, col = unpack(vim.api.nvim_win_get_cursor(0))
    return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match('%s') == nil
end

local cmp = require('cmp')
cmp.setup({
    mapping = cmp.mapping.preset.insert({
    ['<C-Space>'] = cmp.mapping.complete{ reason = cmp.ContextReason.Auto },
    ['<C-e>'] = cmp.mapping.abort(),
    ['<CR>'] = cmp.mapping.confirm({ select = true }),
    ['<Tab>'] = cmp.mapping(function(fallback)
        if not cmp.select_next_item() then
            if vim.bo.buftype ~= 'prompt' and has_words_before() then
                cmp.complete()
            else
                fallback()
            end
        end
    end, { 'i', 's' }),
    ['<S-Tab>'] = cmp.mapping(function(fallback)
        if not cmp.select_prev_item() then
            if vim.bo.buftype ~= 'prompt' and has_words_before() then
                cmp.complete()
            else
                fallback()
            end
        end
    end, { 'i', 's' }),
    }),

    sources = {
        { name = 'nvim_lsp' },
        { name = 'buffer' },
        { name = 'nvim_lsp_signature_help' },
        { name = 'luasnip' },
        { name = 'codeium' },
        -- { name = 'copilot' },
    },

    snippet = {
        expand = function(args)
            require('luasnip').lsp_expand(args.body)
        end,
    },
})

cmp.setup.cmdline('/', {
    mapping = cmp.mapping.preset.cmdline(),
    sources = {
        { name = 'buffer' }
    }
})

Is there something that needs to be changed?

zettlrobert commented 1 year ago

I do not really see anything 'wrong' with your configuration, did you give the cmp wiki a look - https://github.com/hrsh7th/nvim-cmp/wiki/Menu-Appearance#menu-type?

I still think you have an issue with your completeopt please run the following and post the output:

:lua print(vim.inspect(vim.api.nvim_get_option_info("completeopt")))
TroySigX commented 1 year ago

Here's the output:

{                                                                                                                                           
  allows_duplicates = false,
  commalist = true,
  default = "menu,preview",
  flaglist = false,
  global_local = false,
  last_set_chan = -9.2233720368548e+18,
  last_set_linenr = 0,
  last_set_sid = -8,
  name = "completeopt",
  scope = "global",
  shortname = "cot",
  type = "string",
  was_set = true
}
zettlrobert commented 1 year ago

Here's the output:

{                                                                                                                                           
  allows_duplicates = false,
  commalist = true,
  default = "menu,preview",
  flaglist = false,
  global_local = false,
  last_set_chan = -9.2233720368548e+18,
  last_set_linenr = 0,
  last_set_sid = -8,
  name = "completeopt",
  scope = "global",
  shortname = "cot",
  type = "string",
  was_set = true
}

that is identical to what i would expect

sorry i do not see why it would not work for you

the only thing i can think of, is that if i am not mistaken, it is the documentation info that shows of the functin, and if that it was codeium populates you might want to add that to the mappings.

here is my cmp config

if cmp and luasnip then
  require("luasnip.loaders.from_vscode").lazy_load()

  cmp.setup({
    snippet = {
      expand = function(args)
        luasnip.lsp_expand(args.body)
      end,
    },

    mapping = cmp.mapping.preset.insert({
      ["<C-b>"] = cmp.mapping(cmp.mapping.scroll_docs(-1), { "i", "c" }),
      ["<C-f>"] = cmp.mapping(cmp.mapping.scroll_docs(1), { "i", "c" }),
      ["<C-Space>"] = cmp.mapping(cmp.mapping.complete(), { "i", "c" }),
      ["<C-y>"] = cmp.config.disable,
      ["<C-e>"] = cmp.mapping {
        i = cmp.mapping.abort(),
        c = cmp.mapping.close(),
      },
      ["<CR>"] = cmp.mapping.confirm { select = true },
      ["<Tab>"] = cmp.mapping(function(fallback)
        if cmp.visible() then
          cmp.select_next_item()
        elseif luasnip.expandable() then
          luasnip.expand()
        elseif luasnip.expand_or_jumpable() then
          luasnip.expand_or_jump()
        elseif check_backspace() then
          fallback()
        else
          fallback()
        end
      end, {
        "i",
        "s",
      }),
      ["<S-Tab>"] = cmp.mapping(function(fallback)
        if cmp.visible() then
          cmp.select_prev_item()
        elseif luasnip.jumpable(-1) then
          luasnip.jump(-1)
        else
          fallback()
        end
      end, {
        "i",
        "s",
      }),
    }),
    sources = {
      { name = "nvim_lsp" },
      { name = "nvim_lua" },
      { name = "path" },
      { name = "luasnip" },
      { name = "buffer" },
      { name = "treesitter" },
      { name = "omni" },
      { name = "nvim_lsp_signature_help" },
      { name = "conventionalcommits" },
      { name = "spell",
        option = {
          keep_all_entries = false
        } },
      { name = "calc" },
      { name = "codeium" }
    },
    confirm_opts = {
      behavior = cmp.ConfirmBehavior.Replace,
      select = false,
    },

    formatting = {
      fields = { "kind", "abbr", "menu" },
      format = function(entry, vim_item)
        vim_item.kind = string.format('%s %s', kind_icons[vim_item.kind], vim_item.kind)
        vim_item.menu = ({
          nvim_lsp = "[LSP]",
          nvim_lua = "[NVIM_LUA]",
          luasnip = "[Snippet]",
          buffer = "[Buffer]",
          path = "[Path]",
          treesitter = "[Treesitter]",
          codeium = "[AI]"
        })[entry.source.name]
        return vim_item
      end,
    },

    experimental = {
      ghost_text = true
    }
  })
end
TroySigX commented 1 year ago

Hmm, aside from formatting and additional mappings, you seem to have the exact config as me.

jcdickinson commented 1 year ago

Which version of nvim and which OS are you on?

TroySigX commented 1 year ago

I'm using nvim 0.8.3 and Endeavour OS kernel 6.2.9-arch1-1

jcdickinson commented 1 year ago

Could you try install neovim-git from AUR? I'm pretty sure that multiline worked in 0.8, but I haven't used it in a while.

TroySigX commented 1 year ago

It still doesn't work

zettlrobert commented 1 year ago

Hmm, aside from formatting and additional mappings, you seem to have the exact config as me.

Exactly, that's why i posted mine, could not think of a solution. Sorry

TroySigX commented 1 year ago

Hi, any update on this? I recently updated to nvim 0.9.0, but the issue still persists.

TroySigX commented 1 year ago

Hmm, it seems that in order to trigger codeium's multiline suggestions, I need to write a lot of characters first. Here's my case, open a cpp file and type:

void sieve(){
}

In the function body, when typing for only (first thing to do to make a sieve):

void sieve(){
    for
}

I would expect codeium to suggest the rest of the function (like codeium on browser did), but in fact, it just suggested 1-line suggestion. But then I tried typing more characters, e.g for(int:

void sieve(){
    for(int 
}

It starts working properly and suggests multiline suggestions. Is there a way to fix it?