---
title: "Configurar Neovim para Zig — LSP, Tree-sitter e Plugins"
url: "https://ziglang.com.br/instalacao/configurar-neovim-para-zig-lsp-tree-sitter-e-plugins/"
markdown_url: "https://ziglang.com.br/instalacao/configurar-neovim-para-zig-lsp-tree-sitter-e-plugins.MD"
description: "Guia completo para configurar o Neovim para desenvolvimento com Zig. LSP nativo, Tree-sitter, autocompletar, diagnósticos e plugins."
date: "2026-02-21"
author: "Zig Brasil"
---

# Configurar Neovim para Zig — LSP, Tree-sitter e Plugins

Guia completo para configurar o Neovim para desenvolvimento com Zig. LSP nativo, Tree-sitter, autocompletar, diagnósticos e plugins.


# Configurar Neovim para Zig

O **Neovim** é uma excelente escolha para desenvolvimento com Zig, oferecendo LSP nativo, Tree-sitter para syntax highlighting preciso e um ecossistema rico de plugins. Este guia mostra como configurar o Neovim para ter uma experiência de desenvolvimento completa com Zig, incluindo autocompletar, diagnósticos, formatação e navegação de código.

Antes de configurar o Neovim, certifique-se de que o Zig está instalado. Consulte o guia para sua plataforma no [guia completo de instalação](/instalacao/).

---

## Pré-requisitos

- **Neovim 0.9+** (recomendado 0.10+)
- **Zig instalado** e acessível no PATH
- **ZLS instalado** (Zig Language Server)
- **Git** para clonar plugins

### Verificar Versões

```bash
nvim --version | head -1
zig version
zls --version
```

### Instalar o ZLS

Se ainda não instalou o ZLS:

```bash
# Linux (x86_64)
curl -LO "https://github.com/zigtools/zls/releases/download/0.14.0/zls-x86_64-linux.tar.xz"
tar -xf "zls-x86_64-linux.tar.xz"
sudo mv zls /usr/local/bin/

# macOS
brew install zls

# Arch Linux
sudo pacman -S zls
```

---

## Configuração com lazy.nvim (Recomendado)

O [lazy.nvim](https://github.com/folke/lazy.nvim) é o gerenciador de plugins mais popular para Neovim. Vamos configurar tudo do zero.

### Estrutura de Arquivos

```
~/.config/nvim/
├── init.lua
├── lua/
│   ├── plugins/
│   │   ├── lsp.lua
│   │   ├── cmp.lua
│   │   └── treesitter.lua
│   └── config/
│       └── keymaps.lua
```

### init.lua Base

Crie ou edite `~/.config/nvim/init.lua`:

```lua
-- Bootstrap lazy.nvim
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)

-- Opções gerais
vim.g.mapleader = " "
vim.opt.number = true
vim.opt.relativenumber = true
vim.opt.tabstop = 4
vim.opt.shiftwidth = 4
vim.opt.expandtab = true
vim.opt.signcolumn = "yes"
vim.opt.termguicolors = true

-- Carregar plugins
require("lazy").setup("plugins")

-- Carregar keymaps
require("config.keymaps")
```

---

## Configuração do LSP (ZLS)

Crie `~/.config/nvim/lua/plugins/lsp.lua`:

```lua
return {
  {
    "neovim/nvim-lspconfig",
    dependencies = {
      "williamboman/mason.nvim",
      "williamboman/mason-lspconfig.nvim",
    },
    config = function()
      -- Configurar Mason (gerenciador de LSP servers)
      require("mason").setup()
      require("mason-lspconfig").setup({
        ensure_installed = { "zls" },
      })

      local lspconfig = require("lspconfig")

      -- Função para configurar keymaps quando o LSP conecta
      local on_attach = function(client, bufnr)
        local opts = { noremap = true, silent = true, buffer = bufnr }

        -- Navegação
        vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts)
        vim.keymap.set("n", "gD", vim.lsp.buf.declaration, opts)
        vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts)
        vim.keymap.set("n", "gr", vim.lsp.buf.references, opts)
        vim.keymap.set("n", "K", vim.lsp.buf.hover, opts)
        vim.keymap.set("n", "<C-k>", vim.lsp.buf.signature_help, opts)

        -- Ações
        vim.keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts)
        vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action, opts)
        vim.keymap.set("n", "<leader>f", function()
          vim.lsp.buf.format({ async = true })
        end, opts)

        -- Diagnósticos
        vim.keymap.set("n", "[d", vim.diagnostic.goto_prev, opts)
        vim.keymap.set("n", "]d", vim.diagnostic.goto_next, opts)
        vim.keymap.set("n", "<leader>e", vim.diagnostic.open_float, opts)
        vim.keymap.set("n", "<leader>q", vim.diagnostic.setloclist, opts)

        -- Formatar ao salvar
        if client.supports_method("textDocument/formatting") then
          vim.api.nvim_create_autocmd("BufWritePre", {
            buffer = bufnr,
            callback = function()
              vim.lsp.buf.format({ bufnr = bufnr })
            end,
          })
        end
      end

      -- Configurar ZLS
      lspconfig.zls.setup({
        on_attach = on_attach,
        settings = {
          zls = {
            enable_snippets = true,
            enable_autofix = true,
            enable_import_detection = true,
            warn_style = true,
            highlight_global_var_declarations = true,
          },
        },
      })

      -- Configuração de diagnósticos
      vim.diagnostic.config({
        virtual_text = true,
        signs = true,
        underline = true,
        update_in_insert = false,
        severity_sort = true,
        float = {
          border = "rounded",
          source = true,
        },
      })
    end,
  },
}
```

---

## Autocompletar com nvim-cmp

Crie `~/.config/nvim/lua/plugins/cmp.lua`:

```lua
return {
  {
    "hrsh7th/nvim-cmp",
    dependencies = {
      "hrsh7th/cmp-nvim-lsp",
      "hrsh7th/cmp-buffer",
      "hrsh7th/cmp-path",
      "L3MON4D3/LuaSnip",
      "saadparwaiz1/cmp_luasnip",
    },
    config = function()
      local cmp = require("cmp")
      local luasnip = require("luasnip")

      cmp.setup({
        snippet = {
          expand = function(args)
            luasnip.lsp_expand(args.body)
          end,
        },
        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 }),
          ["<Tab>"] = cmp.mapping(function(fallback)
            if cmp.visible() then
              cmp.select_next_item()
            elseif luasnip.expand_or_jumpable() then
              luasnip.expand_or_jump()
            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" },
          { name = "luasnip" },
        }, {
          { name = "buffer" },
          { name = "path" },
        }),
        formatting = {
          format = function(entry, vim_item)
            vim_item.menu = ({
              nvim_lsp = "[LSP]",
              luasnip = "[Snip]",
              buffer = "[Buf]",
              path = "[Path]",
            })[entry.source.name]
            return vim_item
          end,
        },
      })
    end,
  },
}
```

---

## Tree-sitter para Syntax Highlighting

Crie `~/.config/nvim/lua/plugins/treesitter.lua`:

```lua
return {
  {
    "nvim-treesitter/nvim-treesitter",
    build = ":TSUpdate",
    config = function()
      require("nvim-treesitter.configs").setup({
        ensure_installed = { "zig", "lua", "vim", "vimdoc", "c", "markdown" },
        auto_install = true,

        highlight = {
          enable = true,
          additional_vim_regex_highlighting = false,
        },

        indent = {
          enable = true,
        },

        incremental_selection = {
          enable = true,
          keymaps = {
            init_selection = "<C-space>",
            node_incremental = "<C-space>",
            scope_incremental = false,
            node_decremental = "<bs>",
          },
        },
      })
    end,
  },
}
```

---

## Keymaps Específicos para Zig

Crie `~/.config/nvim/lua/config/keymaps.lua`:

```lua
-- Atalhos gerais
local map = vim.keymap.set

-- Compilar e executar Zig
map("n", "<leader>zb", ":!zig build<CR>", { desc = "Zig build" })
map("n", "<leader>zr", ":!zig build run<CR>", { desc = "Zig build run" })
map("n", "<leader>zt", ":!zig build test<CR>", { desc = "Zig build test" })

-- Executar o arquivo atual
map("n", "<leader>zx", function()
  local file = vim.fn.expand("%")
  vim.cmd("!zig run " .. file)
end, { desc = "Zig run current file" })

-- Testar o arquivo atual
map("n", "<leader>zT", function()
  local file = vim.fn.expand("%")
  vim.cmd("!zig test " .. file)
end, { desc = "Zig test current file" })

-- Terminal integrado
map("n", "<leader>tt", ":terminal<CR>", { desc = "Abrir terminal" })
map("t", "<Esc>", "<C-\\><C-n>", { desc = "Sair do modo terminal" })
```

---

## Plugins Adicionais Recomendados

Para uma experiência mais completa, adicione estes plugins ao diretório `lua/plugins/`:

### Telescope (Fuzzy Finder)

```lua
-- lua/plugins/telescope.lua
return {
  {
    "nvim-telescope/telescope.nvim",
    dependencies = { "nvim-lua/plenary.nvim" },
    keys = {
      { "<leader>ff", "<cmd>Telescope find_files<cr>", desc = "Buscar arquivos" },
      { "<leader>fg", "<cmd>Telescope live_grep<cr>", desc = "Buscar texto" },
      { "<leader>fb", "<cmd>Telescope buffers<cr>", desc = "Listar buffers" },
      { "<leader>fh", "<cmd>Telescope help_tags<cr>", desc = "Ajuda" },
      { "<leader>fd", "<cmd>Telescope diagnostics<cr>", desc = "Diagnósticos" },
      { "<leader>fr", "<cmd>Telescope lsp_references<cr>", desc = "Referências LSP" },
    },
  },
}
```

### Lualine (Status Line)

```lua
-- lua/plugins/lualine.lua
return {
  {
    "nvim-lualine/lualine.nvim",
    config = function()
      require("lualine").setup({
        sections = {
          lualine_c = {
            { "filename", path = 1 },
          },
          lualine_x = { "encoding", "fileformat", "filetype" },
        },
      })
    end,
  },
}
```

---

## Verificação da Configuração

Após configurar tudo, reinicie o Neovim e verifique:

1. **LSP ativo:** Abra um arquivo `.zig` e execute `:LspInfo` para verificar se o ZLS está conectado
2. **Tree-sitter:** Execute `:TSInstallInfo` e verifique se `zig` está instalado
3. **Autocompletar:** Comece a digitar `std.` em um arquivo `.zig` e veja as sugestões

### Teste com Código Zig

Crie um arquivo `main.zig` e abra no Neovim:

```zig
const std = @import("std");

pub fn main() !void {
    const allocator = std.heap.page_allocator;
    var list = std.ArrayList(u32).init(allocator);
    defer list.deinit();

    try list.append(42);
    try list.append(100);

    const stdout = std.io.getStdOut().writer();
    for (list.items) |item| {
        try stdout.print("{} ", .{item});
    }
    try stdout.print("\n", .{});
}
```

Verifique se:
- A sintaxe é colorida corretamente (Tree-sitter)
- Ao digitar `std.`, aparecem sugestões (autocompletar)
- Erros são destacados em tempo real (diagnósticos)
- `gd` sobre `main` vai para a definição (navegação LSP)

---

## Problemas Comuns

### ZLS não conecta

Execute `:LspLog` para ver os logs do LSP. Causas comuns:

- ZLS não está no PATH
- Versão do ZLS incompatível com a versão do Zig
- Falta a dependência `nvim-lspconfig`

### Tree-sitter não funciona para Zig

Execute `:TSInstall zig` manualmente e reinicie o Neovim.

### Autocompletar lento

Verifique se não há muitos sources configurados no nvim-cmp e se o ZLS está na versão correta.

Para mais soluções, visite nossa página de [erros comuns](/erros/).

---

## Próximos Passos

Com o Neovim configurado para Zig:

1. **Crie seu primeiro projeto** — [Primeiro projeto Zig](/instalacao/zig-primeiro-projeto/)
2. **Aprenda a linguagem** — [Introdução ao Zig](/tutoriais/introducao-ao-zig/)
3. **Explore outros editores** — [VS Code](/instalacao/configurar-vscode-zig/) ou [Sublime/Emacs](/instalacao/configurar-sublime-emacs-zig/)
4. **Configure CI/CD** — [GitHub Actions com Zig](/instalacao/zig-ci-github-actions/)
5. **Veja exemplos** — [Receitas](/receitas/)
