Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: cmp-nvim "<tab>" mapping clashes with luasnip "<tab>" mapping #44

Closed
3 tasks done
MarWeUMR opened this issue Jan 11, 2023 · 3 comments · Fixed by #28
Closed
3 tasks done

bug: cmp-nvim "<tab>" mapping clashes with luasnip "<tab>" mapping #44

MarWeUMR opened this issue Jan 11, 2023 · 3 comments · Fixed by #28
Labels
bug Something isn't working

Comments

@MarWeUMR
Copy link

MarWeUMR commented Jan 11, 2023

Did you check docs and existing issues?

  • I have read all the LazyVim docs
  • I have searched the existing issues of LazyVim
  • I have searched the exsiting issues of plugins related to this issue

Neovim version (nvim -v)

NVIM v0.9.0-dev-588+g99cf11128

Operating system/version

ubuntu 22.04

Describe the bug

Mapping the tab key for nvim-cmp does not work correctly (mapping taken from here). It freezes the terminal (most likely an infinite loop of the remap), when it should only indent some text. Completion menu navigation works correctly though.

I've pinned the problem down to this mapping from the default luasnip config:

expr = true, remap = true, silent = true, mode = "i",

More specifically, changing the remap=true option to something else like noremap=true, or deleting it makes things work again.
I'm not sure, if this is actually an issue with nvim-cmp, or a conflicting setting for the luasnip mapping.
Anyway, I guess the fix is easy, unless remap=true has some more specific use-cases?

Steps To Reproduce

  • Wipe nvim/lazy caches
  • Use minimal repro.lua from down below and start with nvim -u repro.lua repro.lua
  • enter insert mode in front of some text
  • press tab -> terminal freezes

Expected Behavior

Well, indenting text...

Repro

-- DO NOT change the paths and don't remove the colorscheme
local root = vim.fn.fnamemodify("./.repro", ":p")
-- set stdpaths to use .repro
for _, name in ipairs({ "config", "data", "state", "cache" }) do
  vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
end

-- bootstrap lazy
local lazypath = root .. "/plugins/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", lazypath, })
end
vim.opt.runtimepath:prepend(lazypath)

-- install plugins
local plugins = {
  "folke/tokyonight.nvim",
  "folke/LazyVim",
  -- add any other plugins here

  {
    "L3MON4D3/LuaSnip",
    dependencies = {
      "rafamadriz/friendly-snippets",
      config = function()
        require("luasnip.loaders.from_vscode").lazy_load()
      end,
    },
    opts = {
      history = true,
      delete_check_events = "TextChanged",
    },
    -- stylua: ignore
    keys = {
      {
        "<tab>",
        function()
          return require("luasnip").jumpable(1) and "<Plug>luasnip-jump-next" or "<tab>"
        end,
        expr = true, remap = true, silent = true, mode = "i",
      },
      { "<tab>", function() require("luasnip").jump(1) end, mode = "s" },
      { "<s-tab>", function() require("luasnip").jump(-1) end, mode = { "i", "s" } },
    },
  },

  {
    "hrsh7th/nvim-cmp",
    event = "InsertEnter",
    dependencies = {
      "hrsh7th/cmp-nvim-lsp",
      "hrsh7th/cmp-buffer",
      "hrsh7th/cmp-path",
      "saadparwaiz1/cmp_luasnip",
    },
    opts = function()


      local has_words_before = function()
        unpack = unpack or table.unpack
        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 luasnip = require("luasnip")


      local cmp = require("cmp")
      return {
        completion = {
          completeopt = "menu,menuone,noinsert",
        },
        snippet = {
          expand = function(args)
            require("luasnip").lsp_expand(args.body)
          end,
        },
        mapping = cmp.mapping.preset.insert({
          ["<Tab>"] = cmp.mapping(function(fallback)
            if cmp.visible() then
              cmp.select_next_item()
              -- You could replace the expand_or_jumpable() calls with expand_or_locally_jumpable()
              -- they way you will only jump inside the snippet region
            elseif luasnip.expand_or_jumpable() then
              luasnip.expand_or_jump()
            elseif has_words_before() then
              cmp.complete()
            else
              fallback()
            end
          end, { "i", "s" }),
          ["<C-b>"] = cmp.mapping.scroll_docs(-4),
          ["<C-f>"] = cmp.mapping.scroll_docs(4),
          ["<C-Space>"] = cmp.mapping.complete(),
          ["<C-e>"] = cmp.mapping.abort(),
          ["<CR>"] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
        }),
        sources = cmp.config.sources({
          { name = "nvim_lsp" },
          { name = "luasnip" },
          { name = "buffer" },
          { name = "path" },
        }),
        formatting = {
          format = function(_, item)
            local icons = require("lazyvim.config").icons.kinds
            if icons[item.kind] then
              item.kind = icons[item.kind] .. item.kind
            end
            return item
          end,
        },
        experimental = {
          ghost_text = {
            hl_group = "LspCodeLens",
          },
        },
      }
    end,
  },
}




require("lazy").setup(plugins, {
  root = root .. "/plugins",
})

-- add anything else here
-- do not remove the colorscheme!
vim.cmd([[colorscheme tokyonight]])
@MarWeUMR MarWeUMR added the bug Something isn't working label Jan 11, 2023
@folke folke closed this as completed in 87c37f2 Jan 11, 2023
@folke
Copy link
Collaborator

folke commented Jan 11, 2023

Removed the remap=true. I forgot that's not needed for plug mappings.

@trevarj
Copy link

trevarj commented Jan 12, 2023

Just noting that even after this fix the LuaSnip config is still conflicting with nvim-cmp when you implement a super-tab configuration from the nvim-cmp wiki.

nvim-cmp config:

opts.mapping = cmp.config.mapping.preset.insert({
        ["<CR>"] = cmp.mapping.confirm({ select = false }),
        ["<Tab>"] = cmp.mapping(function(fallback)
          if cmp.visible() then
            cmp.select_next_item()
          elseif luasnip.expand_or_jumpable() 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() then
            cmp.select_prev_item()
          elseif luasnip.jumpable(-1) then
            luasnip.jump(-1)
          else
            fallback()
          end
        end, { "i", "s" }),
      })

Behavior: Hitting tab in insert mode prints out "", since the fallback() is falling into the function defined in the LuaSnip config:

return require("luasnip").jumpable(1) and "<Plug>luasnip-jump-next" or "<tab>"

It seems that a fix is to override keys = { .. } for LuaSnip by overwriting the mapping for <tab>/<s-tab> back to the defaults and with expr = false set.

@folke
Copy link
Collaborator

folke commented Jan 12, 2023

On popular request, I've added an example on how to setup supertab behavior with cmp and luasnip.

Make sure you updated lazy.nvim to the latest version to make this work! (specifically keys= as function is new)

ofrades pushed a commit to ofrades/LazyVim that referenced this issue May 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants