20 Commits
Author SHA1 Message Date
Fabian Ising 13a0f0b2c7 Add cdiff and safe scp alias 2026-07-22 10:45:19 +02:00
Fabian Ising cc196aec46 [ALL] Point CLAUDE.md at AGENTS.md 2026-07-21 13:26:52 +02:00
Fabian Ising aacfba13b3 [ALL] Update codex 2026-07-21 13:17:15 +02:00
Fabian Ising a0ef696325 [TMUX/ZSH] Venv improvements 2026-07-16 14:25:28 +02:00
Fabian Ising 5251ee0f84 Fix comment handling in tex files 2026-07-15 09:31:59 +02:00
7d5d4be328 [ZSH] Bound background git calls to prevent zombie leaks
The check_tools_repo (git ls-remote | awk) and update_dotfiles (git fetch)
background jobs could stall on a network call and, being disowned (&!),
orphan into days-long processes holding unreaped git/awk children.

Bound both network probes with `timeout` (guarded, absent on macOS) and
disable ssh multiplexing so no daemonized mux master inherits our fds.
Also dedup the double update_dotfiles startup call.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 15:54:44 +02:00
Fabian Ising 57a0089b3a [ZSH] Defensive nvim aliasing 2026-07-10 14:56:07 +02:00
Fabian Ising 399b8e0c07 [ZSH] Report outdated tools repo 2026-07-10 13:30:11 +02:00
Fabian Ising ae9ae1ab9c [ZSH] Safe wrappers alias order fix 2026-07-10 11:53:07 +02:00
Fabian Ising 16b421a688 [ZSH] Safe wrappers alias 2026-07-10 11:37:46 +02:00
Fabian Ising 34a51c1e91 [ZSH] Add runai completion 2026-07-07 10:11:37 +02:00
Fabian Ising 2c0282778e [ZSH] Config update robusteness fix 2026-07-05 17:27:56 +02:00
Fabian Ising 1a264a66f8 [ALL] More global gitignores 2026-07-05 17:26:50 +02:00
Fabian Ising 38e8a9ed54 [ALL] Update claude code 2026-07-05 17:15:51 +02:00
Fabian Ising 75deb4987e [ZSH] Remove duplicate plugins 2026-07-05 17:15:37 +02:00
Fabian Ising 7b2c21ddc0 [TMUX] Visual bell fixes 2026-07-05 17:14:22 +02:00
Fabian IsingandClaude Opus 4.8 c0c05c951a Add CLAUDE.md
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 17:13:22 +02:00
Fabian IsingandClaude Opus 4.8 53d420f979 [SETUP] Remove defunct vim subtree and stale subtree metadata
The vim/ subtree had no tracked files or directory and its setup loops
were dead. The tmux/zsh subtrees have not been synced upstream since 2017; all
changes are now direct commits. Delete .gittrees and the vim example-linking
loops.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 17:13:22 +02:00
Fabian IsingandClaude Opus 4.8 d88d0565dc [GIT] Make core.excludesfile path relative for portability
Was hardcoded to /Users/ising/dotfiles; use ~/dotfiles so the base config
works on non-macOS hosts too.

(Separately, a local uncommitted 'credential.helper = store' was removed from
the live config so git uses the macOS keychain instead of writing
~/.git-credentials in plaintext. That line was never committed, so there is no
diff for it here.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 17:13:22 +02:00
Fabian IsingandClaude Opus 4.8 083ff173c7 [ALACRITTY] Auto-copy selection to clipboard
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 17:01:24 +02:00
15 changed files with 220 additions and 42 deletions
+6 -1
View File
@@ -40,7 +40,7 @@ program = "alacritty"
history = 0 history = 0
[selection] [selection]
save_to_clipboard = false save_to_clipboard = true
[terminal] [terminal]
osc52 = "OnlyCopy" osc52 = "OnlyCopy"
@@ -56,3 +56,8 @@ option_as_alt = "None"
[window.padding] [window.padding]
x = 2 x = 2
y = 0 y = 0
[[keyboard.bindings]]
key = "Return"
mods = "Shift"
chars = "\u001B\r"
+27
View File
@@ -1 +1,28 @@
.DS_Store .DS_Store
.localized
__MACOSX/
.AppleDouble
.LSOverride
# Resource forks
._*
# Files and directories that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
.com.apple.timemachine.supported
.PKInstallSandboxManager
.PKInstallSandboxManager-SystemSoftware
.hotfiles.btree
.vol
.file
.disk_label*
lost+found
.nobackup
**/.claude/settings.local.json
-14
View File
@@ -1,14 +0,0 @@
[subtree "tmux"]
url = git@vcs.murgi.de:dotfiles_fabian/tmux.git
path = tmux
branch = master
[subtree "zsh"]
url = git@vcs.murgi.de:dotfiles_fabian/zsh.git
path = zsh
branch = master
[subtree "vim"]
url = git@vcs.murgi.de:dotfiles_fabian/vim.git
path = vim
branch = master
+37
View File
@@ -0,0 +1,37 @@
# AGENTS.md
This file provides guidance to AI Agents when working with code in this repository.
This is a personal dotfiles repository targeting macOS (Apple Silicon + Intel) and Arch Linux. It is installed by symlinking config directories/files from the repo into `$HOME`, so files here are live configs — editing them changes the running system.
## Installation & setup
Setup is platform-specific and runs from the repo root:
- **macOS:** `./setup_mac.sh` — brews dependencies, creates a `neovim` virtualenv, then calls `./clone_and_link_mac.sh`. Uses GNU coreutils' `gln` (not `ln`), so coreutils must be installed first.
- **Arch:** `./setup_arch.sh` — pacman deps, then `./clone_and_link.sh` + `./copy_fonts_arch.sh`.
- `clone_and_link*.sh` create the symlinks (`~/.zsh`, `~/.zshrc`, `~/.tmux`, `~/.tmux.conf`, `~/.config/nvim`, `~/.config/alacritty`, virtualenvwrapper hooks). `link_config.sh` is a simpler standalone variant.
- `general_setup.sh` switches the login shell to zsh and triggers plugin installs.
## Platform-specific config via `.example` templates
The most important repo-wide convention: platform variants live as `.example` files and the active file is a symlink/copy produced at setup time. The setup scripts loop over files matching `zsh/.*_mac.example`, `tmux/.*_arch.example`, etc., and link/copy each to the name with the `_<platform>.example` suffix stripped.
Practical rule: **edit the `.example` source, not the generated symlink target.** The unsuffixed active files are git-ignored (see each subdir's `.gitignore`). Templates that are copied (not symlinked) at setup — `nvim/scheme.vim.template``scheme.vim`, `.config/alacritty/schemes.yml.template``schemes.yml` — are also git-ignored once activated.
## Component architecture
- **zsh** (`zsh/.zshrc`): Powerlevel10k instant prompt + [antidote](https://github.com/mattmc3/antidote) plugin manager (plugin list in `zsh/.zsh_plugins.txt`). `.zshrc` sources optional layered configs if present: `.powerline_config`, `.user_config`, `.virtual_env_config.zsh`, `.mac_config.zsh`, `.local_config`. `update_dotfiles()` auto-`git pull`s this repo in the background on every shell start. Machine-local overrides belong in `.local_config` (not committed).
- **nvim** (`nvim/init.vim`): [vim-plug](https://github.com/junegunn/vim-plug), auto-bootstrapped on first launch (`:PlugInstall`). Python provider points at the `~/python-envs/neovim` virtualenv on Apple Silicon. `colors/` holds a large bundled colorscheme collection.
- **tmux** (`tmux/.tmux.conf`): TPM-style `plugins/`. `tmux/tmux_attach.sh` is an attach helper.
- **alacritty** (`.config/alacritty/`): active theme selected via the `import = [...]` line in `alacritty.toml`.
- **gitconfig** (`gitconfig/gitconfig`): identity/behavior split by remote host using `includeIf "hasconfig:remote.*.url:..."``github`, `fhms` (fh-muenster), `murgi`, and `sit` (Fraunhofer) each load their own `*.gitconfig`. Change per-context email/signing in the matching include file, not the base config.
## Light/dark theme switching
`.config/alacritty/color_switcher.py` toggles light/dark across the terminal **and** nvim in one shot: it rewrites the `import` line in `alacritty.toml` (`solarized_light.toml``dark_mode.toml`) and the `background`/`colorscheme` lines in `~/.config/nvim/scheme.vim`. Keep the regex-matched line formats in those files intact when editing them by hand. `screenshot_mode.py` is a related toggle.
## Maintenance
- `./update_mac.sh` — macOS update runner. Default (no args) runs `--brew-update --cleanup --diagnostics --update-others`; other flags: `--system-update`, `--permission-fix` (strips Caskroom/App quarantine xattrs). Run `./update_mac.sh --help` for the list. `--update-others` also runs `claude --update` and `Codex --update`.
- `brew_autoupdate` — sets up scheduled brew auto-updates.
Symlink
+1
View File
@@ -0,0 +1 @@
AGENTS.md
+1 -1
View File
@@ -25,7 +25,7 @@ email = github@murgi.de
[includeIf "hasconfig:remote.*.url:https://git-int.sit.fraunhofer.de/**"] [includeIf "hasconfig:remote.*.url:https://git-int.sit.fraunhofer.de/**"]
path = ~/dotfiles/gitconfig/sit.gitconfig path = ~/dotfiles/gitconfig/sit.gitconfig
[core] [core]
excludesfile = /Users/ising/dotfiles/.gitignore_global excludesfile = ~/dotfiles/.gitignore_global
[submodule] [submodule]
recurse = true recurse = true
[filter "lfs"] [filter "lfs"]
+1 -1
View File
@@ -1,4 +1,4 @@
set formatoptions+=1rnmBa setlocal formatoptions+=1rnmBj
" Reformat lines (getting the spacing correct) {{{ " Reformat lines (getting the spacing correct) {{{
fun! TeX_fmt() fun! TeX_fmt()
-3
View File
@@ -28,7 +28,4 @@ for filename in tmux/.*_arch.example; do
cp $filename ${filename:0:-13} cp $filename ${filename:0:-13}
done done
for filename in vim/.*_arch.example; do
cp $filename ${filename:0:-13}
done
echo "You should now start tmux (and zsh) and nvim for automatic plugin installation." echo "You should now start tmux (and zsh) and nvim for automatic plugin installation."
-4
View File
@@ -26,10 +26,6 @@ for filename in tmux/.*_mac.example(N); do
gln -Tsvf $PWD/$filename $PWD/${filename:0:-12} gln -Tsvf $PWD/$filename $PWD/${filename:0:-12}
done done
for filename in vim/.*_mac.example(N); do
gln -Tsvf $PWD/$filename $PWD/${filename:0:-12}
done
open fonts/*.ttf open fonts/*.ttf
echo "You should now start tmux (and zsh) and nvim for automatic plugin installation." echo "You should now start tmux (and zsh) and nvim for automatic plugin installation."
+19 -2
View File
@@ -27,8 +27,19 @@ bind -T off F12 \
setw -g mode-keys vi setw -g mode-keys vi
set-option -g status-keys vi set-option -g status-keys vi
bind | split-window -h -c '#{pane_current_path}' # Splits keep the source pane's cwd AND its active Python venv. #{@venv} is set
bind - split-window -v -c '#{pane_current_path}' # per-pane by the shell (see .virtual_env_config.zsh); we go through run-shell
# because tmux expands FORMATS in a run-shell command but NOT in split-window's
# own -e value. The new pane inherits VIRTUAL_ENV and .zshrc re-activates it;
# when the source pane has no venv we omit -e so no empty var leaks in. New
# *windows* deliberately don't inherit it.
bind | run-shell 'v="#{@venv}"; d="#{pane_current_path}"; if [ -n "$v" ]; then tmux split-window -h -c "$d" -e VIRTUAL_ENV="$v"; else tmux split-window -h -c "$d"; fi'
bind - run-shell 'v="#{@venv}"; d="#{pane_current_path}"; if [ -n "$v" ]; then tmux split-window -v -c "$d" -e VIRTUAL_ENV="$v"; else tmux split-window -v -c "$d"; fi'
# New windows always start in the base environment: -e clears any inherited
# VIRTUAL_ENV (e.g. if the tmux server was first started from inside a venv, so
# its global env carries one), regardless of what the source pane had.
bind c new-window -e VIRTUAL_ENV=
# Switch windows # Switch windows
bind-key -n M-Left select-window -t -1 bind-key -n M-Left select-window -t -1
@@ -88,6 +99,12 @@ if '[ `uname` == Darwin ]' \
set-option -g set-titles on set-option -g set-titles on
set -g visual-bell on
# Forward bells from ALL panes to terminal (not just active one)
set -g bell-action any
# Enable bell monitoring
set -g monitor-bell on
# Escape timeout for nvim # Escape timeout for nvim
set -sg escape-time 10 set -sg escape-time 10
+22 -3
View File
@@ -50,14 +50,30 @@ function diagnostics {
brew doctor brew doctor
brew missing brew missing
} }
function update_others {
echo "----------"
echo "Update other stuff"
echo "----------"
if [ -x "$(command -v claude)" ]; then
echo "-- CLAUDE"
claude --update
fi
if [ -x "$(command -v codex)" ]; then
echo "-- CODEX"
codex update
fi
}
if [[ $* == *--help* ]]; then if [[ $* == *--help* ]]; then
echo "Usage: $0 [option]" echo "Usage: $0 [option]"
echo "Default options: --brew-update --cleanup --diagnostics" echo "Default options: --brew-update --update-others --cleanup --diagnostics"
echo -e "Options:\n\t--brew-update\n\t--cleanup\n\t--diagnostics\n\t--permission-fix\n\t--system-update" echo -e "Options:\n\t--brew-update\n\t--update-others\n\t--cleanup\n\t--diagnostics\n\t--permission-fix\n\t--system-update"
fi fi
if [[ -z $* ]]; then if [[ -z $* ]]; then
set -- "$*" "--brew-update --cleanup --diagnostics" set -- "$*" "--brew-update --cleanup --diagnostics --update-others"
fi fi
if [[ $* == *--system-update* ]]; then if [[ $* == *--system-update* ]]; then
@@ -66,6 +82,9 @@ fi
if [[ $* == *--brew-update* ]]; then if [[ $* == *--brew-update* ]]; then
update_brew update_brew
fi fi
if [[ $* == *--update-others* ]]; then
update_others
fi
if [[ $* == *--cleanup* ]]; then if [[ $* == *--cleanup* ]]; then
cleanup cleanup
fi fi
+6
View File
@@ -30,3 +30,9 @@ fi
export DYLD_FALLBACK_LIBRARY_PATH="$HOMEBREW_PREFIX/lib:${DYLD_FALLBACK_LIBRARY_PATH}" export DYLD_FALLBACK_LIBRARY_PATH="$HOMEBREW_PREFIX/lib:${DYLD_FALLBACK_LIBRARY_PATH}"
export GI_TYPELIB_PATH="$HOMEBREW_PREFIX/lib/girepository-1.0:${GI_TYPELIB_PATH}" export GI_TYPELIB_PATH="$HOMEBREW_PREFIX/lib/girepository-1.0:${GI_TYPELIB_PATH}"
export PKG_CONFIG_PATH="$HOMEBREW_PREFIX/lib/pkgconfig:$HOMEBREW_PREFIX/share/pkgconfig:${PKG_CONFIG_PATH}" export PKG_CONFIG_PATH="$HOMEBREW_PREFIX/lib/pkgconfig:$HOMEBREW_PREFIX/share/pkgconfig:${PKG_CONFIG_PATH}"
alias claude="workon claude; claude; deactivate"
alias python="python3"
# Tahoe 26 WindowServer bug: windows stay interactive but can't be moved by
# mouse or API until the window-management daemon is restarted (no logout).
alias unstick-windows="killall WindowManager"
+16 -2
View File
@@ -10,6 +10,20 @@ export VIRTUALENVWRAPPER_VIRTUALENV=$PREFIX/bin/virtualenv
mkdir -p $WORKON_HOME mkdir -p $WORKON_HOME
source $PREFIX/bin/virtualenvwrapper.sh source $PREFIX/bin/virtualenvwrapper.sh
if [ -n "$VIRTUAL_ENV" ] && [[ -f "$VIRTUAL_ENV/bin/activate" ]]; then # NOTE: an inherited VIRTUAL_ENV is *not* re-activated here — that happens at the
source $VIRTUAL_ENV/bin/activate; # very end of .zshrc so activate captures the fully-built PATH (see the comment
# there). Sourcing virtualenvwrapper.sh above only defines workon/deactivate/etc.
# Mirror the current venv into a per-pane tmux option so that splitting a pane
# can carry it into the new pane (.tmux.conf reads #{@venv} with `-e`). Per-pane
# (not session) state is what lets two panes hold different venvs and lets new
# *windows* start clean. Only fork tmux when the value actually changes.
_venv_track_precmd() {
[[ -n $TMUX ]] || return
if [[ "${VIRTUAL_ENV:-}" != "${_LAST_TRACKED_VENV-unset}" ]]; then
tmux set -p @venv "${VIRTUAL_ENV:-}" 2>/dev/null
_LAST_TRACKED_VENV="${VIRTUAL_ENV:-}"
fi fi
}
autoload -Uz add-zsh-hook
add-zsh-hook precmd _venv_track_precmd
-2
View File
@@ -8,7 +8,6 @@ ohmyzsh/ohmyzsh path:plugins/pip
ohmyzsh/ohmyzsh path:plugins/python ohmyzsh/ohmyzsh path:plugins/python
ohmyzsh/ohmyzsh path:plugins/brew ohmyzsh/ohmyzsh path:plugins/brew
ohmyzsh/ohmyzsh path:plugins/virtualenv ohmyzsh/ohmyzsh path:plugins/virtualenv
ohmyzsh/ohmyzsh path:plugins/python
ohmyzsh/ohmyzsh path:plugins/command-not-found ohmyzsh/ohmyzsh path:plugins/command-not-found
ohmyzsh/ohmyzsh path:plugins/docker-compose ohmyzsh/ohmyzsh path:plugins/docker-compose
ohmyzsh/ohmyzsh path:plugins/docker ohmyzsh/ohmyzsh path:plugins/docker
@@ -16,7 +15,6 @@ ohmyzsh/ohmyzsh path:plugins/vi-mode
romkatv/powerlevel10k romkatv/powerlevel10k
zsh-users/zsh-syntax-highlighting
zsh-users/zsh-autosuggestions zsh-users/zsh-autosuggestions
zsh-users/zsh-completions zsh-users/zsh-completions
zsh-users/zsh-history-substring-search zsh-users/zsh-history-substring-search
+83 -8
View File
@@ -6,14 +6,58 @@
[[ -f ~/.zsh/.virtual_env_config.zsh ]] && source ~/.zsh/.virtual_env_config.zsh [[ -f ~/.zsh/.virtual_env_config.zsh ]] && source ~/.zsh/.virtual_env_config.zsh
[[ -f ~/.zsh/.local_config ]] && source ~/.zsh/.local_config [[ -f ~/.zsh/.local_config ]] && source ~/.zsh/.local_config
# On shell start, bring ~/dotfiles up to date by fast-forwarding the CURRENT
# branch to its upstream only. Never rebase or stash in the background: if the
# branch diverged or local edits block it, warn and leave it for a manual pull.
# Per-branch, so `server` on each device fast-forwards to origin/server.
update_dotfiles() { update_dotfiles() {
cd ~/dotfiles || return local repo="$HOME/dotfiles"
if git fetch --dry-run 2>&1 | grep -q .; then # Bound the network call so a stalled fetch can't wedge this backgrounded
git pull > /dev/null 2>&1 # (&!) job into a days-long orphan holding unreaped children. `timeout` is
fi # absent on macOS, so only use it when present. Disable ssh multiplexing so
# no daemonized mux master can inherit and keep our fds open past git's exit.
local -a TO; (( $+commands[timeout] )) && TO=(timeout -k 5 15)
GIT_SSH_COMMAND='ssh -o BatchMode=yes -o ConnectTimeout=5 -o ControlMaster=no -o ControlPath=none' \
$TO git -C "$repo" fetch --quiet </dev/null 2>/dev/null || return
git -C "$repo" rev-parse --abbrev-ref '@{u}' >/dev/null 2>&1 || return # no upstream
git -C "$repo" merge-base --is-ancestor '@{u}' HEAD 2>/dev/null && return # already current
git -C "$repo" merge --ff-only --quiet '@{u}' 2>/dev/null \
|| print -u2 "⚠ dotfiles: $(git -C "$repo" symbolic-ref --short HEAD) can't fast-forward to @{u} — run: git -C ~/dotfiles pull"
} }
update_dotfiles 2>&1 &! update_dotfiles &!
# On shell start, check the security tools repo for upstream updates and print a
# one-line notice if the checkout is behind. Notify only (never auto-pull). This
# stays read-only so it works even when the repo lives in root-owned /opt/tools:
# - `safe.directory=*` sidesteps git's "dubious ownership" refusal on a repo
# owned by root, which would otherwise fail every git command.
# - `ls-remote` queries the remote without writing into .git (a normal user
# can't write a root-owned .git, so `fetch` would fail there).
# Uses the first candidate that is a git checkout; covers global and per-user layouts.
check_tools_repo() {
local repo branch remote mergeref remote_sha local_sha cmd
# See update_dotfiles: bound the network probe (timeout, absent on macOS) and
# disable ssh multiplexing so a stalled ls-remote can't orphan this &! job.
local -a TO; (( $+commands[timeout] )) && TO=(timeout -k 5 10)
for repo in /opt/tools "$HOME/tools" "$HOME/tools/tools-repo"; do
local -a g=(git -c 'safe.directory=*' -C "$repo")
$g rev-parse --is-inside-work-tree >/dev/null 2>&1 || continue
branch=$($g symbolic-ref --short HEAD 2>/dev/null) || return
remote=$($g config "branch.$branch.remote" 2>/dev/null) || return # no upstream
mergeref=$($g config "branch.$branch.merge" 2>/dev/null) || return
remote_sha=$(GIT_SSH_COMMAND='ssh -o BatchMode=yes -o ConnectTimeout=5 -o ControlMaster=no -o ControlPath=none' \
$TO $g ls-remote "$remote" "$mergeref" </dev/null 2>/dev/null | awk '{print $1}')
local_sha=$($g rev-parse HEAD 2>/dev/null)
[[ -n "$remote_sha" && -n "$local_sha" ]] || return # remote unreachable
[[ "$remote_sha" == "$local_sha" ]] && return # already current
$g merge-base --is-ancestor "$remote_sha" HEAD 2>/dev/null && return # remote is an ancestor: ahead/equal (also true if we lack the object -> falls through to "behind")
[[ -w "$repo/.git" ]] && cmd="git -C $repo pull" || cmd="sudo git -C $repo pull"
print -u2 "⬆ tools: updates available in $repo — run: $cmd"
return
done
}
check_tools_repo &!
export LC_OSC52=1 export LC_OSC52=1
# Load Antidote # Load Antidote
@@ -57,13 +101,14 @@ bindkey "^w" kill-region
bindkey -v bindkey -v
VI_MODE_SET_CURSOR=true VI_MODE_SET_CURSOR=true
alias vim=nvim (( $+commands[nvim] )) && alias vim=nvim
alias sudo='sudo ' alias sudo='sudo '
export EDITOR='nvim' (( $+commands[nvim] )) && export EDITOR='nvim'
export VISUAL='nvim' (( $+commands[nvim] )) && export VISUAL='nvim'
alias ls="ls --color=always" alias ls="ls --color=always"
alias cgrep="grep --color=always" alias cgrep="grep --color=always"
alias cdiff="git diff --color-words --no-index"
delzip() { delzip() {
unzip -Z -1 "$@" | xargs -I{} rm -rf {} unzip -Z -1 "$@" | xargs -I{} rm -rf {}
@@ -77,6 +122,11 @@ if `which go &>/dev/null`; then
export GOPATH=$(go env GOPATH) export GOPATH=$(go env GOPATH)
fi fi
# Use safecp/safemv from the tools-repo when available (after ~/.local/bin is on PATH)
(( $+commands[safecp] )) && alias cp=safecp
(( $+commands[safemv] )) && alias mv=safemv
(( $+commands[safescp] )) && alias scp=safescp
if [[ -f ~/.ssh/sudo_key ]]; then if [[ -f ~/.ssh/sudo_key ]]; then
[[ -e /tmp/sudo-agent.sock ]] || ssh-agent -a /tmp/sudo-agent.sock &> /dev/null [[ -e /tmp/sudo-agent.sock ]] || ssh-agent -a /tmp/sudo-agent.sock &> /dev/null
SSH_AUTH_SOCK=/tmp/sudo-agent.sock ssh-add -l | grep -q `ssh-keygen -lf ~/.ssh/sudo_key | awk '{print $2}'` || SSH_AUTH_SOCK=/tmp/sudo-agent.sock ssh-add ~/.ssh/sudo_key SSH_AUTH_SOCK=/tmp/sudo-agent.sock ssh-add -l | grep -q `ssh-keygen -lf ~/.ssh/sudo_key | awk '{print $2}'` || SSH_AUTH_SOCK=/tmp/sudo-agent.sock ssh-add ~/.ssh/sudo_key
@@ -126,3 +176,28 @@ zstyle :bracketed-paste-magic paste-finish pastefinish
# https://github.com/zsh-users/zsh-autosuggestions/issues/351 # https://github.com/zsh-users/zsh-autosuggestions/issues/351
ZSH_AUTOSUGGEST_CLEAR_WIDGETS+=(bracketed-paste) ZSH_AUTOSUGGEST_CLEAR_WIDGETS+=(bracketed-paste)
export PATH=$PATH:/Users/ising/.runai/bin
source <(/Users/ising/.runai/bin/runai --quiet completion zsh)
# Re-activate an inherited virtualenv — MUST be the last PATH-affecting line.
#
# When VIRTUAL_ENV is present in the environment (a tmux pane split carries it
# in via `-e VIRTUAL_ENV=...`, see .tmux.conf) we source the venv's activate
# script here rather than in .virtual_env_config.zsh. activate snapshots the
# current PATH into _OLD_VIRTUAL_PATH and restores it on `deactivate`; if we
# activated earlier (before .mac_config.zsh, go, runai below all prepend to
# PATH) that snapshot would be incomplete and `deactivate` would strip
# ~/.local/bin & friends — dropping claude and co. off PATH. Keeping this last
# guarantees the snapshot is the fully-built PATH.
#
# ANY new PATH mutation must go ABOVE this block.
#
# A new tmux window clears the var to empty (`bind c ... -e VIRTUAL_ENV=`) to
# force the base environment; drop that empty value so nothing sees a bogus venv.
[ -z "${VIRTUAL_ENV:-}" ] && unset VIRTUAL_ENV
if [ -n "$VIRTUAL_ENV" ] && [ -f "$VIRTUAL_ENV/bin/activate" ]; then
# Guard against double-activation on a manual `source ~/.zshrc`.
if [[ ":$PATH:" != *":$VIRTUAL_ENV/bin:"* ]]; then
source "$VIRTUAL_ENV/bin/activate"
fi
fi