Initial commit

This commit is contained in:
2026-05-28 18:23:35 -04:00
commit c5a2bfb6f4
5 changed files with 2106 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
# Per-machine overrides — never commit
.zshrc.local
*.backup.*

1837
.p10k.zsh Normal file

File diff suppressed because it is too large Load Diff

54
.zshrc Normal file
View File

@@ -0,0 +1,54 @@
# ~/.zshrc — managed by https://github.com/<you>/dotfiles
# Reproduces my terminal setup on any Linux/macOS box.
# --- Powerlevel10k instant prompt -------------------------------------------
# Keep close to the top. Anything that prints or prompts must go ABOVE this.
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi
# --- Oh My Zsh --------------------------------------------------------------
export ZSH="$HOME/.oh-my-zsh"
ZSH_THEME="powerlevel10k/powerlevel10k"
plugins=(
git
kubectl
zsh-autosuggestions
sudo
copypath
copyfile
dirhistory
docker
docker-compose
nvm
)
# Only source omz if it's actually installed (lets the file be sourced before install.sh finishes).
[ -s "$ZSH/oh-my-zsh.sh" ] && source "$ZSH/oh-my-zsh.sh"
# --- PATH -------------------------------------------------------------------
export PATH="$HOME/.local/bin:$PATH"
# Homebrew (macOS or Linuxbrew) — only if present.
if [ -x /opt/homebrew/bin/brew ]; then
eval "$(/opt/homebrew/bin/brew shellenv)"
elif [ -x /home/linuxbrew/.linuxbrew/bin/brew ]; then
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
fi
# --- Atuin (shell history) --------------------------------------------------
if [ -f "$HOME/.atuin/bin/env" ]; then
. "$HOME/.atuin/bin/env"
command -v atuin >/dev/null && eval "$(atuin init zsh)"
fi
# --- Completions ------------------------------------------------------------
fpath=(~/.zsh/completions $fpath)
# --- Powerlevel10k user config ---------------------------------------------
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
# --- Local overrides (not checked in) --------------------------------------
# Put machine-specific stuff (API keys, conda init, nvm, etc.) in ~/.zshrc.local.
[ -f "$HOME/.zshrc.local" ] && source "$HOME/.zshrc.local"

57
README.md Normal file
View File

@@ -0,0 +1,57 @@
# dotfiles
My terminal setup as a one-liner. Works on Debian/Ubuntu, Fedora/RHEL, Arch, and macOS.
## What it gives you
- **zsh** as the login shell
- **oh-my-zsh** with plugins: `git kubectl zsh-autosuggestions sudo copypath copyfile dirhistory docker docker-compose nvm`
- **powerlevel10k** prompt with my exact `.p10k.zsh` config
- **atuin** for searchable, sync-able shell history (works in bash too)
## Install
```sh
git clone https://github.com/<you>/dotfiles ~/dotfiles
cd ~/dotfiles && ./install.sh
```
Or, if you trust me:
```sh
curl -fsSL https://raw.githubusercontent.com/<you>/dotfiles/main/install.sh | bash
```
The script is idempotent — re-run it any time to pull updates.
## Machine-specific config
Anything personal (API keys, conda/nvm init, work-laptop paths) goes in
`~/.zshrc.local`. The shipped `.zshrc` sources it if present, and it's not
tracked here.
Example `~/.zshrc.local`:
```sh
# Per-machine overrides
export EDITOR=nvim
export GITHUB_TOKEN=...
# nvm (if you installed it)
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
```
## Fonts
Powerlevel10k looks broken without a Nerd Font. Easiest:
<https://github.com/romkatv/powerlevel10k#meslo-nerd-font-patched-for-powerlevel10k>
Install the four `MesloLGS NF *.ttf` files, then set your terminal font to `MesloLGS NF`.
## Uninstall
```sh
rm ~/.zshrc ~/.p10k.zsh
mv ~/.zshrc.backup.<timestamp> ~/.zshrc # if you want the old one back
```

155
install.sh Executable file
View File

@@ -0,0 +1,155 @@
#!/usr/bin/env bash
# install.sh — bootstrap zsh + oh-my-zsh + powerlevel10k + atuin and link dotfiles.
# Supports: Debian/Ubuntu (apt), Fedora/RHEL (dnf), Arch (pacman), macOS (brew).
# Idempotent: safe to re-run.
#
# Usage:
# git clone https://github.com/<you>/dotfiles ~/dotfiles && cd ~/dotfiles && ./install.sh
# or:
# curl -fsSL https://raw.githubusercontent.com/<you>/dotfiles/main/install.sh | bash
# (the curl form will git clone this repo to ~/dotfiles before running.)
set -euo pipefail
REPO_URL="${DOTFILES_REPO:-https://github.com/<you>/dotfiles}"
DOTFILES_DIR="${DOTFILES_DIR:-$HOME/dotfiles}"
log() { printf '\033[1;34m==>\033[0m %s\n' "$*"; }
warn() { printf '\033[1;33m!! \033[0m %s\n' "$*" >&2; }
die() { printf '\033[1;31mxx \033[0m %s\n' "$*" >&2; exit 1; }
# ---------------------------------------------------------------------------
# 0. If we're being curl|bashed, the script lives in /dev/stdin and there's no
# repo on disk. Clone, then re-exec from the checkout so $SCRIPT_DIR works.
# ---------------------------------------------------------------------------
if [ ! -t 0 ] && [ ! -f "${BASH_SOURCE[0]:-}" ] || [ "${BASH_SOURCE[0]:-}" = "/dev/stdin" ]; then
command -v git >/dev/null || die "git is required to clone the dotfiles repo"
if [ ! -d "$DOTFILES_DIR/.git" ]; then
log "Cloning $REPO_URL$DOTFILES_DIR"
git clone "$REPO_URL" "$DOTFILES_DIR"
fi
exec bash "$DOTFILES_DIR/install.sh" "$@"
fi
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# ---------------------------------------------------------------------------
# 1. Detect package manager and install prerequisites.
# ---------------------------------------------------------------------------
SUDO=""
if [ "$(id -u)" -ne 0 ] && command -v sudo >/dev/null; then SUDO="sudo"; fi
install_pkgs() {
local pkgs=("$@")
if command -v apt-get >/dev/null; then
$SUDO apt-get update -y
$SUDO DEBIAN_FRONTEND=noninteractive apt-get install -y "${pkgs[@]}"
elif command -v dnf >/dev/null; then
$SUDO dnf install -y "${pkgs[@]}"
elif command -v pacman >/dev/null; then
$SUDO pacman -Sy --noconfirm --needed "${pkgs[@]}"
elif command -v brew >/dev/null; then
brew install "${pkgs[@]}"
else
die "No supported package manager found (apt/dnf/pacman/brew)."
fi
}
log "Installing prerequisites (zsh, git, curl)"
install_pkgs zsh git curl
# ---------------------------------------------------------------------------
# 2. Oh My Zsh.
# ---------------------------------------------------------------------------
export ZSH="$HOME/.oh-my-zsh"
if [ ! -d "$ZSH" ]; then
log "Installing oh-my-zsh"
RUNZSH=no CHSH=no KEEP_ZSHRC=yes \
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
else
log "oh-my-zsh already installed"
fi
ZSH_CUSTOM="${ZSH_CUSTOM:-$ZSH/custom}"
# ---------------------------------------------------------------------------
# 3. Powerlevel10k theme.
# ---------------------------------------------------------------------------
P10K_DIR="$ZSH_CUSTOM/themes/powerlevel10k"
if [ ! -d "$P10K_DIR" ]; then
log "Installing powerlevel10k"
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git "$P10K_DIR"
else
log "powerlevel10k already installed; pulling latest"
git -C "$P10K_DIR" pull --ff-only --quiet || warn "p10k pull failed (continuing)"
fi
# ---------------------------------------------------------------------------
# 4. zsh-autosuggestions plugin.
# ---------------------------------------------------------------------------
AUTOSUG_DIR="$ZSH_CUSTOM/plugins/zsh-autosuggestions"
if [ ! -d "$AUTOSUG_DIR" ]; then
log "Installing zsh-autosuggestions"
git clone --depth=1 https://github.com/zsh-users/zsh-autosuggestions "$AUTOSUG_DIR"
else
log "zsh-autosuggestions already installed"
fi
# ---------------------------------------------------------------------------
# 5. Atuin (shell history sync). Works on bash and zsh.
# ---------------------------------------------------------------------------
if ! command -v atuin >/dev/null && [ ! -x "$HOME/.atuin/bin/atuin" ]; then
log "Installing atuin"
curl --proto '=https' --tlsv1.2 -LsSf https://setup.atuin.sh | sh
else
log "atuin already installed"
fi
# ---------------------------------------------------------------------------
# 6. Link dotfiles. Backs up anything already there to *.backup.<timestamp>.
# ---------------------------------------------------------------------------
TS="$(date +%Y%m%d-%H%M%S)"
link_file() {
local src="$1" dest="$2"
if [ -e "$dest" ] && [ ! -L "$dest" ]; then
log "Backing up $dest$dest.backup.$TS"
mv "$dest" "$dest.backup.$TS"
elif [ -L "$dest" ]; then
rm "$dest"
fi
ln -s "$src" "$dest"
log "Linked $dest$src"
}
link_file "$SCRIPT_DIR/.zshrc" "$HOME/.zshrc"
link_file "$SCRIPT_DIR/.p10k.zsh" "$HOME/.p10k.zsh"
# ---------------------------------------------------------------------------
# 7. Change default shell to zsh (no-op if already zsh).
# ---------------------------------------------------------------------------
ZSH_BIN="$(command -v zsh)"
if [ -n "$ZSH_BIN" ] && [ "${SHELL:-}" != "$ZSH_BIN" ]; then
if grep -qx "$ZSH_BIN" /etc/shells 2>/dev/null || echo "$ZSH_BIN" | $SUDO tee -a /etc/shells >/dev/null; then
log "Setting login shell to $ZSH_BIN"
chsh -s "$ZSH_BIN" "$USER" || warn "chsh failed — run it manually: chsh -s $ZSH_BIN"
fi
else
log "Default shell already zsh"
fi
# ---------------------------------------------------------------------------
# 8. Done.
# ---------------------------------------------------------------------------
cat <<EOF
✔ Dotfiles installed.
Next steps:
• Start a new shell: exec zsh -l
• For machine-specific overrides (API keys, conda init, nvm, etc.),
drop them in: ~/.zshrc.local (already sourced by .zshrc, ignored by git)
• If powerlevel10k icons look wrong, install a Nerd Font:
https://github.com/romkatv/powerlevel10k#meslo-nerd-font-patched-for-powerlevel10k
• Atuin sync (optional): atuin register -u <user> -e <email> / atuin login
EOF