DEV Community

Cover image for Como criei um tema para VS Code e terminal como projeto de estudo
Indiorlei de Oliveira
Indiorlei de Oliveira

Posted on Originally published at github.com

Como criei um tema para VS Code e terminal como projeto de estudo

Temas parecem um projeto pequeno: escolher algumas cores e trocar o arquivo de configuração do editor. Foi exatamente com essa expectativa que comecei o Underground, um tema escuro para VS Code e Kiro IDE. No caminho, descobri que um tema bom não é uma coleção de cores bonitas; é um pequeno sistema de design aplicado a muitos contextos.

O Underground nasceu como projeto de estudo. A proposta era simples: uma interface escura, discreta, com contraste confortável e um verde quente como ponto de atenção. Depois, o projeto cresceu para incluir o terminal integrado do editor, o Windows Terminal e o Terminal.app do macOS — todos orientados pela mesma paleta.

Neste artigo, compartilho o processo, as decisões e os problemas que encontrei. O repositório está disponível em GitHub.

Comecei pela intenção, não pelas cores

Antes de escrever JSON, defini a sensação que queria criar:

  • fundo escuro sem ser preto absoluto;
  • pouca competição visual entre as áreas da interface;
  • cores de sintaxe que ajudem a escanear o código;
  • cores semânticas previsíveis para erro, aviso, Git e conflitos;
  • terminal e editor com a mesma identidade.

Essa primeira etapa evitou uma armadilha comum: atribuir cores isoladamente à medida que os elementos aparecem. Em vez disso, cada escolha deveria responder a uma função. O verde, por exemplo, não existe apenas porque eu gosto dele; ele marca elementos ativos e também palavras-chave, parâmetros e tags. Ele é uma cor de atenção moderada, não uma cor usada em todo lugar.

Uma paleta pequena, com papéis claros

O núcleo do tema é composto por poucos tons:

Papel Cor Uso principal
Fundo #222222 editor, barra lateral e painéis
Superfície elevada #272727 abas ativas, inputs e status bar
Texto principal #ffffffde conteúdo de maior prioridade
Texto secundário #ffffff99 descrições e informações auxiliares
Acento verde #9bd4b2 atividade, parâmetros e Git modificado
Azul #90aed3 strings, funções e números
Roxo #ceb0d3 tipos, interfaces e atributos
Comentários #8a8a8a conteúdo propositalmente secundário

Um detalhe importante é o de em #ffffffde. Em temas do VS Code, também podemos usar hex com canal alfa. Assim, em vez de inventar muitos cinzas diferentes, usei branco com transparências distintas para criar uma escala de hierarquia: texto principal, secundário e sutil.

Essa abordagem deixou as decisões mais fáceis de manter. Quando percebi que comentários estavam apagados demais, por exemplo, não precisei redesenhar o tema inteiro: subi seu tom de #6a6a6a para #8a8a8a, preservando seu papel visual e melhorando a legibilidade.

A estrutura mínima de uma extensão de tema

Uma extensão de tema do VS Code pode ser surpreendentemente pequena. No caso do Underground, os dois arquivos essenciais são:

editors/vscode/
├── package.json
└── themes/
    └── underground-color-theme.json
Enter fullscreen mode Exit fullscreen mode

O package.json registra o tema na seção contributes:

{
  "contributes": {
    "themes": [
      {
        "label": "Underground",
        "uiTheme": "vs-dark",
        "path": "./themes/underground-color-theme.json"
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

O arquivo de tema contém duas partes que vale separar mentalmente:

  1. colors: a interface do VS Code — editor, abas, listas, widgets, terminal e estado do Git.
  2. tokenColors e semanticTokenColors: a aparência do código.

Essa separação parece óbvia, mas foi uma boa forma de organizar o trabalho. Primeiro deixei o ambiente confortável para navegar; depois cuidei da leitura do código.

Tokens de sintaxe: cor é uma ferramenta de leitura

Para a primeira camada de sintaxe, associei grupos de scopes a papéis visuais. Uma versão reduzida da configuração é esta:

{
  "scope": ["keyword", "storage", "variable.parameter", "entity.name.tag"],
  "settings": { "foreground": "#9bd4b2" }
},
{
  "scope": ["string", "support.function", "constant.numeric"],
  "settings": { "foreground": "#90aed3" }
},
{
  "scope": ["entity.name.type", "entity.other.attribute-name"],
  "settings": { "foreground": "#ceb0d3" }
}
Enter fullscreen mode Exit fullscreen mode

O ponto não é decorar scopes, e sim testar em linguagens diferentes. A mesma categoria pode receber scopes diferentes em TypeScript, HTML, JSON ou Markdown. Por isso mantive uma amostra de código para abrir no editor enquanto ajustava o tema.

Também adicionei semanticTokenColors. Essa camada moderna permite ao editor informar significados como type, function, parameter e variable.readonly, especialmente útil em TypeScript e JavaScript. O resultado é mais consistente do que depender exclusivamente da gramática textual.

A parte que quase sempre fica esquecida: a interface inteira

Colorir strings e palavras-chave é só o começo. Um tema realmente utilizável precisa lidar com estados menos frequentes: busca, sugestões, mensagens de validação, diff, merge conflict, Peek Definition, foco por teclado e decoração de Git.

Esses casos revelam problemas que uma captura de tela comum não mostra. No Underground, encontrei dois exemplos marcantes:

  • os números de linha tinham contraste insuficiente e praticamente desapareciam;
  • o widget de Peek Definition não tinha cores próprias e usava um fundo claro inesperado.

Corrigi o primeiro caso elevando o tom dos números inativos e mantendo o número ativo em branco. Para o segundo, foi preciso definir as chaves peekView*, usando o fundo elevado e a seleção já existentes na paleta.

Essa experiência mudou meu critério de pronto: um tema não está pronto quando o arquivo de exemplo está bonito. Ele está pronto depois de passar por fluxos reais de edição, busca, autocomplete, Git e resolução de conflitos.

Diferenças e conflitos também comunicam significado

Para diffs, evitei blocos muito saturados. Linhas adicionadas usam verde com baixa opacidade; removidas usam vermelho com baixa opacidade. As palavras alteradas recebem uma opacidade um pouco maior que a linha inteira, para criar hierarquia.

Nos conflitos de merge, mantive uma convenção semântica:

  • versão atual: verde;
  • versão recebida: azul;
  • base comum: cinza;
  • conflito ainda não resolvido: borda amarela.

É uma decisão pequena, mas útil: as cores deixam de ser decoração e passam a explicar o estado da informação.

Um tema, mais de um ambiente

Eu queria que abrir o terminal não parecesse mudar de aplicação. Por isso, documentei a paleta em PALETTE.md e usei o tema do VS Code como fonte canônica. A partir dos valores terminal.ansi*, criei:

  • um esquema JSON para o Windows Terminal;
  • um perfil .terminal para o Terminal.app do macOS.

Há uma sutileza aqui: o fundo do editor é #222222, mas o preto ANSI é #1a1a1a. Isso preserva a convenção de cores do terminal sem transformar toda a interface em preto absoluto.

Ter uma fonte de verdade reduz divergências. Se eu alterar o amarelo de aviso, sei que preciso revisar o amarelo ANSI e a documentação da paleta. Esse cuidado é mais simples do que tentar descobrir, meses depois, por que o editor e o terminal usam cores quase iguais.

O que eu faria desde o início em um próximo tema

Se fosse começar novamente, eu adotaria estes hábitos desde o primeiro commit:

  1. Criar uma paleta com nomes de papel, não apenas uma lista de hexadecimais.
  2. Preparar arquivos de exemplo com várias linguagens e estados de interface.
  3. Testar acessibilidade e contraste antes de considerar uma cor definitiva.
  4. Documentar a relação entre editor e terminal desde cedo.
  5. Registrar mudanças visuais no changelog, incluindo o motivo da alteração.

Também vale testar o tema localmente por meio de um link simbólico na pasta de extensões do VS Code. Esse ciclo curto — editar, recarregar a janela, observar — tornou os ajustes muito mais rápidos.

Conclusão

Criar o Underground foi uma forma excelente de estudar ferramentas de desenvolvimento por outro ângulo. Um tema não altera a lógica do programa, mas influencia diretamente a experiência de ler, navegar e depurar código por horas.

A maior lição foi esta: consistência é mais valiosa do que quantidade de cores. Quando fundo, contraste, estados e semântica contam a mesma história, o resultado é mais calmo e mais útil.

Se você quiser explorar a implementação, contribuir ou adaptar a paleta, o código está no repositório do Underground, sob licença MIT.

Top comments (0)