Open Source

Shitty: novo emulador de terminal em C++23 foca em velocidade no Linux e macOS

Desenvolvido por pg83, o Shitty é um terminal de baixa latência em C++23 com renderização Vulkan e Metal que supera Alacritty e Ghostty em testes.

Compartilhar
Tela de terminal de computador escuro exibindo linhas de código e dados de desempenho.
Tela de terminal de computador escuro exibindo linhas de código e dados de desempenho.

O desenvolvedor pg83 publicou no GitHub e no Hacker News o projeto do Shitty, um novo emulador de terminal projetado para oferecer baixa latência, inicialização rápida e uso previsível de recursos. Desenvolvido em C++23 e compilado via Clang, o software mantém o estado do terminal na CPU e renderiza as células por meio de backends nativos de computação, utilizando Vulkan no Linux e Metal no macOS.

Tela de terminal de computador escuro exibindo linhas de código e dados de desempenho.
Foto: Hacker News

Ao contrário de alternativas focadas em garantias estritas de proteção de memória, o Shitty assume abertamente a ausência dessas verificações em prol do rendimento bruto no processamento de dados. O executável da ferramenta, denominado st, surge como uma reescrita completa e fork do projeto Zutty, criado originalmente por Tom Szilagyi, mas reformula inteiramente a arquitetura de renderização e os testes do sistema original.

Resultados dos testes de desempenho

Em benchmarks de velocidade com um volume de 100 MB de dados em formato ASCII passados via cat em uma interface gráfica no macOS (executados em um MacBook com chip Apple Silicon), o Shitty alcançou o melhor tempo de execução total (wall time) de 0,81s, com 0,50s de tempo de usuário e uma taxa de transferência aproximada de 118 MiB/s. Todos os terminais testados foram equalizados com a fonte Menlo 12pt, células de 14x28px, grade de 80x24 e histórico de rolagem de 500 linhas.

No mesmo cenário de teste de 100 MB em ASCII, o emulador Alacritty 0.17.0 obteve um tempo total de 0,96s (com 0,78s de tempo de usuário e taxa de ~99 MiB/s). O terminal Kitty 0.48.2 registrou 1,28s de tempo total (com 0,95s de tempo de usuário e taxa de ~75 MiB/s), enquanto o Ghostty 1.3.1 finalizou o teste em 1,49s (com 1,60s de tempo de usuário e vazão de ~64 MiB/s).

Em um teste considerado o pior cenário para o analisador de terminal — o envio de 100 MB de bytes aleatórios contendo sequências UTF-8 inválidas —, o Shitty registrou um tempo total de 1,88s, 1,79s de tempo de usuário e taxa de ~51 MiB/s. O Alacritty 0.17.0 levou 3,07s (com 2,92s de CPU do usuário e taxa de ~31 MiB/s), enquanto o Ghostty 1.3.1 necessitou de 4,63s de tempo total e cerca de 7,0s de tempo de usuário (alcançando ~21 MiB/s).

Durante o teste de bytes aleatórios, o emulador Kitty 0.48.2 não completou a medição. Diante da carga de sequências de escape corrompidas no fluxo de dados, a ferramenta respondeu alternando títulos de janela e emitindo sinais sonoros (bells) em vez de realizar a renderização na tela. A validação e reprodução dessas métricas são coordenadas pelo script dev/compare.py, que alinha a configuração dos ambientes antes das medições.

Mecanismos de estabilidade e renderização

Para assegurar a precisão no tratamento de comandos, o Shitty conta com uma suíte de validação com mais de 5.000 testes integrados. Esse acervo de testes foi extraído de mais de uma dúzia de projetos da comunidade, incluindo esctest, vttest, vttests do xterm, tack, libvterm, libtsm, além de testes importados do kitty, alacritty, ghostty, contour, konsole e mosh, executados em modo caixa-preta através de um pseudoterminal real (PTY).

A máquina de estados do analisador sintático do Shitty foi desenvolvida para ser total e imune a falhas, utilizando testes de fuzzing contínuos com corpora armazenados no repositório. Como resultado dessa abordagem, a execução do comando cat /dev/urandom é tratada como um teste padrão de desempenho e carga, e não como uma condição capaz de gerar travamentos ou falhas no sistema.

A renderização visual do Shitty é orientada a danos (damage-driven) e redesenha quadros de redimensionamento na mesma transação de alteração dos limites da janela, evitando oscilações na imagem (flicker-free). O tratamento de caracteres Unicode considera agrupamentos de grafemas (grapheme clusters) e não apenas pontos de código (codepoints), permitindo a exibição adequada de sequências de emojis, seletores de variação, marcas de combinação e caracteres CJK de largura dupla.

O emulador opera de forma autocontida e não depende de toolkits gráficos genéricos de janelas. O binário traz embutido um trio básico de fontes monoespaçadas e emojis, o que garante a inicialização do programa mesmo em sistemas operacionais onde nenhuma fonte externa esteja instalada. Em termos de segurança, o acesso de aplicativos locais à área de transferência via comando OSC 52 ou a manipulação da janela hospedeira são bloqueados por padrão, exigindo autorização explícita do usuário.

Recursos de terminal e protocolos

O Shitty suporta comandos de controle desde a especificação VT52 até a série VT5xx, além de extensões amplamente difundidas do xterm. Ele suporta telas primárias e alternativas, histórico de rolagem na tela principal, margens, tabulações, operações retangulares, células protegidas e saída sincronizada, além de realizar o reajuste automático de texto (reflow) do histórico da tela primária quando a largura da janela é alterada.

O suporte a cores abrange as especificações de 16 cores, 256 cores e suporte a cores de 24 bits (True Color). O emulador permite a personalização de cores para sublinhados e estilos estendidos de linhas, além de renderizar linhas com largura simples, largura dupla e altura dupla no formato padrão de terminais DEC.

Para a entrada de comandos via teclado, o software suporta o protocolo legado, a extensão modifyOtherKeys e o protocolo de teclado do Kitty. Em relação ao ponteiro do mouse, são aceitos os protocolos X10, VT200, UTF-8, SGR, SGR-pixel e urxvt. O terminal oferece modos de seleção linear e retangular, integração com a área de transferência primária e suporte a links clicáveis via protocolo OSC 8.

A ferramenta disponibiliza integração com shells, notificações do sistema, relatórios de progresso de tarefas e notificações de redimensionamento em banda. Internamente, o Shitty utiliza codificação UTF-8 e exporta a variável de ambiente TERM=xterm-256color para os processos filhos, exigindo que o sistema hospedeiro contenha essa entrada configurada no banco de dados terminfo.

Requisitos de compilação e dependências

O código-fonte do Shitty é escrito em C++23 e compilado com o Clang. A biblioteca padrão empacotada no repositório em third_party/libstd requer a opção -std=c++26. Como o utilitário Clang nativo das ferramentas de linha de comando da Apple no macOS não reconhece essa flag, é necessário instalar o conjunto LLVM via Homebrew e direcionar as variáveis de ambiente CC e CXX para os binários atualizados.

A compilação do projeto exige a presença do Python 3, Ragel 6, glslangValidator, librsvg (com a ferramenta rsvg-convert para geração do ícone no momento do build), pkg-config, utf8proc 2.9 ou superior, além de suporte a threads POSIX e interfaces PTY. Toda a camada de janelas e eventos nativos é gerida pelo módulo interno third_party/plt.

No ambiente Linux, a compilação requer FreeType, HarfBuzz, cabeçalhos de cliente do Wayland, xkbcommon, wayland-scanner, além dos arquivos de cabeçalho e carregadores do Vulkan. No macOS, o software requer SPIRV-Cross e utiliza os frameworks de sistema CoreText, Cocoa, Metal e IOSurface. Bibliotecas como Brotli e simdutf 6.5 ou superior são componentes opcionais para aceleração de operações como Base64.

Instalação e comandos de execução

No macOS em arquitetura Apple Silicon, o Shitty pode ser instalado pelo gerenciador de pacotes Homebrew usando o comando brew install pg83/tap/shitty. Cada lançamento no GitHub disponibiliza o binário portátil pré-compilado st-darwin-arm64.tar.gz, sem dependências dinâmicas externas ao sistema operacional.

Em distribuições Linux, os arquivos de instalação posicionam o executável principal denominado st no diretório /usr/local/bin/st, o atalho de área de trabalho em /usr/local/share/applications/shitty.desktop e o ícone vetorial em /usr/local/share/icons/hicolor/scalable/apps/shitty.svg.

O projeto também fornece integração com o ecossistema Nix através de um arquivo de configuração flake.nix, permitindo comandos como nix build e nix run, além de manter o arquivo shell.nix para uso com nix-shell. A inicialização básica é feita pelo comando ./st, podendo receber argumentos como ./st -e tmux new-session para disparar uma sessão do tmux, ou ./st -geometry 120x36 -saveLines 5000 para definir dimensões de janela e linhas de histórico.

A seleção de fontes é feita através do parâmetro -font, que aceita nomes de famílias ou caminhos diretos para arquivos de fonte no disco, podendo ser repetido para indicar fontes de reserva, como em ./st -font 'DejaVu Sans Mono' -font 'Noto Sans Mono CJK JP'. Durante o uso, os atalhos Cmd+=, Cmd+- e Cmd+0 no macOS (ou Ctrl+Shift+=, Ctrl+- e Ctrl+0 no Linux) alteram o tamanho da fonte, ajustando o tamanho da janela para manter fixas as dimensões de linhas e colunas.

Testes de conformidade e cobertura

A execução dos testes de validação do projeto é iniciada pelo comando ./build test para a suíte completa ou ./build test_suite para os testes nativos em caixa-preta. A integração contínua do projeto via GitHub CI utiliza analisadores de sanitização de código como ASan e UBSan no ambiente x86_64-linux, permitindo também a geração de relatórios de cobertura em LCOV e HTML via Nix.

A arquitetura da suíte nativa aciona um binário headless dedicado denominado st_test, que interage com um PTY em modo bruto para validar instantâneos de exibição da tela e dados de saída. Esse ponto de entrada de testes é exclusivo do binário de teste e não está presente no binário final de produção do st.

Origem do projeto e licença

Entre as limitações conhecidas documentadas pelo autor, o Shitty não possui suporte para layout de texto bidirecional (bidi) nem implementa protocolos de gráficos embutidos no terminal, como o padrão sixel. Extensões históricas específicas de terminais antigos foram intencionalmente omitidas do escopo de desenvolvimento.

O Shitty representa um fork e reescrita do emulador Zutty, idealizado por Tom Szilagyi. O projeto está em transição de licença: a base de código importada originalmente segue sob a licença GPLv3, enquanto as novas contribuições feitas no Shitty são disponibilizadas sob licenciamento duplo em GPLv3 e MIT, com o objetivo final de migrar a base de código para ser exclusivamente MIT.

#shitty#terminal#cpp23#vulkan#metal
Compartilhar

Artigos Relacionados