diff --git a/shared/aliases b/shared/aliases new file mode 100644 index 0000000..343a40a --- /dev/null +++ b/shared/aliases @@ -0,0 +1,107 @@ +# Shared Aliases +# Compatible with both bash and zsh + +# Navigation +alias ..='cd ..' +alias ...='cd ../..' +alias ....='cd ../../..' +alias ~='cd ~' +alias -- -='cd -' + +# List files +alias l='ls -lah' +alias la='ls -la' +alias ll='ls -l' +alias ls='ls --color=auto' + +# Grep with color +alias grep='grep --color=auto' +alias fgrep='fgrep --color=auto' +alias egrep='egrep --color=auto' + +# Safety nets +alias rm='rm -i' +alias cp='cp -i' +alias mv='mv -i' + +# Git shortcuts +alias g='git' +alias ga='git add' +alias gc='git commit' +alias gp='git push' +alias gl='git pull' +alias gs='git status' +alias gd='git diff' +alias gb='git branch' +alias gco='git checkout' + +# System monitoring +alias df='df -h' +alias du='du -h' +alias free='free -h' +alias ps='ps aux' + +# Network +alias ping='ping -c 5' +alias ports='netstat -tuln' + +# Package management (Debian/Ubuntu) +alias apt-update='sudo apt update && sudo apt upgrade' +alias apt-install='sudo apt install' +alias apt-search='sudo apt search' + +# Quick edits +alias bashrc='$EDITOR ~/.bashrc' +alias zshrc='$EDITOR ~/.zshrc' +alias vimrc='$EDITOR ~/.vimrc' + +# Utilities +alias weather='curl wttr.in' +alias myip='curl ifconfig.me' +alias path='echo $PATH | tr ":" "\n"' +alias reload='exec $SHELL' + +# Dotfiles sync aliases +alias dotsync='dotfiles_sync_now' +alias dotsyncforce='dotfiles_sync_force' +alias dotstatus='dotfiles_sync_status' +alias dotson='dotfiles_sync_enable' +alias dotsoff='dotfiles_sync_disable' + +# Package management aliases +alias dotpkgs='dotfiles_packages_status' +alias dotinstall='dotfiles_install_packages' +alias dotcheck='dotfiles_check_packages' + +# Profile management aliases +alias dotprofile='dotfiles_profile_status' +alias dotprofileset='dotfiles_profile_set' +alias dotprofiledetect='dotfiles_profile_detect' + +# Reset aliases +alias dotreset='$HOME/.dotfiles/reset.sh' +alias dotresetsoft='$HOME/.dotfiles/reset.sh --soft' +alias dotresethard='$HOME/.dotfiles/reset.sh --hard' +alias dotresetnuke='$HOME/.dotfiles/reset.sh --nuclear' + +# Update aliases +alias dotupdatecheck='dotfiles_update_check' +alias dotupdatestatus='dotfiles_update_status' +alias dotupdate='dotfiles_update_install' + +# Task Master aliases +alias tm='task-master' +alias taskmaster='task-master' + +# SSH tunnel aliases +alias sshuttle-vpn='sudo sshuttle -e "ssh -F /home/eric/.ssh/config" -NH' +alias sshuttle-txtwire='sshuttle-vpn -r root@208.76.194.2 192.168.0.0/21' + +# Project control alias +alias ta="/home/eric/projects/misc/terraform/projectctl.sh" + +# Git remote URL conversion aliases +alias git-remote-toggle='git_remote_toggle' +alias git-remote-ssh='git_remote_to_ssh' +alias git-remote-https='git_remote_to_https' +alias git-convert='git_remote_convert' \ No newline at end of file diff --git a/shared/completions b/shared/completions new file mode 100644 index 0000000..5c97d29 --- /dev/null +++ b/shared/completions @@ -0,0 +1,83 @@ +# Shared Completion Functions +# Compatible with both bash and zsh + +# Custom completion for 'ta' command +_ta_complete() { + local cur prev actions layers tf_cmds ansible_cmds + + # Get current word and previous word based on shell + if [[ -n "$ZSH_VERSION" ]]; then + # Zsh completion + cur="${words[CURRENT]}" + prev="${words[CURRENT-1]}" + local comp_word=$CURRENT + else + # Bash completion + local cur prev + _get_comp_words_by_ref cur prev + local comp_word=$COMP_CWORD + fi + + actions="terraform ansible install remove" + layers="foundation showcase" + tf_cmds="init plan apply refresh destroy" + ansible_cmds="" # Add Ansible-specific commands here if needed + + case $comp_word in + 1) + if [[ -n "$ZSH_VERSION" ]]; then + compadd $actions + else + COMPREPLY=( $(compgen -W "$actions" -- "$cur") ) + fi + ;; + 2) + if [[ "$prev" == "terraform" || "$prev" == "ansible" ]]; then + if [[ -n "$ZSH_VERSION" ]]; then + compadd $layers + else + COMPREPLY=( $(compgen -W "$layers" -- "$cur") ) + fi + fi + ;; + 3) + if [[ -n "$ZSH_VERSION" ]]; then + local first_word="${words[2]}" + else + local first_word="${COMP_WORDS[1]}" + fi + + if [[ "$first_word" == "terraform" ]]; then + if [[ -n "$ZSH_VERSION" ]]; then + compadd $tf_cmds + else + COMPREPLY=( $(compgen -W "$tf_cmds" -- "$cur") ) + fi + elif [[ "$first_word" == "ansible" ]]; then + if [[ -n "$ZSH_VERSION" ]]; then + compadd $ansible_cmds + else + COMPREPLY=( $(compgen -W "$ansible_cmds" -- "$cur") ) + fi + fi + ;; + *) + # Fallback to file completions + if [[ -n "$ZSH_VERSION" ]]; then + _files + else + COMPREPLY=( $(compgen -f -- "$cur") ) + fi + ;; + esac + return 0 +} + +# Register completion based on shell +if [[ -n "$ZSH_VERSION" ]]; then + # Zsh completion registration + compdef _ta_complete ta +else + # Bash completion registration + complete -F _ta_complete ta +fi \ No newline at end of file diff --git a/shared/exports b/shared/exports new file mode 100644 index 0000000..a7ac2b8 --- /dev/null +++ b/shared/exports @@ -0,0 +1,34 @@ +# Environment Variables +# Shared across all shells + +# Editor preferences +export EDITOR=vim +export VISUAL=vim +export PAGER=less + +# Path modifications +export PATH="$HOME/.local/bin:$HOME/bin:/usr/local/bin:$PATH" +export PATH="~/.npm-global/bin:$PATH" +export PATH="/home/eric/.opencode/bin:$PATH" + +# History settings +export HISTSIZE=10000 +export HISTFILESIZE=20000 +export HISTCONTROL=ignoreboth:erasedups + +# Color support +export CLICOLOR=1 +export LSCOLORS=ExFxBxDxCxegedabagacad + +# Less configuration +export LESS='-R -i -M -F -X' + +# Locale settings +export LC_ALL=en_US.UTF-8 +export LANG=en_US.UTF-8 + +# Development tools +export GREP_OPTIONS='--color=auto' + +# Custom environment variables +export LOCAL_ENDPOINT=http://10.13.0.254:11434/v1 \ No newline at end of file diff --git a/shared/functions b/shared/functions new file mode 100644 index 0000000..c27d602 --- /dev/null +++ b/shared/functions @@ -0,0 +1,310 @@ +# Shared Functions +# Compatible with both bash and zsh + +# Create directory and cd into it +mkcd() { + mkdir -p "$1" && cd "$1" +} + +# Extract archives +extract() { + if [ -f "$1" ]; then + case "$1" in + *.tar.bz2) tar xjf "$1" ;; + *.tar.gz) tar xzf "$1" ;; + *.bz2) bunzip2 "$1" ;; + *.rar) unrar x "$1" ;; + *.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" ;; + *) echo "'$1' cannot be extracted via extract()" ;; + esac + else + echo "'$1' is not a valid file" + fi +} + +# Find files by name +findfile() { + find . -type f -name "*$1*" 2>/dev/null +} + +# Find directories by name +finddir() { + find . -type d -name "*$1*" 2>/dev/null +} + +# Process grep +psgrep() { + ps aux | grep "$1" | grep -v grep +} + +# Quick backup +backup() { + cp "$1"{,.bak} +} + +# Show disk usage of current directory +usage() { + du -sh ./* | sort -hr +} + +# Package management functions +dotfiles_packages_status() { + echo "📦 Package Status Check" + echo "======================" + + # Check if package manager is available + if [[ -f "$HOME/.dotfiles/lib/package_manager.sh" ]]; then + source "$HOME/.dotfiles/lib/package_manager.sh" + + echo "📋 System packages:" + for pkg in sshuttle curl git vim; do + case "$pkg" in + "sshuttle") check="which sshuttle" ;; + "curl") check="which curl" ;; + "git") check="which git" ;; + "vim") check="which vim" ;; + esac + if is_package_installed "$check"; then + echo " ✅ $pkg" + else + echo " ❌ $pkg (missing)" + fi + done + + echo "" + echo "⚡ Binary packages:" + for pkg in claude-code gemini-cli; do + case "$pkg" in + "claude-code") check="which claude" ;; + "gemini-cli") check="which gemini" ;; + esac + if is_package_installed "$check"; then + echo " ✅ $pkg" + else + echo " ❌ $pkg (missing)" + fi + done + + echo "" + echo "🐙 GitHub packages:" + for pkg in fzf bat ripgrep fd delta; do + case "$pkg" in + "fzf") check="which fzf" ;; + "bat") check="which bat" ;; + "ripgrep") check="which rg" ;; + "fd") check="which fd" ;; + "delta") check="which delta" ;; + esac + if is_package_installed "$check"; then + echo " ✅ $pkg" + else + echo " ❌ $pkg (missing)" + fi + done + + else + echo "❌ Package manager not available" + fi +} + +dotfiles_install_packages() { + if [[ -f "$HOME/.dotfiles/lib/package_manager.sh" ]]; then + source "$HOME/.dotfiles/lib/package_manager.sh" + install_all_packages + else + echo "❌ Package manager not available" + fi +} + +dotfiles_check_packages() { + if [[ -f "$HOME/.dotfiles/lib/package_manager.sh" ]]; then + source "$HOME/.dotfiles/lib/package_manager.sh" + install_all_packages true # Skip optional packages + else + echo "❌ Package manager not available" + fi +} + +# Profile management functions +dotfiles_profile_status() { + if [[ -f "$HOME/.dotfiles/lib/profile_manager.sh" ]]; then + source "$HOME/.dotfiles/lib/profile_manager.sh" + show_profile_status + else + echo "❌ Profile manager not available" + fi +} + +dotfiles_profile_set() { + local new_profile="$1" + if [[ -z "$new_profile" ]]; then + echo "Usage: dotfiles_profile_set " + echo "Available profiles: server, dev, dev-lite, personal, minimal" + return 1 + fi + + if [[ -f "$HOME/.dotfiles/lib/profile_manager.sh" ]]; then + source "$HOME/.dotfiles/lib/profile_manager.sh" + set_profile "$new_profile" + echo "✅ Profile set to: $new_profile" + echo "🔄 Run 'dotinstall' to apply profile changes" + else + echo "❌ Profile manager not available" + fi +} + +dotfiles_profile_detect() { + if [[ -f "$HOME/.dotfiles/lib/profile_manager.sh" ]]; then + source "$HOME/.dotfiles/lib/profile_manager.sh" + local detected=$(detect_machine_profile) + echo "🤖 Auto-detected profile: $detected" + echo "Current profile: $(get_current_profile)" + echo "" + echo "Set detected profile? [y/N]: " + read -r response + if [[ "$response" =~ ^[Yy]$ ]]; then + set_profile "$detected" + echo "✅ Profile updated to: $detected" + fi + else + echo "❌ Profile manager not available" + fi +} + +# Update management functions +dotfiles_update_check() { + local force=${1:-false} + if [[ "$1" == "--force" ]]; then + force=true + fi + + if [[ -f "$HOME/.dotfiles/lib/update_checker.sh" ]]; then + source "$HOME/.dotfiles/lib/update_checker.sh" + check_for_updates "$force" true + else + echo "❌ Update checker not available" + fi +} + +dotfiles_update_status() { + if [[ -f "$HOME/.dotfiles/lib/update_checker.sh" ]]; then + source "$HOME/.dotfiles/lib/update_checker.sh" + show_update_status + else + echo "❌ Update checker not available" + fi +} + +dotfiles_update_install() { + if [[ -f "$HOME/.dotfiles/lib/update_checker.sh" ]]; then + source "$HOME/.dotfiles/lib/update_checker.sh" + update_packages + else + echo "❌ Update checker not available" + fi +} + +# Git remote URL conversion functions +git_remote_convert() { + local remote_name="${1:-origin}" + local target_format="$2" + + # Get current remote URL + local current_url=$(git remote get-url "$remote_name" 2>/dev/null) + + if [[ -z "$current_url" ]]; then + echo "❌ No remote '$remote_name' found in this repository" + return 1 + fi + + local new_url="" + local current_format="" + + # Detect current format and convert + if [[ "$current_url" =~ ^git@([^:]+):(.+)\.git$ ]]; then + # SSH format: git@hostname:user/repo.git + current_format="ssh" + local hostname="${BASH_REMATCH[1]}" + local repo_path="${BASH_REMATCH[2]}" + new_url="https://${hostname}/${repo_path}.git" + elif [[ "$current_url" =~ ^https://([^/]+)/(.+)\.git$ ]]; then + # HTTPS format: https://hostname/user/repo.git + current_format="https" + local hostname="${BASH_REMATCH[1]}" + local repo_path="${BASH_REMATCH[2]}" + new_url="git@${hostname}:${repo_path}.git" + elif [[ "$current_url" =~ ^https://([^/]+)/(.+)$ ]]; then + # HTTPS format without .git suffix + current_format="https" + local hostname="${BASH_REMATCH[1]}" + local repo_path="${BASH_REMATCH[2]}" + new_url="git@${hostname}:${repo_path}.git" + else + echo "❌ Unknown URL format: $current_url" + return 1 + fi + + # Check if target format is specified and matches current + if [[ -n "$target_format" ]]; then + if [[ "$target_format" == "$current_format" ]]; then + echo "✅ Remote '$remote_name' is already in $current_format format" + echo " Current URL: $current_url" + return 0 + elif [[ "$target_format" != "ssh" && "$target_format" != "https" ]]; then + echo "❌ Invalid target format. Use 'ssh' or 'https'" + return 1 + fi + + # Convert to specific format + if [[ "$target_format" == "ssh" && "$current_format" == "https" ]]; then + # Already converted above + : + elif [[ "$target_format" == "https" && "$current_format" == "ssh" ]]; then + # Already converted above + : + fi + fi + + # Show current and new URLs + echo "🔄 Converting git remote '$remote_name'" + echo " From ($current_format): $current_url" + echo " To ($([[ $current_format == "ssh" ]] && echo "https" || echo "ssh")): $new_url" + echo "" + + # Confirm change + echo "Proceed with conversion? [y/N]: " + read -r response + if [[ "$response" =~ ^[Yy]$ ]]; then + if git remote set-url "$remote_name" "$new_url"; then + echo "✅ Successfully converted remote '$remote_name'" + echo " New URL: $(git remote get-url "$remote_name")" + else + echo "❌ Failed to update remote URL" + return 1 + fi + else + echo "❌ Conversion cancelled" + return 1 + fi +} + +git_remote_to_ssh() { + local remote_name="${1:-origin}" + git_remote_convert "$remote_name" "ssh" +} + +git_remote_to_https() { + local remote_name="${1:-origin}" + git_remote_convert "$remote_name" "https" +} + +git_remote_toggle() { + local remote_name="${1:-origin}" + git_remote_convert "$remote_name" +} \ No newline at end of file diff --git a/shared/prompt b/shared/prompt new file mode 100644 index 0000000..532a73b --- /dev/null +++ b/shared/prompt @@ -0,0 +1,25 @@ +# Shared Prompt Configuration +# Set up a consistent prompt across shells + +# Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +BLUE='\033[0;34m' +PURPLE='\033[0;35m' +CYAN='\033[0;36m' +WHITE='\033[0;37m' +RESET='\033[0m' + +# Git branch display function +git_branch() { + git branch 2>/dev/null | grep '^*' | colrm 1 2 +} + +# Git status indicators +git_status() { + local status=$(git status --porcelain 2>/dev/null) + if [[ -n $status ]]; then + echo "*" + fi +} \ No newline at end of file diff --git a/shared/sync b/shared/sync new file mode 100644 index 0000000..f98da81 --- /dev/null +++ b/shared/sync @@ -0,0 +1,84 @@ +# Dotfiles Auto-Sync Configuration +# This file is sourced by shell configurations to enable automatic syncing + +# Function to run dotfiles sync +dotfiles_sync() { + if [[ -x "$HOME/.dotfiles/sync.sh" ]]; then + "$HOME/.dotfiles/sync.sh" --background + fi +} + +# Function to enable/disable sync +dotfiles_sync_enable() { + echo "true" > "$HOME/.dotfiles/.sync_enabled" + echo "✅ Dotfiles auto-sync enabled" +} + +dotfiles_sync_disable() { + echo "false" > "$HOME/.dotfiles/.sync_enabled" + echo "❌ Dotfiles auto-sync disabled" +} + +# Function to manually trigger sync +dotfiles_sync_now() { + if [[ -x "$HOME/.dotfiles/sync.sh" ]]; then + "$HOME/.dotfiles/sync.sh" --manual + else + echo "❌ Sync script not found or not executable" + fi +} + +# Function to force sync (ignores timing) +dotfiles_sync_force() { + if [[ -x "$HOME/.dotfiles/sync.sh" ]]; then + "$HOME/.dotfiles/sync.sh" --force + else + echo "❌ Sync script not found or not executable" + fi +} + +# Function to show sync status +dotfiles_sync_status() { + local sync_enabled_file="$HOME/.dotfiles/.sync_enabled" + local last_sync_file="$HOME/.dotfiles/.last_sync" + local sync_log="$HOME/.dotfiles/.sync.log" + + echo "🔧 Dotfiles Sync Status:" + + if [[ -f "$sync_enabled_file" ]]; then + local enabled=$(cat "$sync_enabled_file") + if [[ "$enabled" == "true" ]]; then + echo " Status: ✅ Enabled" + else + echo " Status: ❌ Disabled" + fi + else + echo " Status: ✅ Enabled (default)" + fi + + if [[ -f "$last_sync_file" ]]; then + local last_sync=$(cat "$last_sync_file") + local last_sync_date=$(date -d "@$last_sync" 2>/dev/null || echo "Unknown") + echo " Last sync: $last_sync_date" + else + echo " Last sync: Never" + fi + + if [[ -f "$sync_log" ]]; then + echo " Recent activity:" + tail -3 "$sync_log" | sed 's/^/ /' + fi +} + +# Auto-sync on shell startup (only for interactive shells) +if [[ $- == *i* ]] && [[ -n "$HOME" ]] && [[ -d "$HOME/.dotfiles" ]]; then + dotfiles_sync + + # Also check for updates periodically (background, no output) + if [[ -f "$HOME/.dotfiles/lib/update_checker.sh" ]]; then + ( + source "$HOME/.dotfiles/lib/update_checker.sh" + check_for_updates false false >/dev/null 2>&1 & + ) + fi +fi \ No newline at end of file