---
title: "LSP interativo: proposta leva refatorações avançadas ao gopls"
url: "https://golang.com.br/novidades/lsp-interativo-refatoracoes-gopls/"
markdown_url: "https://golang.com.br/novidades/lsp-interativo-refatoracoes-gopls.MD"
description: "Uma proposta para LSP interativo permite ao gopls pedir dados, validar respostas e executar refatorações complexas sem bloquear o editor."
date: "2026-08-10"
author: "Go Brasil"
---

# LSP interativo: proposta leva refatorações avançadas ao gopls

Uma proposta para LSP interativo permite ao gopls pedir dados, validar respostas e executar refatorações complexas sem bloquear o editor.


**TL;DR:** uma nova proposta de design para o Language Server Protocol (LSP) cria um fluxo padronizado em que o `gopls` pode pedir informações ao desenvolvedor, validar as respostas e só então executar uma refatoração. Isso abre caminho para operações como mover declarações entre arquivos, alterar assinaturas e configurar tags de structs com uma interface consistente entre editores. A recomendação usa `command/resolve`, evita bloquear o servidor enquanto o usuário responde e já foi validada em versões do `gopls` e da extensão Go para VS Code.

## O limite das refatorações atuais

O LSP permite que editores como VS Code, Vim e Emacs usem um servidor de linguagem para oferecer navegação, diagnósticos e transformações de código. Em Go, esse servidor é o `gopls`. O protocolo funciona bem quando uma ação pode ser calculada imediatamente: organizar imports, extrair uma variável ou aplicar uma correção sugerida.

O problema aparece quando a transformação precisa fazer perguntas. Para mover uma declaração, o servidor precisa saber o arquivo ou pacote de destino. Para alterar a assinatura de uma função, precisa coletar novos parâmetros. Para adicionar tags a uma struct, pode ser necessário escolher nomes, convenções de caixa e quais tags gerar.

Hoje, cada extensão pode criar uma interface própria para isso, mas a solução fica acoplada ao editor. A proposta tenta colocar o fluxo no LSP: o servidor preserva a inteligência da operação, enquanto o cliente decide se mostra um formulário, menus ou perguntas sequenciais.

## Como funciona o ciclo interativo

A ideia central é um formulário sem estado, parecido com uma submissão HTTP. O servidor retorna campos em `formFields`; o editor coleta respostas e as devolve em `formAnswers`. O servidor pode aceitar, apontar um erro ou fazer uma nova rodada de perguntas.

Uma versão simplificada do intercâmbio para adicionar tags seria:

```text
command: gopls.modify_tags
formFields:
  - id: tags
    tipo: string
    obrigatório: sim
  - id: case
    tipo: enum
    opções: [snake_case, camelCase]
```

Se o usuário fornecer uma tag inválida, o `gopls` devolve o formulário com uma mensagem associada ao campo. Quando não houver mais `formFields`, o comando está pronto para execução.

Os tipos previstos cobrem texto, booleanos, números, arquivos, listas e enums. Há ainda um `lazyEnum`, útil para conjuntos grandes ou dinâmicos: em vez de mandar milhares de símbolos ou caminhos de uma vez, o editor consulta opções conforme o usuário digita.

Ser sem estado é uma escolha importante. O servidor não precisa manter uma chamada RPC aberta, uma thread bloqueada ou um snapshot pesado do workspace enquanto alguém pensa no que responder. As respostas completas acompanham cada rodada; portanto, o fluxo também pode sobreviver a uma reinicialização do servidor de linguagem.

## Por que `command/resolve` foi recomendado

O documento analisa quatro pontos possíveis para inserir a interação. A recomendação é resolver um comando antes de executá-lo, por meio de `command/resolve` — ou, futuramente, de um padrão mais geral `<método>/resolve`.

Esse nível traz três vantagens práticas:

1. **A interação só começa após uma ação explícita.** Alguns clientes resolvem ações antecipadamente para mostrar previews ao passar o mouse. Perguntar algo nessa etapa produziria diálogos inesperados.
2. **O mecanismo não fica limitado a edições de texto.** Um comando interativo também pode iniciar testes com opções de cobertura, executar `govulncheck`, abrir relatórios ou controlar ferramentas de linha de comando.
3. **Não há uma requisição reversa bloqueada.** Pedir dados do servidor para o editor durante um comando manteria recursos presos e poderia ultrapassar timeouts de clientes, que às vezes são de poucos segundos.

A desvantagem é que ações interativas precisam ser representadas como comandos. Elas não podem ser apenas um `WorkspaceEdit` pronto para o editor aplicar. Para refatorações cujo resultado depende das respostas, porém, um preview calculado antes da interação seria pouco confiável de qualquer maneira.

## O que muda para quem programa em Go

A proposta não significa que todos os editores ganharão imediatamente botões para “mover declaração” ou “alterar assinatura”. Ela define a infraestrutura para que clientes LSP implementem uma experiência interoperável. Servidor e cliente também negociam capacidades, incluindo quais tipos de entrada o editor consegue renderizar.

Há um sinal concreto de maturidade: o caminho recomendado foi testado em produção com `gopls` v0.23.0 e VS Code Go v0.56.0, inicialmente no fluxo de modificação de tags. Isso reduz o risco de o design ser apenas teórico, embora sua padronização e adoção mais ampla ainda dependam do ecossistema LSP.

Para equipes Go, o benefício potencial é diminuir refatorações manuais e específicas de IDE. Operações que exigem conhecimento semântico do workspace podem continuar no `gopls`, aproveitando análise de tipos e referências, enquanto cada editor oferece a interface adequada. Isso complementa recursos como o inliner em nível de código-fonte, já usado por refatorações e pelo [`go fix`](/blog/go-blog-go-fix-a-revolucao-na-modernizacao-de-codigo-com-inlining-inteligente/).

O efeito mais interessante é arquitetural: uma refatoração complexa deixa de ser uma feature exclusiva de uma IDE e passa a poder ser um recurso do servidor oficial de Go, consumido por qualquer cliente que implemente o protocolo.

## Saiba mais

- [Proposta completa de ações interativas no LSP](https://raw.githubusercontent.com/golang/proposal/master/design/76331-lsp-interactive-refactoring.md)
- [Release do gopls v0.23.0](https://github.com/golang/tools/releases/tag/gopls%2Fv0.23.0)
- [Release do VS Code Go v0.56.0](https://github.com/golang/vscode-go/releases/tag/v0.56.0)
- [Como o inliner e o go fix modernizam código Go](/blog/go-blog-go-fix-a-revolucao-na-modernizacao-de-codigo-com-inlining-inteligente/)
