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

Complete without snippet expansion

Open Shatur opened this issue 2 years ago • 14 comments

I have a question. Is it possible to confirm completion without snippet expansion by a custom shortcut (using <C-CR>, for example)?

I.e. when completing a function: изображение Insert it like this: изображение Instead of this: изображение

Because I trying to pass a function into another function.

Shatur avatar Jun 16 '22 10:06 Shatur

I thought this feature was feasible with the current feature set, but the perfect solution seems difficult.

Therefore, it is necessary to add a function. Note that this feature is a bit special. nvim-cmp has carefully created the "text inserted when selecting an item", but in some cases it is not perfect.

google translated

hrsh7th avatar Jun 18 '22 17:06 hrsh7th

What I want to say is that nvim-cmp implements the text state after "expand" as the server intended, but the text state at the time of selection is not always perfect. ..

hrsh7th avatar Jun 18 '22 17:06 hrsh7th

As a workaround i press Ctrl+n - it inserts function name without substituting arguments. But it gets problematic when there is a single completion item or the item I need is preselected (via rust magic completion, for example). In this case I press Ctrl+n and then Ctrl+p. Not very convenient, but better then nothing.

Shatur avatar Jun 18 '22 17:06 Shatur

Maybe I can create a hacky workaround by sending Ctrl+n with Ctrl+p to use just in my configuration?

Shatur avatar Jun 18 '22 17:06 Shatur

Yes. <C-n><C-p> combo can be usable as workaround. But you have to write some codes.

hrsh7th avatar Jun 18 '22 17:06 hrsh7th

It's may work for you.

      ['<C-j>'] = function()
        local active = cmp.get_active_entry()
        if active then
          return cmp.close()
        end
        local next = '<Cmd>lua require("cmp").select_next_item()<CR>'
        local prev = '<Cmd>lua require("cmp").select_prev_item()<CR>'
        local close = '<Cmd>lua require("cmp").close()<CR>'
        vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(next .. prev .. close, true, true, true), 'n', true)
      end,

hrsh7th avatar Jun 18 '22 17:06 hrsh7th

Could you help me with this a little bit?

Thank you!

Can I make this work when an item was selected? It inserts messed text If I comment out the check for active.

Shatur avatar Jun 18 '22 17:06 Shatur

Example: изображение изображение

Shatur avatar Jun 18 '22 18:06 Shatur

Reluctantly, I needed vim.schedule to make it work. The nvim-cmp mapping process needs to be refactored. Anyway, I think the following implementation works.

      ['<C-j>'] = function()
        local active = cmp.get_active_entry()
        if active then
          return cmp.close()
        end
        local selected = cmp.get_selected_entry()
        if not selected then
          cmp.select_next_item()
        else
          cmp.select_next_item()
          cmp.select_prev_item()
        end
        vim.schedule(function()
          cmp.close()
        end)
      end,

hrsh7th avatar Jun 18 '22 18:06 hrsh7th

Hm... It inserts wrong item for me:

изображение изображение

Shatur avatar Jun 18 '22 18:06 Shatur

@hrsh7th sorry for the ping, but I think I know why the solution doesn't work for me. Executing cmp.select_prev_item() and cmp.select_next_item() in sequence actually results only in the first action. I assume it somehow related to schedule too?

Shatur avatar Aug 20 '22 17:08 Shatur

hrsh7th's solution also didn't work for me. Eventually I foud workaround, by remapping Up/Down keys by cmp.select_next_item() / cmp.select_prev_item() ( similar to C-n and C-p ) and pressing Escape keeps the signature without snippet.

 opts.mapping['<Down>'] = cmp.mapping(function(fallback)
                if cmp.visible() then
                    cmp.select_next_item()
                else
                    fallback()
                end
            end
            , {"i", "c"})
        opts.mapping['<Up>'] = cmp.mapping(function(fallback)
                if cmp.visible() then
                    cmp.select_prev_item()
                else
                    fallback()
                end
            end
            , {"i", "c"})

alexveden avatar Jun 07 '23 09:06 alexveden

hrsh7th's solution also didn't work for me. Eventually I foud workaround, by remapping Up/Down keys by cmp.select_next_item() / cmp.select_prev_item() ( similar to C-n and C-p ) and pressing Escape keeps the signature without snippet.

 opts.mapping['<Down>'] = cmp.mapping(function(fallback)
                if cmp.visible() then
                    cmp.select_next_item()
                else
                    fallback()
                end
            end
            , {"i", "c"})
        opts.mapping['<Up>'] = cmp.mapping(function(fallback)
                if cmp.visible() then
                    cmp.select_prev_item()
                else
                    fallback()
                end
            end
            , {"i", "c"})

what's the difference of type C-n C-p and esc as mentioned above?

xzbdmw avatar Mar 04 '24 21:03 xzbdmw

I think a workaround in snippet engine can help:

            snippet = {
                expand = function(args)
                    if not expand then
                        local function remove_bracket_contents(input)
                            local pattern = "^(.*)%b().*$"
                            local result = string.gsub(input, pattern, "%1")
                            return result
                        end
                        args.body = remove_bracket_contents(args.body)
                        expand = true
                    end
                    require("luasnip").lsp_expand(args.body)
                end,
            },
                ["<D-b>"] = cmp.mapping(function()
                    if cmp.visible then
                        expand = false
                        cmp.confirm()
                    end
                end),

xzbdmw avatar Mar 24 '24 11:03 xzbdmw