Back to Blog

Autocompletion for Neovim — nvim-cmp, LuaSnip & Friendly Snippets | Episode 11

Sandy LaneSandy Lane

Video: Autocompletion for Neovim — nvim-cmp, LuaSnip & Friendly Snippets | Episode 11 by Taught by Celeste AI - AI Coding Coach

Watch full page →

Autocompletion for Neovim — nvim-cmp, LuaSnip & Friendly Snippets

Enhance your Neovim editing experience by integrating intelligent autocompletion using nvim-cmp. This setup combines multiple completion sources, snippet expansion with LuaSnip, and hundreds of ready-to-use snippet templates from friendly-snippets, all configured in Lua for seamless terminal use.

Code

-- cmp.lua: Configure nvim-cmp with multiple sources and key mappings
local cmp = require('cmp')
local luasnip = require('luasnip')

cmp.setup({
  snippet = {
    -- Use LuaSnip to expand snippets
    expand = function(args)
      luasnip.lsp_expand(args.body)
    end,
  },
  mapping = {
    -- Navigate completion menu and snippets with Tab and Shift-Tab
    ['<Tab>'] = cmp.mapping(function(fallback)
      if cmp.visible() then
        cmp.select_next_item()
      elseif luasnip.expand_or_jumpable() then
        luasnip.expand_or_jump()
      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'}),
    ['<CR>'] = cmp.mapping.confirm({ select = true }),  -- Enter to confirm
    ['<C-Space>'] = cmp.mapping.complete(),             -- Ctrl+Space to trigger completion
    ['<C-e>'] = cmp.mapping.close(),                    -- Ctrl+e to close popup
    ['<C-b>'] = cmp.mapping.scroll_docs(-4),            -- Scroll docs up
    ['<C-f>'] = cmp.mapping.scroll_docs(4),             -- Scroll docs down
  },
  sources = cmp.config.sources({
    { name = 'nvim_lsp' },   -- Language Server Protocol completions
    { name = 'luasnip' },    -- Snippet completions
  }, {
    { name = 'buffer' },     -- Buffer word completions
    { name = 'path' },       -- File path completions
  }),
})

-- lsp.lua: Enhance LSP capabilities for nvim-cmp
local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities = require('cmp_nvim_lsp').default_capabilities(capabilities)

-- Setup your LSP servers with these enhanced capabilities, e.g.:
-- require('lspconfig').pyright.setup { capabilities = capabilities }

-- Load friendly-snippets for LuaSnip
require("luasnip.loaders.from_vscode").lazy_load()

Key Points

  • Use nvim-cmp as the completion engine with multiple sources: LSP, snippets, buffer words, and file paths.
  • Integrate LuaSnip for snippet expansion and placeholder jumping within completions.
  • Configure Tab and Shift-Tab keys for intuitive super-tab navigation through completion items and snippet placeholders.
  • Load hundreds of ready-made snippet templates from friendly-snippets to boost productivity across languages.
  • Enhance LSP capabilities with cmp_nvim_lsp for richer, context-aware completions.