hrsh7th / nvim-cmp

A completion plugin for neovim coded in Lua.
MIT License
7.45k stars 370 forks source link

how to make tab compeletion ignore the word that already compeleted #1898

Closed zhuzy-2018 closed 2 months ago

zhuzy-2018 commented 2 months ago

2024-04-23 12-23-45屏幕截图 like the image above shows, I already triggered tab compeletion. but it won't trigger snip jump for cmp.visiable() still be true.

How can I fix this problem?? below is my setup

  opts.mapping = vim.tbl_extend("force", opts.mapping, {
    ["<Enter>"] = function(fallback)
        -- Don't block <CR> if signature help is active
        -- https://github.com/hrsh7th/cmp-nvim-lsp-signature-help/issues/13
        if not cmp.visible() or not cmp.get_selected_entry() or cmp.get_selected_entry().source.name == 'nvim_lsp_signature_help' then
            fallback()
        else
            cmp.confirm({
                -- Replace word if completing in the middle of a word
                -- https://github.com/hrsh7th/nvim-cmp/issues/664
                behavior = cmp.ConfirmBehavior.Replace,
                -- Don't select first item on CR if nothing was selected
                select = false,
            })
        end
    end,
    ["<Tab>"] = cmp.mapping(function(fallback)
      if cmp.visible() == 1 then
        cmp.select_next_item()
        -- You could replace the expand_or_jumpable() calls with expand_or_locally_jumpable()
        -- this way you will only jump inside the snippet region
      elseif luasnip.expand_or_jumpable() == 1 then
        luasnip.expand_or_jump()
      elseif has_words_before() then
        cmp.complete()
      else
        fallback()
      end
    end, { "i", "s" }),
    ["<S-Tab>"] = cmp.mapping(function(fallback)
      if cmp.visible() == 1 then
        cmp.select_prev_item()
      elseif luasnip.jumpable(-1) then
        luasnip.jump(-1)
      else
        fallback()
      end
    end, { "i", "s" }),
  })
Vanillma commented 2 months ago

2024-04-23 12-23-45屏幕截图 like the image above shows, I already triggered tab compeletion. but it won't trigger snip jump for cmp.visiable() still be true.

How can I fix this problem?? below is my setup

  opts.mapping = vim.tbl_extend("force", opts.mapping, {
    ["<Enter>"] = function(fallback)
        -- Don't block <CR> if signature help is active
        -- https://github.com/hrsh7th/cmp-nvim-lsp-signature-help/issues/13
        if not cmp.visible() or not cmp.get_selected_entry() or cmp.get_selected_entry().source.name == 'nvim_lsp_signature_help' then
            fallback()
        else
            cmp.confirm({
                -- Replace word if completing in the middle of a word
                -- https://github.com/hrsh7th/nvim-cmp/issues/664
                behavior = cmp.ConfirmBehavior.Replace,
                -- Don't select first item on CR if nothing was selected
                select = false,
            })
        end
    end,
    ["<Tab>"] = cmp.mapping(function(fallback)
      if cmp.visible() == 1 then
        cmp.select_next_item()
        -- You could replace the expand_or_jumpable() calls with expand_or_locally_jumpable()
        -- this way you will only jump inside the snippet region
      elseif luasnip.expand_or_jumpable() == 1 then
        luasnip.expand_or_jump()
      elseif has_words_before() then
        cmp.complete()
      else
        fallback()
      end
    end, { "i", "s" }),
    ["<S-Tab>"] = cmp.mapping(function(fallback)
      if cmp.visible() == 1 then
        cmp.select_prev_item()
      elseif luasnip.jumpable(-1) then
        luasnip.jump(-1)
      else
        fallback()
      end
    end, { "i", "s" }),
  })

I don't know where the problem is, but one part of your code confused me, the cmp.visible() function returns true or false... no need to compare it to 1 :)

:h cmp.visible() cmp.visible () Return a boolean showing whether the completion menu is visible or not.

For example, I use it like this and it works

    ['<Left>'] = {
      ---> Disable in Insert Mode. <---
      i = cmp.config.disable,
      ---> Active in Command Mode. <---
      c = function(fallback)
        ---> If List was Open. <---
        if cmp.visible() then
          ---> Go to Prev Item. <---
          cmp.select_prev_item();
        else
          ---> Back to Default Key. <---
          fallback();
        end
      end
    },

In Lua language, zero and one are evaluated as true. www.lua.org: Beware that, unlike some other scripting languages, Lua considers both zero and the empty string as true in conditional tests.

zhuzy-2018 commented 2 months ago

Beware that, unlike some other scripting languages, Lua considers both zero and the empty string as true in conditional tests.

that's the reason why I compare it to one for I've seen a post that said the same thing. So, in case the function doesn't return the standard boolean, I compare it to one. After investigating, I discovered that my issue was not caused by the visible() function, but by has_word_before(). Removing it resolved the problem. Thanks for replying anyway.

Vanillma commented 2 months ago

Beware that, unlike some other scripting languages, Lua considers both zero and the empty string as true in conditional tests.

that's the reason why I compare it to one for I've seen a post that said the same thing. So, in case the function doesn't return the standard boolean, I compare it to one. After investigating, I discovered that my issue was not caused by the visible() function, but by has_word_before(). Removing it resolved the problem. Thanks for replying anyway.

Glad your problem is solved...I don't understand...what other option than true or false can it return? I think that such functions are usually written in such a way that in all cases, even if part of the code in other parts is incomplete, they return a Boolean answer(false)... and only if everything goes well, the answer will be true...