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

After input if snippet, some words repeat. [Java specified]

Open boning-w opened this issue 2 years ago • 9 comments

FAQ

  • [X] I have checked the FAQ and it didn't resolve my problem.

Issues

  • [X] I have checked existing issues and there are no open or closed issues with the same problem.

Neovim Version

NVIM v0.6.1

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-path'
Plug 'hrsh7th/cmp-cmdline'
Plug 'hrsh7th/cmp-nvim-lsp'
Plug 'hrsh7th/vim-vsnip'
Plug 'hrsh7th/cmp-vsnip'
Plug 'neovim/nvim-lspconfig'
Plug 'lukas-reineke/cmp-under-comparator'
call plug#end()
PlugInstall | quit

" Setup global configuration. More on configuration below.
lua << EOF
local has_words_before = function()
  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 feedkey = function(key, mode)
  vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true)
end

local cmp = require "cmp"
local cmp_under_comparator = require("cmp-under-comparator")
cmp.setup {
  snippet = {
    expand = function(args)
      vim.fn["vsnip#anonymous"](args.body) 
    end,
  },
  sources = cmp.config.sources({
    { name = "nvim_lsp" },
    { name = "vsnip" },
  }, {
    { name = "buffer" },
  }),
  sorting = {
    comparators = {
      cmp.config.compare.offset,
      cmp.config.compare.exact,
      cmp.config.compare.score,
      cmp_under_comparator.under,
      cmp.config.compare.kind,
      cmp.config.compare.sort_text,
      cmp.config.compare.length,
      cmp.config.compare.order,
    },
  },
  mapping = {
    ["<C-Space>"] = cmp.mapping.complete(),
    ["<C-e>"] = cmp.mapping({
      i = cmp.mapping.abort(),
      c = cmp.mapping.close(),
    }),
    ["<CR>"] = cmp.mapping.confirm({ select = false }),
    ["<Tab>"] = cmp.mapping(function(fallback)
      if cmp.visible() then
        cmp.select_next_item()
      elseif vim.fn["vsnip#available"](1) == 1 then
        feedkey("<Plug>(vsnip-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() then
        cmp.select_prev_item()
      elseif vim.fn["vsnip#jumpable"](-1) == 1 then
        feedkey("<Plug>(vsnip-jump-prev)", "")
      else
        fallback()
      end
    end, { "i", "s" }),
  },
}
EOF

lua << EOF
local home = vim.fn.getenv("HOME")
local capabilities = require('cmp_nvim_lsp').update_capabilities(vim.lsp.protocol.make_client_capabilities())

require("lspconfig").jdtls.setup {
  capabilities = capabilities,
  cmd = {
    "java",
    "-Declipse.application=org.eclipse.jdt.ls.core.id1",
    "-Dosgi.bundles.defaultStartLevel=4",
    "-Declipse.product=org.eclipse.jdt.ls.core.product",
    "-Dlog.protocol=true",
    "-Dlog.level=ALL",
    "-Xms1g",
    "--add-modules=ALL-SYSTEM",
    "--add-opens",
    "java.base/java.util=ALL-UNNAMED",
    "--add-opens",
    "java.base/java.lang=ALL-UNNAMED",
    "-jar",
    home .. "/.local/share/nvim/lsp_servers/jdtls/plugins/org.eclipse.equinox.launcher_1.6.400.v20210924-0641.jar",
    "-configuration",
    home .. "/.local/share/nvim/lsp_servers/jdtls/config_mac",
    "-data",
    home .. "/.local/share/nvim/lsp_servers/jdtls/workspace",
  },
  root_dir = function(fname)
    return require("lspconfig").util.root_pattern("pom.xml", "gradle.build", ".git")(fname) or vim.fn.getcwd()
  end,
}

require("lspconfig").clangd.setup {
  capabilities = capabilities,
  cmd = { "clangd" }
}
EOF

Description

When working with java file, using if~ snippet will repeat the keyword if twice. Here is the demo: Apr-09-2022 10-17-21

But working with c file, it is ok. Here is the demo: Apr-09-2022 10-18-59

Steps to reproduce

  1. Download the java language server: jdtls
  2. use the config
  3. change the path of jdtls's setting.
require("lspconfig").jdtls.setup {
  capabilities = capabilities,
  cmd = {
    "java",
    "-Declipse.application=org.eclipse.jdt.ls.core.id1",
    "-Dosgi.bundles.defaultStartLevel=4",
    "-Declipse.product=org.eclipse.jdt.ls.core.product",
    "-Dlog.protocol=true",
    "-Dlog.level=ALL",
    "-Xms1g",
    "--add-modules=ALL-SYSTEM",
    "--add-opens",
    "java.base/java.util=ALL-UNNAMED",
    "--add-opens",
    "java.base/java.lang=ALL-UNNAMED",
    "-jar",
    -- !! You should change this path to your jdtls directory
    home .. "/.local/share/nvim/lsp_servers/jdtls/plugins/org.eclipse.equinox.launcher_1.6.400.v20210924-0641.jar",
    "-configuration",
    -- !! You should change this path to your jdtls directory
    home .. "/.local/share/nvim/lsp_servers/jdtls/config_mac",
    "-data",
    -- !! You should change this path to your jdtls directory
    home .. "/.local/share/nvim/lsp_servers/jdtls/workspace",
  },
  root_dir = function(fname)
    return require("lspconfig").util.root_pattern("pom.xml", "gradle.build", ".git")(fname) or vim.fn.getcwd()
  end,
}
  1. Open a simple java file, type some codes like the demo.

Expected behavior

if~ snippet should work correctly.

Actual behavior

if repeats twice.

Additional context

No response

boning-w avatar Apr 09 '22 02:04 boning-w

Got the same issue. Don't know if is caused by jdtls or nvim-cmp

dragove avatar May 16 '22 15:05 dragove

Tried vsnip and luasnip, all have this issue.

btstream avatar May 18 '22 14:05 btstream

Same with me

lu5je0 avatar May 18 '22 16:05 lu5je0

This may only happens when snippet is supplied by jdt.ls server

btstream avatar Jun 07 '22 10:06 btstream

Same here. Snippets from jdt.ls are appended to the existing text when. I see this behavior only on Java with jdt.ls.

  confirmation = {
       default_behavior = types.cmp.ConfirmBehavior.Insert,
   },

Replace fix the issue but it is still annoying to use because it replaces the text to the right side.

   confirmation = {
        default_behavior = types.cmp.ConfirmBehavior.Replace,
    },

s1n7ax avatar Jun 09 '22 19:06 s1n7ax

Me too, happens with the sysout snippet, becomes sysSystem.out.println() instead

tminhvu avatar Aug 22 '22 08:08 tminhvu

Same here. Snippets from jdt.ls are appended to the existing text when. I see this behavior only on Java with jdt.ls.

  confirmation = {
       default_behavior = types.cmp.ConfirmBehavior.Insert,
   },

Replace fix the issue but it is still annoying to use because it replaces the text to the right side.

   confirmation = {
        default_behavior = types.cmp.ConfirmBehavior.Replace,
    },

That's worked before, but it doesn't work after I upgrade jdtls to latest version. I findout the recent update of jdtls removed java.completion.overwrite setting, and when this setting appear and set it to true , cmp.ConfirmBehavior.Replace is work for me.

wenjinnn avatar Aug 24 '22 09:08 wenjinnn

Same here. Snippets from jdt.ls are appended to the existing text when. I see this behavior only on Java with jdt.ls.

  confirmation = {
       default_behavior = types.cmp.ConfirmBehavior.Insert,
   },

Replace fix the issue but it is still annoying to use because it replaces the text to the right side.

   confirmation = {
        default_behavior = types.cmp.ConfirmBehavior.Replace,
    },

That's worked before, but it doesn't work after I upgrade jdtls to latest version. I findout the recent update of jdtls removed java.completion.overwrite setting, and when this setting appear and set it to true , cmp.ConfirmBehavior.Replace is work for me.

So I have to downgrade jdtls and then how exactly do I set it to true? By adding it into my setup function for jdtls like so?

    single_file_support = true,
    settings = {
        java = {
            completion = {
                overwrite = true
            }
        }
    }

tminhvu avatar Aug 24 '22 10:08 tminhvu

Same here. Snippets from jdt.ls are appended to the existing text when. I see this behavior only on Java with jdt.ls.

  confirmation = {
       default_behavior = types.cmp.ConfirmBehavior.Insert,
   },

Replace fix the issue but it is still annoying to use because it replaces the text to the right side.

   confirmation = {
        default_behavior = types.cmp.ConfirmBehavior.Replace,
    },

That's worked before, but it doesn't work after I upgrade jdtls to latest version. I findout the recent update of jdtls removed java.completion.overwrite setting, and when this setting appear and set it to true , cmp.ConfirmBehavior.Replace is work for me.

So I have to downgrade jdtls and then how exactly do I set it to true? By adding it into my setup function for jdtls like so?

    single_file_support = true,
    settings = {
        java = {
            completion = {
                overwrite = true
            }
        }
    }

Yes, it should work if you have the right version of jdtls

wenjinnn avatar Aug 24 '22 11:08 wenjinnn

I have the same behaviour with haskell-language-server and sumneko-lua-language-server, so I don't think it's specific to jdt.ls.

In my config, the problem was solved, when I replaced the vsnip engine with luasnip:

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

But a minimal config with the vsnip engine and sumneko-lua-language-server is working fine for me. Maybe another plugin is conflicting with vsnip?

mrcjkb avatar Dec 22 '22 18:12 mrcjkb

I have no jdtls environment. If someone can provide reproducible steps with another LS, it might be helpful.

hrsh7th avatar May 07 '23 05:05 hrsh7th

I don't have this issue these days (with jdtls). It seems that the original reporter is not active in github. And I also tested it with haskell-language-server with no issue. Maybe it is better to close this issue temporary and wait for a new common issue or reply to reopen it.

dragove avatar May 07 '23 07:05 dragove

Thank you. I close tjis at the moment.

hrsh7th avatar May 07 '23 09:05 hrsh7th

Same problem appears in my config. This seems to fix the problem as mentioned above:

    confirmation = {
        default_behavior = types.cmp.ConfirmBehavior.Replace,
    },

Without this option I got wrong expansion of LSP snippets.

        recording.getVolume().var // snippet to expand 
        float volume = recording.getVolume(); // expanded with replace
        recording.getVolume().float volume2 = recording.getVolume(); // expanded without replace 

cmp config: https://github.com/IlyasYOY/dotfiles/blob/master/config/nvim/lua/plugins/cmp.lua java config: https://github.com/IlyasYOY/dotfiles/blob/master/config/nvim/after/ftplugin/java.lua

Maybe I can send you some logs?

Can we reopen issue? I can provide you some logs if you need them to debug the problem. Sadly JDTLS is quite heavy to setup 😞

cc: @hrsh7th

IlyasYOY avatar Jun 21 '23 19:06 IlyasYOY