Initial commit
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# Per-machine overrides — never commit
|
||||
.zshrc.local
|
||||
*.backup.*
|
||||
54
.zshrc
Normal file
54
.zshrc
Normal 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
57
README.md
Normal 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
155
install.sh
Executable 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
|
||||
Reference in New Issue
Block a user