diff --git a/.zshrc.example b/.zshrc.example index 3bf0d23..5b5c855 100644 --- a/.zshrc.example +++ b/.zshrc.example @@ -1,27 +1,39 @@ -# --------------------------------------------------------------- -# Vanity Shell — Configuración base para Zsh en macOS -# --------------------------------------------------------------- -# Incluye Oh My Zsh, Oh My Posh, historial afinado y alias útiles. -# Este archivo es copiado automáticamente a ~/.zshrc por vanity_setup.sh. +# ======================================================================= +# Vanity Shell - Configuracion base para macOS (inspirada en MG v3.0) +# ======================================================================= +# Orientada a Zsh + Oh My Zsh + Oh My Posh. Ajusta cualquier seccion +# segun tus necesidades personales antes de copiarla a ~/.zshrc. +# ======================================================================= -# --------------------------------------------------------------- -# PATH — añade rutas clave antes del resto del sistema -# --------------------------------------------------------------- -if [ -d /opt/homebrew/bin ]; then - export PATH="/opt/homebrew/bin:/opt/homebrew/sbin:$PATH" -fi -if [ -d "$HOME/.local/bin" ]; then - export PATH="$HOME/.local/bin:$PATH" -fi -if [ -d "$HOME/bin" ]; then - export PATH="$HOME/bin:$PATH" +# --- Locale -------------------------------------------------------------- +export LANG=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 + +# --- Homebrew + PATH ----------------------------------------------------- +if [[ -x /opt/homebrew/bin/brew ]]; then + eval "$(/opt/homebrew/bin/brew shellenv)" +elif [[ -x /usr/local/bin/brew ]]; then + eval "$(/usr/local/bin/brew shellenv)" fi -# --------------------------------------------------------------- -# Oh My Zsh — Framework principal + plugins -# --------------------------------------------------------------- +typeset -U path PATH +path=( + /opt/homebrew/bin + /opt/homebrew/sbin + /usr/local/bin + /usr/local/sbin + $HOME/.local/bin + $HOME/bin + $HOME/.npm-global/bin + $HOME/AppImages + $HOME/go/bin + $path +) +export PATH + +# --- Oh My Zsh ----------------------------------------------------------- export ZSH="$HOME/.oh-my-zsh" -ZSH_THEME="robbyrussell" # el prompt real lo gestiona Oh My Posh +ZSH_THEME="" # el prompt final lo gestiona Oh My Posh plugins=( git sudo history colorize @@ -33,71 +45,237 @@ plugins=( zsh-completions ) -source $ZSH/oh-my-zsh.sh +export ZSH_DISABLE_COMPFIX=true +zstyle ':completion::complete:*' use-cache on +zstyle ':completion::complete:*' cache-path "$HOME/.zcompcache" +zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}' +zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}" +zstyle ':completion:*' menu select -# --------------------------------------------------------------- -# Oh My Posh — Prompt moderno (tema Catppuccin) -# --------------------------------------------------------------- +[[ -r "$ZSH/oh-my-zsh.sh" ]] && source "$ZSH/oh-my-zsh.sh" + +for plugin_file in \ + "${ZSH_CUSTOM:-$ZSH/custom}/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh" \ + "/usr/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh" +do + [[ -r "$plugin_file" ]] && source "$plugin_file" && break +done + +for plugin_file in \ + "${ZSH_CUSTOM:-$ZSH/custom}/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" \ + "/usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" +do + [[ -r "$plugin_file" ]] && source "$plugin_file" && break +done + +# --- Oh My Posh ---------------------------------------------------------- if command -v oh-my-posh >/dev/null 2>&1; then - eval "$(oh-my-posh init zsh --config ~/.poshthemes/catppuccin.omp.json)" + if [[ -f "$HOME/.poshthemes/catppuccin.omp.json" ]]; then + eval "$(oh-my-posh init zsh --config "$HOME/.poshthemes/catppuccin.omp.json")" + else + eval "$(oh-my-posh init zsh)" + fi fi -# --------------------------------------------------------------- -# Historial y opciones de shell -# --------------------------------------------------------------- -HISTFILE=~/.zsh_history -HISTSIZE=50000 -SAVEHIST=50000 -setopt SHARE_HISTORY -setopt HIST_IGNORE_SPACE -setopt HIST_IGNORE_DUPS -setopt HIST_VERIFY -setopt AUTO_CD -setopt CORRECT -setopt COMPLETE_ALIASES - -# --------------------------------------------------------------- -# Preferencias básicas -# --------------------------------------------------------------- -export CLICOLOR=1 -export LSCOLORS="GxFxCxDxBxegedabagacad" -export EDITOR="nano" - -# --------------------------------------------------------------- -# Alias — accesos rápidos de uso frecuente -# --------------------------------------------------------------- -alias ll="ls -lah" -alias gs="git status -sb" -alias gl="git log --oneline --graph --decorate" -alias gc="git commit" -alias gp="git push" -alias d="docker" -alias dc="docker compose" -alias reload-zsh="source ~/.zshrc" -alias portainer="open https://localhost:9443" -alias ytv='yt-dlp -P "$HOME/videos/youtube"' -alias ytm='yt-dlp -x --audio-format mp3 --audio-quality 0 -o "%(title)s.%(ext)s" -P "$HOME/musica/youtube"' - -# --------------------------------------------------------------- -# Integraciones opcionales -# --------------------------------------------------------------- +# --- Direnv -------------------------------------------------------------- if command -v direnv >/dev/null 2>&1; then eval "$(direnv hook zsh)" fi -# --------------------------------------------------------------- -# Ayuda rápida de Vanity Shell -# --------------------------------------------------------------- -help() { - cat <<'EOF' -Vanity Shell — comandos rápidos: - ytv -> Descarga el video completo en ~/videos/youtube - ytm -> Descarga solo el audio (mp3) en ~/musica/youtube +# --- Go / Node / Python -------------------------------------------------- +export GOPATH="$HOME/go" +export GOBIN="$GOPATH/bin" +export PATH="$GOBIN:$PATH" -Ejemplos: - ytv https://youtu.be/videoID - ytm https://youtu.be/trackID +export NVM_DIR="$HOME/.nvm" +[[ -s "$NVM_DIR/nvm.sh" ]] && source "$NVM_DIR/nvm.sh" +[[ -s "$NVM_DIR/bash_completion" ]] && source "$NVM_DIR/bash_completion" -Recuerda que ambos comandos requieren yt-dlp/ffmpeg instalados (el setup ya los incluye). +alias pip='pip3' +alias python='python3' + +venv() { + case "$1" in + create) python -m venv .venv && echo "Entorno virtual creado en .venv" ;; + on|activate) + if [[ -f .venv/bin/activate ]]; then + source .venv/bin/activate && echo "Entorno virtual activado" + else + echo "No se encontro .venv/bin/activate" + fi + ;; + off|deactivate) + command -v deactivate >/dev/null 2>&1 && deactivate && echo "Entorno virtual desactivado" || echo "No hay entorno activo" + ;; + *) echo "Uso: venv [create|on|off|activate|deactivate]" ;; + esac +} + +# --- Alias Generales ------------------------------------------------------ +alias cls='clear' +alias ll='ls -alF' +alias la='ls -A' +alias l='ls -CF' +alias ..='cd ..' +alias ...='cd ../..' +alias ....='cd ../../..' +alias reload='source ~/.zshrc' + +# --- Git ------------------------------------------------------------------ +alias gs='git status -sb' +alias ga='git add' +alias gc='git commit' +alias gcm='git commit -m' +alias gp='git push' +alias gl='git pull' +alias gd='git diff' +alias gb='git branch' +alias gco='git checkout' +alias gcb='git checkout -b' +alias glog='git log --oneline --graph --decorate' +gac() { git add . && git commit -m "$1"; } + +# --- Docker / Colima ------------------------------------------------------ +if docker compose version >/dev/null 2>&1; then + alias dc='docker compose' +else + alias dc='docker-compose' +fi +alias d='docker' +alias dps='docker ps -a' +alias di='docker images' +alias dex='docker exec -it' +alias dlog='docker logs -f' +alias colima-start='colima start --cpu 4 --memory 8 --disk 60' + +# --- NPM ------------------------------------------------------------------ +alias nrs='npm run start' +alias nrd='npm run dev' +alias nrb='npm run build' +alias nrt='npm run test' +alias ni='npm install' +alias nid='npm install --save-dev' +alias nig='npm install -g' + +# --- Utilidades ----------------------------------------------------------- +alias clima='curl wttr.in/Mexico+City' +mkcd() { mkdir -p "$1" && cd "$1"; } +extract() { + [[ ! -f "$1" ]] && echo "No es un archivo" && return 1 + case "$1" in + *.tar.bz2) tar xjf "$1" ;; + *.tar.gz) tar xzf "$1" ;; + *.bz2) bunzip2 "$1" ;; + *.rar) unrar e "$1" ;; + *.gz) gunzip "$1" ;; + *.tar) tar xf "$1" ;; + *.tbz2) tar xjf "$1" ;; + *.tgz) tar xzf "$1" ;; + *.zip) unzip "$1" ;; + *.7z) 7z x "$1" ;; + *) echo "Formato no soportado: $1" ;; + esac +} +killport() { + [[ -z "$1" ]] && echo "Uso: killport " && return 1 + local pid + pid=$(lsof -ti:"$1" 2>/dev/null) + [[ -n "$pid" ]] && kill -9 "$pid" && echo "Proceso $pid detenido en puerto $1" || echo "Sin procesos en puerto $1" +} +serve() { python -m http.server "${1:-8000}"; } + +# --- yt-dlp --------------------------------------------------------------- +export YTDLP_DIR="$HOME/videos/youtube" +mkdir -p "$YTDLP_DIR"/{audio,video} >/dev/null 2>&1 + +ytm() { + if [[ -z "$1" || "$1" == "-h" || "$1" == "--help" ]]; then + echo "Uso: ytm - Descarga audio MP3 en $YTDLP_DIR/audio" + return 0 + fi + yt-dlp -f bestaudio --extract-audio --audio-format mp3 --audio-quality 0 \ + --embed-metadata --embed-thumbnail \ + -o "$YTDLP_DIR/audio/%(title).180s.%(ext)s" "$1" +} + +ytv() { + if [[ -z "$1" ]]; then + echo "Uso: ytv [1080|720|480]" && return 1 + fi + local quality="${2:-best}" + local fmt + case "$quality" in + 1080) fmt='bv*[height<=1080][ext=mp4]+ba/b[height<=1080]' ;; + 720) fmt='bv*[height<=720][ext=mp4]+ba/b[height<=720]' ;; + 480) fmt='bv*[height<=480][ext=mp4]+ba/b[height<=480]' ;; + *) fmt='bv*[ext=mp4]+ba/b[ext=mp4]/b' ;; + esac + yt-dlp -f "$fmt" --embed-subs --embed-metadata --embed-thumbnail \ + -o "$YTDLP_DIR/video/%(title).180s.%(ext)s" "$1" +} + +ytls() { + echo "Audios recientes:" + ls -1t "$YTDLP_DIR/audio" 2>/dev/null | head -5 | sed 's/^/ /' || echo " (vacio)" + echo "Videos recientes:" + ls -1t "$YTDLP_DIR/video" 2>/dev/null | head -5 | sed 's/^/ /' || echo " (vacio)" +} + +# --- SSH Agent ------------------------------------------------------------ +if [[ -z "$SSH_AUTH_SOCK" ]]; then + export SSH_AGENT_DIR="$HOME/.ssh/agent" + mkdir -p "$SSH_AGENT_DIR" + SSH_ENV="$SSH_AGENT_DIR/env" + start_agent() { + ssh-agent >"$SSH_ENV" + chmod 600 "$SSH_ENV" + source "$SSH_ENV" >/dev/null + } + if [[ -f "$SSH_ENV" ]]; then + source "$SSH_ENV" >/dev/null + ps -p "$SSH_AGENT_PID" >/dev/null 2>&1 || start_agent + else + start_agent + fi +fi + +alias ssh-list='ssh-add -l' +alias ssh-clear='ssh-add -D' +alias ssh-github='ssh -T git@github.com' + +# --- zoxide --------------------------------------------------------------- +if command -v zoxide >/dev/null 2>&1; then + eval "$(zoxide init zsh)" + alias zz='z -' + alias zi='zi' +fi + +# --- Historial ------------------------------------------------------------ +HISTFILE="$HOME/.zsh_history" +HISTSIZE=100000 +SAVEHIST=100000 +setopt APPEND_HISTORY SHARE_HISTORY HIST_IGNORE_DUPS HIST_IGNORE_ALL_DUPS HIST_IGNORE_SPACE AUTO_CD EXTENDED_GLOB +stty -ixon 2>/dev/null + +# --- Completions Extras --------------------------------------------------- +if command -v kubectl >/dev/null 2>&1; then + source <(kubectl completion zsh) +fi +if command -v docker >/dev/null 2>&1; then + source <(docker completion zsh) +fi + +# --- Ayuda rapida --------------------------------------------------------- +vanity_help() { + cat <` (video completo) y `ytm ` (solo audio MP3). - Añade un comando `help` dentro de Zsh que describe el uso de estos alias. -## 🐳 Stack Docker + Portainer -1. Instala Docker Desktop via Homebrew Cask. -2. Inicia la app automáticamente y espera a que el daemon esté listo. -3. Instala Lazydocker (`brew install lazydocker`). -4. Lanza Portainer CE con los puertos `8000` y `9443`. Acceso: `https://localhost:9443`. +## 🐳 Stack Docker + Portainer (sin Desktop) +1. Instala el Docker CLI oficial (`brew install docker docker-buildx docker-compose`). +2. Instala Colima, que levanta el daemon de Docker usando Hypervisor.framework. +3. Intenta iniciar Colima automáticamente con `colima start --cpu 4 --memory 8 --disk 60`. +4. Instala Lazydocker (`brew install lazydocker`). +5. Despliega Portainer CE con los puertos `8000` y `9443`. Acceso: `https://localhost:9443`. -> Si Docker Desktop aún no ha terminado de iniciar, el script dejará Portainer pendiente y te indicará que abras la app manualmente y ejecutes de nuevo la opción `D`. +> Si Colima no logra iniciar (por ejemplo, porque falta el permiso de virtualización), el script salta Portainer y te recuerda ejecutar `colima start` manualmente antes de volver a elegir la opción `D`. ## ✅ Verificación rápida - Recargar Zsh: `source ~/.zshrc` @@ -69,14 +70,14 @@ El script muestra un menú para elegir qué componentes instalar. ## ❗️ Solución de problemas - **“command not found: brew”**: ejecuta `eval "$(/opt/homebrew/bin/brew shellenv)"` (o `/usr/local/bin/brew`) y vuelve a correr la opción deseada. -- **Docker no arranca**: abre manualmente Docker Desktop desde Launchpad y espera a que el icono indique “Running” antes de reintentar la opción `D`. +- **Docker no arranca**: ejecuta `colima start` (o `colima status` para verificar) y vuelve a lanzar la opción `D` cuando `docker info` funcione. - **Oh My Posh sin fuente correcta**: instala Meslo manualmente desde `~/Library/Fonts` o selecciona *Meslo LG S DZ Nerd Font* en tu terminal. - **Conflictos con un `.zshrc` previo**: el instalador hace backup implícito sobrescribiendo `~/.zshrc`. Asegúrate de versionar tu archivo antes si necesitas conservarlo. ## 🧽 Desinstalación rápida - Elimina Portainer: `docker stop portainer && docker rm portainer && docker volume rm portainer_data`. - Borra la config Zsh (opcional): `rm -rf ~/.oh-my-zsh ~/.poshthemes ~/.zshrc`. -- Desinstala apps con Homebrew: `brew uninstall --cask docker` o `brew uninstall lazydocker oh-my-posh`. +- Desinstala apps con Homebrew: `brew uninstall docker colima lazydocker oh-my-posh`. ## 📄 Licencia Distribuido bajo la licencia MIT. Consulta `LICENSE` para más detalles. diff --git a/vanity_setup.sh b/vanity_setup.sh index 40c686b..5922996 100644 --- a/vanity_setup.sh +++ b/vanity_setup.sh @@ -136,19 +136,43 @@ ensure_docker_daemon() { fi echo "No se detectó un demonio de Docker en ejecución." >&2 - echo "Asegúrate de tener un entorno Docker corriendo (Docker Desktop, Colima, OrbStack, etc)." >&2 + echo "Asegúrate de tener un entorno Docker corriendo (Colima, OrbStack, Docker Desktop, etc)." >&2 return 1 } +ensure_colima_daemon() { + if ensure_docker_daemon; then + return 0 + fi + + if ! command -v colima >/dev/null 2>&1; then + echo "Colima no está instalado; no se puede iniciar un daemon Docker automáticamente." >&2 + return 1 + fi + + if colima status >/dev/null 2>&1; then + docker context use colima >/dev/null 2>&1 || true + else + echo "Iniciando daemon de Docker con Colima…" + if ! colima start --cpu 4 --memory 8 --disk 60; then + echo "No se pudo iniciar Colima automáticamente; ejecútalo manualmente con 'colima start'." >&2 + return 1 + fi + fi + + sleep 2 + docker context use colima >/dev/null 2>&1 || true + ensure_docker_daemon + return $? +} + install_docker_stack() { - echo "Instalando Docker CLI..." - brew install docker + echo "Instalando Docker CLI y utilidades…" + brew install docker docker-buildx docker-compose lazydocker colima - echo "Instalando Lazydocker…" - brew install lazydocker - - if ! ensure_docker_daemon; then - echo "Se omitió Portainer porque Docker no está operativo." + if ! ensure_colima_daemon; then + echo "Se omitió Portainer porque no hay un daemon Docker en ejecución." >&2 + echo "Sugerencia: inicia Colima manualmente con 'colima start' y vuelve a ejecutar la opción D." >&2 return fi