Compare commits

...

7 Commits

Author SHA1 Message Date
5208e9a5bb install.sh: repoint dangling claude symlink to latest installed version
The committed ~/.local/bin/claude symlink targets a specific Claude Code
version path (whatever was current when this snapshot was taken). On any
host that has Claude Code installed at a different version, that symlink
arrives dangling.

Old behavior: just delete the dangling link and rely on the Claude
installer to recreate it. That doesn't help when the host has Claude
installed but at a version other than the one in the snapshot, and we
also support skipping the installer via DRUNKENDOTFILES_SKIP_CLAUDE=1
(used when the binary is already on disk but at a different version).

New behavior: when the deployed symlink is dangling, scan
~/.local/share/claude/versions/ and repoint the symlink to the highest
installed version (semver sort). Only fall back to deleting the link if
no version is installed at all.
2026-05-06 09:45:52 +00:00
6188583ee9 tmux: enable truecolor + focus-events for TUI apps
- Switch default-terminal from screen-256color to tmux-256color
  (better italics/undercurl/SGR support for nvim, Claude Code, etc.)
- Add terminal-features RGB for the common outer terminals so
  truecolor escape sequences pass through cleanly
- Enable focus-events so inner programs can redraw when the pane
  regains focus
2026-05-06 09:37:20 +00:00
f27ba2710e Pin git identity to dissimulo / connect+gitea@dustin-williams.com
Identity was previously deferred to ~/.gitconfig.user via the include
at the bottom of this file. Per the dotfiles owner, identity should
travel with the dotfiles regardless of host or local user — every
machine where this repo is deployed commits as dissimulo.

Per-machine bits (safe.directory, etc.) still belong in
~/.gitconfig.user, which the existing [include] at the bottom picks
up after this block.
2026-05-06 02:26:08 -07:00
c0e4a88d70 Add ~/.local/bin to PATH from prezto-override zshrc
The Claude Code installer drops the binary at ~/.local/bin/claude.
Without this PATH entry, freshly-installed Claude Code is invisible to
new shells until the user adds it manually. Other ~/.local/bin scripts
in this dotfiles repo (tmux-ip, tmux-window-icon, twitterbot, etc.)
benefit from the same.
2026-05-06 02:24:33 -07:00
700da3aa0b Make tmux/tmux.conf a relative symlink to ../.tmux.conf
YADR's Rakefile maps tmux/tmux.conf -> $HOME/.tmux.conf, but the
canonical, customized tmux config has lived at the repo root since
3d2508a (when the relationship was inverted). Re-running rake install
on its own (without the bash installer's subsequent personal-deploy
overlay) was therefore replacing the deployed real .tmux.conf with a
symlink to the older 3987-byte tmux/tmux.conf, dropping the IP/host
status-right and the bumped history limit.

Pointing tmux/tmux.conf at ../.tmux.conf via a relative symlink fixes
this on any machine, regardless of where ~/.yadr lives or which user
owns it: rake install's symlink chain now resolves to the customized
config no matter the install order.
2026-05-06 02:24:32 -07:00
fb80b6dfb2 gitconfig: use absolute include path for .gitconfig.user
The previous `[include] path = .gitconfig.user` was resolved relative to
the config file being read, which — because `~/.gitconfig` is a symlink
to `~/.yadr/git/gitconfig` — meant git looked for the user-identity
override at `~/.yadr/git/.gitconfig.user` instead of the conventional
`~/.gitconfig.user`. Switch to an absolute path so the include picks up
the homedir file regardless of symlink layout.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 07:41:12 -07:00
1d7df94a1d install.sh: merge PERSONAL_DIRS contents instead of wholesale replace
The previous deploy_one() did `mv $HOME/<dir> $BACKUP_DIR/<dir>` then
`cp -a $YADR_DIR/<dir> $HOME/<dir>` for every entry in PERSONAL_DIRS.
For dirs the repo only partially populates (notably .local — repo only
tracks .local/bin/), this swept away unrelated user data: the most
recent re-bootstrap moved ~/.local/share/fonts/ (Intel One Mono, Open
Gorton, Roboto Mono, GALLAUDET, code128) into the timestamped backup,
making them appear missing.

Rework deploy logic:
- deploy_file: copies one file/symlink, backing up only the conflicting
  destination (if any). Idempotent via paths_equivalent() so re-runs
  with no changes produce no output and no spurious backups.
- deploy_dir: walks the repo's tree for that dir and deploys each leaf
  via deploy_file. Files in $HOME the repo doesn't know about are left
  untouched. Subdirs are mkdir'd as needed.

Also: track the personal fonts at .local/share/fonts/ so they redeploy
on every install, and run fc-cache -f at the end so apps see them
without a logout/login.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 07:28:40 -07:00
19 changed files with 117 additions and 123 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -2,7 +2,20 @@
set -g bell-action any
# Default termtype. If the rcfile sets $TERM, that overrides this value.
set -g default-terminal screen-256color
set -g default-terminal "tmux-256color"
# Truecolor + clipboard passthrough for outer terminals that advertise RGB
# (covers xterm-*, alacritty, kitty, wezterm, iTerm, ghostty, modern Apple Terminal).
set -ga terminal-features ",xterm-256color:RGB"
set -ga terminal-features ",alacritty:RGB"
set -ga terminal-features ",kitty:RGB"
set -ga terminal-features ",wezterm:RGB"
set -ga terminal-features ",ghostty:RGB"
set -ga terminal-features ",screen-256color:RGB"
# TUI apps (Claude Code, nvim, etc.) want focus events so they can redraw
# / refresh state when the pane regains focus.
set -g focus-events on
# Keep your finger on ctrl, or don't
bind-key ^D detach-client

View File

@@ -1,5 +1,8 @@
# set your user tokens as environment variables, such as ~/.secrets
# See the README for examples.
[user]
name = dissimulo
email = connect+gitea@dustin-williams.com
[color]
ui = true
[color "branch"]
@@ -126,4 +129,4 @@
# http://gitfu.wordpress.com/2008/04/20/git-rerere-rereremember-what-you-did-last-time/
enabled = true
[include]
path = .gitconfig.user
path = ~/.gitconfig.user

View File

@@ -30,7 +30,11 @@ PERSONAL_FILES=(
.zprofile .zshenv .zshrc
)
# Directories deployed wholesale to $HOME/<dir>/.
# Directories whose contents are merged into $HOME/<dir>/, file by file. Files
# the repo provides replace conflicting on-disk versions (with the displaced
# version preserved in $BACKUP_DIR); files outside the repo's tree are left
# untouched. This deliberately avoids wholesale-replacing $HOME/.local etc.,
# which would sweep away unrelated user data (fonts, app state, ...).
PERSONAL_DIRS=(
.fonts .irssi .nano .themes .local .mplayer
)
@@ -83,37 +87,104 @@ else
fi
# 3. Deploy personal dotfiles
backup_one() {
local src_name="$1"
local dst="$HOME/$src_name"
# Move $HOME/<rel> aside into $BACKUP_DIR, preserving its sub-path.
backup_one_path() {
local rel="$1"
local dst="$HOME/$rel"
if [ -e "$dst" ] || [ -L "$dst" ]; then
mkdir -p "$BACKUP_DIR/$(dirname "$src_name")"
mv "$dst" "$BACKUP_DIR/$src_name"
mkdir -p "$BACKUP_DIR/$(dirname "$rel")"
mv "$dst" "$BACKUP_DIR/$rel"
fi
}
deploy_one() {
local name="$1"
local src="$YADR_DIR/$name"
local dst="$HOME/$name"
# Returns 0 iff $1 and $2 are equivalent (same symlink target, or identical
# regular-file content). Used to make re-runs idempotent: unchanged files get
# skipped instead of needlessly backed up.
paths_equivalent() {
local a="$1" b="$2"
if [ -L "$a" ] && [ -L "$b" ]; then
[ "$(readlink "$a")" = "$(readlink "$b")" ]
elif [ -L "$a" ] || [ -L "$b" ]; then
return 1
elif [ -f "$a" ] && [ -f "$b" ]; then
cmp -s "$a" "$b"
else
return 1
fi
}
# Deploy one file or symlink at $YADR_DIR/<rel> to $HOME/<rel>. If a different
# file/symlink is already at the destination, it's moved into $BACKUP_DIR first.
deploy_file() {
local rel="$1"
local src="$YADR_DIR/$rel"
local dst="$HOME/$rel"
if [ ! -e "$src" ] && [ ! -L "$src" ]; then
return
fi
backup_one "$name"
if paths_equivalent "$src" "$dst"; then
return
fi
backup_one_path "$rel"
mkdir -p "$(dirname "$dst")"
cp -a "$src" "$dst"
info "$name"
info "$rel"
}
# Deploy a directory by walking its tree and deploying each file/symlink in
# turn. Directories get mkdir'd; existing entries inside $HOME/<rel> that the
# repo doesn't know about are left alone. This is the merge semantics that
# protects e.g. $HOME/.local/share/fonts from being clobbered when the repo
# only tracks $HOME/.local/bin.
deploy_dir() {
local rel="$1"
local src="$YADR_DIR/$rel"
if [ ! -d "$src" ] || [ -L "$src" ]; then
return
fi
mkdir -p "$HOME/$rel"
local sub sub_rel src_path
while IFS= read -r -d '' sub; do
sub="${sub#./}"
[ "$sub" = "." ] && continue
sub_rel="$rel/$sub"
src_path="$YADR_DIR/$sub_rel"
if [ -d "$src_path" ] && [ ! -L "$src_path" ]; then
mkdir -p "$HOME/$sub_rel"
continue
fi
deploy_file "$sub_rel"
done < <(cd "$src" && find . -mindepth 1 -print0)
}
log "Deploying personal dotfiles"
for f in "${PERSONAL_FILES[@]}"; do deploy_one "$f"; done
for d in "${PERSONAL_DIRS[@]}"; do deploy_one "$d"; done
for f in "${PERSONAL_FILES[@]}"; do deploy_file "$f"; done
for d in "${PERSONAL_DIRS[@]}"; do deploy_dir "$d"; done
# .local/bin/claude is a relative symlink to ../share/claude/versions/...
# If that target isn't present on this machine, remove the dangling link so
# Claude Code's own installer (next step) can manage it.
if [ -L "$HOME/.local/bin/claude" ] && [ ! -e "$HOME/.local/bin/claude" ]; then
rm "$HOME/.local/bin/claude"
# .local/bin/claude is a relative symlink to ../share/claude/versions/<version>.
# The version baked into the repo snapshot is whatever was current when this
# was last committed; on a fresh host that exact version probably isn't
# installed. Resolve as follows:
# 1. If the deployed symlink already resolves, leave it alone.
# 2. Else, if any other Claude version is present under
# ~/.local/share/claude/versions/, repoint the symlink to the highest
# one (semver sort) so users get the latest installed binary.
# 3. Else, drop the dangling link and let Claude Code's own installer
# (next step) recreate it.
claude_link="$HOME/.local/bin/claude"
claude_versions_dir="$HOME/.local/share/claude/versions"
if [ -L "$claude_link" ] && [ ! -e "$claude_link" ]; then
latest_claude=""
if [ -d "$claude_versions_dir" ]; then
latest_claude="$(ls -1 "$claude_versions_dir" 2>/dev/null | sort -V | tail -1)"
fi
if [ -n "$latest_claude" ] && [ -e "$claude_versions_dir/$latest_claude" ]; then
ln -sfn "../share/claude/versions/$latest_claude" "$claude_link"
info "Repointed ~/.local/bin/claude -> $latest_claude (latest installed)"
else
rm "$claude_link"
fi
fi
# 4. Install Claude Code (Anthropic's CLI). Skip if already installed or
@@ -137,6 +208,13 @@ if [ -d "$HOME/.local/bin" ]; then
find "$HOME/.local/bin" -maxdepth 1 -type f -exec chmod +x {} \; 2>/dev/null || true
fi
# 5. Refresh font cache so newly-deployed .fonts/ and .local/share/fonts/
# entries are visible to apps without a logout/login.
if have fc-cache; then
log "Refreshing font cache"
fc-cache -f >/dev/null 2>&1 || warn "fc-cache returned non-zero; continuing"
fi
echo
log "Done."
if [ -d "$BACKUP_DIR" ]; then

View File

@@ -1,102 +0,0 @@
# Ring the bell if any background window rang a bell
set -g bell-action any
# Default termtype. If the rcfile sets $TERM, that overrides this value.
set -g default-terminal screen-256color
# Keep your finger on ctrl, or don't
bind-key ^D detach-client
# Create splits and vertical splits
bind-key v split-window -h -p 50 -c "#{pane_current_path}"
bind-key ^V split-window -h -p 50 -c "#{pane_current_path}"
bind-key s split-window -p 50 -c "#{pane_current_path}"
bind-key ^S split-window -p 50 -c "#{pane_current_path}"
# Pane resize in all four directions using vi bindings.
# Can use these raw but I map them to shift-ctrl-<h,j,k,l> in iTerm.
bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5
# Smart pane switching with awareness of Vim splits.
# See: https://github.com/christoomey/vim-tmux-navigator
is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
| grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"
bind-key -n 'C-h' if-shell "$is_vim" 'send-keys C-h' 'select-pane -L'
bind-key -n 'C-j' if-shell "$is_vim" 'send-keys C-j' 'select-pane -D'
bind-key -n 'C-k' if-shell "$is_vim" 'send-keys C-k' 'select-pane -U'
bind-key -n 'C-l' if-shell "$is_vim" 'send-keys C-l' 'select-pane -R'
tmux_version='$(tmux -V | sed -En "s/^tmux ([0-9]+(.[0-9]+)?).*/\1/p")'
if-shell -b '[ "$(echo "$tmux_version < 3.0" | bc)" = 1 ]' \
"bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\' 'select-pane -l'"
if-shell -b '[ "$(echo "$tmux_version >= 3.0" | bc)" = 1 ]' \
"bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\\\' 'select-pane -l'"
bind-key -T copy-mode-vi 'C-h' select-pane -L
bind-key -T copy-mode-vi 'C-j' select-pane -D
bind-key -T copy-mode-vi 'C-k' select-pane -U
bind-key -T copy-mode-vi 'C-l' select-pane -R
bind-key -T copy-mode-vi 'C-\' select-pane -l
# Use vi keybindings for tmux commandline input.
# Note that to get command mode you need to hit ESC twice...
set -g status-keys vi
# Use vi keybindings in copy and choice modes
setw -g mode-keys vi
# easily toggle synchronization (mnemonic: e is for echo)
# sends input to all panes in a given window.
bind e setw synchronize-panes on
bind E setw synchronize-panes off
# set first window to index 1 (not 0) to map more to the keyboard layout...
set-option -g base-index 1
set-window-option -g pane-base-index 1
set-window-option -g mouse on
# color scheme (styled as vim-powerline)
set -g status-left-length 52
set -g status-right-length 451
set -g status-style fg=white,bg=colour234
set -g pane-border-style fg=colour245
set -g pane-active-border-style fg=colour39
set -g message-style fg=colour16,bg=colour221,bold
set -g status-left '#[fg=colour235,bg=colour252,bold] ❐ #S #[fg=colour252,bg=colour238,nobold]⮀#[fg=colour245,bg=colour238,bold] #(whoami) #[fg=colour238,bg=colour234,nobold]⮀'
set -g window-status-format '#[fg=colour235,bg=colour252,bold] #I #(pwd="#{pane_current_path}"; echo ${pwd####*/}) #W '
set -g window-status-current-format '#[fg=colour234,bg=colour39]⮀#[fg=black,bg=colour39,noreverse,bold] #{?window_zoomed_flag,#[fg=colour228],} #I #(pwd="#{pane_current_path}"; echo ${pwd####*/}) #W #[fg=colour39,bg=colour234,nobold]⮀'
set-option -g status-interval 2
# Patch for OS X pbpaste and pbcopy under tmux.
set-option -g default-command "which reattach-to-user-namespace > /dev/null && reattach-to-user-namespace -l $SHELL || $SHELL"
# Screen like binding
unbind C-b
set -g prefix C-a
bind a send-prefix
# No escape time for vi mode
set -sg escape-time 0
# Screen like binding for last window
unbind l
bind C-a last-window
# Bigger history
set -g history-limit 10000
# New windows/pane in $PWD
bind c new-window -c "#{pane_current_path}"
# Fix key bindings broken in tmux 2.1
set -g assume-paste-time 0
# force a reload of the config file
unbind r
bind r source-file ~/.tmux.conf \; display "Reloaded!"
# Local config
if-shell "[ -f ~/.tmux.conf.user ]" 'source ~/.tmux.conf.user'

1
tmux/tmux.conf Symbolic link
View File

@@ -0,0 +1 @@
../.tmux.conf

View File

@@ -1,3 +1,4 @@
source $HOME/.zprezto/runcoms/zshrc
for config_file ($HOME/.yadr/zsh/*.zsh) source $config_file
export PATH="$HOME/.local/bin:$PATH"