Opinionated config
Here I will show you a fully working example configuration that you can use as your init.lua
. This one will have a fair amount code that goes beyond the essential.
Expand: what's an init.lua?
Before I tell you, consider following this tutorial instead of copy/pasting this example config.
init.lua
is the configuration file Neovim looks for during the initialization process.
The location of this file depends on your operating system. If you want to know where it should be located, you can execute this command in your terminal.
sh
nvim --headless -c 'echo stdpath("config") . "\n"' -c 'quit'
Note that Neovim will not create that folder (or the init.lua file) for you. You need to do that manually.
lua
vim.opt.signcolumn = 'yes'
local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim'
-- Auto-install lazy.nvim if not present
if not vim.uv.fs_stat(lazypath) then
print('Installing lazy.nvim....')
vim.fn.system({
'git',
'clone',
'--filter=blob:none',
'https://github.com/folke/lazy.nvim.git',
'--branch=stable', -- latest stable release
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
require('lazy').setup({
{'williamboman/mason.nvim'},
{'williamboman/mason-lspconfig.nvim'},
{'neovim/nvim-lspconfig'},
{'L3MON4D3/LuaSnip'},
{'hrsh7th/nvim-cmp'},
{'hrsh7th/cmp-nvim-lsp'},
{'hrsh7th/cmp-buffer'},
{'hrsh7th/cmp-path'},
{'saadparwaiz1/cmp_luasnip'},
{'rafamadriz/friendly-snippets'},
})
vim.api.nvim_create_autocmd('LspAttach', {
callback = function(event)
local opts = {buffer = event.buf}
vim.keymap.set('n', 'K', '<cmd>lua vim.lsp.buf.hover()<cr>', opts)
vim.keymap.set('n', 'gd', '<cmd>lua vim.lsp.buf.definition()<cr>', opts)
vim.keymap.set('n', 'gD', '<cmd>lua vim.lsp.buf.declaration()<cr>', opts)
vim.keymap.set('n', 'gi', '<cmd>lua vim.lsp.buf.implementation()<cr>', opts)
vim.keymap.set('n', 'go', '<cmd>lua vim.lsp.buf.type_definition()<cr>', opts)
vim.keymap.set('n', 'gr', '<cmd>lua vim.lsp.buf.references()<cr>', opts)
vim.keymap.set('n', 'gs', '<cmd>lua vim.lsp.buf.signature_help()<cr>', opts)
vim.keymap.set('n', '<F2>', '<cmd>lua vim.lsp.buf.rename()<cr>', opts)
vim.keymap.set({'n', 'x'}, '<F3>', '<cmd>lua vim.lsp.buf.format({async = true})<cr>', opts)
vim.keymap.set('n', '<F4>', '<cmd>lua vim.lsp.buf.code_action()<cr>', opts)
end,
})
local lspconfig_defaults = require('lspconfig').util.default_config
lspconfig_defaults.capabilities = vim.tbl_deep_extend(
'force',
lspconfig_defaults.capabilities,
require('cmp_nvim_lsp').default_capabilities()
)
require('mason').setup({})
require('mason-lspconfig').setup({
handlers = {
function(server_name)
require('lspconfig')[server_name].setup({})
end,
}
})
local cmp = require('cmp')
-- this is the function that loads the extra snippets
-- from rafamadriz/friendly-snippets
require('luasnip.loaders.from_vscode').lazy_load()
cmp.setup({
sources = {
{name = 'path'},
{name = 'nvim_lsp'},
{name = 'luasnip', keyword_length = 2},
{name = 'buffer', keyword_length = 3},
},
window = {
completion = cmp.config.window.bordered(),
documentation = cmp.config.window.bordered(),
},
snippet = {
expand = function(args)
require('luasnip').lsp_expand(args.body)
end,
},
mapping = cmp.mapping.preset.insert({
-- confirm completion item
['<Enter>'] = cmp.mapping.confirm({ select = true }),
-- trigger completion menu
['<C-Space>'] = cmp.mapping.complete(),
-- scroll up and down the documentation window
['<C-u>'] = cmp.mapping.scroll_docs(-4),
['<C-d>'] = cmp.mapping.scroll_docs(4),
-- jump to the next snippet placeholder
['<C-f>'] = cmp.mapping(function(fallback)
local luasnip = require('luasnip')
if luasnip.locally_jumpable(1) then
luasnip.jump(1)
else
fallback()
end
end, {'i', 's'}),
-- jump to the previous snippet placeholder
['<C-b>'] = cmp.mapping(function(fallback)
local luasnip = require('luasnip')
if luasnip.locally_jumpable(-1) then
luasnip.jump(-1)
else
fallback()
end
end, {'i', 's'}),
}),
})