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

Neovim crashes in WSL2 when typing path `/tmp/`

Open daephx opened this issue 3 years ago • 0 comments

I'm not sure if anything can or should be done here on cmp's end but I've had some trouble where typing /tmp/ will trigger cmp and cause neovim to freeze for up to a few minutes before either unfreezing or completely crashing crashing without indicating an error, such as a segfault.

Testing against a native linux machine did not have the same problem.

I have native_menu = false and attempted to set max_item_count = 10 for sources.path thinking this would fix the issue but there was no noticeable change.

I tried a clean neovim instance with wildmenu enabled and cmp disabled to see if it would also crash; it was still noticeably slow and hung for ~30sec but didn't result in a crash.

Is there a possible workaround like disabling completion for the tmp directory in both insert and command mode?

lua/plugins/cmp.lua
-- nvim-cmp setup
local cmp = require('cmp')
local luasnip = require('luasnip')

local kinds = require('lsp.icons').completion_kinds

-- Detect whitespace before cursor position.
local check_backspace = function()
  local col = vim.fn.col('.') - 1
  return col == 0 or vim.fn.getline('.'):sub(col, col):match('%s')
end

cmp.setup({
  -- enabled = function()
  --   buftype = vim.api.nvim_buf_get_option(0, 'buftype')
  --   if buftype == 'prompt' then
  --     return false
  --   end
  --   return true
  -- end,
  snippet = {
    expand = function(args)
      luasnip.lsp_expand(args.body) -- For `luasnip` users.
    end,
  },
  experimental = {
    native_menu = false,
    ghost_text = true,
  },
  window = {
    completion = {
      max_width = 80,
      border = 'single',
      completeopt = 'menu,menuone,noselect',
      keyword_pattern = [[\%(-\?\d\+\%(\.\d\+\)\?\|\h\w*\%(-\w*\)*\)]],
      keyword_length = 2,
      winhighlight = table.concat({
        'NormalFloat:NormalFloat',
        'FloatBorder:FloatBorder',
      }, ','),
    },
    documentation = {
      border = 'single',
      winhighlight = table.concat({
        'NormalFloat:NormalFloat',
        'FloatBorder:FloatBorder',
      }, ','),
    },
  },
  view = {
    entries = {
      name = 'custom',
      -- selection_order = 'near_cursor'
    },
  },
  sorting = {
    comparators = {
      cmp.config.compare.offset,
      cmp.config.compare.exact,
      cmp.config.compare.score,

      -- copied from cmp-under, but I don't think I need the plugin for this.
      function(entry1, entry2)
        local _, entry1_under = entry1.completion_item.label:find('^_+')
        local _, entry2_under = entry2.completion_item.label:find('^_+')
        entry1_under = entry1_under or 0
        entry2_under = entry2_under or 0
        if entry1_under > entry2_under then
          return false
        elseif entry1_under < entry2_under then
          return true
        end
      end,

      cmp.config.compare.kind,
      cmp.config.compare.sort_text,
      cmp.config.compare.length,
      cmp.config.compare.order,
    },
  },
  sources = {
    { name = 'nvim_lsp' },
    { name = 'luasnip' },
    -- { name = 'nvim_lua' },
    -- { name = 'treesitter' },
    { name = 'path', max_item_count = 10 },
    {
      name = 'buffer',
      keyword_length = 3,
      option = {
        get_bufnrs = function()
          return vim.api.nvim_list_bufs()
        end,
      },
    },
  },
  formatting = {
    format = function(entry, vim_item)
      vim_item.dup = { buffer = 1, path = 1, nvim_lsp = 0 }
      vim_item.kind = string.format('%s %s', kinds[vim_item.kind], vim_item.kind)
      vim_item.max_width = 80
      vim_item.menu = ({
        buffer = '[Buffer]',
        cmp_tabnine = '[Tabnine]',
        crates = '[Crates]',
        latex_symbols = '[Latex]',
        luasnip = '[Luasnip]',
        nvim_lsp = '[LSP]',
        nvim_lua = '[Lua]',
        path = '[Path]',
        spell = '[Spell]',
        ultisnips = '[Ultisnips]',
        vsnip = '[VSnip]',
        zsh = '[Shell]',
      })[entry.source.name]
      return vim_item
    end,
  },
  mapping = cmp.mapping.preset.insert({
    ['<CR>'] = cmp.mapping.confirm({ select = false }),
    ['<C-Space>'] = cmp.mapping(cmp.mapping.complete(), { 'i', 'c' }),
    ['<C-p>'] = cmp.mapping(cmp.mapping.select_prev_item(), { 'i', 'c' }),
    ['<C-n>'] = cmp.mapping(cmp.mapping.select_next_item(), { 'i', 'c' }),
    ['<C-d>'] = cmp.mapping(cmp.mapping.scroll_docs(-4), { 'i', 'c' }),
    ['<C-f>'] = cmp.mapping.scroll_docs(4),
    ['<C-u>'] = cmp.mapping(cmp.mapping.scroll_docs(4), { 'i', 'c' }),
    ['<C-e>'] = cmp.mapping({
      i = cmp.mapping.abort(),
      c = cmp.mapping.close(),
    }),

    ['<Down>'] = cmp.mapping({
      n = cmp.mapping.select_next_item(),
      c = cmp.mapping.select_next_item(),
      i = cmp.config.disable,
    }),

    ['<Up>'] = cmp.mapping({
      n = cmp.mapping.select_prev_item(),
      c = cmp.mapping.select_prev_item(),
      i = cmp.config.disable,
    }),

    ['<Tab>'] = cmp.mapping(function(fallback)
      if cmp.visible() and not check_backspace() then
        cmp.confirm({ select = true })
      elseif luasnip.expand_or_jumpable() then
        luasnip.expand_or_jump()
      else
        fallback()
      end
    end, { 'i', 's' }),

    ['<S-CR>'] = cmp.mapping(function(fallback)
      if luasnip.jumpable(-1) then
        luasnip.jump(-1)
      else
        fallback()
      end
    end, { 'i', 's' }),
  }),
})

daephx avatar Nov 18 '22 11:11 daephx