Como configurar o Neovim do zero com LSP, treesitter e plugins modernos
1. Preparando o ambiente: Instalação e estrutura inicial
Antes de qualquer configuração, é essencial ter o Neovim 0.9+ instalado. Em sistemas Linux (Ubuntu/Debian), use:
sudo add-apt-repository ppa:neovim-ppa/unstable
sudo apt update
sudo apt install neovim git curl nodejs npm
No macOS, via Homebrew:
brew install neovim git node
No Windows, use o Chocolatey:
choco install neovim git nodejs
Verifique a instalação com nvim --version. Em seguida, crie a estrutura de diretórios:
mkdir -p ~/.config/nvim/lua/plugins
mkdir -p ~/.config/nvim/lua/config
O arquivo principal será ~/.config/nvim/init.lua. Nele, carregaremos módulos organizados por funcionalidade.
2. Gerenciamento de plugins com lazy.nvim
O lazy.nvim é o gerenciador mais moderno, com carregamento sob demanda e otimização automática. Instale-o adicionando ao init.lua:
local lazypath = vim.fn.stdpath("data") .. "/lazy/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",
"--branch=stable",
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
require("lazy").setup("plugins")
Crie o arquivo lua/plugins/init.lua que carregará cada módulo:
-- lua/plugins/init.lua
require("plugins.treesitter")
require("plugins.lsp")
require("plugins.cmp")
require("plugins.telescope")
require("plugins.ui")
3. Configuração do Treesitter
O Treesitter fornece parsing sintático avançado. Configure em lua/plugins/treesitter.lua:
return {
"nvim-treesitter/nvim-treesitter",
build = ":TSUpdate",
config = function()
require("nvim-treesitter.configs").setup({
ensure_installed = { "python", "javascript", "rust", "lua", "vim", "vimdoc" },
auto_install = true,
highlight = { enable = true },
indent = { enable = true },
autotag = { enable = true },
rainbow = {
enable = true,
extended_mode = true,
max_file_lines = 1000,
},
context_commentstring = { enable = true },
})
end,
}
Para instalar parsers adicionais, use :TSInstall python javascript dentro do Neovim.
4. LSP (Language Server Protocol)
O Mason gerencia servidores LSP. Configure em lua/plugins/lsp.lua:
return {
{
"williamboman/mason.nvim",
config = function()
require("mason").setup()
end,
},
{
"williamboman/mason-lspconfig.nvim",
dependencies = { "mason.nvim" },
config = function()
require("mason-lspconfig").setup({
ensure_installed = { "pyright", "tsserver", "rust_analyzer", "lua_ls" },
})
end,
},
{
"neovim/nvim-lspconfig",
dependencies = { "mason-lspconfig.nvim" },
config = function()
local lspconfig = require("lspconfig")
local capabilities = require("cmp_nvim_lsp").default_capabilities()
local on_attach = function(client, bufnr)
local bufopts = { noremap = true, silent = true, buffer = bufnr }
vim.keymap.set("n", "gd", vim.lsp.buf.definition, bufopts)
vim.keymap.set("n", "K", vim.lsp.buf.hover, bufopts)
vim.keymap.set("n", "<space>rn", vim.lsp.buf.rename, bufopts)
vim.keymap.set("n", "<space>ca", vim.lsp.buf.code_action, bufopts)
vim.keymap.set("n", "[d", vim.diagnostic.goto_prev, bufopts)
vim.keymap.set("n", "]d", vim.diagnostic.goto_next, bufopts)
end
lspconfig.pyright.setup({ capabilities = capabilities, on_attach = on_attach })
lspconfig.tsserver.setup({ capabilities = capabilities, on_attach = on_attach })
lspconfig.rust_analyzer.setup({ capabilities = capabilities, on_attach = on_attach })
lspconfig.lua_ls.setup({
capabilities = capabilities,
on_attach = on_attach,
settings = { Lua = { runtime = { version = "LuaJIT" }, diagnostics = { globals = { "vim" } } } },
})
end,
},
}
5. Autocompletar e snippets
Configure o nvim-cmp em lua/plugins/cmp.lua:
return {
{
"hrsh7th/nvim-cmp",
dependencies = {
"hrsh7th/cmp-nvim-lsp",
"hrsh7th/cmp-buffer",
"hrsh7th/cmp-path",
"L3MON4D3/LuaSnip",
"saadparwaiz1/cmp_luasnip",
"rafamadriz/friendly-snippets",
},
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,
},
mapping = cmp.mapping.preset.insert({
["<Tab>"] = cmp.mapping.select_next_item(),
["<S-Tab>"] = cmp.mapping.select_prev_item(),
["<CR>"] = cmp.mapping.confirm({ select = true }),
["<C-Space>"] = cmp.mapping.complete(),
}),
sources = cmp.config.sources({
{ name = "nvim_lsp" },
{ name = "luasnip" },
{ name = "buffer" },
{ name = "path" },
}),
})
end,
},
}
6. Navegação e produtividade
Telescope é essencial para busca fuzzy. Configure em lua/plugins/telescope.lua:
return {
{
"nvim-telescope/telescope.nvim",
dependencies = { "nvim-lua/plenary.nvim" },
config = function()
local telescope = require("telescope")
telescope.setup({
defaults = {
mappings = {
i = { ["<C-j>"] = "move_selection_next", ["<C-k>"] = "move_selection_previous" },
},
},
})
vim.keymap.set("n", "<leader>ff", telescope.extensions.frecency.frecency, {})
vim.keymap.set("n", "<leader>fg", telescope.extensions.live_grep, {})
vim.keymap.set("n", "<leader>fb", telescope.extensions.buffers, {})
vim.keymap.set("n", "<leader>fh", telescope.extensions.help_tags, {})
end,
},
{
"ThePrimeagen/harpoon",
dependencies = { "nvim-lua/plenary.nvim" },
config = function()
require("harpoon").setup()
vim.keymap.set("n", "<leader>a", require("harpoon.mark").add_file)
vim.keymap.set("n", "<leader>h", require("harpoon.ui").toggle_quick_menu)
vim.keymap.set("n", "<C-h>", function() require("harpoon.ui").nav_file(1) end)
end,
},
{
"lewis6991/gitsigns.nvim",
config = function()
require("gitsigns").setup({
signs = { add = { text = "+" }, change = { text = "~" }, delete = { text = "_" } },
current_line_blame = true,
})
end,
},
}
7. Aparência e usabilidade
Configure temas e statusline em lua/plugins/ui.lua:
return {
{
"catppuccin/nvim",
name = "catppuccin",
priority = 1000,
config = function()
require("catppuccin").setup({
flavour = "mocha",
transparent_background = true,
})
vim.cmd.colorscheme("catppuccin")
end,
},
{
"nvim-lualine/lualine.nvim",
dependencies = { "nvim-tree/nvim-web-devicons" },
config = function()
require("lualine").setup({
options = {
theme = "catppuccin",
section_separators = { left = "", right = "" },
component_separators = { left = "", right = "" },
},
sections = {
lualine_a = { "mode" },
lualine_b = { "branch", "diff" },
lualine_c = { "filename" },
lualine_x = { "diagnostics", "filetype" },
lualine_y = { "progress" },
lualine_z = { "location" },
},
})
end,
},
}
8. Otimizações finais e boas práticas
Crie lua/config/options.lua para configurações básicas:
vim.opt.number = true
vim.opt.relativenumber = true
vim.opt.tabstop = 4
vim.opt.shiftwidth = 4
vim.opt.expandtab = true
vim.opt.clipboard = "unnamedplus"
vim.opt.termguicolors = true
vim.opt.mouse = "a"
vim.opt.undofile = true
vim.opt.ignorecase = true
vim.opt.smartcase = true
Crie lua/config/keymaps.lua para atalhos globais:
vim.g.mapleader = " "
vim.keymap.set("n", "<leader>w", "<cmd>w<CR>")
vim.keymap.set("n", "<leader>q", "<cmd>q<CR>")
vim.keymap.set("n", "<leader>e", vim.diagnostic.open_float)
vim.keymap.set("n", "<leader>n", "<cmd>lua vim.diagnostic.goto_next()<CR>")
Carregue tudo no init.lua:
require("config.options")
require("config.keymaps")
require("plugins.init")
Para medir performance, use:
nvim --startuptime /tmp/startup.log
Analise o log com less /tmp/startup.log e identifique plugins lentos.
Referências
- Documentação oficial do lazy.nvim — Repositório com guia completo de instalação, configuração e lazy loading.
- Guia do Neovim LSP — Documentação oficial sobre o suporte a LSP no Neovim, incluindo lspconfig e mason.
- nvim-treesitter wiki — Documentação detalhada sobre parsing, highlight e módulos complementares.
- Tutorial de nvim-cmp — Repositório oficial com exemplos de configuração para autocompletar com múltiplas fontes.
- Configuração completa de Neovim com Lua — Projeto kickstart que serve como template moderno para iniciantes.
- Mason.nvim: gerenciador de servidores LSP — Documentação oficial para instalar e gerenciar servidores LSP, linters e formatters.
- Telescope.nvim: busca fuzzy — Repositório com guia de uso e extensões para busca de arquivos, texto e buffers.