Configuración estándar de zsh — Wiedii
Setup oficial del shell para todos los devs de Wiedii. Tres archivos, cada uno con responsabilidad clara.
Antes de aplicar esta configuración: instalar las herramientas de herramientas-por-rol (Nivel 0 y Nivel 1), incluyendo
starship,zinity el Nerd Font.
brew install starship zinit
brew install font-jetbrains-mono-nerd-font
Por qué Starship en lugar de Oh My Zsh
Wiedii usó Oh My Zsh durante años. Es el framework de zsh más popular y cubre una necesidad real: tener un prompt con información contextual sin configurar todo desde cero. Sin embargo, su modelo de funcionamiento genera costos que escalan con el tiempo.
El problema con Oh My Zsh
Oh My Zsh es un framework, no una herramienta. Carga docenas de archivos de configuración, autocompletions, themes y plugins de zsh al abrir cada terminal. A medida que se agregan plugins (git, docker, kubectl, aws, nvm…) el tiempo de carga crece de forma acumulativa — no es raro llegar a 1-2 segundos en entornos con muchas herramientas instaladas.
Además mezcla responsabilidades: el framework gestiona plugins, themes, completions y aliases al mismo tiempo, lo que dificulta entender exactamente qué está cargando y por qué.
Por qué Starship
Starship es un binario único escrito en Rust. No es un framework de zsh — es exclusivamente un prompt. No carga ningún archivo de zsh, no gestiona plugins, no modifica el entorno. Su única tarea es calcular qué mostrar en el prompt y hacerlo en milisegundos.
| Aspecto | Oh My Zsh | Starship |
|---|---|---|
| Arranque del shell | 500ms–2s | < 5ms |
| Lenguaje | bash/zsh | Rust |
| Plataforma | Solo zsh | bash, zsh, fish, PowerShell, nushell… |
| Plugins/themes | Acoplados al framework | No aplica — solo configura el prompt |
| Mantenimiento | Actualizar el framework + cada plugin | Un binario, un archivo de config |
Starship ejecuta cada módulo de forma paralela y con scan_timeout para no bloquear jamás el prompt aunque un repositorio git sea lento o una herramienta tarde en responder.
Por qué esta configuración específica
La configuración Wiedii (~/.config/starship.toml) aplica el tema Gruvbox Dark powerline con tres decisiones deliberadas:
1. Estilo powerline (segmentos de colores) Los segmentos en forma de flecha separan visualmente la información: sistema operativo → usuario → directorio → git → runtimes → hora. Es más denso que un prompt minimalista pero cada segmento tiene color propio, por lo que los ojos encuentran la información de forma instantánea sin leerla completa.
2. Paleta Gruvbox Dark Los tonos cálidos y saturados de Gruvbox (naranja, amarillo, verde musgo, azul acero) ofrecen alto contraste sin ser agresivos. Es la paleta que mejor funciona con terminales oscuras en sesiones largas de trabajo.
3. Solo módulos relevantes
El prompt muestra el runtime activo (bun, node, python…) solo cuando hay un mise.toml en el directorio. Cuando no hay proyecto activo, el segmento de runtimes desaparece. Esto evita el ruido de prompts que siempre muestran todas las versiones globales.
4. command_timeout = 1000 y scan_timeout = 30
En repos muy grandes, git status puede tardar. Sin estos límites, el prompt se congela hasta que git termina. Con estos valores, Starship muestra un estado parcial y continúa.
5. Integración con mise
El módulo [mise] está habilitado (disabled = false). Muestra la versión activa del runtime según el mise.toml del proyecto — la misma fuente de verdad que usa el código.
Gestión de plugins con zinit (no Oh My Zsh)
Los plugins que hacía Oh My Zsh (syntax highlighting, autosugerencias, búsqueda en historial) se reemplazan con zinit cargado desde brew. La diferencia clave es que zinit los carga de forma asíncrona (wait lucid): el prompt aparece inmediatamente y los plugins se cargan en paralelo sin bloquear.
brew install zinit # no npm install -g, no curl | bash
Arquitectura de los archivos zsh
~/.zshenv → Siempre se carga (scripts, cron, IDE, terminal)
~/.zprofile → Solo al login (una vez por sesión)
~/.zshrc → Solo en shells interactivos (cada terminal nueva)
La regla: PATH base y variables críticas en .zshenv. Activación de herramientas en .zprofile. Comportamiento interactivo (aliases, completions, plugins) en .zshrc.
Cómo aplicar cambios al .zshrc
Esto es algo que confunde a casi todos al principio. Leer con atención.
Cuando guardas un cambio en ~/.zshrc, el archivo se actualiza en disco — pero tu terminal no lo sabe. Cada terminal carga su configuración una sola vez al abrirse y luego no vuelve a leer el archivo. Es como configurar el navegador: los cambios no se aplican solos a las pestañas ya abiertas.
Recargar la terminal actual
exec zsh # ← la forma correcta: reemplaza el shell actual con uno nuevo
# o también:
source ~/.zshrc # carga el archivo en la sesión actual sin reemplazar el shell
exec zsh es preferible porque levanta un shell completamente limpio. source ~/.zshrc puede dejar variables viejas flotando si las renombraste o eliminaste. El alias reload ya hace esto por ti:
reload # equivale a exec zsh
Múltiples terminales abiertas
Si tienes tres ventanas o pestañas abiertas cuando editas .zshrc, cada una corre su propio shell independiente. El cambio no se propaga automáticamente — necesitas ejecutar exec zsh (o reload) en cada terminal donde quieras que el cambio tome efecto.
Terminal 1 (editaste aquí) → exec zsh ✅
Terminal 2 → exec zsh ✅ ← no olvides esta
Terminal 3 → exec zsh ✅ ← ni esta
Las terminales que abras después del cambio ya lo verán automáticamente.
Sesiones SSH
Una sesión SSH es exactamente lo mismo: un shell que se cargó con la configuración del momento en que te conectaste. Si editas .zshrc mientras tienes una sesión SSH activa, tienes dos opciones:
# Opción 1: recargar dentro de la sesión activa
exec zsh
# Opción 2: cerrar la conexión y volver a entrar
exit
ssh usuario@servidor # nueva conexión = config actualizada
Resumen visual
Editas ~/.zshrc y guardas
│
├─ Terminales ya abiertas → NO se actualizan solas → ejecutar: exec zsh
├─ Sesiones SSH activas → NO se actualizan solas → ejecutar: exec zsh (o reconectar)
└─ Terminales nuevas → ✅ ya ven el cambio
~/.zshenv
Se carga en todos los contextos: IDE, cron, scripts, CI local.
# ~/.zshenv — se carga primero en TODOS los contextos de zsh
# Garantiza que las rutas base del sistema siempre estén disponibles
export PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:$PATH"
~/.zprofile
Se carga una vez al login.
# ~/.zprofile
# Homebrew — activar entorno (Apple Silicon: /opt/homebrew)
eval "$(/opt/homebrew/bin/brew shellenv)"
# mise — activar shims (más rápido que eval completo en login)
eval "$(mise activate zsh --shims)"
# JetBrains Toolbox — scripts de IDEs
export PATH="$PATH:$HOME/Library/Application Support/JetBrains/Toolbox/scripts"
# pipx — herramientas Python instaladas con pipx
export PATH="$PATH:$HOME/.local/bin"
# OrbStack — integración Docker/Kubernetes y completions
source ~/.orbstack/shell/init.zsh 2>/dev/null || :
# Starship — prompt (preferir la versión de brew)
if command -v /opt/homebrew/bin/starship >/dev/null 2>&1; then
eval "$(/opt/homebrew/bin/starship init zsh)"
elif command -v starship >/dev/null 2>&1; then
eval "$(starship init zsh)"
fi
~/.zshrc — config completa
# =============================================================================
# CONFIGURACIÓN BASE
# =============================================================================
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
export PATH="/usr/bin:/bin:/usr/sbin:/sbin"
export PATH="$HOME/.orbstack/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:$PATH"
# =============================================================================
# FUNCIONES ZSH
# =============================================================================
autoload -Uz compinit
autoload -Uz bashcompinit && bashcompinit
# Homebrew completions
if command -v brew >/dev/null 2>&1; then
BREW_PREFIX="$(brew --prefix)"
fpath+=("$BREW_PREFIX/share/zsh/site-functions")
-d "$BREW_PREFIX/opt/docker/share/zsh/site-functions" && \
fpath+=("$BREW_PREFIX/opt/docker/share/zsh/site-functions")
fi
# Inicializar completions
compinit -C
# =============================================================================
# STARSHIP PROMPT
# =============================================================================
if command -v starship >/dev/null 2>&1; then
export STARSHIP_CACHE=~/.cache/starship
export STARSHIP_CONFIG=~/.config/starship.toml
! -d ~/.cache/starship && mkdir -p ~/.cache/starship
eval "$(starship init zsh)"
fi
# =============================================================================
# ZINIT PLUGINS (solo si no es Warp)
# =============================================================================
if "$IS_WARP" != "true" && -f "$(brew --prefix)/opt/zinit/zinit.zsh"; then
source "$(brew --prefix)/opt/zinit/zinit.zsh"
# Cargar plugins de forma asíncrona para no bloquear el arranque del shell
zinit wait lucid for \
zdharma-continuum/fast-syntax-highlighting \
atload"_zsh_autosuggest_start" \
zsh-users/zsh-autosuggestions
zinit light zdharma-continuum/history-search-multi-word
fi
# =============================================================================
# ENVIRONMENT VARIABLES
# =============================================================================
# Mise
export MISE_CONFIG_FILE="$HOME/.config/mise/config.toml"
# Docker — BuildKit habilitado por defecto
export DOCKER_BUILDKIT=1
export COMPOSE_DOCKER_CLI_BUILD=1
export BUILDKIT_PROGRESS=plain
# AWS
export AWS_CLI_AUTO_PROMPT=off
# GPG — necesario para firmar commits y descifrar archivos
export GPG_TTY=$(tty)
# Paths opcionales (presentes si se usó bun global o pnpm alguna vez)
-d "$HOME/.bun/bin" && export PATH="$HOME/.bun/bin:$PATH"
-d "$HOME/Library/pnpm" && export PATH="$HOME/Library/pnpm:$PATH"
# =============================================================================
# ZSH OPTIONS
# =============================================================================
HISTSIZE=50000
SAVEHIST=50000
HISTFILE=~/.zsh_history
setopt SHARE_HISTORY # compartir historial entre terminales abiertas
setopt HIST_EXPIRE_DUPS_FIRST # eliminar duplicados primero al truncar
setopt HIST_IGNORE_DUPS # no guardar líneas iguales consecutivas
setopt HIST_VERIFY # expandir !! antes de ejecutar
setopt HIST_IGNORE_SPACE # no guardar líneas que empiezan con espacio
setopt INC_APPEND_HISTORY # agregar al historial en tiempo real
setopt EXTENDED_HISTORY # guardar timestamp en el historial
setopt NO_BEEP # sin pitidos
setopt COMPLETE_IN_WORD # completar en medio de una palabra
setopt AUTO_CD # escribir un directorio entra en él
setopt AUTO_PUSHD # cd guarda el directorio anterior en el stack
setopt PUSHD_IGNORE_DUPS # no duplicar entradas en el stack de dirs
unsetopt correct # sin corrección automática de comandos
unsetopt correct_all # sin corrección automática de argumentos
# =============================================================================
# KEY BINDINGS (solo si no es Warp)
# =============================================================================
# Warp tiene su propio motor de input — los bindings personalizados interfieren
if "$IS_WARP" != "true"; then
bindkey '^| echo "")
fi
# gh CLI
if command -v gh >/dev/null 2>&1; then
eval "$(gh completion -s zsh 2>/dev/null || echo "")"
fi
# GitLab CLI
if command -v glab >/dev/null 2>&1; then
eval "$(glab completion -s zsh 2>/dev/null || echo "")"
fi
# AWS CLI
if command -v aws_completer >/dev/null 2>&1; then
complete -C aws_completer aws 2>/dev/null || true
fi
# =============================================================================
# COMPLETION STYLES
# =============================================================================
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}' # case-insensitive
zstyle ':completion:*' menu select # menú navegable con flechas
zstyle ':completion:*' use-cache on
zstyle ':completion:*' cache-path ~/.zsh/cache
# Eliminar duplicados en PATH — siempre antes de los shims de mise
typeset -U PATH
# =============================================================================
# TERRAFORM / TERRAGRUNT (devs de infra)
# =============================================================================
export TF_PLUGIN_CACHE_DIR="$HOME/terraform-cache/plugins"
export TF_PARALLELISM=$(( $(sysctl -n hw.ncpu) * 3 / 4 ))
export TF_CLI_ARGS_plan="-parallelism=${TF_PARALLELISM}"
export TF_CLI_ARGS_apply="-parallelism=${TF_PARALLELISM}"
export TG_PROVIDER_CACHE=1
# =============================================================================
# MISE SHIMS — debe ser lo ÚLTIMO del archivo
# =============================================================================
# Al ir al final, los shims de mise tienen máxima prioridad en PATH.
# Garantiza que las versiones del proyecto siempre ganen sobre las globales.
export PATH="$HOME/.local/share/mise/shims:$PATH"
Notas importantes sobre el config
Detección de Warp (IS_WARP)
Warp tiene su propio motor de sintaxis, autosugerencias y keybindings. Cargar zinit en Warp causaría conflictos y duplicaría funcionalidades. La variable IS_WARP la inyecta Warp automáticamente; el config la detecta y deshabilita los bloques incompatibles.
# Bloques desactivados en Warp:
# - zinit y todos sus plugins
# - bindkey personalizados para historial
zinit instalado por brew
zinit se instala exclusivamente a través de Homebrew, en línea con la política de Wiedii:
brew install zinit
# zinit.zsh queda en: $(brew --prefix)/opt/zinit/zinit.zsh
Plugins activos:
fast-syntax-highlighting— coloreado de sintaxis en tiempo realzsh-autosuggestions— sugerencias grises basadas en historialhistory-search-multi-word— búsqueda en historial por múltiples palabras (Ctrl+Rmejorado)
El alias update — actualizar todo el sistema
alias update='brewup && zinit update && zinit cclear && mise plugins update && mas upgrade'
Un solo comando actualiza en orden: Homebrew (formulae + casks) → zinit y sus plugins → plugins de mise → apps del Mac App Store. Ejecutar periódicamente para mantener el entorno limpio.
~/.config/starship.toml
Ver [[herramientas-rust#starship → reemplaza el prompt de zsh para el config completo.
Verificar que el config carga correctamente:
starship explain # muestra módulos activos y su formato
starship config # abre starship.toml en el editor
Orden de carga completo
Terminal nueva (interactiva)
↳ .zshenv → LC_ALL, LANG, PATH base
↳ .zprofile → brew, mise --shims, OrbStack, JetBrains, Starship
↳ .zshrc → compinit, starship, zinit, env vars, options,
keybindings, aliases, funciones, completions,
typeset -U PATH, mise shims (último)
IDE / script no interactivo
↳ .zshenv → PATH base (SOLO esto)
Verificación completa
Abrir un terminal nuevo después de aplicar el config:
# Locale
echo $LANG # ✅ en_US.UTF-8
# PATH (sin duplicados)
echo $PATH | tr ':' '\n' | sort | uniq -d # ✅ vacío
# mise shims al final = máxima prioridad
echo $PATH | tr ':' '\n' | head -1 # ✅ /Users/<user>/.local/share/mise/shims
# Homebrew
brew --version # ✅ Homebrew 4.x.x
# mise
mise --version # ✅ mise x.y.z
# GitLab CLI
glab auth status # ✅ Logged in to gitlab.wiedii.co
# OrbStack — verificar por icono en menu bar + contexto Docker
docker context show # ✅ orbstack
# Starship
echo $STARSHIP_CONFIG # ✅ /Users/<user>/.config/starship.toml
starship explain # muestra módulos activos
# zinit (solo en terminal que no sea Warp)
# zinit es una función de shell, no tiene --version
type zinit # ✅ zinit is a shell function
# Herramientas Rust
bat --version && eza --version && fd --version && rg --version
# Alias update
update # actualiza brew + zinit + mise + mas
Troubleshooting
Starship no aparece el prompt con colores:
# Verificar que la fuente es JetBrains Mono Nerd Font en el terminal
# Warp: Settings → Appearance → Font
# En otras terminales: Preferences → Font
compinit lento al abrir terminal:
# La opción -C omite la comprobación de seguridad (más rápido)
# Si hay warnings de permisos:
chmod go-w /opt/homebrew/share/zsh /opt/homebrew/share/zsh/site-functions
Autosugerencias no aparecen (zinit):
# Verificar que no se está en Warp
echo $IS_WARP # debe estar vacío en Warp para activarse... verificar
# Reinstalar plugins
zinit delete --clean && zinit update
mise shims no tienen prioridad:
# Verificar que la línea de shims es la ÚLTIMA del .zshrc
tail -3 ~/.zshrc # debe terminar con la línea de mise shims
Referencias
- herramientas-por-rol — qué instalar antes de configurar el shell
- herramientas-rust — config completo de starship.toml
- glab — configuración completa de GitLab CLI
- orbstack — configuración de OrbStack
- guia-nuevo-dev — tutorial de onboarding completo