From 63429ff2f3d7df2eed921d45a6e298b7871528b2 Mon Sep 17 00:00:00 2001 From: Viktor Habchak Date: Mon, 29 Dec 2025 18:08:09 +0100 Subject: [PATCH 1/9] Add macos config --- bin/dot | 34 ++- bin/install-macos | 102 ++++++++ debian/kmonad/build | 7 +- debian/kmonad/config/laptop.kbd | 57 ----- debian/shell/build | 67 +---- debian/tools/00-mise/build | 2 +- debian/tools/01-ghostty/build | 9 +- debian/tools/emacs/build | 17 +- debian/tools/git/build | 47 +--- debian/tools/gpg/build | 31 +-- lib/macos/constants.sh | 10 + lib/macos/include.sh | 14 ++ lib/macos/utils.sh | 102 ++++++++ macos/00-mise/build | 26 ++ macos/00-mise/deps/ruby/install | 27 ++ macos/00-mise/install | 54 ++++ macos/kanata/build | 82 ++++++ macos/kanata/install | 233 ++++++++++++++++++ macos/shell/build | 9 + macos/tools/emacs/build | 38 +++ macos/tools/emacs/install | 21 ++ macos/tools/ghostty/build | 32 +++ macos/tools/git/build | 9 + macos/tools/git/install | 22 ++ macos/tools/gpg/build | 9 + shared/ghostty/build | 36 +++ .../ghostty}/config/config | 4 + shared/ghostty/install | 71 ++++++ shared/kanata/config/config.kbd | 63 +++++ shared/shell/build | 89 +++++++ shared/shell/config/.aliases | 4 + {debian => shared}/shell/config/.bash_profile | 0 {debian => shared}/shell/config/.bashrc | 23 +- {debian => shared}/shell/config/.inputrc | 0 {debian => shared}/shell/config/.irbrc | 0 {debian => shared}/shell/config/.profile | 7 + .../shell/config/.profile.local.example | 0 {debian => shared}/shell/config/.pryrc | 0 shared/shell/config/.zshrc | 44 ++++ .../tools/emacs/config/config.org | 0 .../tools/emacs/config/early-init.el | 0 {debian => shared}/tools/emacs/config/init.el | 0 shared/tools/git/build | 54 ++++ .../tools/git/config/.gitconfig | 0 {debian => shared}/tools/git/config/ignore | 0 .../git/scripts/git-branch-files-changed | 0 .../tools/git/scripts/git-default-branch | 0 .../tools/git/scripts/git-deploy | 0 .../tools/git/scripts/git-log-changed | 0 {debian => shared}/tools/git/scripts/git-nuke | 0 .../tools/git/scripts/git-summary | 0 shared/tools/gpg/build | 39 +++ .../tools/gpg/config/gpg-agent.conf | 0 .../tools/mise}/config/mise.toml | 0 54 files changed, 1252 insertions(+), 243 deletions(-) create mode 100755 bin/install-macos delete mode 100644 debian/kmonad/config/laptop.kbd create mode 100644 lib/macos/constants.sh create mode 100644 lib/macos/include.sh create mode 100644 lib/macos/utils.sh create mode 100755 macos/00-mise/build create mode 100755 macos/00-mise/deps/ruby/install create mode 100755 macos/00-mise/install create mode 100755 macos/kanata/build create mode 100755 macos/kanata/install create mode 100755 macos/shell/build create mode 100755 macos/tools/emacs/build create mode 100755 macos/tools/emacs/install create mode 100755 macos/tools/ghostty/build create mode 100755 macos/tools/git/build create mode 100755 macos/tools/git/install create mode 100755 macos/tools/gpg/build create mode 100755 shared/ghostty/build rename {debian/tools/01-ghostty => shared/ghostty}/config/config (66%) create mode 100755 shared/ghostty/install create mode 100644 shared/kanata/config/config.kbd create mode 100755 shared/shell/build create mode 100644 shared/shell/config/.aliases rename {debian => shared}/shell/config/.bash_profile (100%) rename {debian => shared}/shell/config/.bashrc (83%) rename {debian => shared}/shell/config/.inputrc (100%) rename {debian => shared}/shell/config/.irbrc (100%) rename {debian => shared}/shell/config/.profile (64%) rename {debian => shared}/shell/config/.profile.local.example (100%) rename {debian => shared}/shell/config/.pryrc (100%) create mode 100644 shared/shell/config/.zshrc rename {debian => shared}/tools/emacs/config/config.org (100%) rename {debian => shared}/tools/emacs/config/early-init.el (100%) rename {debian => shared}/tools/emacs/config/init.el (100%) create mode 100755 shared/tools/git/build rename {debian => shared}/tools/git/config/.gitconfig (100%) rename {debian => shared}/tools/git/config/ignore (100%) rename {debian => shared}/tools/git/scripts/git-branch-files-changed (100%) rename {debian => shared}/tools/git/scripts/git-default-branch (100%) rename {debian => shared}/tools/git/scripts/git-deploy (100%) rename {debian => shared}/tools/git/scripts/git-log-changed (100%) rename {debian => shared}/tools/git/scripts/git-nuke (100%) rename {debian => shared}/tools/git/scripts/git-summary (100%) create mode 100755 shared/tools/gpg/build rename {debian => shared}/tools/gpg/config/gpg-agent.conf (100%) rename {debian/tools/00-mise => shared/tools/mise}/config/mise.toml (100%) diff --git a/bin/dot b/bin/dot index 7d717ed1..0515cb18 100755 --- a/bin/dot +++ b/bin/dot @@ -167,15 +167,19 @@ get_available_modules() { fi # Find all modules with the given command script + # Use -perm for BSD find compatibility (macOS) while IFS= read -r -d '' script; do local module_path=$(dirname "$script") # Get the full relative path from system_dir local module_name="${module_path#$system_dir/}" - + modules+=("$module_name") - done < <(find "$system_dir" -name "$command" -type f -executable -print0) - - printf '%s\n' "${modules[@]}" | sort + done < <(find "$system_dir" -name "$command" -type f -perm +111 -print0 2>/dev/null) + + # Handle empty array to avoid unbound variable error + if [[ ${#modules[@]} -gt 0 ]]; then + printf '%s\n' "${modules[@]}" | sort + fi } # Run install command @@ -199,9 +203,11 @@ cmd_install() { log_info "Installing all modules" # Get all available install scripts - local available_modules - mapfile -t available_modules < <(get_available_modules "install") - + local available_modules=() + while IFS= read -r line; do + [[ -n "$line" ]] && available_modules+=("$line") + done < <(get_available_modules "install") + for mod in "${available_modules[@]}"; do log_step "Running install for module: $mod" "$(get_system_dir)/$mod/install" @@ -241,9 +247,11 @@ cmd_build() { log_info "Building all modules" # Get all available build scripts - local available_modules - mapfile -t available_modules < <(get_available_modules "build") - + local available_modules=() + while IFS= read -r line; do + [[ -n "$line" ]] && available_modules+=("$line") + done < <(get_available_modules "build") + for mod in "${available_modules[@]}"; do log_step "Running build for module: $mod" "$(get_system_dir)/$mod/build" @@ -283,8 +291,10 @@ cmd_upgrade() { log_info "Upgrading all modules" # Get all available upgrade scripts - local available_modules - mapfile -t available_modules < <(get_available_modules "upgrade") + local available_modules=() + while IFS= read -r line; do + [[ -n "$line" ]] && available_modules+=("$line") + done < <(get_available_modules "upgrade") if [[ ${#available_modules[@]} -eq 0 ]]; then log_info "No modules have upgrade scripts" diff --git a/bin/install-macos b/bin/install-macos new file mode 100755 index 00000000..4ff11f90 --- /dev/null +++ b/bin/install-macos @@ -0,0 +1,102 @@ +#!/bin/bash + +set -euo pipefail + +# Check if running with --local flag (already cloned and running locally) +if [[ "${1:-}" != "--local" ]]; then + # Remote execution - clone repo and re-exec locally + echo "[INFO] Cloning dotfiles and running local setup..." + + DOTFILES_DIR="$HOME/Repositories/dotfiles" + + if [[ ! -d "$DOTFILES_DIR" ]]; then + echo "[INFO] Creating Repositories directory" + mkdir -p "$HOME/Repositories" + + echo "[INFO] Cloning dotfiles repository" + git clone https://github.com/vikdotdev/dotfiles.git "$DOTFILES_DIR" + else + echo "[INFO] Dotfiles repository already exists, pulling latest changes" + cd "$DOTFILES_DIR" + git pull origin master + fi + + # Re-exec the local script with --local flag + echo "[INFO] Running local install script..." + chmod +x "$DOTFILES_DIR/bin/install-macos" + exec "$DOTFILES_DIR/bin/install-macos" --local +fi + +# Local execution from here on +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$SCRIPT_DIR")" + +# Source local utilities +source "$DOT_HOME/lib/macos/include.sh" + +# Initialize +init_logging "install-macos" + +# Don't run as root +if is_root; then + log_error "Don't run install-macos as root/sudo. It will ask for sudo when needed." + exit 1 +fi + +log_header "macOS Installation Setup" + +# Check if we're on macOS +if ! is_macos; then + log_error "This script is designed for macOS systems" + exit 1 +fi + +# Basic system setup +log_step "Setting up basic system requirements" + +# Install Homebrew if not present +if ! command_exists brew; then + log_info "Installing Homebrew" + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + + # Add Homebrew to PATH for Apple Silicon Macs + if [[ -f "/opt/homebrew/bin/brew" ]]; then + eval "$(/opt/homebrew/bin/brew shellenv)" + fi +else + log_info "Homebrew already installed" +fi + +# Update Homebrew +log_info "Updating Homebrew" +brew update + +# Install essential tools +log_info "Installing minimal essential packages" +ESSENTIAL_FORMULAS=( + "curl" + "wget" + "git" + "gnupg" +) + +brew install "${ESSENTIAL_FORMULAS[@]}" + +# Mark system as installed +mark_system_installed "macos" +log_success "System marked as macOS installation" + +# Run dot install to install all packages and applications +log_step "Running dot install to set up all packages and applications" +"$DOT_HOME/bin/dot" install + +# Run dot build to configure all dotfiles +log_step "Running dot build to configure all dotfiles" +"$DOT_HOME/bin/dot" build + +log_success "macOS setup complete!" +echo +echo "All packages installed and dotfiles configured!" +echo "You may need to restart your shell for some changes to take effect." + +finalize_logging "success" diff --git a/debian/kmonad/build b/debian/kmonad/build index 2ea898ec..d62366c6 100755 --- a/debian/kmonad/build +++ b/debian/kmonad/build @@ -29,10 +29,11 @@ log_step "Deploying KMonad configuration" CONFIG_DIR="$HOME/.config/kmonad" mkdir -p "$CONFIG_DIR" -# Deploy keyboard configuration -if [[ -f "$SCRIPT_DIR/config/laptop.kbd" ]]; then +# Deploy keyboard configuration from shared +SHARED_CONFIG="$DOT_HOME/shared/kmonad/config/laptop.kbd" +if [[ -f "$SHARED_CONFIG" ]]; then log_info "Deploying keyboard configuration" - cp "$SCRIPT_DIR/config/laptop.kbd" "$CONFIG_DIR/config.kbd" + cp "$SHARED_CONFIG" "$CONFIG_DIR/config.kbd" else log_warning "No keyboard configuration found" fi diff --git a/debian/kmonad/config/laptop.kbd b/debian/kmonad/config/laptop.kbd deleted file mode 100644 index db472b47..00000000 --- a/debian/kmonad/config/laptop.kbd +++ /dev/null @@ -1,57 +0,0 @@ -(defcfg - input (device-file "/dev/input/by-path/platform-i8042-serio-0-event-kbd") - output (uinput-sink "KMonad output" "/usr/bin/sleep 1") - cmp-seq ralt - cmp-seq-delay 5 - fallthrough true - allow-cmd true -) - -(defalias - mta (tap-hold-next-release 150 tab lmet) - rta (tap-hold-next-release 150 \ rmet) - qta (tap-hold-next-release 150 ' lalt) - ces (tap-hold-next-release 150 esc lctl) - laa (tap-hold-next-release 300 a lalt) - lac (tap-hold-next-release 300 ; rctl) - lsb (tap-hold-next-release 170 lbrc lsft) - cst (tap-macro (around-next lsft) (around-next lctl)) - rsb (tap-hold-next-release 170 rbrc rsft) - sid (tap-hold-next-release 300 spc (layer-toggle side)) - ;; browser history navigation - hfo (around lalt right) - hba (around lalt left) - ;; browser tab navigation - tba (around lctl (around lsft tab)) - tfo (around lctl tab) -) - -(defsrc - esc mute vold volu end ins del - grv 1 2 3 4 5 6 7 8 9 0 - = bspc - tab q w e r t y u i o p [ ] \ - caps a s d f g h j k l ; ' ret - lsft z x c v b n m , . / rsft - lctl lmet lalt spc ralt prnt rctl pgup up pgdn - left down rght -) - -(deflayer main - esc mute vold volu end ins del - = 1 2 3 4 5 6 7 8 9 0 - grv XX - @mta q w e r t y u i o p @rta XX XX - @ces @laa s d f g h j k l @lac @qta ret - @lsb z x c v b n m , . / @rsb - caps _ lalt @sid ralt prnt rctl pgup up pgdn - left down rght -) - -(deflayer side - _ _ _ _ _ _ _ - _ _ _ _ _ _ _ _ _ _ _ _ _ _ - _ @hba @hfo @tba @tfo _ _ _ _ _ up _ _ _ - _ _ _ bspc rght ret _ _ _ _ _ _ _ - _ _ _ _ _ left down @cst _ _ _ _ - _ _ _ _ _ _ _ _ _ _ - _ _ _ -) diff --git a/debian/shell/build b/debian/shell/build index 7b8f86c3..625ca7fe 100755 --- a/debian/shell/build +++ b/debian/shell/build @@ -5,68 +5,5 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DOT_HOME="$(dirname "$(dirname "$SCRIPT_DIR")")" -source "$DOT_HOME/lib/debian/include.sh" - -MODULE="shell" -init_module_logging "$MODULE" - -log_header "Building Shell Configuration" - -# Deploy shell configuration files from existing plans -log_step "Deploying shell configuration" - -# Bash configuration -log_step "Installing bash configuration" - -# Copy bash configuration files -if [[ -f "$SCRIPT_DIR/config/.bashrc" ]]; then - cp "$SCRIPT_DIR/config/.bashrc" "$HOME/.bashrc" - log_info "Deployed .bashrc" -fi - -if [[ -f "$SCRIPT_DIR/config/.profile" ]]; then - cp "$SCRIPT_DIR/config/.profile" "$HOME/.profile" - log_info "Deployed .profile" -fi - -if [[ -f "$SCRIPT_DIR/config/.bash_profile" ]]; then - cp "$SCRIPT_DIR/config/.bash_profile" "$HOME/.bash_profile" - log_info "Deployed .bash_profile" -fi - -# Pry configuration -if [[ -f "$SCRIPT_DIR/config/.pryrc" ]]; then - cp "$SCRIPT_DIR/config/.pryrc" "$HOME/.pryrc" - log_info "Deployed .pryrc" -fi - -# IRB configuration -if [[ -f "$SCRIPT_DIR/config/.irbrc" ]]; then - cp "$SCRIPT_DIR/config/.irbrc" "$HOME/.irbrc" - log_info "Deployed .irbrc" -fi - -# Readline configuration -if [[ -f "$SCRIPT_DIR/config/.inputrc" ]]; then - cp "$SCRIPT_DIR/config/.inputrc" "$HOME/.inputrc" - log_info "Deployed .inputrc" -fi - -# Deploy .profile.local example if it doesn't exist -if [[ ! -f "$HOME/.profile.local" ]] && [[ -f "$SCRIPT_DIR/config/.profile.local.example" ]]; then - cp "$SCRIPT_DIR/config/.profile.local.example" "$HOME/.profile.local" - log_info "Deployed .profile.local from example (customize as needed)" -fi - -# Bash completions -log_step "Installing bash completions" -mkdir -p "$HOME/.bashrc.d" - -# Source dot completions from top-level -if [[ -f "$DOT_HOME/completions/dot.bash" ]]; then - cp "$DOT_HOME/completions/dot.bash" "$HOME/.bashrc.d/dot-completion.bash" - log_info "Deployed dot command completions" -fi - -log_success "Shell configuration completed" -finalize_module_logging "success" +# Call shared build script +"$DOT_HOME/shared/shell/build" diff --git a/debian/tools/00-mise/build b/debian/tools/00-mise/build index 4e6f0e90..003100fa 100755 --- a/debian/tools/00-mise/build +++ b/debian/tools/00-mise/build @@ -15,7 +15,7 @@ log_header "Building Mise Configuration" if command_exists mise; then log_step "Creating mise.toml" mkdir -p "$HOME/.config/mise/" - cp "$SCRIPT_DIR/config/mise.toml" "$HOME/.config/mise/config.toml" + cp "$DOT_HOME/shared/tools/mise/config/mise.toml" "$HOME/.config/mise/config.toml" log_success "Deployed mise config to ~/.config/mise/config.toml" log_step "Installing tools" mise install diff --git a/debian/tools/01-ghostty/build b/debian/tools/01-ghostty/build index 9175d879..4bbbbe40 100755 --- a/debian/tools/01-ghostty/build +++ b/debian/tools/01-ghostty/build @@ -16,13 +16,14 @@ log_header "Building Ghostty Configuration" log_step "Creating Ghostty config directory" mkdir -p "$HOME/.config/ghostty" -# Deploy Ghostty configuration +# Deploy Ghostty configuration from shared log_step "Deploying Ghostty configuration" -if [[ -f "$SCRIPT_DIR/config/config" ]]; then - cp "$SCRIPT_DIR/config/config" "$HOME/.config/ghostty/config" +SHARED_CONFIG="$DOT_HOME/shared/ghostty/config/config" +if [[ -f "$SHARED_CONFIG" ]]; then + cp "$SHARED_CONFIG" "$HOME/.config/ghostty/config" log_info "Deployed Ghostty config to ~/.config/ghostty/config" else - log_error "Ghostty config file not found" + log_error "Ghostty config file not found at $SHARED_CONFIG" finalize_module_logging "failed" exit 1 fi diff --git a/debian/tools/emacs/build b/debian/tools/emacs/build index c713ec3e..0361f70d 100755 --- a/debian/tools/emacs/build +++ b/debian/tools/emacs/build @@ -4,6 +4,7 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" +SHARED_CONFIG_DIR="$DOT_HOME/shared/tools/emacs/config" source "$DOT_HOME/lib/debian/include.sh" @@ -24,11 +25,11 @@ cleanup_temp() { trap cleanup_temp EXIT # Tangle the org file to extract elisp code blocks -if [[ -f "$SCRIPT_DIR/config/config.org" ]]; then +if [[ -f "$SHARED_CONFIG_DIR/config.org" ]]; then log_info "Extracting elisp code from config.org..." emacs --batch \ --eval "(require 'org)" \ - --eval "(org-babel-tangle-file \"$SCRIPT_DIR/config/config.org\" \"$TEMP_EL\")" \ + --eval "(org-babel-tangle-file \"$SHARED_CONFIG_DIR/config.org\" \"$TEMP_EL\")" \ 2>&1 | grep -v "^Loading" || true if [[ ! -f "$TEMP_EL" ]]; then @@ -64,18 +65,18 @@ log_step "Deploying Emacs configuration" EMACS_CONFIG_DIR="$HOME/.emacs.d" mkdir -p "$EMACS_CONFIG_DIR" -if [[ -f "$SCRIPT_DIR/config/early-init.el" ]]; then - cp "$SCRIPT_DIR/config/early-init.el" "$EMACS_CONFIG_DIR/early-init.el" +if [[ -f "$SHARED_CONFIG_DIR/early-init.el" ]]; then + cp "$SHARED_CONFIG_DIR/early-init.el" "$EMACS_CONFIG_DIR/early-init.el" log_info "Deployed early-init.el" fi -if [[ -f "$SCRIPT_DIR/config/init.el" ]]; then - cp "$SCRIPT_DIR/config/init.el" "$EMACS_CONFIG_DIR/init.el" +if [[ -f "$SHARED_CONFIG_DIR/init.el" ]]; then + cp "$SHARED_CONFIG_DIR/init.el" "$EMACS_CONFIG_DIR/init.el" log_info "Deployed init.el" fi -if [[ -f "$SCRIPT_DIR/config/config.org" ]]; then - cp "$SCRIPT_DIR/config/config.org" "$EMACS_CONFIG_DIR/config.org" +if [[ -f "$SHARED_CONFIG_DIR/config.org" ]]; then + cp "$SHARED_CONFIG_DIR/config.org" "$EMACS_CONFIG_DIR/config.org" log_info "Deployed config.org" fi diff --git a/debian/tools/git/build b/debian/tools/git/build index 7024cc5c..288307ac 100755 --- a/debian/tools/git/build +++ b/debian/tools/git/build @@ -5,48 +5,5 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" -source "$DOT_HOME/lib/debian/include.sh" - -MODULE="git" -init_module_logging "$MODULE" - -log_header "Building Git Configuration" - -log_step "Installing Git configuration" - -# Copy .gitconfig file -if [[ -f "$SCRIPT_DIR/config/.gitconfig" ]]; then - cp "$SCRIPT_DIR/config/.gitconfig" "$HOME/.gitconfig" - log_success "Git configuration installed" -else - log_warning "Git configuration file not found" -fi - -# Copy global gitignore file -if [[ -f "$SCRIPT_DIR/config/ignore" ]]; then - mkdir -p "$HOME/.config/git" - cp "$SCRIPT_DIR/config/ignore" "$HOME/.config/git/ignore" - log_success "Global gitignore installed" -else - log_warning "Global gitignore file not found" -fi - -log_step "Installing git scripts" - -# Create scripts directory -mkdir -p "$HOME/.local/bin" - -# Copy git utility scripts -if [[ -d "$SCRIPT_DIR/scripts" ]]; then - for script in "$SCRIPT_DIR/scripts"/*; do - if [[ -f "$script" ]]; then - script_name=$(basename "$script") - cp "$script" "$HOME/.local/bin/$script_name" - chmod +x "$HOME/.local/bin/$script_name" - log_info "Installed script: $script_name" - fi - done -fi - -log_success "Git configuration build completed" -finalize_module_logging "success" +# Call shared build script +"$DOT_HOME/shared/tools/git/build" diff --git a/debian/tools/gpg/build b/debian/tools/gpg/build index 4d74de1f..7b88cc8b 100755 --- a/debian/tools/gpg/build +++ b/debian/tools/gpg/build @@ -5,32 +5,5 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" -source "$DOT_HOME/lib/debian/include.sh" - -MODULE="gpg" -init_module_logging "$MODULE" - -log_header "Building GPG Configuration" - -log_step "Installing GPG agent configuration" - -# Create GPG directory if it doesn't exist -mkdir -p "$HOME/.gnupg" - -# Set proper permissions for GPG directory -chmod 700 "$HOME/.gnupg" - -# Copy GPG agent configuration -if [[ -f "$SCRIPT_DIR/config/gpg-agent.conf" ]]; then - cp "$SCRIPT_DIR/config/gpg-agent.conf" "$HOME/.gnupg/gpg-agent.conf" - chmod 600 "$HOME/.gnupg/gpg-agent.conf" - - # Restart GPG agent to pick up new config - if command_exists gpgconf; then - log_info "Reloading GPG agent configuration" - gpgconf --reload gpg-agent || log_warning "Failed to reload GPG agent" - fi -fi - -log_success "GPG configuration build completed" -finalize_module_logging "success" +# Call shared build script +"$DOT_HOME/shared/tools/gpg/build" diff --git a/lib/macos/constants.sh b/lib/macos/constants.sh new file mode 100644 index 00000000..da776ff6 --- /dev/null +++ b/lib/macos/constants.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# Get the lib directory path +LIB_DIR="$(dirname "$(dirname "${BASH_SOURCE[0]}")")" + +# Source general constants first +source "$LIB_DIR/constants.sh" + +MACOS_VERSION=$(sw_vers -productVersion 2>/dev/null || echo "unknown") +MACOS_CODENAME=$(get_macos_codename 2>/dev/null || echo "unknown") diff --git a/lib/macos/include.sh b/lib/macos/include.sh new file mode 100644 index 00000000..c591a9d5 --- /dev/null +++ b/lib/macos/include.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# Get the macos lib directory path +MACOS_LIB_DIR="$(dirname "${BASH_SOURCE[0]}")" +LIB_DIR="$(dirname "$MACOS_LIB_DIR")" + +source "$LIB_DIR/colors.sh" +source "$LIB_DIR/logging.sh" +source "$LIB_DIR/constants.sh" +source "$LIB_DIR/utils.sh" + +# May override some functions +source "$MACOS_LIB_DIR/utils.sh" +source "$MACOS_LIB_DIR/constants.sh" diff --git a/lib/macos/utils.sh b/lib/macos/utils.sh new file mode 100644 index 00000000..e03d1193 --- /dev/null +++ b/lib/macos/utils.sh @@ -0,0 +1,102 @@ +#!/bin/bash + +# macOS-specific utilities - extends the general utilities + +ensure_homebrew() { + if ! command_exists brew; then + log_warning "Homebrew not found. Installing Homebrew..." + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + + # Add Homebrew to PATH for Apple Silicon Macs + if [[ -f "/opt/homebrew/bin/brew" ]]; then + eval "$(/opt/homebrew/bin/brew shellenv)" + fi + fi +} + +brew_installed() { + local formula="$1" + brew list "$formula" &>/dev/null +} + +cask_installed() { + local cask="$1" + brew list --cask "$cask" &>/dev/null +} + +install_formula() { + local formulas=("$@") + + ensure_homebrew + log_info "Installing formulas with brew: ${formulas[*]}" + brew install "${formulas[@]}" +} + +install_cask() { + local casks=("$@") + + ensure_homebrew + log_info "Installing casks with brew: ${casks[*]}" + brew install --cask "${casks[@]}" +} + +remove_formula() { + local formulas=("$@") + + log_info "Removing formulas with brew: ${formulas[*]}" + brew uninstall "${formulas[@]}" +} + +update_homebrew() { + log_info "Updating Homebrew" + ensure_homebrew + brew update +} + +upgrade_formulas() { + log_info "Upgrading all formulas" + ensure_homebrew + brew upgrade +} + +cleanup_homebrew() { + log_info "Cleaning up Homebrew" + ensure_homebrew + brew cleanup +} + +get_macos_version() { + sw_vers -productVersion +} + +is_macos() { + [[ "$OSTYPE" == "darwin"* ]] +} + +get_macos_codename() { + local version=$(sw_vers -productVersion) + local major=$(echo "$version" | cut -d. -f1) + local minor=$(echo "$version" | cut -d. -f2) + + case "$major" in + 15) echo "Sequoia" ;; + 14) echo "Sonoma" ;; + 13) echo "Ventura" ;; + 12) echo "Monterey" ;; + 11) echo "Big Sur" ;; + 10) + case "$minor" in + 15) echo "Catalina" ;; + 14) echo "Mojave" ;; + 13) echo "High Sierra" ;; + *) echo "unknown" ;; + esac + ;; + *) echo "unknown" ;; + esac +} + +formula_available() { + local formula="$1" + brew info "$formula" &>/dev/null +} diff --git a/macos/00-mise/build b/macos/00-mise/build new file mode 100755 index 00000000..02276a59 --- /dev/null +++ b/macos/00-mise/build @@ -0,0 +1,26 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$SCRIPT_DIR")")" + +source "$DOT_HOME/lib/macos/include.sh" + +MODULE="mise" +init_module_logging "$MODULE" + +log_header "Building Mise Configuration" + +if command_exists mise; then + log_step "Creating mise.toml" + mkdir -p "$HOME/.config/mise/" + cp "$DOT_HOME/shared/tools/mise/config/mise.toml" "$HOME/.config/mise/config.toml" + log_success "Deployed mise config to ~/.config/mise/config.toml" + log_step "Installing tools" + mise install + finalize_module_logging "success" +else + log_error "mise build failed - mise binary not found" + exit 0 +fi diff --git a/macos/00-mise/deps/ruby/install b/macos/00-mise/deps/ruby/install new file mode 100755 index 00000000..e73314dd --- /dev/null +++ b/macos/00-mise/deps/ruby/install @@ -0,0 +1,27 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")")" + +source "$DOT_HOME/lib/macos/include.sh" + +MODULE="ruby-deps" +init_module_logging "$MODULE" + +log_header "Installing Ruby dependencies for mise" + +# Install libyaml which is needed for Ruby to compile through mise (3.4.5) +log_step "Installing libyaml" + +if brew_installed libyaml; then + log_info "libyaml already installed" +else + install_formula libyaml +fi + +log_success "Ruby dependencies installed" +log_info "You can now install Ruby versions with: mise install ruby@3.4.5" + +finalize_module_logging "success" diff --git a/macos/00-mise/install b/macos/00-mise/install new file mode 100755 index 00000000..c78d4f1b --- /dev/null +++ b/macos/00-mise/install @@ -0,0 +1,54 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$SCRIPT_DIR")")" + +source "$DOT_HOME/lib/macos/include.sh" + +MODULE="mise" +init_module_logging "$MODULE" + +log_header "Installing mise" + +# Check if mise is already installed +if command_exists mise; then + log_info "mise is already installed, skipping" +else + log_step "Installing mise via official installer" + + # Download and run the mise installer + log_info "Downloading and running mise installer" + curl https://mise.run | sh + + # Verify installation + if [[ -f "$HOME/.local/bin/mise" ]]; then + log_success "mise installed successfully to $HOME/.local/bin/mise" + else + log_error "mise installation failed - binary not found" + exit 1 + fi +fi + +# Add mise activation to shell config if not already present +log_step "Configuring shell integration" + +BASHRC="$HOME/.bashrc" +MISE_INIT='eval "$(~/.local/bin/mise activate bash)"' + +if [[ -f "$BASHRC" ]]; then + if ! grep -q "mise activate bash" "$BASHRC"; then + log_info "Adding mise activation to .bashrc" + echo "" >> "$BASHRC" + echo "# mise version manager" >> "$BASHRC" + echo "$MISE_INIT" >> "$BASHRC" + else + log_info "mise activation already in .bashrc" + fi +fi + +log_success "mise installation completed" +log_info "Run 'source ~/.bashrc' or start a new shell to activate mise" + +finalize_module_logging "success" diff --git a/macos/kanata/build b/macos/kanata/build new file mode 100755 index 00000000..4109d484 --- /dev/null +++ b/macos/kanata/build @@ -0,0 +1,82 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$SCRIPT_DIR")")" + +source "$DOT_HOME/lib/macos/include.sh" + +MODULE="kanata" +init_module_logging "$MODULE" + +log_header "Building Kanata Configuration" + +# Check if kanata is installed +if ! command_exists kanata; then + log_warning "kanata not installed, skipping configuration deployment" + log_info "Run 'dot install kanata' to install kanata first" + log_success "kanata build skipped" + finalize_module_logging "success" + exit 0 +fi + +# Deploy configuration files +log_step "Deploying kanata configuration" + +CONFIG_DIR="$HOME/.config/kanata" +mkdir -p "$CONFIG_DIR" + +# Check for macOS-specific config first, fall back to shared +MACOS_CONFIG="$SCRIPT_DIR/config/config.kbd" +SHARED_CONFIG="$DOT_HOME/shared/kanata/config/config.kbd" + +if [[ -f "$MACOS_CONFIG" ]]; then + log_info "Deploying macOS-specific keyboard configuration" + cp "$MACOS_CONFIG" "$CONFIG_DIR/config.kbd" +elif [[ -f "$SHARED_CONFIG" ]]; then + log_info "Deploying shared keyboard configuration" + cp "$SHARED_CONFIG" "$CONFIG_DIR/config.kbd" +else + log_warning "No keyboard configuration found, creating minimal example" + cat > "$CONFIG_DIR/config.kbd" << 'EOF' +;; Minimal kanata configuration +;; Edit this file to customize your keyboard layout + +(defcfg + process-unmapped-keys yes +) + +(defsrc + caps +) + +(deflayer base + esc +) +EOF + log_info "Created example config at $CONFIG_DIR/config.kbd" +fi + +log_success "Configuration deployed to $CONFIG_DIR/config.kbd" + +# Load kanata LaunchDaemon if it exists +KANATA_PLIST="/Library/LaunchDaemons/com.kanata.plist" +if [[ -f "$KANATA_PLIST" ]]; then + log_step "Starting kanata service" + + # Check if already loaded + if sudo launchctl list | grep -q "com.kanata"; then + log_info "Reloading kanata service" + sudo launchctl unload "$KANATA_PLIST" 2>/dev/null || true + fi + + sudo launchctl load "$KANATA_PLIST" + log_success "kanata service started" +else + log_warning "kanata LaunchDaemon not found" + log_info "Run 'dot install kanata' to set up the launch service" +fi + +log_success "kanata build completed" +finalize_module_logging "success" diff --git a/macos/kanata/install b/macos/kanata/install new file mode 100755 index 00000000..bd095f73 --- /dev/null +++ b/macos/kanata/install @@ -0,0 +1,233 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$SCRIPT_DIR")")" + +source "$DOT_HOME/lib/macos/include.sh" + +MODULE="kanata" +init_module_logging "$MODULE" + +log_header "Installing Kanata" + +# Kanata and Karabiner versions +KANATA_VERSION="1.10.1" +KARABINER_VERSION="6.7.0" + +# Check if everything is already set up +KARABINER_DAEMON_PLIST="/Library/LaunchDaemons/org.pqrs.karabiner.virtualhiddevice.daemon.plist" +KANATA_PLIST="/Library/LaunchDaemons/com.kanata.plist" + +if command_exists kanata && [[ -f "$KARABINER_DAEMON_PLIST" ]] && [[ -f "$KANATA_PLIST" ]]; then + INSTALLED_VERSION=$(kanata --version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || echo "unknown") + log_success "kanata is already fully installed and configured (version: $INSTALLED_VERSION)" + finalize_module_logging "success" + exit 0 +fi + +# Install Karabiner DriverKit VirtualHIDDevice v6.7.0 +log_step "Installing Karabiner DriverKit VirtualHIDDevice v${KARABINER_VERSION}" + +KARABINER_PKG="Karabiner-DriverKit-VirtualHIDDevice-${KARABINER_VERSION}.pkg" +KARABINER_URL="https://github.com/pqrs-org/Karabiner-DriverKit-VirtualHIDDevice/releases/download/v${KARABINER_VERSION}/${KARABINER_PKG}" +TEMP_DIR=$(mktemp -d) + +# Check if Karabiner is already installed and what version +if [[ -d "/Applications/.Karabiner-VirtualHIDDevice-Manager.app" ]]; then + log_info "Karabiner driver is installed, checking version..." + + # Try to get version from the app bundle + CURRENT_VERSION=$(defaults read "/Applications/.Karabiner-VirtualHIDDevice-Manager.app/Contents/Info.plist" CFBundleShortVersionString 2>/dev/null || echo "unknown") + + if [[ "$CURRENT_VERSION" == "$KARABINER_VERSION" ]]; then + log_info "Karabiner v${KARABINER_VERSION} already installed" + else + log_warning "Karabiner v${CURRENT_VERSION} is installed, upgrading to v${KARABINER_VERSION}" + + # Uninstall old version + log_info "Deactivating old Karabiner driver" + bash '/Library/Application Support/org.pqrs/Karabiner-DriverKit-VirtualHIDDevice/scripts/uninstall/deactivate_driver.sh' || true + + log_info "Removing old Karabiner files (requires sudo)" + ensure_sudo + sudo bash '/Library/Application Support/org.pqrs/Karabiner-DriverKit-VirtualHIDDevice/scripts/uninstall/remove_files.sh' || true + + # Download and install new version + log_info "Downloading Karabiner v${KARABINER_VERSION}" + if download_file "$KARABINER_URL" "$TEMP_DIR/$KARABINER_PKG"; then + log_info "Installing Karabiner driver (requires sudo)" + ensure_sudo + sudo installer -pkg "$TEMP_DIR/$KARABINER_PKG" -target / + log_success "Karabiner v${KARABINER_VERSION} installed" + else + log_error "Failed to download Karabiner driver" + finalize_module_logging "failed" + exit 1 + fi + fi +else + # Fresh install + log_info "Downloading Karabiner DriverKit VirtualHIDDevice v${KARABINER_VERSION}" + if download_file "$KARABINER_URL" "$TEMP_DIR/$KARABINER_PKG"; then + log_info "Installing Karabiner driver (requires sudo)" + ensure_sudo + sudo installer -pkg "$TEMP_DIR/$KARABINER_PKG" -target / + log_success "Karabiner driver installed" + else + log_error "Failed to download Karabiner driver" + finalize_module_logging "failed" + exit 1 + fi +fi + +# Activate Karabiner driver (run in background with timeout workaround) +log_step "Activating Karabiner driver" +# macOS doesn't have timeout command, use perl-based alternative +perl -e 'alarm 60; exec @ARGV' /Applications/.Karabiner-VirtualHIDDevice-Manager.app/Contents/MacOS/Karabiner-VirtualHIDDevice-Manager activate || true +log_info "Driver activation completed (may require approval in System Settings)" + +# Set up LaunchDaemon for Karabiner VirtualHIDDevice daemon +log_step "Setting up Karabiner daemon to start on boot" +DAEMON_PLIST="/Library/LaunchDaemons/org.pqrs.karabiner.virtualhiddevice.daemon.plist" + +if [[ -f "$DAEMON_PLIST" ]]; then + log_info "LaunchDaemon already configured" +else + log_info "Creating LaunchDaemon plist (requires sudo)" + ensure_sudo + + sudo tee "$DAEMON_PLIST" > /dev/null << 'EOF' + + + + + Label + org.pqrs.karabiner.virtualhiddevice.daemon + ProgramArguments + + /Library/Application Support/org.pqrs/Karabiner-DriverKit-VirtualHIDDevice/Applications/Karabiner-VirtualHIDDevice-Daemon.app/Contents/MacOS/Karabiner-VirtualHIDDevice-Daemon + + ProcessType + Interactive + RunAtLoad + + KeepAlive + + StandardOutPath + /var/log/karabiner-daemon.log + StandardErrorPath + /var/log/karabiner-daemon.log + + +EOF + + # Set correct permissions + sudo chmod 644 "$DAEMON_PLIST" + sudo chown root:wheel "$DAEMON_PLIST" + + # Load the daemon + log_info "Loading Karabiner daemon" + sudo launchctl load "$DAEMON_PLIST" || true + + log_success "Karabiner daemon configured to start on boot" +fi + +# Clean up temp directory +rm -rf "$TEMP_DIR" + +# Download and install kanata binary +log_step "Installing kanata v${KANATA_VERSION}" + +KANATA_ZIP="kanata-macos-binaries-arm64-v${KANATA_VERSION}.zip" +KANATA_URL="https://github.com/jtroo/kanata/releases/download/v${KANATA_VERSION}/${KANATA_ZIP}" +INSTALL_DIR="$HOME/.local/bin" +KANATA_PATH="$INSTALL_DIR/kanata" +TEMP_KANATA=$(mktemp -d) + +ensure_dir "$INSTALL_DIR" + +log_info "Downloading kanata v${KANATA_VERSION} for ARM64" +if download_file "$KANATA_URL" "$TEMP_KANATA/$KANATA_ZIP"; then + log_info "Extracting kanata binary" + cd "$TEMP_KANATA" + unzip -q "$KANATA_ZIP" + + # Find the binary (might be kanata_macos_arm64 or similar) + BINARY=$(find . -name "kanata*" -type f | head -1) + + if [[ -n "$BINARY" ]]; then + mv "$BINARY" "$KANATA_PATH" + chmod +x "$KANATA_PATH" + log_success "kanata installed to $KANATA_PATH" + else + log_error "Could not find kanata binary in zip" + finalize_module_logging "failed" + exit 1 + fi + + rm -rf "$TEMP_KANATA" +else + log_error "Failed to download kanata" + finalize_module_logging "failed" + exit 1 +fi + +# Verify installation +if command_exists kanata; then + VERSION=$(kanata --version 2>&1 | head -1) + log_success "kanata installation completed: $VERSION" +else + log_warning "kanata installed but not in PATH. Add $INSTALL_DIR to your PATH" +fi + +# Set up LaunchDaemon to run kanata on boot +log_step "Setting up kanata to start on boot" +KANATA_PLIST="/Library/LaunchDaemons/com.kanata.plist" +KANATA_CONFIG="$HOME/.config/kanata/config.kbd" + +log_info "Creating kanata LaunchDaemon (requires sudo)" +ensure_sudo + +sudo tee "$KANATA_PLIST" > /dev/null << EOF + + + + + Label + com.kanata + ProgramArguments + + $KANATA_PATH + --cfg + $KANATA_CONFIG + + RunAtLoad + + KeepAlive + + StandardErrorPath + /var/log/kanata.err + StandardOutPath + /var/log/kanata.out + + +EOF + +# Set correct permissions +sudo chmod 644 "$KANATA_PLIST" +sudo chown root:wheel "$KANATA_PLIST" + +log_success "kanata LaunchDaemon created" +log_info "kanata will start automatically after 'dot build kanata' deploys the config" + +echo "" +log_warning "IMPORTANT: Kanata requires system permissions" +log_info "1. Approve the Karabiner extension in System Settings > Privacy & Security if needed" +log_info "2. Restart your Mac if prompted" +log_info "3. Grant Input Monitoring permissions to your terminal app (e.g., Ghostty)" +log_info "4. Run 'dot build kanata' to deploy configuration and start kanata" +echo "" + +finalize_module_logging "success" diff --git a/macos/shell/build b/macos/shell/build new file mode 100755 index 00000000..625ca7fe --- /dev/null +++ b/macos/shell/build @@ -0,0 +1,9 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$SCRIPT_DIR")")" + +# Call shared build script +"$DOT_HOME/shared/shell/build" diff --git a/macos/tools/emacs/build b/macos/tools/emacs/build new file mode 100755 index 00000000..ac6ddaab --- /dev/null +++ b/macos/tools/emacs/build @@ -0,0 +1,38 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" +SHARED_CONFIG_DIR="$DOT_HOME/shared/tools/emacs/config" + +source "$DOT_HOME/lib/macos/include.sh" + +MODULE="emacs" +init_module_logging "$MODULE" + +log_header "Building Emacs Configuration" + +# Deploy Emacs configuration +log_step "Deploying Emacs configuration" + +EMACS_CONFIG_DIR="$HOME/.emacs.d" +mkdir -p "$EMACS_CONFIG_DIR" + +if [[ -f "$SHARED_CONFIG_DIR/early-init.el" ]]; then + cp "$SHARED_CONFIG_DIR/early-init.el" "$EMACS_CONFIG_DIR/early-init.el" + log_info "Deployed early-init.el" +fi + +if [[ -f "$SHARED_CONFIG_DIR/init.el" ]]; then + cp "$SHARED_CONFIG_DIR/init.el" "$EMACS_CONFIG_DIR/init.el" + log_info "Deployed init.el" +fi + +if [[ -f "$SHARED_CONFIG_DIR/config.org" ]]; then + cp "$SHARED_CONFIG_DIR/config.org" "$EMACS_CONFIG_DIR/config.org" + log_info "Deployed config.org" +fi + +log_success "Emacs configuration completed" +finalize_module_logging "success" diff --git a/macos/tools/emacs/install b/macos/tools/emacs/install new file mode 100755 index 00000000..089a15ca --- /dev/null +++ b/macos/tools/emacs/install @@ -0,0 +1,21 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" + +source "$DOT_HOME/lib/macos/include.sh" + +MODULE="emacs" +init_module_logging "$MODULE" + +log_header "Installing Emacs" + +log_step "Installing emacs via Homebrew" +install_cask "emacs" + +log_success "Emacs installation completed" +log_info "Run 'dot build emacs' to configure emacs" + +finalize_module_logging "success" diff --git a/macos/tools/ghostty/build b/macos/tools/ghostty/build new file mode 100755 index 00000000..bd6e0509 --- /dev/null +++ b/macos/tools/ghostty/build @@ -0,0 +1,32 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" + +source "$DOT_HOME/lib/macos/include.sh" + +MODULE="ghostty" +init_module_logging "$MODULE" + +log_header "Building Ghostty Configuration" + +# Create Ghostty config directory +log_step "Creating Ghostty config directory" +mkdir -p "$HOME/.config/ghostty" + +# Deploy Ghostty configuration from shared +log_step "Deploying Ghostty configuration" +SHARED_CONFIG="$DOT_HOME/shared/ghostty/config/config" +if [[ -f "$SHARED_CONFIG" ]]; then + cp "$SHARED_CONFIG" "$HOME/.config/ghostty/config" + log_info "Deployed Ghostty config to ~/.config/ghostty/config" +else + log_error "Ghostty config file not found at $SHARED_CONFIG" + finalize_module_logging "failed" + exit 1 +fi + +log_success "Ghostty configuration completed" +finalize_module_logging "success" diff --git a/macos/tools/git/build b/macos/tools/git/build new file mode 100755 index 00000000..288307ac --- /dev/null +++ b/macos/tools/git/build @@ -0,0 +1,9 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" + +# Call shared build script +"$DOT_HOME/shared/tools/git/build" diff --git a/macos/tools/git/install b/macos/tools/git/install new file mode 100755 index 00000000..67ad6925 --- /dev/null +++ b/macos/tools/git/install @@ -0,0 +1,22 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" + +source "$DOT_HOME/lib/macos/include.sh" + +MODULE="git" +init_module_logging "$MODULE" + +log_header "Installing Git" + +log_step "Installing git packages via Homebrew" +FORMULAS=("git" "git-delta" "gh") +install_formula "${FORMULAS[@]}" + +log_success "Git installation completed" +log_info "Run 'dot build git' to configure git" + +finalize_module_logging "success" diff --git a/macos/tools/gpg/build b/macos/tools/gpg/build new file mode 100755 index 00000000..7b88cc8b --- /dev/null +++ b/macos/tools/gpg/build @@ -0,0 +1,9 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" + +# Call shared build script +"$DOT_HOME/shared/tools/gpg/build" diff --git a/shared/ghostty/build b/shared/ghostty/build new file mode 100755 index 00000000..aae786f0 --- /dev/null +++ b/shared/ghostty/build @@ -0,0 +1,36 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$SCRIPT_DIR")")" + +# Detect OS and source appropriate include file +if [[ "$OSTYPE" == "darwin"* ]]; then + source "$DOT_HOME/lib/macos/include.sh" +else + source "$DOT_HOME/lib/debian/include.sh" +fi + +MODULE="ghostty" +init_module_logging "$MODULE" + +log_header "Building Ghostty Configuration" + +# Create Ghostty config directory +log_step "Creating Ghostty config directory" +mkdir -p "$HOME/.config/ghostty" + +# Deploy Ghostty configuration +log_step "Deploying Ghostty configuration" +if [[ -f "$SCRIPT_DIR/config/config" ]]; then + cp "$SCRIPT_DIR/config/config" "$HOME/.config/ghostty/config" + log_info "Deployed Ghostty config to ~/.config/ghostty/config" +else + log_error "Ghostty config file not found" + finalize_module_logging "failed" + exit 1 +fi + +log_success "Ghostty configuration completed" +finalize_module_logging "success" \ No newline at end of file diff --git a/debian/tools/01-ghostty/config/config b/shared/ghostty/config/config similarity index 66% rename from debian/tools/01-ghostty/config/config rename to shared/ghostty/config/config index a005ce39..7f6f4b5b 100644 --- a/debian/tools/01-ghostty/config/config +++ b/shared/ghostty/config/config @@ -1,5 +1,9 @@ # Ghostty terminal configuration +# macOS: Make left Option/Alt act as Meta key for terminal shortcuts (Alt+f, Alt+b, etc.) +# Right Option/Alt will still produce special characters (ń, ƒ, etc.) +macos-option-as-alt = left + # Cursor cursor-style = block cursor-style-blink = false diff --git a/shared/ghostty/install b/shared/ghostty/install new file mode 100755 index 00000000..994211ad --- /dev/null +++ b/shared/ghostty/install @@ -0,0 +1,71 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" + +source "$DOT_HOME/lib/debian/include.sh" + +MODULE="ghostty" +init_module_logging "$MODULE" + +log_header "Installing Ghostty Terminal" + +# Install dependencies +log_step "Installing build dependencies" +PACKAGES=( + "libgtk-4-dev" + "libadwaita-1-dev" + "git" + "blueprint-compiler" + "gettext" + "libxml2-utils" + "libgtk4-layer-shell-dev" +) + +install_packages "${PACKAGES[@]}" + +if ! command_exists mise; then + log_error "mise not found. Please install mise first" + log_info "Run: dot install tools/00-mise" + exit 0 +fi + +# Clone or update Ghostty repository +log_step "Setting up Ghostty repository" +GHOSTTY_DIR="$HOME/Repositories/ghostty" +GHOSTTY_VERSION="v1.2.2" +GHOSTTY_ZIG_VERSION="0.14" + +if [[ ! -d "$GHOSTTY_DIR" ]]; then + log_info "Cloning Ghostty repository" + git clone https://github.com/ghostty-org/ghostty "$GHOSTTY_DIR" +else + log_info "Updating existing Ghostty repository" + cd "$GHOSTTY_DIR" + git fetch +fi + +# Checkout specific version +log_step "Checking out Ghostty version $GHOSTTY_VERSION" +cd "$GHOSTTY_DIR" +git checkout "$GHOSTTY_VERSION" + +# Build Ghostty +log_step "Building Ghostty" +log_info "Running zig build with mise (this may take a while)" +pushd "$GHOSTTY_DIR" +mise exec zig@$GHOSTTY_ZIG_VERSION -- zig build -p "$HOME/.local" -Doptimize=ReleaseFast +popd + +# Verify installation +if [[ -f "$HOME/.local/bin/ghostty" ]]; then + log_success "Ghostty installed successfully to $HOME/.local/bin/ghostty" +else + log_error "Ghostty installation failed - binary not found" + exit 1 +fi + +log_success "Ghostty installation completed" +finalize_module_logging "success" diff --git a/shared/kanata/config/config.kbd b/shared/kanata/config/config.kbd new file mode 100644 index 00000000..c10f9570 --- /dev/null +++ b/shared/kanata/config/config.kbd @@ -0,0 +1,63 @@ +;; Kanata keyboard configuration +;; Converted from kmonad config + +(defcfg + process-unmapped-keys yes + ;; Allow command execution (use with caution) + danger-enable-cmd yes +) + +(defalias + ;; Custom Hyper key (Cmd+Ctrl+Alt all together) + hyp (multi lctl lalt lmet) + + ;; Tap-hold aliases + ;; kanata uses: (tap-hold tap-timeout hold-timeout tap-action hold-action) + mta (tap-hold 150 150 tab @hyp) + rta (tap-hold 150 150 \ rmet) + qta (tap-hold 150 150 ' lalt) + ces (tap-hold 150 150 esc lctl) + laa (tap-hold 300 300 a lalt) + lac (tap-hold 300 300 ; rctl) + lsb (tap-hold 170 170 [ lsft) + rsb (tap-hold 170 170 ] rsft) + sid (tap-hold 300 300 spc (layer-toggle side)) + + ;; Browser history navigation + hfo (multi lalt rght) + hba (multi lalt left) + + ;; Browser tab navigation + tba (multi lctl (multi lsft tab)) + tfo (multi lctl tab) +) + +(defsrc + esc mute vold volu end ins del + nubs 1 2 3 4 5 6 7 8 9 0 - = bspc + tab q w e r t y u i o p [ ] + caps a s d f g h j k l ; ' \ ret + lsft grv z x c v b n m , . / rsft + lctl lmet lalt spc ralt rctl pgup up pgdn + left down rght +) + +(deflayer main + esc mute vold volu end ins del + = 1 2 3 4 5 6 7 8 9 0 - grv bspc + @mta q w e r t y u i o p @hyp \ + @ces @laa s d f g h j k l @lac @qta ret ret + lsft lsft z x c v b n m , . / @rsb + caps _ lalt @sid ralt rctl pgup up pgdn + left down rght +) + +(deflayer side + _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ _ _ _ _ _ _ + _ @hba @hfo @tba @tfo _ _ _ _ _ up _ _ + _ _ _ bspc rght ret _ _ _ _ _ _ _ _ + _ _ _ _ _ _ left down _ _ _ _ _ + _ _ _ _ _ _ _ _ _ + _ _ _ +) diff --git a/shared/shell/build b/shared/shell/build new file mode 100755 index 00000000..f16126e9 --- /dev/null +++ b/shared/shell/build @@ -0,0 +1,89 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$SCRIPT_DIR")")" + +# Source universal libraries (OS-agnostic) +source "$DOT_HOME/lib/colors.sh" +source "$DOT_HOME/lib/logging.sh" + +MODULE="shell" +init_module_logging "$MODULE" + +log_header "Building Shell Configuration" + +# Deploy shell configuration files from existing plans +log_step "Deploying shell configuration" + +# Bash configuration +log_step "Installing bash configuration" + +# Copy bash configuration files +if [[ -f "$SCRIPT_DIR/config/.bashrc" ]]; then + cp "$SCRIPT_DIR/config/.bashrc" "$HOME/.bashrc" + log_info "Deployed .bashrc" +fi + +if [[ -f "$SCRIPT_DIR/config/.profile" ]]; then + cp "$SCRIPT_DIR/config/.profile" "$HOME/.profile" + log_info "Deployed .profile" +fi + +if [[ -f "$SCRIPT_DIR/config/.bash_profile" ]]; then + cp "$SCRIPT_DIR/config/.bash_profile" "$HOME/.bash_profile" + log_info "Deployed .bash_profile" +fi + +# Pry configuration +if [[ -f "$SCRIPT_DIR/config/.pryrc" ]]; then + cp "$SCRIPT_DIR/config/.pryrc" "$HOME/.pryrc" + log_info "Deployed .pryrc" +fi + +# IRB configuration +if [[ -f "$SCRIPT_DIR/config/.irbrc" ]]; then + cp "$SCRIPT_DIR/config/.irbrc" "$HOME/.irbrc" + log_info "Deployed .irbrc" +fi + +# Readline configuration +if [[ -f "$SCRIPT_DIR/config/.inputrc" ]]; then + cp "$SCRIPT_DIR/config/.inputrc" "$HOME/.inputrc" + log_info "Deployed .inputrc" +fi + +# Shared aliases +if [[ -f "$SCRIPT_DIR/config/.aliases" ]]; then + cp "$SCRIPT_DIR/config/.aliases" "$HOME/.aliases" + log_info "Deployed .aliases" +fi + +# Zsh configuration +if [[ -f "$SCRIPT_DIR/config/.zshrc" ]]; then + cp "$SCRIPT_DIR/config/.zshrc" "$HOME/.zshrc" + log_info "Deployed .zshrc" +fi + +# Deploy .profile.local example if it doesn't exist +if [[ ! -f "$HOME/.profile.local" ]] && [[ -f "$SCRIPT_DIR/config/.profile.local.example" ]]; then + cp "$SCRIPT_DIR/config/.profile.local.example" "$HOME/.profile.local" + log_info "Deployed .profile.local from example (customize as needed)" +fi + +# Bash completions +log_step "Installing bash completions" +mkdir -p "$HOME/.bashrc.d" + +# Source dot completions from top-level +if [[ -f "$DOT_HOME/completions/dot.bash" ]]; then + cp "$DOT_HOME/completions/dot.bash" "$HOME/.bashrc.d/dot-completion.bash" + log_info "Deployed dot bash completions" +fi + +# Zsh completions +# TODO: Add proper zsh completions (bash completions don't work in zsh) + +log_success "Shell configuration completed" +finalize_module_logging "success" diff --git a/shared/shell/config/.aliases b/shared/shell/config/.aliases new file mode 100644 index 00000000..a7b680df --- /dev/null +++ b/shared/shell/config/.aliases @@ -0,0 +1,4 @@ +# ~/.aliases +# Shared aliases for bash and zsh + +alias ll='ls -alF' diff --git a/debian/shell/config/.bash_profile b/shared/shell/config/.bash_profile similarity index 100% rename from debian/shell/config/.bash_profile rename to shared/shell/config/.bash_profile diff --git a/debian/shell/config/.bashrc b/shared/shell/config/.bashrc similarity index 83% rename from debian/shell/config/.bashrc rename to shared/shell/config/.bashrc index 5b932a9b..8a09a8fa 100644 --- a/debian/shell/config/.bashrc +++ b/shared/shell/config/.bashrc @@ -10,11 +10,6 @@ if ! [[ "$PATH" =~ "$HOME/.local/bin:" ]]; then PATH="$HOME/.local/bin:$PATH" fi -# Add dotfiles bin to PATH -if ! [[ "$PATH" =~ "$HOME/Repositories/dotfiles/bin:" ]]; then - PATH="$HOME/Repositories/dotfiles/bin:$PATH" -fi - export PATH # User specific aliases and functions @@ -26,20 +21,10 @@ if [ -d ~/.bashrc.d ]; then done fi -# Aliases -alias ll='ls -alF' -alias la='ls -A' -alias l='ls -CF' -alias grep='grep --color=auto' -alias fgrep='fgrep --color=auto' -alias egrep='egrep --color=auto' - -# Git aliases -alias gs='git status' -alias ga='git add' -alias gc='git commit' -alias gp='git push' -alias gl='git pull' +# Source shared aliases +if [ -f "$HOME/.aliases" ]; then + . "$HOME/.aliases" +fi # History settings HISTSIZE=10000 diff --git a/debian/shell/config/.inputrc b/shared/shell/config/.inputrc similarity index 100% rename from debian/shell/config/.inputrc rename to shared/shell/config/.inputrc diff --git a/debian/shell/config/.irbrc b/shared/shell/config/.irbrc similarity index 100% rename from debian/shell/config/.irbrc rename to shared/shell/config/.irbrc diff --git a/debian/shell/config/.profile b/shared/shell/config/.profile similarity index 64% rename from debian/shell/config/.profile rename to shared/shell/config/.profile index 0dac4ac4..904f9d11 100644 --- a/debian/shell/config/.profile +++ b/shared/shell/config/.profile @@ -1,9 +1,16 @@ # ~/.profile +# Add user's local bin to PATH if [ -d "$HOME/.local/bin" ] ; then PATH="$HOME/.local/bin:$PATH" fi +# Add dotfiles bin to PATH +DOTFILES_BIN="$HOME/Repositories/dotfiles/bin" +if [ -d "$DOTFILES_BIN" ] && ! echo "$PATH" | grep -q "$DOTFILES_BIN" ; then + PATH="$DOTFILES_BIN:$PATH" +fi + # Set default editor export EDITOR=emacs export VISUAL=emacs diff --git a/debian/shell/config/.profile.local.example b/shared/shell/config/.profile.local.example similarity index 100% rename from debian/shell/config/.profile.local.example rename to shared/shell/config/.profile.local.example diff --git a/debian/shell/config/.pryrc b/shared/shell/config/.pryrc similarity index 100% rename from debian/shell/config/.pryrc rename to shared/shell/config/.pryrc diff --git a/shared/shell/config/.zshrc b/shared/shell/config/.zshrc new file mode 100644 index 00000000..cdff382a --- /dev/null +++ b/shared/shell/config/.zshrc @@ -0,0 +1,44 @@ +# ~/.zshrc + +# Source common profile (PATH, EDITOR, etc.) +if [ -f "$HOME/.profile" ]; then + source "$HOME/.profile" +fi + +# Source shared aliases +if [ -f "$HOME/.aliases" ]; then + source "$HOME/.aliases" +fi + +# History settings +HISTSIZE=10000 +SAVEHIST=20000 +HISTFILE=~/.zsh_history +setopt SHARE_HISTORY +setopt HIST_IGNORE_DUPS +setopt HIST_IGNORE_SPACE + +# Zsh completions +autoload -Uz compinit +compinit + +# Note: Bash completions don't work in zsh +# TODO: Add proper zsh completions later + +# Git prompt (using vcs_info) +autoload -Uz vcs_info +precmd_vcs_info() { vcs_info } +precmd_functions+=( precmd_vcs_info ) +setopt prompt_subst +zstyle ':vcs_info:git:*' formats '[%b%u%c] ' +zstyle ':vcs_info:*' check-for-changes true +zstyle ':vcs_info:*' unstagedstr '!' +zstyle ':vcs_info:*' stagedstr '+' + +# Colorful prompt with git info +PROMPT='%F{yellow}%n%f%F{cyan}@%f%F{magenta}%m%f: %F{green}%~%f %F{magenta}${vcs_info_msg_0_}%f%F{cyan}%#%f ' + +# Tool version manager +if [ -f ~/.local/bin/mise ]; then + eval "$(~/.local/bin/mise activate zsh)" +fi diff --git a/debian/tools/emacs/config/config.org b/shared/tools/emacs/config/config.org similarity index 100% rename from debian/tools/emacs/config/config.org rename to shared/tools/emacs/config/config.org diff --git a/debian/tools/emacs/config/early-init.el b/shared/tools/emacs/config/early-init.el similarity index 100% rename from debian/tools/emacs/config/early-init.el rename to shared/tools/emacs/config/early-init.el diff --git a/debian/tools/emacs/config/init.el b/shared/tools/emacs/config/init.el similarity index 100% rename from debian/tools/emacs/config/init.el rename to shared/tools/emacs/config/init.el diff --git a/shared/tools/git/build b/shared/tools/git/build new file mode 100755 index 00000000..e0d0ef25 --- /dev/null +++ b/shared/tools/git/build @@ -0,0 +1,54 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" + +# Source universal libraries (OS-agnostic) +source "$DOT_HOME/lib/colors.sh" +source "$DOT_HOME/lib/logging.sh" + +MODULE="git" +init_module_logging "$MODULE" + +log_header "Building Git Configuration" + +log_step "Installing Git configuration" + +# Copy .gitconfig file +if [[ -f "$SCRIPT_DIR/config/.gitconfig" ]]; then + cp "$SCRIPT_DIR/config/.gitconfig" "$HOME/.gitconfig" + log_success "Git configuration installed" +else + log_warning "Git configuration file not found" +fi + +# Copy global gitignore file +if [[ -f "$SCRIPT_DIR/config/ignore" ]]; then + mkdir -p "$HOME/.config/git" + cp "$SCRIPT_DIR/config/ignore" "$HOME/.config/git/ignore" + log_success "Global gitignore installed" +else + log_warning "Global gitignore file not found" +fi + +log_step "Installing git scripts" + +# Create scripts directory +mkdir -p "$HOME/.local/bin" + +# Copy git utility scripts +if [[ -d "$SCRIPT_DIR/scripts" ]]; then + for script in "$SCRIPT_DIR/scripts"/*; do + if [[ -f "$script" ]]; then + script_name=$(basename "$script") + cp "$script" "$HOME/.local/bin/$script_name" + chmod +x "$HOME/.local/bin/$script_name" + log_info "Installed script: $script_name" + fi + done +fi + +log_success "Git configuration build completed" +finalize_module_logging "success" diff --git a/debian/tools/git/config/.gitconfig b/shared/tools/git/config/.gitconfig similarity index 100% rename from debian/tools/git/config/.gitconfig rename to shared/tools/git/config/.gitconfig diff --git a/debian/tools/git/config/ignore b/shared/tools/git/config/ignore similarity index 100% rename from debian/tools/git/config/ignore rename to shared/tools/git/config/ignore diff --git a/debian/tools/git/scripts/git-branch-files-changed b/shared/tools/git/scripts/git-branch-files-changed similarity index 100% rename from debian/tools/git/scripts/git-branch-files-changed rename to shared/tools/git/scripts/git-branch-files-changed diff --git a/debian/tools/git/scripts/git-default-branch b/shared/tools/git/scripts/git-default-branch similarity index 100% rename from debian/tools/git/scripts/git-default-branch rename to shared/tools/git/scripts/git-default-branch diff --git a/debian/tools/git/scripts/git-deploy b/shared/tools/git/scripts/git-deploy similarity index 100% rename from debian/tools/git/scripts/git-deploy rename to shared/tools/git/scripts/git-deploy diff --git a/debian/tools/git/scripts/git-log-changed b/shared/tools/git/scripts/git-log-changed similarity index 100% rename from debian/tools/git/scripts/git-log-changed rename to shared/tools/git/scripts/git-log-changed diff --git a/debian/tools/git/scripts/git-nuke b/shared/tools/git/scripts/git-nuke similarity index 100% rename from debian/tools/git/scripts/git-nuke rename to shared/tools/git/scripts/git-nuke diff --git a/debian/tools/git/scripts/git-summary b/shared/tools/git/scripts/git-summary similarity index 100% rename from debian/tools/git/scripts/git-summary rename to shared/tools/git/scripts/git-summary diff --git a/shared/tools/gpg/build b/shared/tools/gpg/build new file mode 100755 index 00000000..0f53bead --- /dev/null +++ b/shared/tools/gpg/build @@ -0,0 +1,39 @@ +#!/bin/bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" + +# Source universal libraries (OS-agnostic) +source "$DOT_HOME/lib/colors.sh" +source "$DOT_HOME/lib/logging.sh" +source "$DOT_HOME/lib/utils.sh" + +MODULE="gpg" +init_module_logging "$MODULE" + +log_header "Building GPG Configuration" + +log_step "Installing GPG agent configuration" + +# Create GPG directory if it doesn't exist +mkdir -p "$HOME/.gnupg" + +# Set proper permissions for GPG directory +chmod 700 "$HOME/.gnupg" + +# Copy GPG agent configuration +if [[ -f "$SCRIPT_DIR/config/gpg-agent.conf" ]]; then + cp "$SCRIPT_DIR/config/gpg-agent.conf" "$HOME/.gnupg/gpg-agent.conf" + chmod 600 "$HOME/.gnupg/gpg-agent.conf" + + # Restart GPG agent to pick up new config + if command_exists gpgconf; then + log_info "Reloading GPG agent configuration" + gpgconf --reload gpg-agent || log_warning "Failed to reload GPG agent" + fi +fi + +log_success "GPG configuration build completed" +finalize_module_logging "success" diff --git a/debian/tools/gpg/config/gpg-agent.conf b/shared/tools/gpg/config/gpg-agent.conf similarity index 100% rename from debian/tools/gpg/config/gpg-agent.conf rename to shared/tools/gpg/config/gpg-agent.conf diff --git a/debian/tools/00-mise/config/mise.toml b/shared/tools/mise/config/mise.toml similarity index 100% rename from debian/tools/00-mise/config/mise.toml rename to shared/tools/mise/config/mise.toml From fff74de65bf98a8e36fcfb184299cf4001cbe718 Mon Sep 17 00:00:00 2001 From: Viktor Habchak Date: Tue, 30 Dec 2025 11:18:53 +0100 Subject: [PATCH 2/9] Add os-specific git config --- debian/tools/git/build | 6 ++++++ debian/tools/git/config/gitconfig.os | 5 +++++ macos/tools/git/build | 6 ++++++ macos/tools/git/config/gitconfig.os | 5 +++++ shared/tools/git/config/.gitconfig | 6 ++---- 5 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 debian/tools/git/config/gitconfig.os create mode 100644 macos/tools/git/config/gitconfig.os diff --git a/debian/tools/git/build b/debian/tools/git/build index 288307ac..7657848f 100755 --- a/debian/tools/git/build +++ b/debian/tools/git/build @@ -7,3 +7,9 @@ DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" # Call shared build script "$DOT_HOME/shared/tools/git/build" + +# Copy Debian-specific git configuration +if [[ -f "$SCRIPT_DIR/config/gitconfig.os" ]]; then + cp "$SCRIPT_DIR/config/gitconfig.os" "$HOME/.gitconfig.os" + echo "[Debian] OS-specific git configuration installed" +fi diff --git a/debian/tools/git/config/gitconfig.os b/debian/tools/git/config/gitconfig.os new file mode 100644 index 00000000..4bf4bebd --- /dev/null +++ b/debian/tools/git/config/gitconfig.os @@ -0,0 +1,5 @@ +# Debian-specific git configuration +[credential "https://github.com"] + helper = !/usr/bin/gh auth git-credential +[credential "https://gist.github.com"] + helper = !/usr/bin/gh auth git-credential diff --git a/macos/tools/git/build b/macos/tools/git/build index 288307ac..c8748afe 100755 --- a/macos/tools/git/build +++ b/macos/tools/git/build @@ -7,3 +7,9 @@ DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" # Call shared build script "$DOT_HOME/shared/tools/git/build" + +# Copy macOS-specific git configuration +if [[ -f "$SCRIPT_DIR/config/gitconfig.os" ]]; then + cp "$SCRIPT_DIR/config/gitconfig.os" "$HOME/.gitconfig.os" + echo "[macOS] OS-specific git configuration installed" +fi diff --git a/macos/tools/git/config/gitconfig.os b/macos/tools/git/config/gitconfig.os new file mode 100644 index 00000000..767ac9be --- /dev/null +++ b/macos/tools/git/config/gitconfig.os @@ -0,0 +1,5 @@ +# macOS-specific git configuration +[credential "https://github.com"] + helper = !/opt/homebrew/bin/gh auth git-credential +[credential "https://gist.github.com"] + helper = !/opt/homebrew/bin/gh auth git-credential diff --git a/shared/tools/git/config/.gitconfig b/shared/tools/git/config/.gitconfig index dbb0d23c..9c859cb4 100644 --- a/shared/tools/git/config/.gitconfig +++ b/shared/tools/git/config/.gitconfig @@ -2,10 +2,8 @@ email = vikdotdev@gmail.com name = Viktor Habchak signingkey = 7392D21113383CBB -[credential "https://github.com"] - helper = !/usr/bin/gh auth git-credential -[credential "https://gist.github.com"] - helper = !/usr/bin/gh auth git-credential +[include] + path = ~/.gitconfig.os [alias] ci = commit st = status From ab1b4841d5ba961b4279e147b987443d3df70739 Mon Sep 17 00:00:00 2001 From: Viktor Habchak Date: Tue, 30 Dec 2025 12:48:30 +0100 Subject: [PATCH 3/9] Restructure --- bin/dot | 223 +++++++++++------- macos/00-mise/deps/ruby/install | 27 --- macos/{00-mise/build => build/01-00-mise} | 11 +- .../{tools/emacs/build => build/02-00-emacs} | 12 +- macos/build/03-00-git | 10 + macos/build/04-00-gpg | 5 + macos/build/05-00-kanata | 37 +++ macos/build/06-00-shell | 5 + .../ghostty/build => build/07-00-ghostty} | 14 +- .../git/config => config/git}/gitconfig.os | 0 .../config/kanata/iso-us-international.kbd | 0 macos/install/01-10-mise-deps-ruby | 16 ++ macos/{00-mise/install => install/01-50-mise} | 10 - macos/install/02-10-emacs-deps-cmake | 15 ++ macos/install/02-50-emacs | 11 + .../{tools/git/install => install/03-10-git} | 10 - .../{kanata/install => install/05-10-kanata} | 14 -- macos/kanata/build | 82 ------- macos/shell/build | 9 - macos/tools/emacs/install | 21 -- macos/tools/git/build | 15 -- macos/tools/gpg/build | 9 - 22 files changed, 240 insertions(+), 316 deletions(-) delete mode 100755 macos/00-mise/deps/ruby/install rename macos/{00-mise/build => build/01-00-mise} (53%) rename macos/{tools/emacs/build => build/02-00-emacs} (67%) create mode 100755 macos/build/03-00-git create mode 100755 macos/build/04-00-gpg create mode 100755 macos/build/05-00-kanata create mode 100755 macos/build/06-00-shell rename macos/{tools/ghostty/build => build/07-00-ghostty} (53%) rename macos/{tools/git/config => config/git}/gitconfig.os (100%) rename shared/kanata/config/config.kbd => macos/config/kanata/iso-us-international.kbd (100%) create mode 100755 macos/install/01-10-mise-deps-ruby rename macos/{00-mise/install => install/01-50-mise} (85%) create mode 100755 macos/install/02-10-emacs-deps-cmake create mode 100755 macos/install/02-50-emacs rename macos/{tools/git/install => install/03-10-git} (54%) rename macos/{kanata/install => install/05-10-kanata} (94%) delete mode 100755 macos/kanata/build delete mode 100755 macos/shell/build delete mode 100755 macos/tools/emacs/install delete mode 100755 macos/tools/git/build delete mode 100755 macos/tools/gpg/build diff --git a/bin/dot b/bin/dot index 0515cb18..8b2e7c6c 100755 --- a/bin/dot +++ b/bin/dot @@ -88,47 +88,36 @@ get_system_dir() { echo "$DOT_HOME/$installed_system" } -# Resolve module name (handles numeric prefixes like 00-, 01-) -resolve_module_path() { +# Resolve script name (handles numeric prefixes like 01-50-mise) +resolve_script_name() { local module="$1" + local command="$2" local system_dir="$(get_system_dir)" - - # First, try the module as-is - if [[ -d "$system_dir/$module" ]]; then + local command_dir="$system_dir/$command" + + # First, try the module name as-is + if [[ -f "$command_dir/$module" && -x "$command_dir/$module" ]]; then echo "$module" return 0 fi - - # If module contains /, handle each part - if [[ "$module" == */* ]]; then - local parent="${module%/*}" - local child="${module##*/}" - - # Try with numeric prefix on child - for prefix in {00..99}; do - if [[ -d "$system_dir/$parent/${prefix}-${child}" ]]; then - echo "$parent/${prefix}-${child}" - return 0 - fi - done - - # Try with numeric prefix on parent - for prefix in {00..99}; do - if [[ -d "$system_dir/${prefix}-${parent}/$child" ]]; then - echo "${prefix}-${parent}/$child" - return 0 - fi - done - else - # Try with numeric prefixes for top-level modules - for prefix in {00..99}; do - if [[ -d "$system_dir/${prefix}-${module}" ]]; then - echo "${prefix}-${module}" - return 0 - fi - done + + # Try to find a script that ends with the module name (e.g., "mise" -> "01-50-mise") + local found_script="" + for script in "$command_dir"/*; do + [[ ! -f "$script" || ! -x "$script" ]] && continue + local script_name=$(basename "$script") + # Check if script ends with -$module + if [[ "$script_name" == *-"$module" ]]; then + found_script="$script_name" + break + fi + done + + if [[ -n "$found_script" ]]; then + echo "$found_script" + return 0 fi - + # Return original if no match found echo "$module" return 1 @@ -151,7 +140,7 @@ check_system_for_list() { get_available_modules() { local command="$1" local modules=() - + # Get the installed system type local installed_system if [[ -n "${INSTALLATION:-}" ]]; then @@ -160,21 +149,19 @@ get_available_modules() { installed_system=$(head -n1 "$INSTALLATION_MARKER") fi local system_dir="$DOT_HOME/$installed_system" - - # Check if system directory exists - if [[ ! -d "$system_dir" ]]; then + local command_dir="$system_dir/$command" + + # Check if command directory exists + if [[ ! -d "$command_dir" ]]; then return fi - - # Find all modules with the given command script + + # Find all executable files in the command directory # Use -perm for BSD find compatibility (macOS) while IFS= read -r -d '' script; do - local module_path=$(dirname "$script") - # Get the full relative path from system_dir - local module_name="${module_path#$system_dir/}" - - modules+=("$module_name") - done < <(find "$system_dir" -name "$command" -type f -perm +111 -print0 2>/dev/null) + local script_name=$(basename "$script") + modules+=("$script_name") + done < <(find "$command_dir" -maxdepth 1 -type f -perm +111 -print0 2>/dev/null) # Handle empty array to avoid unbound variable error if [[ ${#modules[@]} -gt 0 ]]; then @@ -185,7 +172,7 @@ get_available_modules() { # Run install command cmd_install() { local module="${1:-all}" - + # Handle --list option if [[ "$module" == "--list" ]]; then check_system_for_list @@ -193,43 +180,65 @@ cmd_install() { get_available_modules "install" return 0 fi - + check_system_setup init_logging "install" - + log_header "Installing: $module" - + + # Export common variables for scripts + export DOT_HOME="$DOT_HOME" + export SYSTEM_DIR="$(get_system_dir)" + export SHARED_DIR="$DOT_HOME/shared" + if [[ "$module" == "all" ]]; then log_info "Installing all modules" - + # Get all available install scripts local available_modules=() while IFS= read -r line; do [[ -n "$line" ]] && available_modules+=("$line") done < <(get_available_modules "install") - for mod in "${available_modules[@]}"; do - log_step "Running install for module: $mod" - "$(get_system_dir)/$mod/install" + for script_name in "${available_modules[@]}"; do + # Extract module name from script filename (e.g., "01-50-mise" -> "mise") + export MODULE_NAME="$(basename "$script_name" | sed 's/^[0-9]*-[0-9]*-//')" + + init_module_logging "$MODULE_NAME" + if "$SYSTEM_DIR/install/$script_name"; then + finalize_module_logging "success" + else + finalize_module_logging "failed" + exit 1 + fi done else # Install specific module - local resolved_module=$(resolve_module_path "$module") - if [[ -x "$(get_system_dir)/$resolved_module/install" ]]; then - "$(get_system_dir)/$resolved_module/install" + local script_name=$(resolve_script_name "$module" "install") + if [[ -x "$SYSTEM_DIR/install/$script_name" ]]; then + # Extract module name from script filename + export MODULE_NAME="$(basename "$script_name" | sed 's/^[0-9]*-[0-9]*-//')" + + init_module_logging "$MODULE_NAME" + if "$SYSTEM_DIR/install/$script_name"; then + finalize_module_logging "success" + else + finalize_module_logging "failed" + exit 1 + fi else log_error "Module $module does not have an install script" exit 1 fi fi - + finalize_logging "success" } # Run build command cmd_build() { local module="${1:-all}" - + # Handle --list option if [[ "$module" == "--list" ]]; then check_system_for_list @@ -237,43 +246,65 @@ cmd_build() { get_available_modules "build" return 0 fi - + check_system_setup init_logging "build" - + log_header "Building: $module" - + + # Export common variables for scripts + export DOT_HOME="$DOT_HOME" + export SYSTEM_DIR="$(get_system_dir)" + export SHARED_DIR="$DOT_HOME/shared" + if [[ "$module" == "all" ]]; then log_info "Building all modules" - + # Get all available build scripts local available_modules=() while IFS= read -r line; do [[ -n "$line" ]] && available_modules+=("$line") done < <(get_available_modules "build") - for mod in "${available_modules[@]}"; do - log_step "Running build for module: $mod" - "$(get_system_dir)/$mod/build" + for script_name in "${available_modules[@]}"; do + # Extract module name from script filename (e.g., "03-00-git" -> "git") + export MODULE_NAME="$(basename "$script_name" | sed 's/^[0-9]*-[0-9]*-//')" + + init_module_logging "$MODULE_NAME" + if "$SYSTEM_DIR/build/$script_name"; then + finalize_module_logging "success" + else + finalize_module_logging "failed" + exit 1 + fi done else # Build specific module - local resolved_module=$(resolve_module_path "$module") - if [[ -x "$(get_system_dir)/$resolved_module/build" ]]; then - "$(get_system_dir)/$resolved_module/build" + local script_name=$(resolve_script_name "$module" "build") + if [[ -x "$SYSTEM_DIR/build/$script_name" ]]; then + # Extract module name from script filename + export MODULE_NAME="$(basename "$script_name" | sed 's/^[0-9]*-[0-9]*-//')" + + init_module_logging "$MODULE_NAME" + if "$SYSTEM_DIR/build/$script_name"; then + finalize_module_logging "success" + else + finalize_module_logging "failed" + exit 1 + fi else log_error "Module $module does not have a build script" exit 1 fi fi - + finalize_logging "success" } # Run upgrade command cmd_upgrade() { local module="${1:-all}" - + # Handle --list option if [[ "$module" == "--list" ]]; then check_system_for_list @@ -281,42 +312,64 @@ cmd_upgrade() { get_available_modules "upgrade" return 0 fi - + check_system_setup init_logging "upgrade" - + log_header "Upgrading: $module" - + + # Export common variables for scripts + export DOT_HOME="$DOT_HOME" + export SYSTEM_DIR="$(get_system_dir)" + export SHARED_DIR="$DOT_HOME/shared" + if [[ "$module" == "all" ]]; then log_info "Upgrading all modules" - + # Get all available upgrade scripts local available_modules=() while IFS= read -r line; do [[ -n "$line" ]] && available_modules+=("$line") done < <(get_available_modules "upgrade") - + if [[ ${#available_modules[@]} -eq 0 ]]; then log_info "No modules have upgrade scripts" finalize_logging "success" return fi - - for mod in "${available_modules[@]}"; do - log_step "Running upgrade for module: $mod" - "$(get_system_dir)/$mod/upgrade" + + for script_name in "${available_modules[@]}"; do + # Extract module name from script filename + export MODULE_NAME="$(basename "$script_name" | sed 's/^[0-9]*-[0-9]*-//')" + + init_module_logging "$MODULE_NAME" + if "$SYSTEM_DIR/upgrade/$script_name"; then + finalize_module_logging "success" + else + finalize_module_logging "failed" + exit 1 + fi done else # Upgrade specific module - local resolved_module=$(resolve_module_path "$module") - if [[ -x "$(get_system_dir)/$resolved_module/upgrade" ]]; then - "$(get_system_dir)/$resolved_module/upgrade" + local script_name=$(resolve_script_name "$module" "upgrade") + if [[ -x "$SYSTEM_DIR/upgrade/$script_name" ]]; then + # Extract module name from script filename + export MODULE_NAME="$(basename "$script_name" | sed 's/^[0-9]*-[0-9]*-//')" + + init_module_logging "$MODULE_NAME" + if "$SYSTEM_DIR/upgrade/$script_name"; then + finalize_module_logging "success" + else + finalize_module_logging "failed" + exit 1 + fi else log_error "Module $module does not have an upgrade script" exit 1 fi fi - + finalize_logging "success" } diff --git a/macos/00-mise/deps/ruby/install b/macos/00-mise/deps/ruby/install deleted file mode 100755 index e73314dd..00000000 --- a/macos/00-mise/deps/ruby/install +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -DOT_HOME="$(dirname "$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")")" - -source "$DOT_HOME/lib/macos/include.sh" - -MODULE="ruby-deps" -init_module_logging "$MODULE" - -log_header "Installing Ruby dependencies for mise" - -# Install libyaml which is needed for Ruby to compile through mise (3.4.5) -log_step "Installing libyaml" - -if brew_installed libyaml; then - log_info "libyaml already installed" -else - install_formula libyaml -fi - -log_success "Ruby dependencies installed" -log_info "You can now install Ruby versions with: mise install ruby@3.4.5" - -finalize_module_logging "success" diff --git a/macos/00-mise/build b/macos/build/01-00-mise similarity index 53% rename from macos/00-mise/build rename to macos/build/01-00-mise index 02276a59..67a5b51c 100755 --- a/macos/00-mise/build +++ b/macos/build/01-00-mise @@ -2,24 +2,15 @@ set -euo pipefail -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -DOT_HOME="$(dirname "$(dirname "$SCRIPT_DIR")")" - source "$DOT_HOME/lib/macos/include.sh" -MODULE="mise" -init_module_logging "$MODULE" - -log_header "Building Mise Configuration" - if command_exists mise; then log_step "Creating mise.toml" mkdir -p "$HOME/.config/mise/" - cp "$DOT_HOME/shared/tools/mise/config/mise.toml" "$HOME/.config/mise/config.toml" + cp "$SHARED_DIR/tools/mise/config/mise.toml" "$HOME/.config/mise/config.toml" log_success "Deployed mise config to ~/.config/mise/config.toml" log_step "Installing tools" mise install - finalize_module_logging "success" else log_error "mise build failed - mise binary not found" exit 0 diff --git a/macos/tools/emacs/build b/macos/build/02-00-emacs similarity index 67% rename from macos/tools/emacs/build rename to macos/build/02-00-emacs index ac6ddaab..069abc8f 100755 --- a/macos/tools/emacs/build +++ b/macos/build/02-00-emacs @@ -2,21 +2,12 @@ set -euo pipefail -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" -SHARED_CONFIG_DIR="$DOT_HOME/shared/tools/emacs/config" - source "$DOT_HOME/lib/macos/include.sh" -MODULE="emacs" -init_module_logging "$MODULE" - -log_header "Building Emacs Configuration" - -# Deploy Emacs configuration log_step "Deploying Emacs configuration" EMACS_CONFIG_DIR="$HOME/.emacs.d" +SHARED_CONFIG_DIR="$SHARED_DIR/tools/emacs/config" mkdir -p "$EMACS_CONFIG_DIR" if [[ -f "$SHARED_CONFIG_DIR/early-init.el" ]]; then @@ -35,4 +26,3 @@ if [[ -f "$SHARED_CONFIG_DIR/config.org" ]]; then fi log_success "Emacs configuration completed" -finalize_module_logging "success" diff --git a/macos/build/03-00-git b/macos/build/03-00-git new file mode 100755 index 00000000..95592b16 --- /dev/null +++ b/macos/build/03-00-git @@ -0,0 +1,10 @@ +#!/bin/bash + +set -euo pipefail + +"$SHARED_DIR/tools/git/build" + +if [[ -f "$SYSTEM_DIR/config/git/gitconfig.os" ]]; then + cp "$SYSTEM_DIR/config/git/gitconfig.os" "$HOME/.gitconfig.os" + echo "[macOS] OS-specific git configuration installed" +fi diff --git a/macos/build/04-00-gpg b/macos/build/04-00-gpg new file mode 100755 index 00000000..304ca0aa --- /dev/null +++ b/macos/build/04-00-gpg @@ -0,0 +1,5 @@ +#!/bin/bash + +set -euo pipefail + +"$SHARED_DIR/tools/gpg/build" diff --git a/macos/build/05-00-kanata b/macos/build/05-00-kanata new file mode 100755 index 00000000..800e192e --- /dev/null +++ b/macos/build/05-00-kanata @@ -0,0 +1,37 @@ +#!/bin/bash + +set -euo pipefail + +source "$DOT_HOME/lib/macos/include.sh" + +if ! command_exists kanata; then + log_warning "kanata not installed, skipping configuration deployment" + log_info "Run 'dot install kanata' to install kanata first" + exit 0 +fi + +log_step "Deploying kanata configuration" + +CONFIG_DIR="$HOME/.config/kanata" +mkdir -p "$CONFIG_DIR" + +cp "$SYSTEM_DIR/config/kanata/iso-us-international.kbd" "$CONFIG_DIR/config.kbd" +log_success "Configuration deployed to $CONFIG_DIR/config.kbd" + +KANATA_PLIST="/Library/LaunchDaemons/com.kanata.plist" +if [[ -f "$KANATA_PLIST" ]]; then + log_step "Starting kanata service" + + if sudo launchctl list | grep -q "com.kanata"; then + log_info "Reloading kanata service" + sudo launchctl unload "$KANATA_PLIST" 2>/dev/null || true + fi + + sudo launchctl load "$KANATA_PLIST" + log_success "kanata service started" +else + log_warning "kanata LaunchDaemon not found" + log_info "Run 'dot install kanata' to set up the launch service" +fi + +log_success "kanata build completed" diff --git a/macos/build/06-00-shell b/macos/build/06-00-shell new file mode 100755 index 00000000..d860b194 --- /dev/null +++ b/macos/build/06-00-shell @@ -0,0 +1,5 @@ +#!/bin/bash + +set -euo pipefail + +"$SHARED_DIR/shell/build" diff --git a/macos/tools/ghostty/build b/macos/build/07-00-ghostty similarity index 53% rename from macos/tools/ghostty/build rename to macos/build/07-00-ghostty index bd6e0509..5f5091ea 100755 --- a/macos/tools/ghostty/build +++ b/macos/build/07-00-ghostty @@ -2,31 +2,19 @@ set -euo pipefail -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" - source "$DOT_HOME/lib/macos/include.sh" -MODULE="ghostty" -init_module_logging "$MODULE" - -log_header "Building Ghostty Configuration" - -# Create Ghostty config directory log_step "Creating Ghostty config directory" mkdir -p "$HOME/.config/ghostty" -# Deploy Ghostty configuration from shared log_step "Deploying Ghostty configuration" -SHARED_CONFIG="$DOT_HOME/shared/ghostty/config/config" +SHARED_CONFIG="$SHARED_DIR/ghostty/config/config" if [[ -f "$SHARED_CONFIG" ]]; then cp "$SHARED_CONFIG" "$HOME/.config/ghostty/config" log_info "Deployed Ghostty config to ~/.config/ghostty/config" else log_error "Ghostty config file not found at $SHARED_CONFIG" - finalize_module_logging "failed" exit 1 fi log_success "Ghostty configuration completed" -finalize_module_logging "success" diff --git a/macos/tools/git/config/gitconfig.os b/macos/config/git/gitconfig.os similarity index 100% rename from macos/tools/git/config/gitconfig.os rename to macos/config/git/gitconfig.os diff --git a/shared/kanata/config/config.kbd b/macos/config/kanata/iso-us-international.kbd similarity index 100% rename from shared/kanata/config/config.kbd rename to macos/config/kanata/iso-us-international.kbd diff --git a/macos/install/01-10-mise-deps-ruby b/macos/install/01-10-mise-deps-ruby new file mode 100755 index 00000000..006b59ee --- /dev/null +++ b/macos/install/01-10-mise-deps-ruby @@ -0,0 +1,16 @@ +#!/bin/bash + +set -euo pipefail + +source "$DOT_HOME/lib/macos/include.sh" + +log_step "Installing libyaml" + +if brew_installed libyaml; then + log_info "libyaml already installed" +else + install_formula libyaml +fi + +log_success "Ruby dependencies installed" +log_info "You can now install Ruby versions with: mise install ruby@3.4.5" diff --git a/macos/00-mise/install b/macos/install/01-50-mise similarity index 85% rename from macos/00-mise/install rename to macos/install/01-50-mise index c78d4f1b..2a78c4fc 100755 --- a/macos/00-mise/install +++ b/macos/install/01-50-mise @@ -2,16 +2,8 @@ set -euo pipefail -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -DOT_HOME="$(dirname "$(dirname "$SCRIPT_DIR")")" - source "$DOT_HOME/lib/macos/include.sh" -MODULE="mise" -init_module_logging "$MODULE" - -log_header "Installing mise" - # Check if mise is already installed if command_exists mise; then log_info "mise is already installed, skipping" @@ -50,5 +42,3 @@ fi log_success "mise installation completed" log_info "Run 'source ~/.bashrc' or start a new shell to activate mise" - -finalize_module_logging "success" diff --git a/macos/install/02-10-emacs-deps-cmake b/macos/install/02-10-emacs-deps-cmake new file mode 100755 index 00000000..b8c2c7ee --- /dev/null +++ b/macos/install/02-10-emacs-deps-cmake @@ -0,0 +1,15 @@ +#!/bin/bash + +set -euo pipefail + +source "$DOT_HOME/lib/macos/include.sh" + +log_step "Installing cmake" + +if brew_installed cmake; then + log_info "cmake already installed" +else + install_formula cmake +fi + +log_success "cmake dependency installed" diff --git a/macos/install/02-50-emacs b/macos/install/02-50-emacs new file mode 100755 index 00000000..a8f9655b --- /dev/null +++ b/macos/install/02-50-emacs @@ -0,0 +1,11 @@ +#!/bin/bash + +set -euo pipefail + +source "$DOT_HOME/lib/macos/include.sh" + +log_step "Installing emacs via Homebrew" +install_cask "emacs" + +log_success "Emacs installation completed" +log_info "Run 'dot build emacs' to configure emacs" diff --git a/macos/tools/git/install b/macos/install/03-10-git similarity index 54% rename from macos/tools/git/install rename to macos/install/03-10-git index 67ad6925..3a3dbe14 100755 --- a/macos/tools/git/install +++ b/macos/install/03-10-git @@ -2,21 +2,11 @@ set -euo pipefail -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" - source "$DOT_HOME/lib/macos/include.sh" -MODULE="git" -init_module_logging "$MODULE" - -log_header "Installing Git" - log_step "Installing git packages via Homebrew" FORMULAS=("git" "git-delta" "gh") install_formula "${FORMULAS[@]}" log_success "Git installation completed" log_info "Run 'dot build git' to configure git" - -finalize_module_logging "success" diff --git a/macos/kanata/install b/macos/install/05-10-kanata similarity index 94% rename from macos/kanata/install rename to macos/install/05-10-kanata index bd095f73..9d9a81f9 100755 --- a/macos/kanata/install +++ b/macos/install/05-10-kanata @@ -2,16 +2,8 @@ set -euo pipefail -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -DOT_HOME="$(dirname "$(dirname "$SCRIPT_DIR")")" - source "$DOT_HOME/lib/macos/include.sh" -MODULE="kanata" -init_module_logging "$MODULE" - -log_header "Installing Kanata" - # Kanata and Karabiner versions KANATA_VERSION="1.10.1" KARABINER_VERSION="6.7.0" @@ -23,7 +15,6 @@ KANATA_PLIST="/Library/LaunchDaemons/com.kanata.plist" if command_exists kanata && [[ -f "$KARABINER_DAEMON_PLIST" ]] && [[ -f "$KANATA_PLIST" ]]; then INSTALLED_VERSION=$(kanata --version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || echo "unknown") log_success "kanata is already fully installed and configured (version: $INSTALLED_VERSION)" - finalize_module_logging "success" exit 0 fi @@ -63,7 +54,6 @@ if [[ -d "/Applications/.Karabiner-VirtualHIDDevice-Manager.app" ]]; then log_success "Karabiner v${KARABINER_VERSION} installed" else log_error "Failed to download Karabiner driver" - finalize_module_logging "failed" exit 1 fi fi @@ -77,7 +67,6 @@ else log_success "Karabiner driver installed" else log_error "Failed to download Karabiner driver" - finalize_module_logging "failed" exit 1 fi fi @@ -163,14 +152,12 @@ if download_file "$KANATA_URL" "$TEMP_KANATA/$KANATA_ZIP"; then log_success "kanata installed to $KANATA_PATH" else log_error "Could not find kanata binary in zip" - finalize_module_logging "failed" exit 1 fi rm -rf "$TEMP_KANATA" else log_error "Failed to download kanata" - finalize_module_logging "failed" exit 1 fi @@ -230,4 +217,3 @@ log_info "3. Grant Input Monitoring permissions to your terminal app (e.g., Ghos log_info "4. Run 'dot build kanata' to deploy configuration and start kanata" echo "" -finalize_module_logging "success" diff --git a/macos/kanata/build b/macos/kanata/build deleted file mode 100755 index 4109d484..00000000 --- a/macos/kanata/build +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -DOT_HOME="$(dirname "$(dirname "$SCRIPT_DIR")")" - -source "$DOT_HOME/lib/macos/include.sh" - -MODULE="kanata" -init_module_logging "$MODULE" - -log_header "Building Kanata Configuration" - -# Check if kanata is installed -if ! command_exists kanata; then - log_warning "kanata not installed, skipping configuration deployment" - log_info "Run 'dot install kanata' to install kanata first" - log_success "kanata build skipped" - finalize_module_logging "success" - exit 0 -fi - -# Deploy configuration files -log_step "Deploying kanata configuration" - -CONFIG_DIR="$HOME/.config/kanata" -mkdir -p "$CONFIG_DIR" - -# Check for macOS-specific config first, fall back to shared -MACOS_CONFIG="$SCRIPT_DIR/config/config.kbd" -SHARED_CONFIG="$DOT_HOME/shared/kanata/config/config.kbd" - -if [[ -f "$MACOS_CONFIG" ]]; then - log_info "Deploying macOS-specific keyboard configuration" - cp "$MACOS_CONFIG" "$CONFIG_DIR/config.kbd" -elif [[ -f "$SHARED_CONFIG" ]]; then - log_info "Deploying shared keyboard configuration" - cp "$SHARED_CONFIG" "$CONFIG_DIR/config.kbd" -else - log_warning "No keyboard configuration found, creating minimal example" - cat > "$CONFIG_DIR/config.kbd" << 'EOF' -;; Minimal kanata configuration -;; Edit this file to customize your keyboard layout - -(defcfg - process-unmapped-keys yes -) - -(defsrc - caps -) - -(deflayer base - esc -) -EOF - log_info "Created example config at $CONFIG_DIR/config.kbd" -fi - -log_success "Configuration deployed to $CONFIG_DIR/config.kbd" - -# Load kanata LaunchDaemon if it exists -KANATA_PLIST="/Library/LaunchDaemons/com.kanata.plist" -if [[ -f "$KANATA_PLIST" ]]; then - log_step "Starting kanata service" - - # Check if already loaded - if sudo launchctl list | grep -q "com.kanata"; then - log_info "Reloading kanata service" - sudo launchctl unload "$KANATA_PLIST" 2>/dev/null || true - fi - - sudo launchctl load "$KANATA_PLIST" - log_success "kanata service started" -else - log_warning "kanata LaunchDaemon not found" - log_info "Run 'dot install kanata' to set up the launch service" -fi - -log_success "kanata build completed" -finalize_module_logging "success" diff --git a/macos/shell/build b/macos/shell/build deleted file mode 100755 index 625ca7fe..00000000 --- a/macos/shell/build +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -DOT_HOME="$(dirname "$(dirname "$SCRIPT_DIR")")" - -# Call shared build script -"$DOT_HOME/shared/shell/build" diff --git a/macos/tools/emacs/install b/macos/tools/emacs/install deleted file mode 100755 index 089a15ca..00000000 --- a/macos/tools/emacs/install +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" - -source "$DOT_HOME/lib/macos/include.sh" - -MODULE="emacs" -init_module_logging "$MODULE" - -log_header "Installing Emacs" - -log_step "Installing emacs via Homebrew" -install_cask "emacs" - -log_success "Emacs installation completed" -log_info "Run 'dot build emacs' to configure emacs" - -finalize_module_logging "success" diff --git a/macos/tools/git/build b/macos/tools/git/build deleted file mode 100755 index c8748afe..00000000 --- a/macos/tools/git/build +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" - -# Call shared build script -"$DOT_HOME/shared/tools/git/build" - -# Copy macOS-specific git configuration -if [[ -f "$SCRIPT_DIR/config/gitconfig.os" ]]; then - cp "$SCRIPT_DIR/config/gitconfig.os" "$HOME/.gitconfig.os" - echo "[macOS] OS-specific git configuration installed" -fi diff --git a/macos/tools/gpg/build b/macos/tools/gpg/build deleted file mode 100755 index 7b88cc8b..00000000 --- a/macos/tools/gpg/build +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -DOT_HOME="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" - -# Call shared build script -"$DOT_HOME/shared/tools/gpg/build" From 043133dd84bd3ab46f5999df1a44a3adb8e52f7b Mon Sep 17 00:00:00 2001 From: Viktor Habchak Date: Tue, 30 Dec 2025 15:50:27 +0100 Subject: [PATCH 4/9] Fix kanata --- macos/build/05-00-kanata | 43 +++++++++++++++++++++++++++++--------- macos/install/05-10-kanata | 22 +++++++++++++++++-- 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/macos/build/05-00-kanata b/macos/build/05-00-kanata index 800e192e..3ce5de5f 100755 --- a/macos/build/05-00-kanata +++ b/macos/build/05-00-kanata @@ -10,25 +10,48 @@ if ! command_exists kanata; then exit 0 fi -log_step "Deploying kanata configuration" +log_step "Validating kanata configuration" +NEW_CONFIG="$SYSTEM_DIR/config/kanata/iso-us-international.kbd" + +# Basic validation: check if file exists and is not empty +if [[ ! -f "$NEW_CONFIG" ]]; then + log_error "Config file not found: $NEW_CONFIG" + exit 1 +fi + +if [[ ! -s "$NEW_CONFIG" ]]; then + log_error "Config file is empty: $NEW_CONFIG" + exit 1 +fi +log_info "Config file validation passed" + +log_step "Deploying kanata configuration" CONFIG_DIR="$HOME/.config/kanata" mkdir -p "$CONFIG_DIR" -cp "$SYSTEM_DIR/config/kanata/iso-us-international.kbd" "$CONFIG_DIR/config.kbd" +cp "$NEW_CONFIG" "$CONFIG_DIR/config.kbd" log_success "Configuration deployed to $CONFIG_DIR/config.kbd" KANATA_PLIST="/Library/LaunchDaemons/com.kanata.plist" if [[ -f "$KANATA_PLIST" ]]; then - log_step "Starting kanata service" - - if sudo launchctl list | grep -q "com.kanata"; then - log_info "Reloading kanata service" - sudo launchctl unload "$KANATA_PLIST" 2>/dev/null || true + log_step "Restarting kanata service" + + # Bootout (unload) - will fail silently if not loaded + sudo launchctl bootout system "$KANATA_PLIST" 2>/dev/null || true + sleep 0.5 + + # Bootstrap (load and start) + if sudo launchctl bootstrap system "$KANATA_PLIST" 2>/dev/null; then + log_success "kanata service restarted (passwordless sudo)" + else + # Try kickstart if already loaded + if sudo launchctl kickstart -k system/com.kanata 2>/dev/null; then + log_success "kanata service restarted via kickstart" + else + log_warning "Could not restart service - may need manual intervention" + fi fi - - sudo launchctl load "$KANATA_PLIST" - log_success "kanata service started" else log_warning "kanata LaunchDaemon not found" log_info "Run 'dot install kanata' to set up the launch service" diff --git a/macos/install/05-10-kanata b/macos/install/05-10-kanata index 9d9a81f9..c59226af 100755 --- a/macos/install/05-10-kanata +++ b/macos/install/05-10-kanata @@ -202,18 +202,36 @@ sudo tee "$KANATA_PLIST" > /dev/null << EOF EOF -# Set correct permissions sudo chmod 644 "$KANATA_PLIST" sudo chown root:wheel "$KANATA_PLIST" log_success "kanata LaunchDaemon created" + +# Set up passwordless sudo for kanata service management +log_step "Setting up passwordless sudo for kanata management" +SUDOERS_FILE="/etc/sudoers.d/kanata" + +sudo tee "$SUDOERS_FILE" > /dev/null << 'SUDOEOF' +# Allow passwordless sudo for kanata service management +%admin ALL=(root) NOPASSWD: /bin/launchctl bootout system /Library/LaunchDaemons/com.kanata.plist +%admin ALL=(root) NOPASSWD: /bin/launchctl bootstrap system /Library/LaunchDaemons/com.kanata.plist +%admin ALL=(root) NOPASSWD: /bin/launchctl kickstart -k system/com.kanata +SUDOEOF + +sudo chmod 440 "$SUDOERS_FILE" +log_success "Sudoers configured for passwordless kanata management" log_info "kanata will start automatically after 'dot build kanata' deploys the config" echo "" log_warning "IMPORTANT: Kanata requires system permissions" log_info "1. Approve the Karabiner extension in System Settings > Privacy & Security if needed" log_info "2. Restart your Mac if prompted" -log_info "3. Grant Input Monitoring permissions to your terminal app (e.g., Ghostty)" +log_info "3. Grant Input Monitoring permissions to: $KANATA_PATH" +log_info " Go to: System Settings > Privacy & Security > Input Monitoring" log_info "4. Run 'dot build kanata' to deploy configuration and start kanata" +log_info "" +log_info "Manage kanata service without password:" +log_info " sudo launchctl bootout system /Library/LaunchDaemons/com.kanata.plist" +log_info " sudo launchctl bootstrap system /Library/LaunchDaemons/com.kanata.plist" echo "" From dabf3386a3bd25104e95d4ace1bfd0efca1bef52 Mon Sep 17 00:00:00 2001 From: Viktor Habchak Date: Tue, 30 Dec 2025 16:37:07 +0100 Subject: [PATCH 5/9] Configure Amethyst --- macos/build/04-00-amethyst | 24 ++++ macos/config/amethyst/.amethyst.yml | 119 +++++++++++++++++++ macos/config/kanata/iso-us-international.kbd | 5 +- macos/install/04-10-amethyst | 16 +++ 4 files changed, 162 insertions(+), 2 deletions(-) create mode 100755 macos/build/04-00-amethyst create mode 100644 macos/config/amethyst/.amethyst.yml create mode 100755 macos/install/04-10-amethyst diff --git a/macos/build/04-00-amethyst b/macos/build/04-00-amethyst new file mode 100755 index 00000000..9a636483 --- /dev/null +++ b/macos/build/04-00-amethyst @@ -0,0 +1,24 @@ +#!/bin/bash + +set -euo pipefail + +source "$DOT_HOME/lib/macos/include.sh" + +if ! command -v open >/dev/null || [[ ! -d "/Applications/Amethyst.app" ]]; then + log_warning "Amethyst not installed, skipping configuration deployment" + log_info "Run 'dot install amethyst' to install Amethyst first" + exit 0 +fi + +log_step "Deploying Amethyst configuration" +SOURCE_CONFIG="$SYSTEM_DIR/config/amethyst/.amethyst.yml" +DEST_CONFIG="$HOME/.amethyst.yml" + +if [[ ! -f "$SOURCE_CONFIG" ]]; then + log_error "Config file not found: $SOURCE_CONFIG" + exit 1 +fi + +cp "$SOURCE_CONFIG" "$DEST_CONFIG" +log_success "Amethyst configuration deployed to $DEST_CONFIG" +log_info "Restart Amethyst for changes to take effect" diff --git a/macos/config/amethyst/.amethyst.yml b/macos/config/amethyst/.amethyst.yml new file mode 100644 index 00000000..fe65afbb --- /dev/null +++ b/macos/config/amethyst/.amethyst.yml @@ -0,0 +1,119 @@ +# Amethyst Configuration + +# Modifier keys (mod1 and mod2 can be customized) +mod1: + - option + - control + - command + +mod2: + - option + - control + - command + - shift + +# Layouts +layouts: + - tall + - fullscreen + - 3column-left + - floating + +# Window settings +window-margins: true +window-margin-size: 8 +window-resize-step: 5 + +# Focus behavior +mouse-follows-focus: false +focus-follows-mouse: false + +# Floating applications (bundle identifiers) +floating: + - com.apple.systempreferences + - com.apple.ActivityMonitor + +# Keyboard shortcuts +cycle-layout: + mod: mod1 + key: t + +shrink-main: + mod: mod1 + key: '=' + +expand-main: + mod: mod1 + key: '-' + +increase-main: + mod: mod1 + key: '.' + +decrease-main: + mod: mod1 + key: ',' + +focus-ccw: + mod: mod1 + key: i + +focus-cw: + mod: mod1 + key: o + +swap-cw: + mod: mod1 + key: n + +swap-main: + mod: mod1 + key: enter + +focus-screen-1: + mod: mod1 + key: m + +focus-screen-2: + mod: mod1 + key: l + +select-fullscreen-layout: + mod: mod1 + key: f + +select-wide-layout: + mod: mod2 + key: s + +throw-space-1: + mod: mod2 + key: '1' + +throw-space-2: + mod: mod2 + key: '2' + +throw-space-3: + mod: mod2 + key: '3' + +throw-space-4: + mod: mod2 + key: '4' + +throw-space-5: + mod: mod2 + key: '5' + +throw-space-6: + mod: mod2 + key: '6' + +throw-space-7: + mod: mod2 + key: '7' + +throw-space-8: + mod: mod2 + key: '8' diff --git a/macos/config/kanata/iso-us-international.kbd b/macos/config/kanata/iso-us-international.kbd index c10f9570..84bd8e56 100644 --- a/macos/config/kanata/iso-us-international.kbd +++ b/macos/config/kanata/iso-us-international.kbd @@ -22,6 +22,7 @@ lsb (tap-hold 170 170 [ lsft) rsb (tap-hold 170 170 ] rsft) sid (tap-hold 300 300 spc (layer-toggle side)) + 1cm (tap-hold 300 300 1 lmet) ;; Browser history navigation hfo (multi lalt rght) @@ -44,11 +45,11 @@ (deflayer main esc mute vold volu end ins del - = 1 2 3 4 5 6 7 8 9 0 - grv bspc + = @1cm 2 3 4 5 6 7 8 9 0 - grv bspc @mta q w e r t y u i o p @hyp \ @ces @laa s d f g h j k l @lac @qta ret ret lsft lsft z x c v b n m , . / @rsb - caps _ lalt @sid ralt rctl pgup up pgdn + caps lalt lmet @sid ralt rctl pgup up pgdn left down rght ) diff --git a/macos/install/04-10-amethyst b/macos/install/04-10-amethyst new file mode 100755 index 00000000..a8fc3b6f --- /dev/null +++ b/macos/install/04-10-amethyst @@ -0,0 +1,16 @@ +#!/bin/bash + +set -euo pipefail + +source "$DOT_HOME/lib/macos/include.sh" + +log_step "Installing Amethyst via Homebrew" +CASKS=("amethyst") +install_cask "${CASKS[@]}" + +log_success "Amethyst installation completed" +log_info "Run 'dot build amethyst' to configure Amethyst" +log_info "" +log_warning "IMPORTANT: Grant Accessibility permissions to Amethyst" +log_info "Go to: System Settings > Privacy & Security > Accessibility" +log_info "Enable Amethyst to allow window management" From 6b91aa6663cacd1bb1b8e9d0537243a71372c01d Mon Sep 17 00:00:00 2001 From: Viktor Habchak Date: Tue, 30 Dec 2025 16:46:01 +0100 Subject: [PATCH 6/9] Fix dired & vterm --- macos/install/02-10-emacs-deps-cmake | 15 --------------- macos/install/02-10-emacs-deps-vterm | 19 +++++++++++++++++++ shared/tools/emacs/config/config.org | 4 ++++ 3 files changed, 23 insertions(+), 15 deletions(-) delete mode 100755 macos/install/02-10-emacs-deps-cmake create mode 100755 macos/install/02-10-emacs-deps-vterm diff --git a/macos/install/02-10-emacs-deps-cmake b/macos/install/02-10-emacs-deps-cmake deleted file mode 100755 index b8c2c7ee..00000000 --- a/macos/install/02-10-emacs-deps-cmake +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -source "$DOT_HOME/lib/macos/include.sh" - -log_step "Installing cmake" - -if brew_installed cmake; then - log_info "cmake already installed" -else - install_formula cmake -fi - -log_success "cmake dependency installed" diff --git a/macos/install/02-10-emacs-deps-vterm b/macos/install/02-10-emacs-deps-vterm new file mode 100755 index 00000000..494324dd --- /dev/null +++ b/macos/install/02-10-emacs-deps-vterm @@ -0,0 +1,19 @@ +#!/bin/bash + +set -euo pipefail + +source "$DOT_HOME/lib/macos/include.sh" + +log_step "Installing Emacs dependencies (cmake, libtool)" + +FORMULAS=("cmake" "libtool") + +for formula in "${FORMULAS[@]}"; do + if brew_installed "$formula"; then + log_info "$formula already installed" + else + install_formula "$formula" + fi +done + +log_success "Emacs dependencies installed" diff --git a/shared/tools/emacs/config/config.org b/shared/tools/emacs/config/config.org index c0a5ec88..a59b2312 100644 --- a/shared/tools/emacs/config/config.org +++ b/shared/tools/emacs/config/config.org @@ -985,6 +985,10 @@ Attaches eglot to every programming language buffer: (with-eval-after-load 'dired (define-key dired-mode-map (kbd "e") 'eshell)) +;; Use GNU ls from coreutils on macOS +(when (eq system-type 'darwin) + (setq insert-directory-program "/opt/homebrew/bin/gls")) + (setq dired-listing-switches "-lah --group-directories-first") #+end_src From e7abdd5593a5fa1ee5e43af6cb2857350ce2ff0f Mon Sep 17 00:00:00 2001 From: Viktor Habchak Date: Tue, 30 Dec 2025 17:17:50 +0100 Subject: [PATCH 7/9] fix f-keys on mac --- macos/config/kanata/iso-us-international.kbd | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/macos/config/kanata/iso-us-international.kbd b/macos/config/kanata/iso-us-international.kbd index 84bd8e56..ab7fe4cb 100644 --- a/macos/config/kanata/iso-us-international.kbd +++ b/macos/config/kanata/iso-us-international.kbd @@ -34,7 +34,7 @@ ) (defsrc - esc mute vold volu end ins del + esc f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 nubs 1 2 3 4 5 6 7 8 9 0 - = bspc tab q w e r t y u i o p [ ] caps a s d f g h j k l ; ' \ ret @@ -44,7 +44,7 @@ ) (deflayer main - esc mute vold volu end ins del + esc brdn brup mctl sls dtn dnd prev pp next mute vold volu = @1cm 2 3 4 5 6 7 8 9 0 - grv bspc @mta q w e r t y u i o p @hyp \ @ces @laa s d f g h j k l @lac @qta ret ret @@ -54,7 +54,7 @@ ) (deflayer side - _ _ _ _ _ _ _ + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ @hba @hfo @tba @tfo _ _ _ _ _ up _ _ _ _ _ bspc rght ret _ _ _ _ _ _ _ _ From 2be48784edcee8e9012af93bf5d1de80837e24c5 Mon Sep 17 00:00:00 2001 From: Viktor Habchak Date: Tue, 30 Dec 2025 17:18:01 +0100 Subject: [PATCH 8/9] fix fonts in emacs --- macos/install/02-20-fonts | 24 ++++++++++++++++++++++++ shared/tools/emacs/config/config.org | 2 ++ 2 files changed, 26 insertions(+) create mode 100755 macos/install/02-20-fonts diff --git a/macos/install/02-20-fonts b/macos/install/02-20-fonts new file mode 100755 index 00000000..646585ac --- /dev/null +++ b/macos/install/02-20-fonts @@ -0,0 +1,24 @@ +#!/bin/bash + +set -euo pipefail + +source "$DOT_HOME/lib/macos/include.sh" + +log_step "Installing fonts via Homebrew" + +# Iosevka font variants +CASKS=( + "font-iosevka" + "font-iosevka-nerd-font" +) + +for cask in "${CASKS[@]}"; do + if brew list --cask "$cask" &>/dev/null; then + log_info "$cask already installed" + else + install_cask "$cask" + fi +done + +log_success "Fonts installation completed" +log_info "Restart applications to use the new fonts" diff --git a/shared/tools/emacs/config/config.org b/shared/tools/emacs/config/config.org index a59b2312..13052d2a 100644 --- a/shared/tools/emacs/config/config.org +++ b/shared/tools/emacs/config/config.org @@ -138,12 +138,14 @@ Different machines get different values. #+begin_src emacs-lisp (defvar vik/big-font-size (cond + ((eq system-type 'darwin) 180) ;; macOS needs larger due to scaling ((string= (getenv "DESKTOP") "1") 180) ((string= (getenv "LAPTOP") "2") 170) (t 170))) (defvar vik/default-font-size (cond + ((eq system-type 'darwin) 180) ;; macOS needs larger due to scaling ((string= (getenv "DESKTOP") "1") 110) ((string= (getenv "LAPTOP") "2") 150) (t 110))) From 9c2c7769a69c82961cecd451a6058462dbaeebc6 Mon Sep 17 00:00:00 2001 From: Viktor Habchak Date: Tue, 30 Dec 2025 17:28:31 +0100 Subject: [PATCH 9/9] fix mise in emacs --- shared/tools/emacs/config/config.org | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/shared/tools/emacs/config/config.org b/shared/tools/emacs/config/config.org index 13052d2a..bb5df376 100644 --- a/shared/tools/emacs/config/config.org +++ b/shared/tools/emacs/config/config.org @@ -755,11 +755,22 @@ Use =C-h .= to look up documentation of thing at point. (setq eldoc-echo-area-prefer-doc-buffer t) #+end_src ** Mise +Shared mise configuration: #+begin_src elisp (use-package mise :ensure t :hook (after-init . global-mise-mode)) #+end_src + +macOS-specific PATH and mise executable: +#+begin_src elisp :tangle (if (eq system-type 'darwin) "yes" "no") +(use-package exec-path-from-shell + :ensure t + :config + (exec-path-from-shell-initialize)) + +(setq mise-executable (expand-file-name "~/.local/bin/mise")) +#+end_src ** Eglot Attaches eglot to every programming language buffer: #+begin_src emacs-lisp