Course Lessons
LSP-based completions!
Now we have a pretty good setup for our completions and snippets. We have a snippet engine, a completion engine, and a snippet source to generate all the snippets for us to complete.
But there is one piece missing. LSP completions!
You see, most LSPs will offer completions when editing a text file. The LSP attached to whatever buffer you're using can be asked for completions at any given point in time given whatever context you're currently in. And there is a plugin that facilitates this communication in Neovim really well.
That plugin is: https://github.com/hrsh7th/cmp-nvim-lsp
In order to facilitate the communication of autocompletion between neovim and LSP servers, we need to take a few steps.
First: Install the plugin in our completions.lua file, like so:
" Add another package to our completions.lua file
{
"hrsh7th/cmp-nvim-lsp"
},
Second: Add the plugin to our list of completion sources:
sources = cmp.config.sources({
{ name = "nvim_lsp" },
{ name = "luasnip" }, -- For luasnip users.
}, {
{ name = "buffer" },
}),
Third: Add the capabilities of the cmp-nvim-lsp
plugin to our LSP configuration.
This step is essential. We need to tell our buffers that we have the capabilities to reach out to LSP for completions. We can do this by adding the following to our LSP file.
local capabilities = require('cmp_nvim_lsp').default_capabilities()
THEN, when we have our capabilities in a variable. We need to broadcast it to all our LSP setups. So we add these capabilites to each language we set up in our lsp-config.lua
file, here is an example:
lspconfig.tsserver.setup({
capabilities = capabilities
})
In Summary
We installed cmp-nvim-lsp
as a completion source to be used in our snippet/completions file. We then added the capabilities of this package to our LSP configuration, so we can facilitate the communication between our LSP, and Neovim, to show completion options as we type.
final completions.lua
file
return {
{
"hrsh7th/cmp-nvim-lsp"
},
{
"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 = "nvim_lsp" },
{ name = "luasnip" }, -- For luasnip users.
}, {
{ name = "buffer" },
}),
})
end,
},
}
Final lsp-config.lua
file:
return {
{
"williamboman/mason.nvim",
lazy = false,
config = function()
require("mason").setup()
end,
},
{
"williamboman/mason-lspconfig.nvim",
lazy = false,
opts = {
auto_install = true,
},
},
{
"neovim/nvim-lspconfig",
lazy = false,
config = function()
local capabilities = require('cmp_nvim_lsp').default_capabilities()
local lspconfig = require("lspconfig")
lspconfig.tsserver.setup({
capabilities = capabilities
})
vim.keymap.set("n", "K", vim.lsp.buf.hover, {})
vim.keymap.set("n", "<leader>gd", vim.lsp.buf.definition, {})
vim.keymap.set("n", "<leader>gr", vim.lsp.buf.references, {})
vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action, {})
vim.keymap.set("n", "<leader>rn", vim.lsp.buf.code_action, {})
vim.keymap.set('n', '<space>rn', vim.lsp.buf.rename, {})
end,
},
}
You've completed this lesson!
You completed this lesson less than a minute ago.