Olá, pessoal! Chegamos ao último capítulo da nossa jornada de transformação da configuração do Neovim. Se você acompanhou os passos anteriores, agora é o momento crucial para migrar init.vim para lua e finalizar a transição, tornando seu editor ainda mais poderoso e eficiente. Preparem-se para os ajustes finais, pois vamos dar um upgrade definitivo na nossa experiência com o Neovim!
Conteúdo
Se você perdeu as partes anteriores, é altamente recomendável que você siga desde a primeira parte, para que a estrutura de pastas esteja igual, e você esteja no mesmo ponto da configuração antes de continuar.
Anteriormente instalamos o gerenciador de plugins lazy.nvim e adicionamos o tema tokyonight.nvim. Neste post vamos concluir a configuração e instalar os seguintes componentes:
- Alguns plugins que são requisitos para outros plugins.
- Treesitter: Serve para montar uma árvore de sintaxe do seu código fonte, melhorando as cores de acordo com o tema.
- Configurar o LSP e Mason: O Mason vai nos ajudar a instalar os servidores de linguagem (LSP) para as linguagens que você utiliza.
- Snippets: Templates de código para facilitar no desenvolvimento.
- Telescope: É um file picker, para você poder pesquisar e abrir arquivos de um projeto mais rapidamente.
- Oil: Vai funcionar como a árvore de navegação.
- Lualine: Barra de status um pouco mais informativa e que se integra melhor com o tema.
- Configurar atalhos de teclado
Há um longo post pela frente, mas ao final, teremos um editor completamente funcional, com tema melhor aplicado ao código com o treesitter, função para completar código, snippets, detecção de erros de sintaxe, e gerenciador de arquivos.
Requisitos
Antes de instalar os maiores plugins, vamos instalar alguns que são dependência para que outros funcionem.
Dentro da pasta de plugins
, adicione um arquivo chamado ui.lua
. Este arquivo vai conter alguns plugins que alteram ou melhoram a interface:
return {
--[[
-- Lualine
--]]
{
"nvim-lualine/lualine.nvim",
event = "VeryLazy",
opts = {
options = {
theme = "tokyonight",
icons_enabled = true,
globalstatus = false,
section_separators = { left = '', right = '' },
component_separators = '|'
},
sections = {
lualine_a = {
{ 'mode', separator = { right = '' }, right_padding = 2 },
}
},
tabline = {}
}
},
-- better vim.ui
{
"stevearc/dressing.nvim",
lazy = true,
init = function()
---@diagnostic disable-next-line: duplicate-set-field
vim.ui.select = function(...)
require("lazy").load({ plugins = { "dressing.nvim" } })
return vim.ui.select(...)
end
---@diagnostic disable-next-line: duplicate-set-field
vim.ui.input = function(...)
require("lazy").load({ plugins = { "dressing.nvim" } })
return vim.ui.input(...)
end
end,
opts = {
input = {
win_options = {
winblend = 0
}
},
select = {
win_options = {
winblend = 0
}
}
}
},
-- icons
{ "nvim-tree/nvim-web-devicons", lazy = true },
-- plenary
{ "nvim-lua/plenary.nvim", lazy = true },
-- ui components
{ "MunifTanjim/nui.nvim", lazy = true },
}
lualine.nvim
O lualine.nvim é uma barra de status desenvolvida em lua, que é melhor integrada ao tema e um tanto mais informativa que a padrão. Lembrando que você terá melhores resultados se tiver uma fonte do NerdFonts instalada e configurada no seu terminal, para que os ícones sejam exibidos corretamente.
No momento que escrevo esta postagem, requer o Neovim na versão 0.7 ou mais recente.
dressing.nvim
O dressing.nvim possui um conjunto de melhorias em componentes da interface padrão. Requer Neovim na versão 0.8 ou mais recente.
nvim-web-devicons
Conjunto de ícones que são utilizados por inúmeros plugins. Requer Neovim na versão 0.7 ou mais recente, e a fonte do NerdFonts configurada no seu terminal.
plenary.nvim
Conjunto de funções escritas em lua para facilitar o desenvolvimento de outros plugins.
nui.nvim
Conjunto de componentes de interface. Requer Neovim na versão 0.5 ou mais recente.
Após adicionar o arquivo ui.lua
na pasta de plugins
, reinicie o Neovim. O lazy.nvim vai automaticamente detectar e instalar os arquivos necessários. Quando a instalação for concluída, já é possível ver o lualine na parte inferior.

Treesitter
O próximo passo para um editor de código fantástico é instalar o treesitter, para melhorar as cores do tema de acordo com a sintaxe. Para tal, adicione o arquivo treesitter.lua
na pasta de plugins com o seguinte conteúdo:
return {
{
"nvim-treesitter/nvim-treesitter",
version = false,
build = ":TSUpdate",
event = { "BufReadPost", "BufNewFile" },
opts = {
auto_install = true,
highlight = {
enable = true,
additional_vim_regex_highlighting = false
},
indent = { enable = false },
context_commentstring = {
enable = true,
enable_autocmd = false
},
ensure_installed = {
"html",
"javascript",
"json",
"lua",
"luadoc",
"markdown",
"markdown_inline",
"regex",
"tsx",
"typescript",
"vim",
"vimdoc",
"yaml",
},
incremental_selection = {
enable = true,
keymaps = {
init_selection = "<C-space>",
node_incremental = "<C-space>",
scope_incremental = false,
node_decremental = "<bs>",
},
},
},
---@param opts TSConfig
config = function(_, opts)
if type(opts.ensure_installed) == "table" then
---@type table<string, boolean>
local added = {}
opts.ensure_installed = vim.tbl_filter(function(lang)
if added[lang] then
return false
end
added[lang] = true
return true
end, opts.ensure_installed)
end
require("nvim-treesitter.configs").setup(opts)
end,
},
}
O que o código faz
O código acima desabilita as cores de sintaxe padrões do neovim, que são baseadas em expressões regulares, e habilita as cores de sintaxe baseadas no treesitter, que é a árvore de sintaxe do seu código.
Na chave ensure_installed
, informamos uma lista das linguagens que serão automaticamente instaladas. Não é necessário adicionar caso você deseje instalar sob demanda.
Além disso, define atalhos de teclado para aumentar ou reduzir a seleção atual, utilizando Ctrl + espaço para aumentar e backspace para reduzir a seleção, como no exemplo abaixo:

Mason e LSP
Neste ponto, vamos instalar algo que eu julgo mais importante para quem desenvolve, que são os LSPs. Os LSPs vão ajudar fornecendo ajuda com a sintaxe, autocompletar código, formatação de código fonte, entre muitas outras coisas legais.
Certifique-se de atender os requisitos mínimos antes de prosseguir:
- Neovim 0.7 ou mais recente
- git
- curl ou wget
- unzip
- tar ou gtar
- gzip
Para configurar o Mason e habilitar o suporte aos LSPs, crie o arquivo lsp.lua
na pasta plugins
, e adicione o seguinte código:
return {
-- lspconfig
{
"neovim/nvim-lspconfig",
event = { "BufReadPre", "BufNewFile" },
dependencies = {
{ "folke/neoconf.nvim", cmd = "Neoconf", config = true },
{ "folke/neodev.nvim", opts = { experimental = { pathStrict = true } } },
"mason.nvim",
"williamboman/mason-lspconfig.nvim",
"hrsh7th/cmp-nvim-lsp"
},
opts = {
diagnostics = {
underline = true,
update_in_insert = false,
virtual_text = {
spacing = 4,
source = "if_many",
prefix = "●",
},
severity_sort = true,
},
capabilities = {},
autoformat = true,
format = {
formatting_options = nil,
timeout_ms = nil,
},
servers = {
lua_ls = {
settings = {
Lua = {
workspace = {
checkThirdParty = false,
},
completion = {
callSnippet = "Replace",
},
},
},
},
},
setup = { },
},
config = function(_, opts)
local icons = {
diagnostics = {
Error = " ",
Warn = " ",
Hint = " ",
Info = " ",
Information = " ",
}
}
-- diagnostics
for name, icon in pairs(icons.diagnostics) do
name = "DiagnosticSign" .. name
vim.fn.sign_define(name, { text = icon, texthl = name, numhl = "" })
end
if type(opts.diagnostics.virtual_text) == "table" and opts.diagnostics.virtual_text.prefix == "icons" then
opts.diagnostics.virtual_text.prefix = vim.fn.has("nvim-0.10.0") == 0 and "●"
or function(diagnostic)
for d, icon in pairs(icons.diagnostics) do
if diagnostic.severity == vim.diagnostic.severity[d:upper()] then
return icon
end
end
end
end
vim.diagnostic.config(vim.deepcopy(opts.diagnostics))
local servers = opts.servers
local capabilities = vim.tbl_deep_extend(
"force",
{},
vim.lsp.protocol.make_client_capabilities(),
require("cmp_nvim_lsp").default_capabilities(),
opts.capabilities or {}
)
local function setup(server)
local server_opts = vim.tbl_deep_extend("force", {
capabilities = vim.deepcopy(capabilities),
}, servers[server] or {})
if opts.setup[server] then
if opts.setup[server](server, server_opts) then
return
end
elseif opts.setup["*"] then
if opts.setup["*"](server, server_opts) then
return
end
end
require("lspconfig")[server].setup(server_opts)
end
-- get all the servers that are available thourgh mason-lspconfig
local have_mason, mlsp = pcall(require, "mason-lspconfig")
local all_mslp_servers = {}
if have_mason then
all_mslp_servers = vim.tbl_keys(require("mason-lspconfig.mappings.server").lspconfig_to_package)
end
local ensure_installed = {} ---@type string[]
for server, server_opts in pairs(servers) do
if server_opts then
server_opts = server_opts == true and {} or server_opts
-- run manual setup if mason=false or if this is a server that cannot be installed with mason-lspconfig
if server_opts.mason == false or not vim.tbl_contains(all_mslp_servers, server) then
setup(server)
else
ensure_installed[#ensure_installed + 1] = server
end
end
end
if have_mason then
mlsp.setup({ ensure_installed = ensure_installed })
mlsp.setup_handlers({ setup })
end
end,
},
-- cmdline tools and lsp servers
{
"williamboman/mason.nvim",
cmd = "Mason",
keys = { { "<leader>cm", "<cmd>Mason<cr>", desc = "Mason" } },
opts = {
ensure_installed = {
"typescript-language-server",
},
},
config = function(_, opts)
require("mason").setup(opts)
local mr = require("mason-registry")
local function ensure_installed()
for _, tool in ipairs(opts.ensure_installed) do
local p = mr.get_package(tool)
if not p:is_installed() then
p:install()
end
end
end
if mr.refresh then
mr.refresh(ensure_installed)
else
ensure_installed()
end
end,
},
}
O código acima instala o plugin Mason e o plugin nvim-lspconfig e suas dependências, e adiciona a integração entre eles.
O nvim-lspconfig fornece uma série de configurações prontas pra gente não precisar fazer tudo do zero, pois seria muito tedioso.
O Mason por sua vez serve para instalar os language servers em uma interface mais intuitiva.
Após salvar o arquivo, reinicie o Neovim e você verá o lazy.nvim instalar os plugins recém adicionados. Para acessar o Mason, basta utilizar o comando :Mason.

LuaSnip
Podemos incrementar ainda mais as funções dos servidores de linguagem adicionando snippets de código. Snippets são templates de código reutilizáveis para facilitar a programação. No momento em que escrevo esta postagem, requer Neovim versão 0.7 ou mais recente.
Para instalar o LuaSnip, adicione o arquivo luasnip.lua
na pasta plugins
com o seguinte código:
return {
"L3MON4D3/LuaSnip",
build = "make install_jsregexp",
lazy = true,
dependencies = {
"rafamadriz/friendly-snippets",
config = function()
require("luasnip.loaders.from_vscode").lazy_load()
end,
},
opts = {
history = true,
delete_check_events = {"InsertEnter"},
region_check_events = {"InsertLeave", "InsertEnter"}
}
}
nvim-cmp
Por fim, para tirar maior proveito dos servidores de linguagem, é necessário instalar um plugin que vai auxiliar na função de autocompletar o código. O nvim-cmp serve para exibir o menu de contexto com as opções de código enquanto você digita, ou quando pressionar Ctrl + espaço.
Para configurar o nvim-cmp, crie o arquivo cmp.lua
na pasta de plugins
com o código abaixo:
return {
"hrsh7th/nvim-cmp",
version = false,
event = "InsertEnter",
dependencies = {
"hrsh7th/cmp-nvim-lsp",
"hrsh7th/cmp-buffer",
"hrsh7th/cmp-path",
"saadparwaiz1/cmp_luasnip",
},
opts = function()
local cmp = require("cmp")
local luasnip = require("luasnip")
local has_words_before = function()
unpack = unpack or table.unpack
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
end
return {
completion = {
completeopt = "menu,menuone",
get_trigger_characters = function (trigger_characters)
-- Don't open cmp suggestions on space or tab
local filter_characters = function(char)
return char ~= ' ' and char ~= '\t'
end
return vim.tbl_filter(filter_characters, trigger_characters)
end
},
snippet = {
expand = function(args)
require("luasnip").lsp_expand(args.body)
end,
},
mapping = {
["<C-p>"] = cmp.mapping.select_prev_item(),
["<C-n>"] = cmp.mapping.select_next_item(),
["<C-d>"] = cmp.mapping.scroll_docs(-4),
["<C-f>"] = cmp.mapping.scroll_docs(4),
["<C-Space>"] = cmp.mapping.complete(),
["<C-e>"] = cmp.mapping.close(),
["<CR>"] = cmp.mapping.confirm {
behavior = cmp.ConfirmBehavior.Replace,
select = false,
}, -- Tab, Shift + Tab to cycle through list
['<Tab>'] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_next_item()
elseif luasnip.expand_or_locally_jumpable() then
luasnip.expand_or_jump()
elseif has_words_before() then
cmp.complete()
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' }),
},
sources = cmp.config.sources({
{
name = "nvim_lsp",
max_item_count = 15,
priority = 1000,
entry_filter = function(entry)
return cmp.lsp.CompletionItemKind.Snippet ~= entry:get_kind()
end
},
{ name = "luasnip", max_item_count = 5, priority = 750 },
{ name = "path", max_item_count = 5, priority = 500 },
{ name = "buffer", max_item_count = 5, priority = 250 },
}),
formatting = {
format = function(_, item)
local icons = {
Text = "",
Method = "",
Function = "",
Constructor = "",
Field = "",
Variable = "",
Class = "",
Interface = "",
Module = "",
Property = "",
Unit = "",
Value = "",
Enum = "",
Keyword = "",
Snippet = "",
Color = "",
File = "",
Reference = "",
Folder = "",
EnumMember = "",
Constant = "",
Struct = "",
Event = "",
Operator = "",
TypeParameter = ""
}
if icons[item.kind] then
item.kind = icons[item.kind] .. ' ' .. item.kind
end
return item
end,
},
experimental = {
ghost_text = {
hl_group = "LspCodeLens",
},
},
}
end,
}
Utilize o Mason para instalar os LSPs desejados, e reinicie o Neovim. Você terá uma instalação com LSP completamente funcional, com função de autocompletar código, verificação de erros, sintaxe melhorada, entre muitas outras funcionalidades.
⚠️ Importante! Alguns servidores de linguagem necessitam que o NodeJs esteja instalado, portanto, instale a última versão LTS disponível para garantir máxima compatibilidade, e garanta que o comando node e npm estejam acessíveis no terminal.
O nvim-cmp define algumas teclas de atalho, conforme segue:
- Ctrl + p ou Shift + Tab: Seleciona o item anterior na lista de sugestões
- Ctrl + n ou Tab: Seleciona o próximo item na lista de sugestões
- Ctrl + d e Ctrl + f: Se estiver vendo a documentação de um método, serve para navegar para cima ou para baixo
- Ctrl + espaço: Aciona o autocompletar
- Ctrl + e: Fecha a lista de sugestões
- Enter: Confirma a seleção na lista de sugestões

Telescope e Oil
Outra parte importante para quem trabalha com programação, é conseguir navegar entre os arquivos do projeto com facilidade. Muita gente gosta de usar aquela árvore do projeto, que geralmente fica do lado esquerdo da janela do editor, entretanto, minha abordagem vai ser um pouco diferente, pois não teremos uma árvore de navegação visível.
Vamos usar o Telescope para abrir arquivos do projeto, ou alternar entre os arquivos abertos sem usar abas, e quando for necessário criar novas pastas e arquivos, usamos o Oil para realizar as modificações sem precisar sair do Neovim.
Para instalar o Telescope, é necessário atender aos requisitos abaixo:
- Neovim versão 0.9 ou mais recente
- plenary.nvim (já instalado previamente)
- ripgrep: Pesquisa textual dentro de arquivos do projeto
- fd: Pesquisa de arquivos
- nvim-treesitter (já instalado previamente)
- LSP (já instalado previamente)
- nvim-webdev-icons (já instalado previamente)
Depois que estiver com as dependencias instaladas, crie o arquivo telescope.lua
na pasta plugins
e adicione o seguinte código:
return {
"nvim-telescope/telescope.nvim",
lazy = true,
cmd = "Telescope",
version = false,
dependencies = {
{ 'nvim-telescope/telescope-fzf-native.nvim', build = 'make' }
},
config = function()
require('telescope').setup({
defaults = {
prompt_prefix = " ",
selection_caret = " ",
sorting_strategy = "ascending",
scroll_strategy = "limit",
layout_strategy = "vertical",
layout_config = {
vertical = {
prompt_position = "top",
mirror = true
}
}
}
})
require('telescope').load_extension('fzf')
end,
keys = {
-- find
{ "<leader>fb", "<cmd>Telescope buffers<cr>", desc = "Buffers" },
{ "<leader>ff", function() require('telescope.builtin').find_files({ hidden = true }) end, desc = "Find Files (root dir)" },
{ "<leader>fF", function() require('telescope.builtin').find_files({ hidden = true, cwd = false }) end, desc = "Find Files (cwd)" },
{ "<leader>fr", "<cmd>Telescope oldfiles<cr>", desc = "Recent" },
-- search
{ "<leader>sb", "<cmd>Telescope current_buffer_fuzzy_find<cr>", desc = "Buffer" },
{ "<leader>sd", "<cmd>Telescope diagnostics bufnr=0<cr>", desc = "Document diagnostics" },
{ "<leader>sD", "<cmd>Telescope diagnostics<cr>", desc = "Workspace diagnostics" },
{ "<leader>sg", function() require('telescope.builtin').live_grep() end, desc = "Grep (root dir)" },
{ "<leader>sG", function() require('telescope.builtin').live_grep({ cwd = false }) end, desc = "Grep (cwd)" },
{ "<leader>sk", "<cmd>Telescope keymaps<cr>", desc = "Key Maps" },
{ "<leader>sm", "<cmd>Telescope marks<cr>", desc = "Jump to Mark" },
{ "<leader>sr", "<cmd>Telescope resume<cr>", desc = "Resume" },
{ "<leader>sw", function() require('telescope.builtin').grep_string() end, desc = "Word (root dir)" },
{ "<leader>sW", function() require('telescope.builtin').grep_string({ cwd = false }) end, desc = "Word (cwd)" },
{
"<leader>ss",
function()
require('telescope.builtin').lsp_document_symbols({
symbols = {
"Class",
"Function",
"Method",
"Constructor",
"Interface",
"Module",
"Struct",
"Trait",
"Field",
"Property",
},
})
end,
desc = "Goto Symbol",
},
{
"<leader>sS",
function()
require('telescope.builtin').lsp_dynamic_workspace_symbols({
symbols = {
"Class",
"Function",
"Method",
"Constructor",
"Interface",
"Module",
"Struct",
"Trait",
"Field",
"Property",
},
})
end,
desc = "Goto Symbol (Workspace)",
},
},
}
O código acima instala o plugin Telescope, e adiciona o suporte ao fzf, que é uma pesquisa super rápida de arquivos nos diretórios do projeto. Além disso, adiciona algumas teclas de atalho pra facilitar a utilização. Abaixo estão as principais:
- <leader>fb: Exibe a lista de arquivos (buffers) abertos
- <leader>ff: Abre a pesquisa de arquivos a partir do diretório onde o Neovim foi aberto
- <leader>fr: Reabre a última pesquisa do Telescope, útil para continuar a verificar arquivos de uma lista de pesquisa anterior
- <leader>sg: Abre a pesquisa textual de arquivos no projeto, ou seja, exibe arquivos que contenham determinado texto.
- <leader>sk: Exibe as teclas de atalho configuradas
- <leader>ss: Exibe a lista de símbolos do documento. Símbolos dependem do contexto, mas, num código fonte, podem ser nomes de métodos e variáveis.
Gostaria de lembrar que a tecla <leader>
foi mapeada para a tecla espaço
anteriormente, portanto, caso você tenha configurado uma tecla diferente, basta utilizá-la.

Oil.nvim
O Oil.nvim servirá como gerenciador de arquivos, onde você poderá criar, renomear e excluir arquivos e diretórios. Para instalar, crie o arquivo oil.lua na pasta plugins com o seguinte código:
return {
'stevearc/oil.nvim',
lazy = false,
dependencies = { "nvim-tree/nvim-web-devicons" },
opts = {
default_file_explorer = true,
columns = {
"icon",
},
float = {
padding = 4,
max_width = 100
}
},
config = function(_, opts)
require('oil').setup(opts)
end
}
Para abrir o Oil, basta utilizar o comando :Oil. Ele se parece muito com um buffer normal, e você edita os diretórios como se fosse um buffer mesmo.
Adicione novas linhas e dê nomes aos arquivos. Caso queira criar um diretório, basta terminar a linha com uma barra /. Quando você tentar salvar o buffer, será exibida a mensagem para confirmar as alterações no sistema de arquivos.

Você pode estar mais acostumado a usar uma árvore, e talvez queira manter assim no Neovim, e é perfeitamente compreensível. Existem opções caso você queira substituir o Oil por uma árvore de navegação, sendo uma delas o nvim-tree.
Com o conhecimento adquirido até agora, deve ser fácil para você alterar a configuração para substituir o Oil pelo nvim-tree. Tente você mesmo e me diga nos comentários o que achou das duas alternativas.
Atalhos de teclado
Finalmente, com todos os plugins instalados, podemos adicionar os atalhos de teclado para facilitar o acesso a algumas funções. Crie o arquivo keymaps.lua na pasta fsg (se você criou a pasta com outro nome, substitua) e adicione o código abaixo:
--[[
-- All keymaps are grouped in this file for convenience
--]]
local function map(mode, lhs, rhs, options)
local default_options = { noremap = true, silent = true }
if options then
default_options = vim.tbl_extend('force', default_options, options)
end
vim.api.nvim_set_keymap(mode, lhs, rhs, default_options)
end
-- Oil
map('n', '<leader>e', '<cmd>Oil<CR>')
-- Close current buffer
map('n', '<leader>fa', '<cmd>bd<CR>', { desc = "Close current buffer" })
-- Close all buffers
map('n', '<leader>ft', '<cmd>%bd<CR>', { desc = "Close all buffers" })
-- Paste replacing selected text, without losing data
map('x', '<leader>p', '"_dP', { desc = "Paste without losing clipboard content" })
-- Delete without yanking
map('x', '<leader>d', '"_d', { desc = "Delete without yanking" })
-- jk exits insert mode and abandon any snippets
vim.keymap.set('i', 'jk', function ()
local luasnip = require("luasnip")
local current_nodes = luasnip.session.current_nodes
if current_nodes then
if current_nodes[vim.api.nvim_get_current_buf()] then
current_nodes[vim.api.nvim_get_current_buf()] = nil
end
end
vim.cmd("stopinsert")
end)
-- Create/resize splits
map('n', '<leader>|', '<cmd>vs<CR>', { desc = "Create vertical split" })
map('n', '<leader>-', '<cmd>sp<CR>', { desc = "Create horizontal split" })
map('n', '<leader>q', '<cmd>q<CR>', { desc = "Quit" })
map('n', '<C-Up>', '<cmd>resize +2<CR>', { desc = "Increase horizontal split size" })
map('n', '<C-Down>', '<cmd>resize -2<CR>', { desc = "Decrease horizontal split size" })
map('n', '<C-Left>', '<cmd>vertical resize -2<CR>', { desc = "Decrease vertical split size" })
map('n', '<C-Right>', '<cmd>vertical resize +2<CR>', { desc = "Increase vertical split size" })
-- Use LspAttach autocommand to only map the following keys
-- after the language server attaches to the current buffer
vim.api.nvim_create_autocmd('LspAttach', {
group = vim.api.nvim_create_augroup('UserLspConfig', {}),
callback = function(ev)
-- Enable completion triggered by <c-x><c-o>
vim.bo[ev.buf].omnifunc = 'v:lua.vim.lsp.omnifunc'
-- Buffer local mappings.
-- See `:help vim.lsp.*` for documentation on any of the below functions
local opts = { buffer = ev.buf, desc = "Go to previous diagnostic" }
vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, opts)
opts = { buffer = ev.buf, desc = "Go to next diagnostic" }
vim.keymap.set('n', ']d', vim.diagnostic.goto_next, opts)
opts = { buffer = ev.buf, desc = "Go to declaration" }
vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, opts)
opts = { buffer = ev.buf, desc = "Go to definition" }
vim.keymap.set('n', 'gd', vim.lsp.buf.definition, opts)
opts = { buffer = ev.buf, desc = "Show documentation" }
vim.keymap.set('n', 'K', vim.lsp.buf.hover, opts)
opts = { buffer = ev.buf, desc = "Go to implementation" }
vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, opts)
opts = { buffer = ev.buf, desc = "Signature help" }
vim.keymap.set('n', '<C-k>', vim.lsp.buf.signature_help, opts)
opts = { buffer = ev.buf, desc = "Type definition" }
vim.keymap.set('n', '<space>D', vim.lsp.buf.type_definition, opts)
opts = { buffer = ev.buf, desc = "Rename" }
vim.keymap.set('n', '<f2>', vim.lsp.buf.rename, opts)
opts = { buffer = ev.buf, desc = "Code action" }
vim.keymap.set({ 'n', 'v' }, '<space>ca', vim.lsp.buf.code_action, opts)
opts = { buffer = ev.buf, desc = "Find references" }
vim.keymap.set('n', 'gr', vim.lsp.buf.references, opts)
opts = { buffer = ev.buf, desc = "Format buffer" }
vim.keymap.set('n', '<space>fc', function()
vim.lsp.buf.format { async = true }
end, opts)
end
})
No código acima, definimos diversos atalhos de teclado para as funções do editor e de alguns plugins que instalamos. Segue abaixo a explicação das principais:
- <leader>e: Abre o Oil para poder modificar o sistema de arquivos
- <leader>fa: Fecha o arquivo (buffer) atual (se não tiver modificações)
- <leader>ft: Fecha todos os arquivos (buffers) abertos (se não tiver modificações)
- <leader>p: Cola o conteúdo da área de transferência sem sobrescrever o registrador
- <leader>d: Remova o texto selecionado sem copiar
- jk: Sai do modo insert e abandona qualquer snippet que não tenha sido completado
- <leader>q: Fechar o Neovim
Foram adicionados alguns atalhos quando um servidor de linguagem é ligado para o arquivo que foi aberto:
- [d: Vai para oitem anterior de diagnóstico do arquivo
- ]d: Vai para o próximo item de diagnóstico do arquivo
- gd: Vai para a declaração de uma variável, método ou classe
- K: Exibe a documentação do método
- gi: Vai para a implementação da interface ou método
- F2: Renomear uma variável, classe ou método
- <leader>ca: Ações contextuais de código. As opções dependem do servidor LSP que está ligado ao editor no momento.
- gr: Exibe a lista de referências para um classe, método ou variável
- <leader>fc: Formata o código
Outros plugins
Neste ponto, apesar de já ter um editor bastante funcional, vale a pena dar uma olhada em alguns plugins para ampliar ainda mais as funcionalidades do editor. Confira abaixo que eu utilizo diariamente:
- fidget.nvim: Melhora a aparência das mensagens exibidas pelo Neovim.
- leap.nvim: Adiciona uma funcionalidade de navegação vertical no texto que é exibido na tela.
- mini.pairs: Adiciona a funcionalidade de fechar aspas, parênteses, chaves e colchetes automaticamente quando são abertas.
- mini.comment: Adiciona mais opções de comentários
- trouble.nvim: Exibe uma lista de problemas de código do projeto, com avisos e erros, permitindo a navegação até eles.
- which-key.nvim: Ao pressionar uma tecla de atalho, exibe na parte inferior da tela uma lista das teclas que podem ser pressionadas na sequência e os comandos que elas acionam. É útil para ajudar a decorar os atalhos.
Importante
A medida que você for instalando novos plugins, sempre execute o comando :checkhealth
para verificar se existe algum ponto que necessita de atenção. Muitos plugins possuem sua própria sessão de verificação no :checkhealth
, e vários problemas podem ser resolvidos analisando as mensagens exibidas lá.
Conclusão
Existem no mercado algumas distribuições do Neovim que já vem com quase tudo o que eu citei nesta série pré instalado, porém, eu acredito que é bom saber fazer as coisas por conta própria, caso necessite de alguma intervenção manual na sua configuração.
Eu, particularmente, gosto de botar a mão na massa e fazer acontecer, para que, no final, eu tenha algo pra me orgulhar.
Se você quiser usar a configuração pronta, visite meu perfil do github, faça um clone, explore…
E você, conseguiu criar a sua configuração do Neovim em lua? Diga nos comentários como foi sua experiência e se você teve alguma dificuldade.