diff --git a/omarchy_zsh_setup/.zshrc b/omarchy_zsh_setup/.zshrc index 0d1ac96..0b1ae3b 100644 --- a/omarchy_zsh_setup/.zshrc +++ b/omarchy_zsh_setup/.zshrc @@ -1,83 +1,395 @@ -# ================================================================ -# Omarchy Zsh Configuration v2.5 (Omarchy-MG Edition) -# ================================================================ +# ============================================================================= +# CONFIGURACIÓN ZSH - OMARCHY v2.1 +# ============================================================================= +# --- PATH -------------------------------------------------------------------- +typeset -U PATH path +path=( + $HOME/.local/bin + $HOME/bin + $HOME/.npm-global/bin + $HOME/AppImages + $HOME/go/bin + $path +) + +# --- Oh My Zsh --------------------------------------------------------------- export ZSH="$HOME/.oh-my-zsh" -ZSH_THEME="agnoster" +ZSH_THEME="" # Oh My Posh manejará el prompt, así que el tema de OMZ queda vacío. -# Plugins -plugins=(git zsh-autosuggestions zsh-syntax-highlighting zsh-completions) +plugins=( + git sudo history colorize + docker docker-compose + npm node python pip golang + copypath copyfile + # Si usas zoxide, no lo añadas aquí, se inicializa más abajo +) -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 -# ---------------------------- -# Aliases y herramientas base -# ---------------------------- -alias ll='eza -lh --icons' -alias la='eza -lha --icons' -alias gs='git status' -alias v='nvim' -alias cat='bat' -alias cls='clear' +# Cargar Oh My Zsh +[ -r "$ZSH/oh-my-zsh.sh" ] && source "$ZSH/oh-my-zsh.sh" -# ---------------------------- -# FZF y Zoxide (si existen) -# ---------------------------- -if command -v fzf &>/dev/null; then - export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git' - export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND" -fi +# Cargar plugins específicos (zsh-autosuggestions y zsh-syntax-highlighting) +[ -r "${ZSH_CUSTOM:-$ZSH/custom}/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh" ] && \ + source "${ZSH_CUSTOM:-$ZSH/custom}/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh" -if command -v zoxide &>/dev/null; then - eval "$(zoxide init zsh)" -fi +[ -r "${ZSH_CUSTOM:-$ZSH/custom}/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" ] && \ + source "${ZSH_CUSTOM:-$ZSH/custom}/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" -# ---------------------------- -# Oh My Posh Prompt -# ---------------------------- -if command -v oh-my-posh &>/dev/null; then - eval "$(oh-my-posh init zsh --config ~/.poshthemes/omarchy.omp.json)" -fi - -# ---------------------------- -# PATH -# ---------------------------- -export PATH="$HOME/.local/bin:$PATH" - -# ================================================================ -# >>> Omarchy MG v2.5 additions >>> -# ================================================================ - -# --- Homebrew (Linuxbrew) integration --- -if [ -d /home/linuxbrew/.linuxbrew ]; then - eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" -elif [ -d "$HOME/.linuxbrew" ]; then - eval "$($HOME/.linuxbrew/bin/brew shellenv)" -fi - -# --- Docker group check --- -if command -v docker &>/dev/null; then - if ! groups $USER | grep -q '\bdocker\b'; then - echo "⚠️ Nota: el usuario $USER no pertenece al grupo docker." - echo " Ejecute: sudo usermod -aG docker $USER && newgrp docker" +# --- Oh My Posh -------------------------------------------------------------- +# Asegúrate de que Oh My Posh esté instalado y el tema 'catppuccin.omp.json' +# esté en ~/.poshthemes/ +if command -v oh-my-posh >/dev/null 2>&1; then + if [ -f ~/.poshthemes/catppuccin.omp.json ]; then + eval "$(oh-my-posh init zsh --config ~/.poshthemes/catppuccin.omp.json)" + else + # Fallback si el tema Catppuccin no se encuentra + eval "$(oh-my-posh init zsh)" + echo "Advertencia: Tema Catppuccin para Oh My Posh no encontrado en ~/.poshthemes/. Usando el tema por defecto." fi fi -# --- TeamViewer control helpers --- -alias teamviewerd-start="sudo systemctl start teamviewerd.service" -alias teamviewerd-enable="sudo systemctl enable teamviewerd.service" +# --- Go ---------------------------------------------------------------------- +export GOPATH="$HOME/go" +export GOBIN="$GOPATH/bin" -# --- Creative tools quick launch --- -alias aud="audacity &>/dev/null & disown" -alias inks="inkscape &>/dev/null & disown" +# --- NVM --------------------------------------------------------------------- +# Es importante que NVM se cargue después de la configuración de PATH, +# pero antes de que intentes usar 'node' o 'npm'. +export NVM_DIR="$HOME/.nvm" +[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # Esto carga nvm +[ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion" # Esto carga nvm bash_completion -# --- Info banner --- -# echo -e "\n${ZSH_THEME:+🎨 }Bienvenido a Omarchy Zsh v2.5 (MG Edition)" -echo "Sistema: $(uname -a | cut -d ' ' -f1-3)" -echo "Shell: $(zsh --version)" -echo "Usuario: $USER" -echo "--------------------------------------" +# --- Python ------------------------------------------------------------------ +alias pip='pip3' +alias python='python3' -# ================================================================ -# >>> End of Omarchy MG v2.5 additions <<< -# ================================================================ +venv() { + case "$1" in + create) python -m venv .venv && echo "✅ Entorno virtual creado en ./.venv" ;; + on|activate) + if [ -f ".venv/bin/activate" ]; then + . .venv/bin/activate + echo "🟢 Entorno virtual activado" + else + echo "❌ Entorno virtual no encontrado en ./.venv" + fi + ;; + off|deactivate) + if command -v deactivate &>/dev/null; then + deactivate 2>/dev/null + echo "🔴 Entorno virtual desactivado" + else + echo "🤷 No hay un entorno virtual activo para desactivar" + fi + ;; + *) echo "Uso: venv [create|on|off|activate|deactivate]" ;; + esac +} + +# --- Aliases ----------------------------------------------------------------- +alias cls='clear' +alias ll='ls -alF' +alias la='ls -A' +alias l='ls -CF' +alias ..='cd ..' +alias ...='cd ../..' +alias ....='cd ../../..' + +# System info +alias ff='fastfetch' # Requiere fastfetch +alias nf='fastfetch' # Requiere fastfetch + +# Arch Linux (si aplica) +alias pacu='sudo pacman -Syu' +alias paci='sudo pacman -S' +alias pacr='sudo pacman -Rns' +alias pacs='pacman -Ss' +alias yayu='yay -Syu' # Requiere yay AUR helper +alias yayi='yay -S' # Requiere yay AUR helper + +# Git +alias gs='git status' +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 +# Detecta si se usa 'docker compose' o 'docker-compose' +docker compose version >/dev/null 2>&1 && alias dc='docker compose' || alias dc='docker-compose' +alias d='docker' +alias dps='docker ps -a' +alias di='docker images' +alias dex='docker exec -it' +alias dlog='docker logs -f' + +# 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' + +# Python +alias py='python' +alias pir='pip install -r requirements.txt' +alias pipi='pip install' +alias pipf='pip freeze > requirements.txt' + +# ZeroTier +alias zt='sudo zerotier-cli' +alias ztstatus='sudo zerotier-cli listnetworks' +alias ztinfo='sudo zerotier-cli info' + +# Clima (requiere curl) +alias clima='curl wttr.in/Saltillo' + +# --- Funciones --------------------------------------------------------------- +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" ;; # Requiere 'unrar' + *.gz) gunzip "$1" ;; + *.tar) tar xf "$1" ;; + *.tbz2) tar xjf "$1" ;; + *.tgz) tar xzf "$1" ;; + *.zip) unzip "$1" ;; + *.Z) uncompress "$1" ;; + *.7z) 7z x "$1" ;; # Requiere '7zip' + *) echo "No se puede extraer '$1': formato no reconocido o herramienta no instalada." ;; + esac +} + +killport(){ + [ $# -eq 0 ] && echo "Uso: killport " && return 1 + local pid=$(lsof -ti:"$1" 2>/dev/null) # Requiere 'lsof' + [ -n "$pid" ] && kill -9 "$pid" && echo "✅ Proceso en puerto $1 eliminado (PID: $pid)" || echo "🤷 No se encontró ningún proceso en el puerto $1" +} + +serve(){ python -m http.server "${1:-8000}"; } + +# --- yt-dlp MEJORADO --------------------------------------------------------- +# Requiere yt-dlp instalado +export YTDLP_DIR="$HOME/Videos/YouTube" +mkdir -p "$YTDLP_DIR"/{Music,Videos} 2>/dev/null # Crear directorios si no existen + +ytm() { + case "$1" in + -h|--help|'') + echo "🎵 ytm - Descarga audio (MP3 320kbps) a $YTDLP_DIR/Music/" + echo "Ejemplos:" + echo " ytm https://youtu.be/dQw4w9WgXcQ" + echo " ytm 'Never Gonna Give You Up'" + return 0 + ;; + esac + + if ! command -v yt-dlp &>/dev/null; then + echo "❌ yt-dlp no está instalado. Por favor, instálalo para usar esta función." + return 1 + fi + + local out="$YTDLP_DIR/Music/%(title).180s.%(ext)s" + local opts=( + --extract-audio --audio-format mp3 --audio-quality 320K + --embed-metadata --embed-thumbnail --convert-thumbnails jpg + --no-playlist --retries 10 --fragment-retries 10 + --user-agent "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36" + --extractor-args "youtube:player_client=android,web" + --progress --newline -o "$out" + ) + + if [[ "$1" == http* ]]; then + echo "📥 Descargando audio..." + yt-dlp "${opts[@]}" "$@" + else + echo "🔍 Buscando: $*" + yt-dlp "${opts[@]}" "ytsearch1:$*" + fi + + [ $? -eq 0 ] && echo "✅ Audio descargado en: $YTDLP_DIR/Music/" || echo "❌ Falló la descarga de audio." +} + +ytv() { + case "$1" in + -h|--help|'') + echo "🎬 ytv [calidad] - Descarga video a $YTDLP_DIR/Videos/" + echo "Calidades disponibles: 1080, 720, 480 (por defecto: mejor disponible MP4)" + echo "Ejemplos:" + echo " ytv https://youtu.be/dQw4w9WgXcQ 1080" + echo " ytv 'Rick Astley - Never Gonna Give You Up' 720" + return 0 + ;; + esac + + if ! command -v yt-dlp &>/dev/null; then + echo "❌ yt-dlp no está instalado. Por favor, instálalo para usar esta función." + return 1 + fi + + local quality="${2:-best}" + local out="$YTDLP_DIR/Videos/%(title).180s.%(ext)s" + + 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' ;; # Mejor calidad MP4 + esac + + local opts=( + -f "$fmt" --embed-metadata --embed-thumbnail + --embed-subs --sub-langs "es.*,en.*" --convert-thumbnails jpg + --no-playlist --retries 10 --fragment-retries 10 + --user-agent "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36" + --extractor-args "youtube:player_client=android,web" + --progress --newline -o "$out" + ) + + if [[ "$1" == http* ]]; then + echo "📥 Descargando video..." + yt-dlp "${opts[@]}" "$1" + else + echo "🔍 Buscando: $1" + yt-dlp "${opts[@]}" "ytsearch1:$1" + fi + + [ $? -eq 0 ] && echo "✅ Video descargado en: $YTDLP_DIR/Videos/" || echo "❌ Falló la descarga de video." +} + +ytls() { + echo "🎵 Últimos 5 audios descargados en Music:" + ls -1t "$YTDLP_DIR/Music" 2>/dev/null | head -5 | sed 's/^/ /' || echo " (vacío)" + echo "" + echo "🎬 Últimos 5 videos descargados en Videos:" + ls -1t "$YTDLP_DIR/Videos" 2>/dev/null | head -5 | sed 's/^/ /' || echo " (vacío)" +} + +# --- GNOME Keyring ----------------------------------------------------------- +# Iniciar gnome-keyring-daemon si la sesión es gráfica y no está corriendo +if [ -n "$DESKTOP_SESSION" ]; then + if ! pgrep -u "$USER" gnome-keyring-daemon > /dev/null 2>&1; then + eval $(gnome-keyring-daemon --start --components=pkcs11,secrets,ssh 2>/dev/null) + fi + export SSH_AUTH_SOCK GPG_AGENT_INFO GNOME_KEYRING_CONTROL GNOME_KEYRING_PID +fi + +# --- SSH Agent --------------------------------------------------------------- +# Iniciar ssh-agent si no está corriendo y manejar las llaves SSH +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() { + echo "🔑 Iniciando ssh-agent..." + ssh-agent > "$SSH_ENV" + chmod 600 "$SSH_ENV" + . "$SSH_ENV" > /dev/null + } + + if [ -f "$SSH_ENV" ]; then + . "$SSH_ENV" > /dev/null + ps -p $SSH_AGENT_PID > /dev/null 2>&1 || start_agent + else + start_agent + fi + + if [ -d "$HOME/.ssh" ]; then + for key in "$HOME/.ssh"/*; do + if [ -f "$key" ] && [[ ! "$key" =~ \.pub$ ]] && \ + [[ ! "$key" =~ known_hosts ]] && [[ ! "$key" =~ authorized_keys ]] && \ + [[ ! "$key" =~ config ]] && [[ ! "$key" =~ agent ]]; then + if ssh-keygen -l -f "$key" &>/dev/null; then + local key_fingerprint=$(ssh-keygen -lf "$key" 2>/dev/null | awk '{print $2}') + if ! ssh-add -l 2>/dev/null | grep -q "$key_fingerprint"; then + if ssh-add "$key" 2>/dev/null; then + echo "✅ Llave SSH agregada: $(basename $key)" + fi + fi + fi + fi + done + fi +fi + +# Alias útiles para SSH +alias ssh-list='ssh-add -l' # Listar llaves cargadas +alias ssh-clear='ssh-add -D' # Limpiar todas las llaves +alias ssh-reload=' # Recargar todas las llaves + ssh-add -D 2>/dev/null + for key in ~/.ssh/*; do + if [ -f "$key" ] && [[ ! "$key" =~ \.pub$ ]] && ssh-keygen -l -f "$key" &>/dev/null; then + ssh-add "$key" 2>/dev/null && echo "✅ $(basename $key)" + fi + done +' + +alias ssh-github='ssh -T git@github.com' # Test GitHub connection + +# --- zoxide ------------------------------------------------------------------ +# Reemplazo inteligente de cd (requiere zoxide) +if command -v zoxide >/dev/null 2>&1; then + eval "$(zoxide init zsh)" + + # Alias para compatibilidad con el comportamiento tradicional + alias cd='z' + alias cdi='zi' # Interactive mode + alias zz='z -' # Ir al directorio anterior +else + echo "Advertencia: zoxide no está instalado. Instálalo para usar 'z', 'zi', 'zz'." +fi + + +# --- Historial de Zsh -------------------------------------------------------- +HISTSIZE=100000 # Número de comandos guardados en el historial en RAM +SAVEHIST=100000 # Número de comandos guardados en el archivo de historial +HISTFILE=~/.zsh_history # Archivo donde se guarda el historial +setopt APPEND_HISTORY # Añadir nuevos comandos al archivo de historial +setopt SHARE_HISTORY # Compartir historial entre sesiones de Zsh +setopt HIST_IGNORE_DUPS # No guardar comandos duplicados consecutivamente +setopt HIST_IGNORE_ALL_DUPS # No guardar comandos duplicados en el historial +setopt HIST_IGNORE_SPACE # No guardar comandos que comienzan con espacio +setopt AUTO_CD # Si se introduce un directorio, cambiar a él +setopt EXTENDED_GLOB # Habilitar características de expansión de comodines extendidas + +stty -ixon 2>/dev/null # Deshabilita CTRL+S (pause) y CTRL+Q (resume) + +export LESS='-R' # Habilita colores en man pages y less + +# --- Funciones externas ------------------------------------------------------ +# Cargar cualquier archivo .zsh que se encuentre en ~/.zsh_functions/ +[ -d "$HOME/.zsh_functions" ] || mkdir -p "$HOME/.zsh_functions" +for func_file in "$HOME/.zsh_functions"/*.zsh(N); do + source "$func_file" +done + +# --- Local Overrides --------------------------------------------------------- +# Permite tener un archivo ~/.zshrc.local para configuraciones personales +# sin modificar el archivo principal. Este archivo se cargará al final. +[ -f ~/.zshrc.local ] && source ~/.zshrc.local + +# Mensaje de bienvenida (opcional, puedes borrarlo) +#echo "🌈 Zsh está configurado con Catppuccin Frappe. ¡Disfruta!"