2026-04-10

Escrever Go no GoLand já é uma experiência sólida. Adicionar o GitHub Copilot em cima deixa o combo quase injusto de bom. Mas tem uma pegadinha: o Copilot genérico tende a sugerir código que não é idiomático de Go (abuso de interfaces, erros engolidos, generics onde não cabe). Neste guia eu vou te mostrar a configuração que eu uso pra deixar o Copilot com cara de gopher, e os atalhos que mais economizam tempo no dia a dia.
Se você também trabalha com front-end, vale dar uma olhada no meu outro guia: GitHub Copilot no WebStorm: a melhor configuração para turbinar seu dia a dia.
Pra seguir esse tutorial, você vai precisar de:
Se você ainda está numa versão antiga do GoLand, atualize antes. Versões anteriores têm conflito entre Copilot e Full Line Code Completion disputando o Tab.
Cmd + , no Mac / Ctrl + Alt + S no Windows/Linux)GitHub Copilot na buscaNo GoLand 2025+ o plugin GitHub Copilot já inclui o chat. Se você só vê um plugin chamado GitHub Copilot, é ele que traz tudo junto.
Depois do restart, o ícone do Copilot aparece na barra inferior direita.
Quando o ícone ficar verde, o Copilot está pronto pra uso.
Esse é o passo mais importante pra quem quer o Tab funcionando sem surpresa. O GoLand tem o Full Line Code Completion nativo, que também ocupa o Tab e compete com o Copilot. Se ficar nos dois, você nunca sabe qual vai aceitar.
Insert Inline CompletionCmd + Shift + ] (Mac) / Ctrl + Shift + ] (Windows/Linux)Apply completions to Editor (do Copilot) no TabNa prática, pra Go eu prefiro a opção A: o Copilot sabe mais sobre o contexto do projeto todo e o Full Line acaba adicionando pouco.
Vá em Settings > Tools > GitHub Copilot > Completions e ajuste:
| Opção | Valor recomendado | Motivo |
|---|---|---|
| Show completions automatically | Ativo | Sugere conforme você digita |
| Automatically check for updates | Ativo | Mantém o plugin atualizado |
| Enable Copilot | Ativo | Controle fino fica na seção de linguagens |
Na seção Languages, a minha recomendação pro dia a dia com Go:
*_gen.go, *.pb.go, mock_*.go): o Copilot só atrapalha aquiSe você usa muito Bazel ou Buf, ative também os arquivos .bazel, .bzl, buf.yaml.
Abra o chat com Ctrl + Shift + C ou pela barra lateral direita, no ícone do Copilot.
Os três modos disponíveis:
Para habilitar o Agent Mode:
Esse é o segredo pra o Copilot parar de sugerir código JavaScript disfarçado de Go. Custom instructions são regras que o Copilot lê antes de cada resposta.
.github/ (se não existir)copilot-instructions.md# Instruções para o Copilot
Este é um serviço em Go 1.22+ que expõe uma API HTTP.
## Stack
- Go 1.22 (standard library preferida sempre que possível)
- Router: net/http com ServeMux novo (sem frameworks externos)
- Banco: PostgreSQL via pgx/v5 (sem ORM)
- Logging: log/slog estruturado em JSON
- Testes: testing padrão + testify para assertions
## Padrões idiomáticos obrigatórios
- Nunca engola erros: sempre retorne ou logue com contexto
- Use errors.Is / errors.As, nunca compare erros com ==
- Nunca use panic em código de produção, apenas em init ou main
- Receivers pointer só quando precisar mutar ou o struct for grande
- Funções que retornam error devem retornar (T, error), nunca o contrário
- Nunca nomeie variáveis com err genéricos quando há mais de um erro no escopo
- Use context.Context como primeiro parâmetro em qualquer função que toque I/O
## Testes
- Sempre use table-driven tests
- Subtests via t.Run com nomes descritivos
- Use t.Helper() em funções auxiliares de teste
- Use t.Cleanup ao invés de defer quando apropriado
- Mocks apenas para interfaces de I/O externo, nunca para lógica interna
## Concorrência
- Nunca crie goroutines sem um plano claro de término (context ou WaitGroup)
- Channels buferizados só com justificativa clara
- Proteja estado compartilhado com sync.Mutex, não com canais se for lock simples
- Prefira errgroup.Group para fan-out com erro
## O que nunca fazer
- Nunca usar init() para lógica de negócio
- Nunca usar variáveis globais mutáveis
- Nunca retornar nil para slice ou map quando o chamador espera iterar (retorne vazio)
- Nunca ignorar o retorno de Close() em arquivos e conexões
Salve, reinicie o chat e vai sentir a diferença na primeira sugestão.
Pra regras que valem pra todos os projetos Go:
A partir da versão 2026.2 o Copilot lê também AGENTS.md e CLAUDE.md aninhados. Se você já usa Claude Code, reaproveita o mesmo arquivo: Settings > Tools > GitHub Copilot > Customizations > Enable nested AGENTS.md and CLAUDE.md.
| Ação | Mac | Windows/Linux |
|---|---|---|
| Aceitar sugestão completa | Tab | Tab |
| Rejeitar sugestão | Esc | Esc |
| Aceitar linha por linha | Shift + Option + → | Shift + Alt + → |
| Próxima sugestão | Shift + Option + ] | Shift + Alt + ] |
| Sugestão anterior | Shift + Option + [ | Shift + Alt + [ |
| Forçar sugestão (chamar manualmente) | Shift + Option + \ | Shift + Alt + \ |
| Abrir painel de sugestões (10 opções) | Cmd + Shift + A > Open Copilot | Ctrl + Shift + A > Open Copilot |
Importante pra quem usa teclado ABNT2: o padrão oficial do Copilot é
Option + ],Option + [eOption + \, mas no teclado brasileiro essas combinações geram caracteres tipográficos («,», entre outros) e nunca chegam no Copilot. A solução é adicionarShiftna combinação (viraShift + Option + ...), que é o que deixei na tabela acima. Se você usar teclado US, pode usar o padrão sem oShift.
| Ação | Mac | Windows/Linux |
|---|---|---|
| Abrir inline chat no cursor | Ctrl + Shift + I | Ctrl + Shift + G |
| Executar prompt | Enter | Enter |
| Cancelar | Esc | Esc |
Com o inline chat você seleciona uma função, aperta Ctrl + Shift + I, digita “escreve table-driven tests pra essa função” e o Copilot gera direto no arquivo de teste.
| Ação | Mac | Windows/Linux |
|---|---|---|
| Abrir janela de chat | Ctrl + Shift + C | Ctrl + Shift + C |
| Nova conversa | Cmd + N dentro do chat | Ctrl + N dentro do chat |
| Focar campo de input | Cmd + L | Ctrl + L |
| Anexar arquivo ao contexto | #nome-do-arquivo.go | Idem |
Em Settings > Keymap, busca copilot e você vai ver que o plugin só expõe algumas ações bindáveis (copilot.chat.show, copilot.chat.inline, copilot.openCopilot, copilot.applyInlays, copilot.cycleNextInlays, copilot.cyclePrevInlays e copilot.requestCompletions). As funcionalidades tipo “explain”, “fix”, “generate tests” não são ações do plugin: são slash commands que você digita dentro do chat (veja a próxima seção).
O que eu deixo no meu keymap:
| Ação do plugin | Atalho customizado |
|---|---|
copilot.chat.show (abrir janela de chat) | Cmd + Shift + K |
copilot.chat.inline (abrir inline chat no cursor) | Cmd + Shift + I |
copilot.openCopilot (tool window do Copilot) | Ctrl + Option + \ |
Se algum atalho conflitar, o Keymap avisa. O Cmd + Shift + K por padrão abre o Push… do Git no GoLand: eu prefiro acionar Push pelo menu e libero a tecla pro Copilot. Se você usa Push pelo atalho, escolha outra combinação (tipo Cmd + Alt + K).
Depois que o chat está aberto, os slash commands resolvem o resto:
/explain explica a função selecionada/fix corrige erros apontados pelo gopls/tests gera table-driven tests/doc gera comentário godoc/simplify propõe uma versão mais idiomáticaEscreva um godoc descritivo acima da função e o Copilot implementa baseado nele:
// FetchActivePosts retorna os posts publicados nos últimos 30 dias,
// ordenados por data de publicação decrescente, limitados a 10.
// Retorna erro se o banco estiver indisponível ou se houver falha
// na query. O contexto é usado para cancelamento.
func (r *PostsRepository) FetchActivePosts(ctx context.Context) ([]Post, error) {
// o Copilot preenche aqui seguindo o padrão do resto do repositório
}
Quanto mais específico o godoc, melhor a sugestão. Colocar o nome de arquivos relevantes no comentário ajuda ainda mais.
Seleciona a função, aperta Ctrl + Shift + I e digita:
escreve table-driven tests pra essa função, cobrindo caminho feliz, erro de banco, contexto cancelado e slice vazia. Usa testify/require nas assertions.
O Copilot gera o arquivo _test.go completo, já com t.Run e subtests nomeados.
Se o projeto ainda usa fmt.Errorf("%v") e você quer migrar pra %w + errors.Is, abra o chat em Agent Mode e peça:
Refatora todos os wrappers de erro no pacote
internal/servicepra usar%we substitua comparações com == por errors.Is. Mantém os testes passando.
Você revisa as mudanças arquivo por arquivo antes de aceitar.
# pra contextualizar o chatNo chat, digite #internal/repository/posts.go e #internal/service/posts.go pra carregar os arquivos como contexto. Evita ficar colando código.
/tests: gera testes pro código selecionado/doc: gera comentário godoc/fix: corrige erros apontados pelo gopls/explain: explica o código selecionado/simplify: propõe versão mais idiomáticaPra Go, o /simplify é ouro: ele costuma propor versões que removem loops desnecessários, aproveitam slices da stdlib e enxugam código sem perder legibilidade.
Se você usa interfaces pra I/O, seleciona a interface, abre o inline chat e pede:
gera um mock dessa interface usando testify/mock, no arquivo mocks/mock_repository.go
Ele respeita as custom instructions e gera algo consistente com o resto do projeto.
Se você quer que o Copilot use o gopls do seu projeto como fonte de verdade (go to definition, coverage, go test, go mod tidy), dá pra configurar um servidor MCP como o mcp-gopls. O Copilot passa a consultar o LSP do Go antes de sugerir, o que reduz muito alucinação em projetos grandes. É avançado, mas vale a curva de aprendizado se você trabalha num monorepo Go.
func(http.Handler) http.Handler).pb.go (são gerados, qualquer sugestão quebra o generator).proto se for escrever contratosFull Line Code Completion brigando. Volte no Passo 3 e aplique uma das duas soluções.
Provavelmente o custom instructions está vazio ou genérico. Revise o Passo 6 e detalhe os padrões idiomáticos que você usa.
Shift + Option + \ (Mac) / Shift + Alt + \ (Windows/Linux)Instale o plugin GitHub Copilot Chat separadamente (algumas versões ainda vêm separadas).
interface{} ou any demaisAcrescente no custom instructions: “Evite any e interface{} exceto quando realmente não houver tipo conhecido. Prefira tipos concretos ou generics tipados.”
.github/copilot-instructions.md criado com regras idiomáticasCom esse setup fechado, o Copilot para de ser um auto-completador genérico e vira um pair programmer que entende Go. Em uma semana de uso você vai estar escrevendo godocs que geram funções inteiras e usando o inline chat pra gerar table-driven tests sem tirar as mãos do teclado.