Antes de começar, recomendo dar uma olhada na primeira parte, onde mostrei como configurar o Neovim do zero, começando pela instalação e configuração do terminal e terminando com uma série de plugins essenciais para trabalhar com código:
Guia completo para configurar o NeoVim para desenvolvedores - parte 1
Neovim (nvim) é o mesmo vim, só que melhorado, reescrito e que atraiu para o seu lado boa parte da comunidade do editor original. Hoje esse projeto ultrapassou de longe o vim original nas estatísticas do github (34 vs 75k estrelas em 2024), então se por algum motivo você decidiu começar a programar no terminal

O material abaixo é melhor lido depois de ler e reproduzir o que foi descrito na primeira parte. Mas, caso você já tenha uma configuração pronta e precise adicionar algum dos plugins descritos abaixo, você conseguirá fazer isso sem problemas: procurei descrever todos os plugins de forma independente uns dos outros, em subseções separadas.
Antes de partir para a configuração do editor, proponho ajustar um pouco o nosso terminal — o wezterm, que instalamos e configuramos na primeira parte.
Estou mostrando a configuração tanto do editor quanto do terminal para Mac, então as ações seguintes com o terminal servem para usuários de Macos. Se você usa Linux, é bem provável que os problemas com o terminal resolvidos abaixo nem apareçam para você, e pode ir direto para a configuração dos plugins.
Mapeando a tecla Command para trabalhar com wezterm e neovim
Ao longo do trabalho percebi que é muito mais confortável mapear diferentes combinações na tecla Command. Por exemplo, por padrão no vim/neovim, para ir até a janela vizinha é preciso apertar Control + w, o que, para dizer o mínimo, não é muito prático. É bem mais confortável redefinir todas as combinações de Control para Command. Definir combinações no neovim não é difícil, normalmente isso é feito pelo comando
vim.api.nvim_set_keymap(mode, combination, command, options...)Mas a particularidade do wezterm, assim como da maioria dos outros terminais para mac, é que eles não passam a combinação para o editor de forma legível (se você sabe como fazer isso de um jeito mais simples, escreve nos comentários). A forma como eu faço é a seguinte: fazemos o bind, no config do wezterm, de todas as combinações que precisamos como caracteres utf8, que serão enviados ao neovim. Depois, no config do neovim, fazemos o bind das combinações usando esses caracteres utf-8 já recebidos.
Config no wezterm:
--- cmd+keys that we want to send to neovim.
local super_vim_keys_map = {
-- Command + s: saving file
s = utf8.char(0xAA),
-- Command + e: scroll downwords (ctrl + e analog)
e = utf8.char(0xAB),
-- Command + y: scroll upwords (ctrl + y analog)
y = utf8.char(0xAC),
-- Command + h: go to prev tab
h = utf8.char(0xAD),
-- Command + l: go to next tab
l = utf8.char(0xAE),
-- Command + w: close current tab
w = utf8.char(0xAF),
-- Command + t: find file toogle (NvimTree)
t = utf8.char(0xA1),
}
local function bind_super_key_to_vim(key)
return {
key = key,
mods = 'CMD',
action = wezterm.action_callback(function(win, pane)
local char = super_vim_keys_map[key]
if char and is_vim(pane) then
-- pass the keys through to vim/nvim
win:perform_action({
SendKey = { key = char, mods = nil },
}, pane)
else
win:perform_action({
SendKey = {
key = key,
mods = 'CMD'
}
}, pane)
end
end)
}
end
local keys = {
...,
bind_super_key_to_vim('s'),
bind_super_key_to_vim('h'),
bind_super_key_to_vim('l'),
bind_super_key_to_vim('w'),
bind_super_key_to_vim('e'),
bind_super_key_to_vim('y'),
bind_super_key_to_vim('t'),
bind_super_key_to_vim('['),
bind_super_key_to_vim(']'),
bind_super_key_to_vim('n'),
bind_super_key_to_vim('m')
}
config.keys = keys
return configO código completo do config pode ser encontrado aqui.
E em seguida mapeamos esses caracteres utf8 já do lado do neovim. Criamos um arquivo lua onde vamos definir todos os mapeamentos — combinations.lua:
local keymap = vim.api.nvim_set_keymap
local default_opts = {noremap = true, silent = true}
-- cmd+s: save file
keymap("n", "<Char-0xAA>", "<cmd>write<cr>", default_opts)
-- cmd+e: scroll downwords
keymap("n", "<Char-0xAB>", "<C-e>", default_opts)
-- cmd+e: scroll upwords
keymap("n", "<Char-0xAC>", "<C-y>", default_opts)
-- cmd+h: next tab
keymap("n", "<Char-0xAD>", "<cmd>BufferPrevious<cr>", default_opts)
-- cmd+l: last tab
keymap("n", "<Char-0xAE>", "<cmd>BufferNext<cr>", default_opts)
-- cmd+w: close current tab
keymap("n", "<Char-0xAF>", "<cmd>BufferClose<cr>", default_opts)
-- cmd+t: find file toogle
keymap("n", "<Char-0xA1>", "<cmd>NvimTreeFindFile<cr>", default_opts)
-- cmd+1: open left bar
keymap('n', '<Char-0xA4>', '<cmd>NvimTreeToggle<cr>', default_opts)Agora incluímos esse arquivo na seção com require no init.lua:
...
require"combinations"Agora reiniciamos o neovim e testamos: se você abrir algum arquivo e apertar command + t, o neovim vai automaticamente te levar até esse arquivo na árvore de arquivos.
Agora, se você voltar para o arquivo e apertar Command + e, o nvim vai começar a rolar o arquivo para baixo, Command + y — para cima. Command + s salva o arquivo, e Command + h / Command + l alternam entre as diferentes abas dentro do neovim. Agora podemos partir para a configuração dos plugins.
Telescope - busca por arquivos e conteúdo
O primeiro plugin que uso constantemente é o Telescope. No momento, é o plugin mais popular para busca por arquivos e por conteúdo. Uso ele já há alguns anos e posso dizer que, na maioria dos casos, o plugin dá conta muito bem das suas tarefas.
Para a busca pelo conteúdo dos arquivos, o plugin usa a ferramenta de busca no terminal fzf. Antes de partir para os plugins, precisamos instalá-la:
brew install fzfE, depois de instalar, carregá-la na sessão atual do terminal:
source <(fzf --zsh)Depois, nessa mesma sessão, abrimos o nvim e criamos o arquivo telescope_config.lua:
-- Use vim.keymap.set instead of vim.api.nvim_set_keymap
local keymap = vim.keymap.set
-- Map <leader>f to fzf-lua's file search
keymap("n", "<leader>f", require("fzf-lua").files, { desc = "Fzf files" })
-- Map <leader>g to fzf-lua's live grep
keymap("n", "<leader>g", require("fzf-lua").live_grep, { desc = "Fzf live grep" })Incluímos os plugins necessários e o config no init.lua:
...
-- Telescope
Plug('nvim-lua/plenary.nvim') --for fzf
Plug('nvim-telescope/telescope.nvim', { [ 'tag' ] = '0.1.4' })
Plug('ibhagwan/fzf-lua', {['branch'] = 'main'})
...
require"telescope_config"Reiniciamos, pulamos o erro apertando enter e executamos :PlugInstall. Depois da instalação, reiniciamos mais uma vez. Agora apertamos a combinação \ + f
e vemos a janela de busca por arquivos:

Depois apertamos a combinação \ + g e vemos a janela de busca por conteúdo:

Autosession
Autosession é um plugin que adiciona algo muito familiar para nós — ele memoriza quais arquivos estavam abertos antes de fechar o nvim e os abre automaticamente na próxima vez que o nvim for aberto.
Criamos o arquivo autosession.lua:
require'auto-session'.setup {
suppressed_dirs = { "~/", "~/Projects", "~/Downloads", "/"},
auto_restore_last_session = true
}Depois, no init.lua, incluímos o arquivo e o config dele no init.lua:
Plug('rmagatti/auto-session')
...
require"autosession"Instalamos, reiniciamos e testamos:

Comment - comentários no código
Agora vamos adicionar mais um recurso básico — a possibilidade de comentar e descomentar código. Para isso eu uso o plugin Comment — ele funciona out of the box e tem suporte a treesitter, o que nos dá suporte à maioria das linguagens de programação.
Criamos o arquivo comment_config.lua:
require('Comment').setup()Depois incluímos o plugin e o config dele no init.lua:
...
Plug('numToStr/Comment.nvim')
...
require("comment_config")Instalamos, reiniciamos e, em seguida, selecionando qualquer trecho de código pelo modo visual (Shift+V + ↑/↓), com a combinação gc podemos comentar e descomentar de volta o trecho de código selecionado:

Trouble
O nvim tem suas próprias ferramentas para exibir erros no código, mas chegar até elas, para dizer o mínimo, não é nada simples.
Trouble é um plugin que adiciona uma interface para exibir todos os erros do projeto aberto. O Trouble tem suporte ao lsp-server, o que nos permite ver todos os erros de forma familiar, com comentários claros.
Criamos o config trouble_config.lua:
require('trouble').setup()
vim.keymap.set("n", "<leader>xx", function() require("trouble").toggle() end)
vim.keymap.set("n", "<leader>xw", function() require("trouble").toggle("workspace_diagnostics") end)
vim.keymap.set("n", "<leader>xd", function() require("trouble").toggle("document_diagnostics") end)
vim.keymap.set("n", "<leader>xq", function() require("trouble").toggle("quickfix") end)
vim.keymap.set("n", "<leader>xl", function() require("trouble").toggle("loclist") end)
vim.keymap.set("n", "gR", function() require("trouble").toggle("lsp_references") end)init.lua:
...
Plug('folke/trouble.nvim')
...
require"trouble_config"
...O plugin já vem com um conjunto de combinações prontas para uso, mas eu reconfigurei a abertura da interface para a combinação Command + [.
Para fazer o mesmo, é preciso voltar ao config do wezterm e adicionar mais uma combinação para abrir o Trouble pelo Command:
wezterm.lua:
-- Command + [: open trouble window
['['] = utf8.char(0xA2),
-- Command + ]: close trouble window
[']'] = utf8.char(0xA3),
...
bind_super_key_to_vim('['),
bind_super_key_to_vim(']'),
...Depois adicionamos essas combinações no config do nvim:
combinations.lua:
...
-- cmd+[: get troubles
keymap("n", "<Char-0xA2>", "<cmd>Trouble diagnostics toggle<cr>", default_opts)
-- cmd+]: close troubles
keymap("n", "<Char-0xA3>", "<cmd>TroubleClose<cr>", default_opts)
...Reiniciamos e testamos:

git-blame - histórico interativo de commits
git-blame é um plugin minimalista que faz a mesma coisa que estamos acostumados a ver na IDE quando abrimos as anotações no código: exibe o autor e o nome do commit.
O plugin não precisa de configuração e, para ativá-lo, basta incluí-lo no init.lua:
Plug 'f-person/git-blame.nvim'E instalá-lo. Depois, passando o cursor sobre qualquer linha de um projeto com git, vemos:

Conclusão
Com isso, a configuração básica está concluída. Descrevi os plugins mais essenciais, que dão os recursos fundamentais aos quais estamos acostumados nas diversas IDEs.
Meu config é um pouco mais amplo do que o que mostrei acima. Por exemplo, lá tem plugins para trabalhar com testes, para um trabalho mais avançado com o git, para resolver conflitos de git, para uma busca e depuração de código mais convenientes.
Mas, para não alongar demais o texto, vou descrever esses plugins e a configuração deles em artigos separados.
Meu config completo, que é atualizado constantemente, pode ser encontrado aqui:
GitHub - itxor/go-rust-nvim-config
Contribute to itxor/go-rust-nvim-config development by creating an account on GitHub.
Config do wezterm:
wezterm_config/wezterm.lua at main · itxor/wezterm_config
Contribute to itxor/wezterm_config development by creating an account on GitHub.
Também mantenho um canal no telegram em inglês com um resumo de materiais sobre Go:
https://t.me/the_dev_signalE um canal autoral no telegram, onde escrevo diversas notas, ferramentas e compartilho experiências:
https://t.me/junseniorE não deixe de se inscrever para os novos materiais deste site, em breve eles vão começar a sair com mais frequência :)