Course Lessons
The Setup
The very first plugin we’ll have to install is nvim-cmp. nvim-cmp is the completion engine written in lua for neovim. I see nvim-cmp as the plugin that displays completions and snippets in a window as you type. This is just the engine for completions though. We are going to have to find other plugins to actually supply the “sources” of these completions and snippets.
nvim-cmp has some pretty good documentation, and a GREAT example config. lets go ahead and copy their config, because it has literally everything we need. and lets check it out.
check out: https://github.com/hrsh7th/nvim-cmp for the example config that we'll base OUR config off of.
Here is our config after looking at the example above:
return {
{
"hrsh7th/nvim-cmp",
config = function()
local cmp = require("cmp")
require("luasnip.loaders.from_vscode").lazy_load()
cmp.setup({
snippet = {
expand = function(args)
" Install luasnip and use it here
end,
},
window = {
completion = cmp.config.window.bordered(),
documentation = cmp.config.window.bordered(),
},
mapping = cmp.mapping.preset.insert({
["<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 }),
}),
sources = cmp.config.sources({
" put sources in here.
}, {
{ name = "buffer" },
}),
})
end,
},
}
In our sekeleton configuration ☝️we have:
- A window attribute that describes the window that pops up when you type.
- We have the snippet argument that supplies the function that gets run whenever nvim-cmp tries to complete a snippet.
- We have mappings that, you guessed it, deals with keymaps, we can use what is given here, they are pretty sane defaults.
- And we have sources, which are the snippet and completion sources that nvim-cmp uses to display and complete when you press carriage return.
Now lets work on filling in the missing gaps. Sources, and our Snippet Engine.
The first thing we'll want to do is install our Snippet Engine luasnip
. We achieve this by checking out the example config of nvim-cmp
and copying the section that includes "L3MON4D3/LuaSnip"
and "saadparwaiz1/cmp_luasnip"
. LuaSnip is our snippet engine, and cmp_luasnip
is the luasnip completion engine.
But we still don't actually have any pre-defined snippets. We just have the engines that power the snippet, AND autocomplete expansion. So lets install some VSCode-like snippets with rafamadriz/friendly-snippets
.
We can add all these packages to our completions.lua
file, like so 👇
return {
{
"hrsh7th/cmp-nvim-lsp"
},
{
"L3MON4D3/LuaSnip",
dependencies = {
"saadparwaiz1/cmp_luasnip",
"rafamadriz/friendly-snippets",
},
},
...rest of file here.
}
Then, in order to actually load these packages in our configuration, we'll want to add them to our nvim-cmp
configuration.
require("luasnip").lsp_expand(args.body)
☝️Needs to be placed in the expand
function for cmp.setup({
{ name = "luasnip" }, -- For luasnip users.
☝️Needs to be added to our list of sources.
And, to actually load our VSCode like snippets, we'll have to... well... you know, load them.
require("luasnip.loaders.from_vscode").lazy_load()
At the end of this section, your completions.lua
file should look something like this:
return {
{
"L3MON4D3/LuaSnip",
dependencies = {
"saadparwaiz1/cmp_luasnip",
"rafamadriz/friendly-snippets",
},
},
{
"hrsh7th/nvim-cmp",
config = function()
local cmp = require("cmp")
require("luasnip.loaders.from_vscode").lazy_load()
cmp.setup({
snippet = {
expand = function(args)
require("luasnip").lsp_expand(args.body)
end,
},
window = {
completion = cmp.config.window.bordered(),
documentation = cmp.config.window.bordered(),
},
mapping = cmp.mapping.preset.insert({
["<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 }),
}),
sources = cmp.config.sources({
{ name = "luasnip" }, -- For luasnip users.
}, {
{ name = "buffer" },
}),
})
end,
},
}
You've completed this lesson!
You completed this lesson less than a minute ago.