Zsh + Starship + plugins: terminal produtivo sem complicar

1. Por que trocar o bash pelo Zsh?

O bash é o shell padrão da maioria das distribuições Linux e macOS, mas suas limitações ficam evidentes quando você passa horas no terminal. Autocomplete básico, sem correção ortográfica, expansão de globs limitada e personalização complexa são alguns dos problemas que o Zsh resolve de forma nativa.

O Zsh oferece:
- Autocomplete inteligente: sugestões contextuais que aprendem com seu uso
- Correção ortográfica automática: ao digitar cd Documnts, o Zsh pergunta se você quis dizer Documents
- Expansão de globs avançada: padrões como **/*.py para buscar recursivamente ou ls *(.) para listar apenas arquivos
- Compatibilidade com plugins: ecossistema maduro sem comprometer performance

A transição é suave: o Zsh é compatível com scripts bash na maioria dos casos, então você não precisa reescrever nada.

2. Instalação e configuração base do Zsh

Instalação

No Ubuntu/Debian:

sudo apt install zsh
chsh -s $(which zsh)

No macOS (via Homebrew):

brew install zsh
sudo sh -c "echo $(which zsh) >> /etc/shells"
chsh -s $(which zsh)

Arquivos de configuração

O Zsh usa três arquivos principais:
- .zshrc: configurações interativas (aliases, plugins, prompt)
- .zprofile: comandos executados em login (variáveis de ambiente)
- .zshenv: variáveis para todos os shells (raro de usar)

Habilitando recursos nativos

Adicione ao .zshrc:

# Habilitar menu de autocomplete
autoload -Uz compinit && compinit
zstyle ':completion:*' menu select

# Autocd: navegar sem digitar cd
setopt autocd

# Correção ortográfica
setopt correct

# Expansão de globs estendida
setopt extendedglob

Após salvar, recarregue com source ~/.zshrc.

3. Starship: prompt minimalista e informativo

Starship é um prompt minimalista que funciona em qualquer shell (Zsh, Fish, Bash). Diferente de Oh My Zsh ou Powerlevel10k, ele é escrito em Rust — extremamente rápido e com configuração declarativa via arquivo TOML.

Instalação

# Linux/macOS
curl -sS https://starship.rs/install.sh | sh

# Adicione ao .zshrc
echo 'eval "$(starship init zsh)"' >> ~/.zshrc

Configuração básica do starship.toml

Crie ~/.config/starship.toml:

# Módulo git simplificado
[git_branch]
symbol = "🌱 "
format = "on [$symbol$branch]($style) "

# Mostrar tempo de execução apenas acima de 2 segundos
[cmd_duration]
min_time = 2000
format = "took [$duration]($style) "

# Versão do Node.js
[nodejs]
format = "via [⬢ $version](bold green) "

# Desabilitar módulo de pacotes
[package]
disabled = true

O resultado é um prompt limpo, com informações relevantes apenas quando necessário.

4. Gerenciamento de plugins com zinit

Oh My Zsh é popular, mas pode deixar o terminal lento. O zinit (antigo zplugin) é um gerenciador leve que carrega plugins sob demanda.

Instalação do zinit

bash -c "$(curl --fail --show-error --silent --location \
  https://raw.githubusercontent.com/zdharma-continuum/zinit/HEAD/scripts/install.sh)"

Sintaxe básica

No .zshrc, após a instalação:

# Carregar plugin imediatamente
zinit light zsh-users/zsh-autosuggestions

# Carregar com lazy loading (só quando necessário)
zinit ice wait'0' lucid
zinit light zsh-users/zsh-syntax-highlighting

O parâmetro wait'0' atrasa o carregamento para não impactar a inicialização do shell.

5. Plugins indispensáveis para produtividade

zsh-autosuggestions

Sugere comandos baseados no histórico enquanto você digita:

zinit light zsh-users/zsh-autosuggestions

# Tecla para aceitar sugestão (Ctrl+Espaço)
bindkey '^ ' autosuggest-accept

zsh-syntax-highlighting

Destaca comandos válidos em verde e inválidos em vermelho:

zinit light zsh-users/zsh-syntax-highlighting

zsh-completions

Completions extras para ferramentas modernas:

zinit light zsh-users/zsh-completions

# Ativar completions carregadas
autoload -Uz compinit && compinit

Agora git checkout <TAB> mostra branches, docker run <TAB> lista imagens e npm install <TAB> completa pacotes.

6. Atalhos e truques que viram o jogo

zoxide — navegação inteligente

Substituto do cd que aprende seus diretórios mais usados:

# Instalação
curl -sS https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | sh

# No .zshrc
eval "$(zoxide init zsh)"

Use z proj para ir ao diretório ~/projetos e zi para navegação interativa com fuzzy matching.

fzf — busca fuzzy integrada

# Instalação
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install

# No .zshrc
source <(fzf --zsh)

Atalhos úteis:
- Ctrl+R: busca fuzzy no histórico de comandos
- Ctrl+T: busca fuzzy por arquivos
- Alt+C: busca fuzzy por diretórios

Expansão de globs

# Todos os arquivos Python recursivamente
ls **/*.py

# Apenas arquivos regulares (não diretórios)
ls *(.)

# Arquivos maiores que 1MB
ls *(Lm+1)

# Substituir extensão
cp *.txt(.:r).md .   # renomeia .txt para .md

7. Automatizando com aliases e funções

Aliases inteligentes

Organize em seções no .zshrc:

# Git
alias gst='git status'
alias gp='git push'
alias gco='git checkout'
alias glog='git log --oneline --graph --decorate'

# Docker
alias dcup='docker compose up'
alias dcdown='docker compose down'
alias dclogs='docker compose logs -f'

# Navegação
alias ..='cd ..'
alias ...='cd ../..'
alias ll='ls -lah'

Funções úteis

# mkcd: criar diretório e entrar
mkcd() {
  mkdir -p "$1" && cd "$1"
}

# extract: extrair qualquer arquivo
extract() {
  if [ -f "$1" ]; then
    case "$1" in
      *.tar.bz2) tar xjf "$1" ;;
      *.tar.gz)  tar xzf "$1" ;;
      *.zip)     unzip "$1" ;;
      *.rar)     unrar x "$1" ;;
      *)         echo "Formato não suportado" ;;
    esac
  fi
}

# git log formatado
glogf() {
  git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
}

Aliases por projeto

Crie um arquivo .aliases no diretório do projeto:

# .aliases
alias run='npm run dev'
alias test='npm test'

No .zshrc, carregue automaticamente:

if [ -f .aliases ]; then
  source .aliases
fi

8. Mantendo o terminal rápido e organizado

Lazy loading de plugins pesados

Use o zinit para carregar apenas quando necessário:

# Carregar docker-completion apenas se docker estiver instalado
if (( $+commands[docker] )); then
  zinit ice wait'1' lucid
  zinit light docker/compose
fi

Boas práticas no .zshrc

  1. Ordem de carregamento: variáveis de ambiente → plugins → completions → aliases → prompt
  2. Modularização: divida em arquivos separados:
source ~/.zsh/aliases.zsh
source ~/.zsh/functions.zsh
source ~/.zsh/plugins.zsh
  1. Evite comandos lentos: não use eval $(something slow) no carregamento

Manutenção regular

# Atualizar plugins do zinit
zinit update

# Limpar histórico duplicado
sort -u ~/.zsh_history -o ~/.zsh_history

# Verificar tempo de carregamento
zinit times

Com estas práticas, seu terminal inicializa em menos de 200ms mesmo com dezenas de plugins.

Referências