hrsh7th / nvim-cmp

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

Compeltion is not correct when triggers smart indent. #1035

Open LimbicSys opened 2 years ago

LimbicSys commented 2 years ago

FAQ

Announcement

Minimal reproducible full config

if has('vim_starting')
  set encoding=utf-8
endif
scriptencoding utf-8

if &compatible
  set nocompatible
endif

let s:plug_dir = expand('/tmp/plugged/vim-plug')
if !filereadable(s:plug_dir .. '/plug.vim')
  execute printf('!curl -fLo %s/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim', s:plug_dir)
end

execute 'set runtimepath+=' . s:plug_dir
call plug#begin(s:plug_dir)
Plug 'hrsh7th/nvim-cmp'
Plug 'hrsh7th/cmp-buffer'
Plug 'hrsh7th/cmp-nvim-lsp'
Plug 'hrsh7th/vim-vsnip'
Plug 'neovim/nvim-lspconfig'
call plug#end()
PlugInstall | quit

" Setup global configuration. More on configuration below.
lua << EOF
local cmp = require "cmp"
cmp.setup {
  snippet = {
    expand = function(args)
      vim.fn["vsnip#anonymous"](args.body)
    end,
  },

  mapping = {
    ['<CR>'] = cmp.mapping.confirm({ select = true })
  },

  sources = {
    { name = "nvim_lsp" },
    { name = "buffer" },
  },
}
EOF

lua << EOF
local capabilities = require('cmp_nvim_lsp').update_capabilities(vim.lsp.protocol.make_client_capabilities())

require'lspconfig'.clangd.setup {
  capabilities = capabilities,
}
EOF

Description

Like #640, when the completion item is private: (or public:, protected:) in C++, the inserted text is not correct.

截屏2022-06-16 10 13 32 截屏2022-06-16 10 14 07

clangd --version Homebrew clangd version 13.0.1 Features: mac+xpc Platform: arm64-apple-darwin21.5.0

Steps to reproduce

#include <iostream>
#include <vector>

using namespace std;

class A
{
public:
    A(int aa, int bb);
private:
    int a, b;
};

Type pri at the end of class A to trigger the completion, then select private: and confirm.

Expected behavior

Code like blow:

#include <iostream>
#include <vector>

using namespace std;

class A
{
public:
    A(int aa, int bb);
private:
    int a, b;

private:
};

Actual behavior

#include <iostream>
#include <vector>

using namespace std;

class A
{
public:
    A(int aa, int bb);
private:
    int a, b;

privprivate:
};

Additional context

No response

LimbicSys commented 2 years ago

The option cindent is default on when the filetype is c or cpp. So the indent is controlled by the cinkeys instead of the indentkeys.

So setting cinkeys to an empty string temporarily should fix the problem.

local cmp = require("cmp")
local keymap = require("cmp.utils.keymap")
local feedkeys = require("cmp.utils.feedkeys")

local keymap_cinkeys = function(expr)
  return string.format(keymap.t("<Cmd>set cinkeys=%s<CR>"), expr and vim.fn.escape(expr, "| \t\\") or "")
end

local confirm = function(fallback)
   if cmp.visible() then
    feedkeys.call(keymap_cinkeys(), "n")
    cmp.confirm({ select = true })
    feedkeys.call(keymap_cinkeys(vim.bo.cinkeys), "n")
  else
    fallback()
  end
end

cmp.setup({
  mapping = {
    ["<CR>"] = cmp.mapping(confirm, { "i" })
  }
})
epheien commented 1 week ago

same issue