- Um usuário que usava iTerm 2 há muito tempo decidiu dar outra chance ao WezTerm para ter configuração baseada em texto e compartilhar seus dotfiles, ajustando com precisão aparência, atalhos, multiplexação e workspaces com a API de configuração em Lua
- A configuração fica em
wezterm.lua e é recarregada a quente assim que o arquivo é salvo; no overlay de depuração com CTRL + SHIFT + L, é possível ver logs e um REPL de Lua imediatamente
- Com configuração em Lua, dá para montar dinamicamente mais de 1.000 esquemas de cores embutidos, integração com modo escuro/claro do sistema, fontes, decoração de janela no macOS e uma barra de status em estilo powerline
- Os atalhos padrão podem ser mantidos ou desativados, e o usuário define por conta própria navegação por palavras com
Option + Arrow, abrir configuração com CMD +,, além de manipulação de panes com leader key e key table
- A multiplexação embutida e os workspaces preservam o estado de janelas, panes e abas por projeto como em sessões do tmux, e com Lua dá até para criar a UI de seleção de projetos e o fluxo de troca
Por que migrei do iTerm 2 para o WezTerm
- Usei o iTerm 2 por quase 10 anos, mas queria um terminal em que fosse possível gerenciar toda a configuração em texto, colocar isso nos dotfiles e compartilhar entre a máquina de trabalho e a pessoal
- O WezTerm se destaca pela API poderosa e pela configuração em Lua; na segunda tentativa, consegui montar um terminal mais bonito e mais funcional
- O escopo aqui cobre aparência, atalhos de teclado, multiplexação, navegação entre workspaces, barra de status e configuração dinâmica de temas
- Há recursos que este texto não cobre
- regras personalizadas de destaque de hyperlinks
- scrollback pesquisável
- quick copy mode
- suporte a imagens
- A configuração de exemplo foi pensada para a experiência de uso no macOS; não foi testada em outros sistemas, embora o próprio WezTerm funcione em vários ambientes
- O exemplo final de configuração está disponível em gist
Instalação e estrutura básica da configuração em Lua
brew install wezterm
- O fluxo adotado usa o arquivo de configuração em
$XDG_CONFIG_HOME/wezterm/wezterm.lua
- Na maioria dos sistemas, incluindo o macOS, isso normalmente significa
~/.config/wezterm/wezterm.lua
- Em vez de colocar tudo em um único
~/.wezterm.lua, usar um diretório facilita dividir a configuração em vários arquivos
local wezterm = require 'wezterm'
local config = wezterm.config_builder()
return config
- Como a configuração do WezTerm é escrita em Lua, fica mais fácil criar ajustes dinâmicos e complexos do que com YAML ou TOML
- Lua é uma linguagem de programação e, portanto, mais difícil de aprender do que YAML/TOML, mas quem já tiver experiência com linguagens dinâmicas como Ruby, Python ou JavaScript deve conseguir ler os exemplos com facilidade
- Como material de aprendizado de Lua, dá para consultar o Getting Started guide
Hot reload e overlay de depuração
- O WezTerm detecta mudanças no arquivo de configuração e faz reload automático, então dá para ver o efeito das mudanças sem reiniciar o terminal
- Se você salvar uma configuração com erro, como um nome de função incorreto, um pop-up de erro em tempo de execução aparece imediatamente
wezterm.config_builderZ()
- Logs podem ser gravados com
wezterm.log_info()
wezterm.log_info("hello world! my name is " .. wezterm.hostname())
- Com
CTRL + SHIFT + L, é possível abrir o debug overlay e ver logs e o REPL de Lua
- Dá para executar expressões Lua como
1 + 1
- Também é possível inspecionar valores do módulo
wezterm, como wezterm.home_dir
- Usar hot reload junto com o overlay de depuração encurta bastante o ciclo de feedback ao alterar e validar a configuração
Configuração visual: cores, tema do sistema, fontes e estilo da janela
-
Esquemas de cores e configuração dinâmica
- O WezTerm oferece mais de 1.000 esquemas de cores embutidos, selecionados com
config.color_scheme
config.color_scheme = 'Tokyo Night'
- A lista de esquemas pode ser consultada em WezTerm colorschemes
- Com o evento
window-config-reloaded e wezterm.color.get_builtin_schemes(), também dá para fazer configuração dinâmica e aplicar um esquema aleatório em cada nova janela
- Depois de definir overrides de configuração por janela, voltar para um esquema de cores estático pode não refletir imediatamente no hot reload
- É possível limpar os overrides executando
window:set_config_overrides({}) no terminal de depuração, ou fechando e abrindo a janela novamente
-
Integração com modo escuro/claro do sistema
- A configuração pode ser separada em um módulo
appearance.lua para trocar o esquema de cores conforme a aparência do sistema operacional
- O código verifica a presença da string
"Dark" em wezterm.gui.get_appearance() para decidir se o modo escuro está ativo
- Em ambientes sem
wezterm.gui, o comportamento padrão é assumir modo escuro
if appearance.is_dark() then
config.color_scheme = 'Tokyo Night'
else
config.color_scheme = 'Tokyo Night Day'
end
-
Fontes e decoração da janela
- O WezTerm inclui por padrão JetBrains Mono e Nerd Font Symbols
- A configuração de exemplo usa Berkeley Mono em 13pt
config.font = wezterm.font({ family = 'Berkeley Mono' })
config.font_size = 13
- O exemplo de estilo de janela no macOS inclui fundo semitransparente, blur, remoção da barra de título e configuração de fonte da tab bar
config.window_background_opacity = 0.9
config.macos_window_background_blur = 30
config.window_decorations = 'RESIZE'
Barra de status e API de eventos do WezTerm
- O callback do evento
update-status adiciona segmentos em estilo powerline à barra de status da direita
- O exemplo inicial mostra um segmento de hostname usando a cor de fundo e a cor de primeiro plano do esquema atual, além de
wezterm.hostname()
wezterm.on conecta callbacks a eventos do terminal
update-status é disparado periodicamente quando chega o momento de atualizar o status
- O WezTerm garante que apenas uma atualização rode por vez e interrompe o handler se o código demorar demais
window:effective_config().resolved_palette permite obter a paleta atual já com os overrides aplicados
wezterm.format é usado para aplicar estilos como cor, negrito e sublinhado a strings
- Nos exemplos posteriores, a barra de status ganha mais segmentos
- workspace atual
- data e hora
- hostname
wezterm.color.parse, color:lighten, color:darken e wezterm.color.gradient são usados para calcular cores em gradiente com base no tema atual
Atalhos: navegação por palavras no macOS e abertura da configuração
- O WezTerm já oferece atalhos padrão, e o exemplo os mantém
- Para desativá-los, pode-se usar
config.disable_default_key_bindings = true
- No macOS, para reproduzir o comportamento do iTerm 2 e do Terminal.app com
Option + LeftArrow e Option + RightArrow movendo por palavra, a configuração envia ESC + b e ESC + f
{
key = 'LeftArrow',
mods = 'OPT',
action = wezterm.action.SendString '\x1bb',
}
- Também dá para configurar
CMD + , para abrir o arquivo de configuração do WezTerm em uma nova aba
- O exemplo usa
nvim e wezterm.config_file
- Se o WezTerm for iniciado pelo Finder no macOS, pode acontecer de o binário do editor não estar no
PATH, fazendo o comando falhar
- Com
config.set_environment_variables, é possível complementar as variáveis de ambiente padrão, e o mesmo ambiente será passado aos comandos iniciados depois
config.set_environment_variables = {
PATH = '/opt/homebrew/bin:' .. os.getenv('PATH')
}
Multiplexação embutida e leader key
- A multiplexação embutida do WezTerm pode substituir o tmux
- Ela oferece buffer de scrollback por pane, melhor controle de mouse, seleção mais simples e, em geral, desempenho mais rápido
- Com
CTRL + SHIFT + P, é possível abrir a command palette e executar comandos como “Shell: Split Horizontally” e “Shell: Split Vertically”
- Como os atalhos padrão de split são mais complexos para evitar conflitos, a leader key permite criar combinações mais simples
config.leader = { key = 'a', mods = 'CTRL', timeout_milliseconds = 1000 }
- No exemplo, em estilo tmux, pressionar
" após a leader faz split horizontal, e % faz split vertical
{
key = '"',
mods = 'LEADER',
action = wezterm.action.SplitHorizontal { domain = 'CurrentPaneDomain' },
}
- Quando se quer enviar
CTRL + A para o terminal propriamente dito, a configuração mapeia LEADER|CTRL para reenviar CTRL + A
Navegação entre panes, redimensionamento e key table
- A navegação entre panes mapeia
h, j, k, l com a leader, no estilo das teclas de direção do vim
ActivatePaneDirection executa a movimentação para Down, Up, Left e Right
- Tabelas Lua repetidas podem ser reduzidas com funções
local function move_pane(key, direction)
return {
key = key,
mods = 'LEADER',
action = wezterm.action.ActivatePaneDirection(direction),
}
end
- Embora seja possível redimensionar panes com o mouse, o exemplo usa key table para um fluxo mais centrado no teclado
- Key table é uma forma de entrar em um modo específico e usar atalhos próprios desse modo
- É parecida com a leader key, mas pode continuar ativa após uma ação, em vez de desativar logo em seguida
- Isso é útil para tarefas como redimensionamento, em que a mesma tecla precisa ser repetida várias vezes
- No exemplo,
LEADER + r ativa a key table resize_panes, e h/j/k/l ajustam o tamanho do pane em 3 células por vez
- Com
timeout_milliseconds = 1000, o modo de redimensionamento é encerrado após 1 segundo
- Usuários de Neovim podem conferir o smart-splits.nvim, que ajuda na navegação entre panes do WezTerm e do vim
Organização de workspaces por projeto
- Ao lidar com vários projetos ao mesmo tempo, surge a vontade de manter uma instância separada do multiplexador, além do estado de janelas, panes e abas para cada projeto
- No WezTerm, esse papel é cumprido pelos workspaces, com propósito semelhante ao das sessões do tmux
- A estrutura usada cria um
projects.lua com uma função de seleção de projetos, importada pela configuração principal
- O exemplo inicial lista manualmente os caminhos de projeto e usa
InputSelector para exibir a interface de seleção
- Com
fuzzy = true, a busca difusa é ativada
- No começo, o resultado da seleção é apenas exibido como log no overlay de depuração
LEADER + p abre a interface de seleção de projetos, enquanto LEADER + f mostra a lista de workspaces existentes com busca difusa
action = wezterm.action.ShowLauncherArgs { flags = 'FUZZY|WORKSPACES' }
- O incômodo de manter manualmente os caminhos de projeto é reduzido com
wezterm.glob(), que coleta automaticamente subdiretórios da pasta de projetos
- No exemplo, os subdiretórios de
~/Projects são tratados como projetos, e o diretório home também entra na lista
- Ao selecionar um projeto, a ação executada é
SwitchToWorkspace
- Se o workspace já existir, ocorre a troca
- Se não existir, ele é criado
- O nome do workspace usa o último segmento do caminho
- O diretório de trabalho do novo terminal é definido como o caminho do projeto selecionado
O que mais dá para explorar
- O WezTerm tem muitos outros recursos listados em features
- As possibilidades da configuração em Lua podem ser exploradas mais a fundo na documentação da API do WezTerm
- Ao montar uma configuração passo a passo, faz sentido deixar só o que realmente vai usar, reescrever no seu próprio estilo e depois adicionar os recursos necessários
- Se você gostar do WezTerm, também pode apoiar o Wez, que mantém o projeto open source
1 comentários
Comentários do Hacker News
Migrei recentemente para o WezTerm e estou muito satisfeito
Antes eu usava kitty e, ao sair do iTerm2, gostei da configuração e da simplicidade, mas em termos de recursos nativos o WezTerm é muito melhor. A configuração do terminal também é curta o bastante para caber em uma tela do editor e, depois disso, o terminal simplesmente não atrapalha, então não preciso me preocupar com ele
O golpe final para eu abandonar o kitty foi ver respostas curtas e meio desdenhosas do maintainer sempre que eu encontrava algum problema ou tentava reproduzir recursos do iTerm2
Por exemplo, lembro de uma pergunta como “como configurar o tmux no kitty?” à qual ele respondeu algo na linha de “não faça isso, tmux é idiota” e encerrou o assunto, então no fim desisti
Claro, é o projeto dele e ele é um ótimo programador, mas um pouco de humildade também não faria mal
Para quem não conhece, é uma janela que pode ser mostrada/ocultada com um atalho específico e, quando aparece, fica acima de todas as janelas para que você possa usar o terminal imediatamente de qualquer lugar. Dá para viver sem isso, mas não é um recurso do qual eu queira abrir mão; então, por melhores que sejam os outros recursos do WezTerm, se isso não existir, para mim ele já está fora desde o começo
Por fora, muitas vezes parece o melhor produto possível, mas, quando você começa a usá-lo a fundo, fica preso às escolhas daquela pessoa e sem ter para onde voltar
Dito isso, quando comecei a usar o WezTerm no começo deste ano, fiquei realmente impressionado. Li muitos textos do Wez, e o tom era perfeito todas as vezes; achei isso realmente admirável
É simbólico que ele nem consiga renderizar corretamente a velha UI
make menuconfigdo Linux, e não dê para corrigir isso por configuração porque ele não acredita em configurações. Ao ler os tópicos no issue tracker, além de parecer ofensivo, eu até sinto uma vontade pouco saudável de também “defender” com a mesma intensidade algum jeito aleatório de usar terminalNão dá para ter certeza, mas acho que, mesmo se eu concordasse com ele em tudo sobre terminais, ainda assim eu preferiria criar meu próprio terminal a usar o dele
Pela minha experiência, o Wez responde no GitHub Issues com uma rapidez surpreendente e, quando algo realmente está errado, normalmente corrige em um ou dois dias
Tirando uma ou duas pequenas reclamações sobre teclas modificadoras via SSH, o conjunto de recursos atende quase perfeitamente ao que eu preciso e, além disso, é rápido. Antes eu era um grande fã do Alacritty, mas precisava de suporte melhor a modificadores no Emacs remoto
Comentei em uma issue já fechada, mas, de todo modo, ela tinha sido encerrada como “won’t do”, e meu comentário foi ignorado. Eu não queria abrir uma nova issue com o mesmo assunto que já tinha sido rejeitado
https://github.com/wez/wezterm/issues/4706
Combinações como
C-S-\"não têm uma boa forma de ser enviadas porque o protocolo de terminal não as suporta. Então fiz o WezTerm enviar\" c s '\"no lugar e adicionei bindings extras no Emacs. Com esse truque do F12, consegui até enviar combinações bem complexas que o protocolo de terminal não consegue suportarOriginalmente instalei o WezTerm ao migrar do Kubuntu para o Ubuntu, porque queria usar alguns recursos do Konsole sem precisar instalar o Konsole, como scrollback infinito e busca no scrollback
Eu sei que também dá para instalar o Konsole no Gnome, mas de alguma forma isso não parecia a combinação certa. Gostei do WezTerm na hora, mas ao ler este post percebi que ainda só arranhei a superfície do que ele permite configurar
Minha única reclamação é que muitos recursos não são fáceis de descobrir. A documentação é realmente muito boa, e o autor é ativo e prestativo, mas, por exemplo, uma vez procurei como selecionar um grande bloco de texto usando só o teclado, consegui fazer e pensei “preciso lembrar disso!”, mas logo esqueci, e agora voltei a selecionar com o mouse como um completo iniciante. Como não é algo que eu faça com frequência, isso acaba sendo mais rápido do que ficar procurando de novo essa página na documentação
A propósito, a página de que eu estava falando é https://wezfurlong.org/wezterm/copymode.html, e não https://wezfurlong.org/wezterm/quickselect.html, que pelo nome parecia ser o que eu procurava, mas na verdade é outra funcionalidade. Ela também é muito útil e uma ótima ideia, mas não era o que eu estava buscando
https://github.com/bbkane/dotfiles/tree/master/wezterm
Já é útil no padrão, mas a verdadeira força está em poder customizar as regexes de correspondência. Adicionei uma regex para localizar todos os nomes de arquivo na saída de
eza --icons, e\p{Co}corresponde aos ícones. Então, depois de definirlscomo alias paraeza, posso simplesmente digitar shift+as letras do QuickSelect para qualquer nome de arquivoAinda não encontrei esse jeito e, por isso, frequentemente deixo uma sessão do Konsole aberta também. Ao dar tail em logs em tempo real, esses dois recursos são realmente poderosos
Depois de usar Mac Terminal, iTerm2, Kitty, Warp e outros, acabei ficando com o WezTerm
É fácil de configurar, rápido e bonito. Até criei um tema
https://tiniri.vlad.studio/
Por acaso encontrei este site para comparar vários terminais: https://terminaltrove.com/terminals/
Parece bem útil para quem quiser comparar terminais
Uso o WezTerm há cerca de 1 ano e apoio o Wez no GitHub; é um terminal excelente, e ele é um ótimo desenvolvedor
O post diz que não vai cobrir isso, mas uma das minhas funcionalidades favoritas é Quick Copy e os outros modos de cópia. Eu uso o tempo todo. Basta pressionar
C-S-Spacee digitar as letras mostradas ao lado do item que você quer copiarUm grande caso de uso para mim é ter algo parecido com mosh+tmux de um notebook macOS para uma máquina Linux da empresa. Posso manter uma sessão sempre aberta e trabalhar na máquina da empresa a partir do Mac. Como há sessões reconectáveis, além de panes e tabs, consigo trabalhar mesmo longe da mesa, e a qualidade é muito boa
Fico pensando no que haveria para não gostar no WezTerm
Meu recurso favorito, apesar de frequentemente ignorado, é o suporte totalmente cross-OS. Num ambiente como o meu, em que uso Linux, macOS e Windows, basta aprender a usar o WezTerm e pronto. Uma boa parte da configuração do terminal também é compartilhada entre os sistemas operacionais
Pode ser um problema só meu ou do meu jeito de usar tmux, mas quando eu copiava com as linhas em wrap, o texto copiado parecia incluir quebras de linha. Isso me incomodava muito, e presumi que fosse por causa da interação entre WezTerm e tmux
Não tenho evidências suficientes para fazer um bom bug report, e como o WezTerm tem seu próprio servidor de multiplexação de terminal, os “ssh domains”, talvez isso nem seja importante o bastante para corrigirem. Mas eu não quero sair instalando o servidor de multiplexação do WezTerm em todo lugar, e onde eu entro por SSH geralmente já tem tmux
Fora isso, o WezTerm é excelente
As opções de configuração do macOS são limitadas e exigem vários contornos; até dá para ajustar o Linux para ficar parecido com o macOS, mas eu também não gosto muito dos atalhos do próprio macOS. Então acaba virando uma mistura esquisita, e toda vez que troco de máquina continuo apertando a tecla errada
Queria saber se alguém encontrou uma configuração que funcione bem
Não sei por quê, nem sei como diagnosticar. Meu único palpite é um scrollback grande, mas disso eu não posso abrir mão. No fim migrei para o Kitty, e o Kitty também tem seus problemas, mas pelo menos funciona
A linguagem de configuração Lua brilha porque torna bem fácil fazer mudanças específicas por ambiente. Também acho que existe um efeito colateral subestimado do Rust. Ferramentas modernas em Rust muitas vezes têm excelente suporte cross-platform, talvez por causa da boa camada de abstração entre linguagem e sistema operacional
Lá por 2019, bastou comparar por alto o repositório do wez com outros em termos de GitHub Actions, issues e documentação para eu me convencer, e desde então não voltei atrás. Ele ainda vem com suporte a abas por padrão
Foi o primeiro terminal a realmente substituir o urxvt em termos de suporte e velocidade. Antes disso eu usava termite e mantinha o urxvt como backup caso o termite bugasse em alguma situação estranha
O motivo de eu continuar no iTerm2 é
Edit->Selection Respects Soft BoundariesÉ a função que “quando ativada, interpreta as barras verticais
|como divisores de painel do vim ou do emacs, e a seleção faz wrap naquele ponto”No meu caso, preciso disso para selecionar texto no IRC
https://github.com/wez/wezterm/issues/596
Ninguém precisa de todos os recursos, mas cada pessoa tem 10 recursos de nicho que quer, e esses 10 não são os mesmos para todo mundo. Então, para conseguir seus 10 recursos de nicho, a gente acaba aceitando o inchaço
Edit: falei de forma meio brusca, desculpa. Passei batido pela parte de usar isso no IRC
Eu era usuário de iTerm2 desde que comecei a usar macOS pela primeira vez, quase 10 anos atrás
Mas recentemente comecei a sentir que ele ficou realmente lento, e cheguei ao meu limite quando passei a esperar mais de 1 segundo para o terminal aparecer ao alternar com
cmd-tabDei uma olhada em algumas alternativas, mas nenhuma parecia ideal. Um terminal exigia conta/login para funcionar, o que era uma grande desvantagem, e outro era escrito em {Java,Type}Script e, por causa da natureza assíncrona dos streams do Node.js, quebrava até comandos simples como
yesAté agora estou gostando bastante do WezTerm. Ele é bem rápido, muito configurável e já vem com o tema OneDark(base16), que eu usava no iTerm2, incluído por padrão
O único incômodo inicial foi ter que adicionar manualmente a configuração de
cmd-leftecmd-rightno Lua; acho que isso deveria fazer parte do padrãoO Wez também publicou um livro sobre programação de sistemas em Rust
https://leanpub.com/sysprog
Gostei do texto e talvez eu experimente o WezTerm, mas acabei de migrar para o Kitty recentemente, então não quero ficar trocando com tanta frequência
Só que preciso fazer uma correção sobre o Kitty. O Kitty não usa YAML nem TOML; ele usa uma DSL de configuração simples própria e, além disso, pode ser totalmente automatizado com Python