From 0718f6d21c3e7721ba5e882d38b8329aeee59528 Mon Sep 17 00:00:00 2001 From: Ray Andrew Date: Fri, 19 Dec 2025 16:36:05 -0600 Subject: [PATCH] feat: add MANIFEST and dotfiles-link script --- MANIFEST | 34 +++++ bin/dotfiles-link | 176 ++++++++++++++++++++++++++ config/sioyek/prefs_user.linux.config | 2 +- hosts/pickwick/default.nix | 1 + 4 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 MANIFEST create mode 100755 bin/dotfiles-link diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..0130412 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,34 @@ +# Dotfiles Symlink Manifest +# +# Format: :: +# os = common | linux | darwin +# source = path relative to config/ +# target = destination path ($HOME and $XDG_CONFIG_HOME are expanded) +# +# Lines starting with # are comments. Empty lines are ignored. + +# Common configs (both Linux and Darwin) +common:direnv:${XDG_CONFIG_HOME}/direnv +common:fish:${XDG_CONFIG_HOME}/fish +common:ghostty:${XDG_CONFIG_HOME}/ghostty +common:git:${XDG_CONFIG_HOME}/git +common:kitty:${XDG_CONFIG_HOME}/kitty +common:nvim:${XDG_CONFIG_HOME}/nvim +common:sesh:${XDG_CONFIG_HOME}/sesh +common:spotify-player:${XDG_CONFIG_HOME}/spotify-player +common:tmux:${XDG_CONFIG_HOME}/tmux +common:yazi:${XDG_CONFIG_HOME}/yazi +common:zathura:${XDG_CONFIG_HOME}/zathura +common:emacs:${XDG_CONFIG_HOME}/emacs + +# Linux-only configs +linux:autorandr:${XDG_CONFIG_HOME}/autorandr +linux:sioyek/keys_user.config:${XDG_CONFIG_HOME}/sioyek/keys_user.config +linux:sioyek/prefs_user.linux.config:${XDG_CONFIG_HOME}/sioyek/prefs_user.config + +# Darwin-only configs +darwin:aerospace:${XDG_CONFIG_HOME}/aerospace +darwin:sketchybar:${XDG_CONFIG_HOME}/sketchybar +darwin:yabai:${XDG_CONFIG_HOME}/yabai +darwin:sioyek/keys_user.config:${HOME}/Library/Application Support/sioyek/keys_user.config +darwin:sioyek/prefs_user.darwin.config:${HOME}/Library/Application Support/sioyek/prefs_user.config diff --git a/bin/dotfiles-link b/bin/dotfiles-link new file mode 100755 index 0000000..05574af --- /dev/null +++ b/bin/dotfiles-link @@ -0,0 +1,176 @@ +#!/usr/bin/env bash +# +# dotfiles-link - Symlink dotfiles without Nix +# +# Usage: dotfiles-link [--dry-run] [--force] +# +# Reads MANIFEST file from dotfiles root and creates symlinks accordingly. +# Works on both Linux and macOS (Darwin). +# + +set -euo pipefail + +# ============================================================================ +# Configuration +# ============================================================================ + +DOTFILES_DIR="$(cd "$(dirname "$0")/.." && pwd)" +CONFIG_DIR="${DOTFILES_DIR}/config" +MANIFEST="${DOTFILES_DIR}/MANIFEST" + +# Detect OS +case "$(uname -s)" in +Darwin) OS="darwin" ;; +Linux) OS="linux" ;; +*) + echo "Unsupported OS: $(uname -s)" >&2 + exit 1 + ;; +esac + +# XDG config directory +XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" + +# ============================================================================ +# Functions +# ============================================================================ + +DRY_RUN=true +FORCE=false + +usage() { + echo "Usage: $(basename "$0") [--apply] [--force]" + echo "" + echo "Options:" + echo " --apply Actually create symlinks (dry-run is default)" + echo " --force Remove existing files/symlinks before linking" + echo "" + echo "Manifest: ${MANIFEST}" + echo "Detected OS: ${OS}" +} + +log() { + echo "[dotfiles-link] $*" +} + +# Expand variables in target path +expand_path() { + local path="$1" + # Use eval to expand $HOME and $XDG_CONFIG_HOME + eval echo "$path" +} + +create_symlink() { + local source="$1" + local target="$2" + local target_dir + target_dir="$(dirname "$target")" + + # Check if source exists + if [[ ! -e $source ]]; then + log "SKIP: Source does not exist: $source" + return + fi + + # Create parent directory if needed + if [[ ! -d $target_dir ]]; then + if $DRY_RUN; then + log "WOULD CREATE DIR: $target_dir" + else + log "CREATE DIR: $target_dir" + mkdir -p "$target_dir" + fi + fi + + # Handle existing target + if [[ -e $target || -L $target ]]; then + if [[ -L $target ]] && [[ "$(readlink "$target")" == "$source" ]]; then + log "OK: $target (already linked)" + return + fi + + if $FORCE; then + if $DRY_RUN; then + log "WOULD REMOVE: $target" + else + log "REMOVE: $target" + rm -rf "$target" + fi + else + log "SKIP: $target exists (use --force to override)" + return + fi + fi + + # Create symlink + if $DRY_RUN; then + log "WOULD LINK: $target -> $source" + else + log "LINK: $target -> $source" + ln -s "$source" "$target" + fi +} + +process_manifest() { + if [[ ! -f $MANIFEST ]]; then + log "ERROR: Manifest not found: $MANIFEST" + exit 1 + fi + + while IFS= read -r line || [[ -n $line ]]; do + # Skip comments and empty lines + [[ -z $line || $line =~ ^[[:space:]]*# ]] && continue + + # Parse: os:source:target + local entry_os="${line%%:*}" + local rest="${line#*:}" + local source="${rest%%:*}" + local target="${rest#*:}" + + # Check if this entry applies to current OS + if [[ $entry_os != "common" && $entry_os != "$OS" ]]; then + continue + fi + + # Expand variables and create symlink + target="$(expand_path "$target")" + create_symlink "${CONFIG_DIR}/${source}" "$target" + done <"$MANIFEST" +} + +# ============================================================================ +# Main +# ============================================================================ + +# Parse arguments +while [[ $# -gt 0 ]]; do + case "$1" in + --apply) + DRY_RUN=false + shift + ;; + --force) + FORCE=true + shift + ;; + -h | --help) + usage + exit 0 + ;; + *) + echo "Unknown option: $1" + usage + exit 1 + ;; + esac +done + +log "Dotfiles directory: ${DOTFILES_DIR}" +log "OS: ${OS}" +$DRY_RUN && log "DRY RUN MODE - no changes will be made" +echo "" + +process_manifest + +echo "" +log "Done!" diff --git a/config/sioyek/prefs_user.linux.config b/config/sioyek/prefs_user.linux.config index 984616d..efedc83 100644 --- a/config/sioyek/prefs_user.linux.config +++ b/config/sioyek/prefs_user.linux.config @@ -50,7 +50,7 @@ zoom_inc_factor 1.2 # Inverse search - click PDF to jump to Neovim source # %1 = filename, %2 = line number -inverse_search_command /Users/rayandrew/dotfiles/bin/nvim-vimtex-callback %2 %1 +inverse_search_command /home/rayandrew/dotfiles/bin/nvim-vimtex-callback %2 %1 # Control+click triggers synctex inverse search control_click_command synctex_under_cursor diff --git a/hosts/pickwick/default.nix b/hosts/pickwick/default.nix index 19fe9aa..93cb891 100644 --- a/hosts/pickwick/default.nix +++ b/hosts/pickwick/default.nix @@ -51,6 +51,7 @@ hm.home.packages = with pkgs; [ vscode claude-code + codex ]; # home manager