Просмотр исходного кода

chore: sync uncommitted dotfile changes from mactom.local

Replay the working-tree changes that lived only on the old machine onto
the fresh clone: tmux tab-bar config, git delta pager + difftastic include,
podman-only-if-no-docker alias guard, tt/ts tmux helpers, cc/ccw claude
aliases, gdsw/gsom git aliases, gitignore_global additions, and the
uv-upgrade helper.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Tom McKenzie 1 месяц назад
Родитель
Сommit
b59d5a1e7b
10 измененных файлов с 245 добавлено и 51 удалено
  1. 5 0
      .bashrc
  2. 57 47
      .gitconfig
  3. 15 0
      .gitconfig_difftastic
  4. 5 0
      .gitignore_global
  5. 41 3
      .rc.d/aliases.sh
  6. 3 0
      .rc.d/git.sh
  7. 64 0
      .tmux.conf
  8. 8 0
      .zshrc
  9. 46 0
      bin/uv-upgrade
  10. 1 1
      setup.sh

+ 5 - 0
.bashrc

@@ -27,3 +27,8 @@ bind '"\e[A": history-search-backward'
 bind '"\e[B": history-search-forward'
 
 . "$HOME/.cargo/env"
+
+# Added by LM Studio CLI (lms)
+export PATH="$PATH:/Users/tom/.lmstudio/bin"
+# End of LM Studio CLI section
+

+ 57 - 47
.gitconfig

@@ -1,56 +1,49 @@
 [user]
-    email = tom@chillidonut.com
-    name = Tom McKenzie
-    signingkey = 896D4BE5
-
+	email = tom@chillidonut.com
+	name = Tom McKenzie
+	signingkey = 896D4BE5
 [color]
-    branch = auto
-    diff = auto
-    status = auto
-
+	branch = auto
+	diff = auto
+	status = auto
 [color "branch"]
-    current = yellow reverse
-    local = yellow
-    remote = green
-
+	current = yellow reverse
+	local = yellow
+	remote = green
 [color "diff"]
-    meta = yellow bold
-    frag = magenta bold
-    old = red
-    new = cyan
-
+	meta = yellow bold
+	frag = magenta bold
+	old = red
+	new = cyan
 [color "status"]
-    added = yellow
-    changed = green
-    untracked = cyan
-
+	added = yellow
+	changed = green
+	untracked = cyan
 [help]
-    autocorrect = 10
-
+	autocorrect = 10
 [alias]
-    p = push
-    pp = publish
-    s = switch
-    sc = switch create
-    rb = pull --rebase
-    rbc = rebase --continue
-    rba = rebase --abort
-    l = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(cyan)<%an>%Creset' --abbrev-commit --date=relative
-    b = for-each-ref --count=10 --sort='-authordate:iso8601' --format=' %(color:green)%(authordate:relative) %09%(color:white)%(objectname:short) %(color:yellow)%(refname:short) %09%(color:white)%(upstream:track) %(contents:subject)' refs/heads --no-merged
-    edit-conflicted = ! git diff --name-only | uniq | xargs $(echo $EDITOR)
-    history = log -p --
+	p = push
+	pp = publish
+	s = switch
+	sc = switch create
+	rb = pull --rebase
+	rbc = rebase --continue
+	rba = rebase --abort
+	l = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(cyan)<%an>%Creset' --abbrev-commit --date=relative
+	b = for-each-ref --count=10 --sort='-authordate:iso8601' --format=' %(color:green)%(authordate:relative) %09%(color:white)%(objectname:short) %(color:yellow)%(refname:short) %09%(color:white)%(upstream:track) %(contents:subject)' refs/heads --no-merged
+	edit-conflicted = ! git diff --name-only | uniq | xargs $(echo $EDITOR)
+	history = log -p --
 	pushf = push --force-with-lease
-    pullall = ! git pull && git submodule update --init --recursive --remote
-    publish = ! git push -u origin `git rev-parse --abbrev-ref HEAD`
-    diverged = ! git log --graph --date=relative --oneline `git rev-parse --abbrev-ref HEAD` origin/`git rev-parse --abbrev-ref HEAD`
-    fixup = "!f() { TARGET=$(git rev-parse "$1"); git commit --fixup=$TARGET ${@:2} && EDITOR=true git rebase -i --autostash --autosquash $TARGET^; }; f"
-    last = rev-list -1 HEAD
+	pullall = ! git pull && git submodule update --init --recursive --remote
+	publish = ! git push -u origin `git rev-parse --abbrev-ref HEAD`
+	diverged = ! git log --graph --date=relative --oneline `git rev-parse --abbrev-ref HEAD` origin/`git rev-parse --abbrev-ref HEAD`
+	fixup = "!f() { TARGET=$(git rev-parse "$1"); git commit --fixup=$TARGET ${@:2} && EDITOR=true git rebase -i --autostash --autosquash $TARGET^; }; f"
+	last = rev-list -1 HEAD
 [core]
-	excludesfile = /Users/tom/.gitignore_global
+	excludesfile = /Users/tom/dotfiles/.gitignore_global
 	whitespace = tab-in-indent,trailing-space,space-before-tab
 	ignorecase = false
-# editor = vim -c 'startinsert'
-
+	pager = delta
 [push]
 	default = upstream
 [status]
@@ -58,8 +51,6 @@
 [merge "npm-merge-driver"]
 	name = automatically merge npm lockfiles
 	driver = npx npm-merge-driver merge %A %O %B %P
-# [pull]
-#	rebase = preserve
 [pull]
 	ff = only
 [advice]
@@ -69,7 +60,26 @@
 	smudge = git-lfs smudge -- %f
 	process = git-lfs filter-process
 	required = true
-
 [include]
-    path = ~/dotfiles/.gitconfig_difftastic
-    condition = command -v difft >/dev/null 2>&1
+	path = ~/dotfiles/.gitconfig_difftastic
+	condition = command -v difft >/dev/null 2>&1
+[interactive]
+	diffFilter = delta --color-only
+[delta]
+    features = decorations
+	navigate = true
+	line-numbers = true
+	hyperlinks = true
+ [delta "decorations"]
+     ; commit-decoration-style = bold yellow box ul
+     ; file-style = bold yellow ul
+     file-decoration-style = bold
+     hunk-header-decoration-style = bold
+[merge]
+	conflictStyle = zdiff3
+[credential "https://github.com"]
+	helper = 
+	helper = !/opt/homebrew/bin/gh auth git-credential
+[credential "https://gist.github.com"]
+	helper = 
+	helper = !/opt/homebrew/bin/gh auth git-credential

+ 15 - 0
.gitconfig_difftastic

@@ -0,0 +1,15 @@
+[diff]
+    tool = difftastic
+
+[difftool]
+    prompt = false
+
+[difftool "difftastic"]
+    cmd = difft "$LOCAL" "$REMOTE"
+
+[pager]
+    difftool = true
+
+[alias]
+    dft = difftool
+    dlog = "-c diff.external=difft log -p --ext-diff"

+ 5 - 0
.gitignore_global

@@ -8,5 +8,10 @@ Icon
 ._*
 
 .todo
+.worktrees
 bak
 _docs
+
+tmp_code_*
+
+**/.claude/settings.local.json

+ 41 - 3
.rc.d/aliases.sh

@@ -16,8 +16,8 @@ alias duh="du -sh * | sort -h"
 # export local .env file
 alias export-env="export \$(grep -v '^#' .env | xargs -0)"
 
-# docker / podman
-if [ -f '/usr/bin/podman' ] || [ -f '/opt/homebrew/bin/podman' ]; then
+# docker / podman — only alias to podman if docker CLI isn't installed
+if ! command -v docker >/dev/null 2>&1 && command -v podman >/dev/null 2>&1; then
   alias docker='podman'
   alias docker-compose='podman-compose'
   alias dc='docker-compose'
@@ -84,7 +84,45 @@ checkout() {
   cd "$HOME/repos/$DIR" || return
 }
 
-alias ac="git diff --staged | llm -m openrouter/meta-llama/llama-4-maverick:free -s 'Write a concise, imperative-mood git commit message summarizing these changes. Begin with feat, fix, bug, docs, or chore. No preamble or yapping.' | git commit -F -"
+alias ac='git diff --staged | head -c $((128 * 1024 * 3)) | llm -m openrouter/openrouter/free '\''Write a concise, imperative-mood git commit message summarizing these changes. Begin with feat, fix, bug, docs, or chore. No preamble or yapping.'\'' | git commit -F -'
 
 alias pbjson="pbpaste | jq -r"
 alias pbjsons="pbpaste | jq -sRr '@json'"
+
+alias vscode-server="docker run -it --init -p 3000:3000 -v "$(pwd):/home/workspace:cached" gitpod/openvscode-server"
+
+alias cc='claude --dangerously-skip-permissions --system-prompt "."'
+alias ccw='claude --dangerously-skip-permissions --system-prompt "." --tmux -w'
+
+alias t-claude="tmux has-session -t claude-session || tmux new-session -d -s claude-session; tmux attach-session -t claude-session"
+alias t-code="tmux has-session -t code-session || tmux new-session -d -s code-session; tmux attach-session -t code-session"
+
+# tt — attach/create the tmux session for the CURRENT dir, matching Zed's naming
+# (parent_current via -A). Switches instead of nesting when already inside tmux.
+tt() {
+  local name
+  name="$(basename "$(dirname "$PWD")")_$(basename "$PWD")"
+  if [ -n "$TMUX" ]; then
+    tmux has-session -t "=$name" 2>/dev/null || tmux new-session -d -s "$name"
+    tmux switch-client -t "=$name"
+  else
+    tmux new-session -A -s "$name"
+  fi
+}
+
+# tmux picker: native choose-tree (real tree, '/' filter, live preview, -Z zoom).
+# -F colorizes the right-hand descriptive column — the session/window NAME on the
+# left is drawn plain by tmux and can't be styled. Three line types handled via
+# the pane_format / window_format conditional (else-branch = session line).
+ts() {
+  local h="$HOME" pane win sess fmt
+  pane="#[fg=magenta]#{pane_current_command}#[default] #[fg=blue]#{s|$h|~|:pane_current_path}#[default]"
+  win="#[fg=magenta]#{pane_current_command}#[default]  #[fg=blue]#{s|$h|~|:pane_current_path}#[default]#{?window_zoomed_flag, #[fg=yellow]Z#[default],}#{?window_active, #[fg=green]●#[default],}  #[fg=colour244]#{t/f/%b %d %H#:%M:window_activity}#[default]"
+  sess="#[fg=yellow]#{session_windows}w#[default]  #{?session_attached,#[fg=green]● attached#[default],#[fg=colour244]detached#[default]}  #[fg=colour244]#{t/f/%b %d %H#:%M:session_activity}#[default]"
+  fmt="#{?pane_format,$pane,#{?window_format,$win,$sess}}"
+  if [ -n "$TMUX" ]; then
+    tmux choose-tree -Zs -F "$fmt"
+  else
+    tmux attach \; choose-tree -Zs -F "$fmt" 2>/dev/null || echo "no tmux sessions"
+  fi
+}

+ 3 - 0
.rc.d/git.sh

@@ -53,6 +53,7 @@ alias gdt='git diff-tree --no-commit-id --name-only -r'
 alias gdw='git diff --word-diff'
 
 alias gds='git diff --stat'
+alias gdsw='watch -n 0.5 -c -d git -c color.ui=always diff --stat'
 
 alias gf='git fetch'
 alias gfa='git fetch --all --prune'
@@ -76,3 +77,5 @@ alias gsu='git submodule update'
 alias gp='git push'
 alias gpf='git push --force-with-lease'
 alias gpl='git pull'
+
+alias gsom='git checkout origin/main'

+ 64 - 0
.tmux.conf

@@ -0,0 +1,64 @@
+set -g mouse on
+set -g base-index 1
+setw -g pane-base-index 1
+set -g history-limit 50000
+set -s escape-time 0
+set -g focus-events on
+set -g extended-keys on
+set -g display-time 4000
+set -g status-interval 5
+setw -g aggressive-resize on
+set -g status-keys emacs
+
+# Status bar as a tab bar
+set -g status-position bottom
+set -g status-style 'bg=colour235 fg=colour7'
+set -g status-left ' '
+# prefix-highlight (native #{client_prefix} — no plugin needed) + copy/sync indicators.
+# Indicators prepend to status-right so [+] [d] stay flush-right (mouse math intact).
+set -g status-right '#{?client_prefix,#[bg=colour3#,fg=colour235#,bold] ^B #[default] ,}#{?#{==:#{pane_mode},copy-mode},#[bg=colour2#,fg=colour235#,bold] COPY #[default] ,}#{?pane_synchronized,#[bg=colour1#,fg=colour15#,bold] SYNC #[default] ,} [+] [d] '
+# Tab label = the app's pane title (Claude Code sets a good one), trimmed to 24;
+# falls back to the running command for bare shells (where pane_title == hostname).
+# #{E:...} forces the stored format in @wtitle to expand. Replaces #W to dodge the
+# window-name pollution (apps leak junk like "2.1.156" into the window NAME).
+set -g @wtitle '#{?#{||:#{==:#{pane_title},},#{==:#{pane_title},#{host}}},#{pane_current_command},#{=/24/…:pane_title}}'
+# Tab: index:(NpZ) title — pane count + zoom flag prefixed in parens, only when split.
+setw -g window-status-format ' #I:#{?#{>:#{window_panes},1},(#{window_panes}p#{?window_zoomed_flag,Z,}) ,}#{E:@wtitle} '
+setw -g window-status-current-format ' #I:#{?#{>:#{window_panes},1},(#{window_panes}p#{?window_zoomed_flag,Z,}) ,}#{E:@wtitle} '
+setw -g window-status-current-style 'bg=colour4 fg=colour15 bold'
+set -g pane-border-status top
+
+# Click [+] to create new tab, [d] to detach
+bind -n MouseDown1StatusRight run-shell -b '\
+  x="#{mouse_x}"; \
+  w=$(tmux display-message -p "#{window_width}"); \
+  pos=$((w - x)); \
+  if [ "$pos" -ge 0 ] && [ "$pos" -le 3 ]; then \
+    tmux detach-client; \
+  elif [ "$pos" -ge 4 ] && [ "$pos" -le 8 ]; then \
+    tmux new-window; \
+  fi'
+
+# Close tab: just type exit (or Ctrl-d) in the shell
+
+# Window management menu (prefix + w)
+bind w display-menu -T "Windows" \
+    "New Window"      n "new-window" \
+    "Kill Window"     k "kill-window" \
+    "Next Window"     l "next-window" \
+    "Prev Window"     h "previous-window" \
+    "" \
+    "Horizontal Split" - "split-window -v" \
+    "Vertical Split"   | "split-window -h" \
+    "" \
+    "Kill Pane"        x "kill-pane" \
+    "Zoom Pane"        z "resize-pane -Z" \
+    "" \
+    "Choose Session"   s "choose-tree -s"
+
+bind-key -n M-w new-window
+
+# Fork Claude Code session into a new window
+bind R source-file ~/.tmux.conf \; display "Reloaded"
+
+bind f run-shell 'T="Fork ($(date "+%a %H:%M"))"; tmux new-window -a -n "$T" "claude --dangerously-skip-permissions --continue --fork-session"; tmux select-pane -T "$T"'

+ 8 - 0
.zshrc

@@ -43,3 +43,11 @@ export PATH="$BUN_INSTALL/bin:$PATH"
 if command -v zoxide >/dev/null 2>&1; then eval "$(zoxide init zsh)"; fi
 
 . "$HOME/.cargo/env"
+
+# opencode
+export PATH=/Users/tom/.opencode/bin:$PATH
+
+# Added by LM Studio CLI (lms)
+export PATH="$PATH:/Users/tom/.lmstudio/bin"
+# End of LM Studio CLI section
+

+ 46 - 0
bin/uv-upgrade

@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+
+import re
+import subprocess
+import tomllib
+from pathlib import Path
+
+
+def uv(subcommand: str, packages: list[str], group: str | None):
+    extra_arguments = []
+    if group:
+        extra_arguments.extend(["--group", group])
+
+    subprocess.check_call(["uv", subcommand, *packages, "--no-sync"] + extra_arguments)
+
+
+def main():
+    """WARNING:
+    from the `pyproject.toml` file, this may delete:
+        - comments
+        - upper bounds etc
+        - markers
+        - ordering of dependencies
+        - tool.uv.sources
+    """
+    pyproject = tomllib.loads(Path("pyproject.toml").read_text())
+    package_name_pattern = re.compile(r"^([-a-zA-Z\d]+)(\[[-a-zA-Z\d,]+])?")
+    for group, dependencies in {
+        None: pyproject["project"]["dependencies"],
+        **pyproject.get("dependency-groups", {}),
+    }.items():
+        to_remove = []
+        to_add = []
+        for dependency in dependencies:
+            package_match = package_name_pattern.match(dependency)
+            assert package_match, f"invalid package name '{dependency}'"
+            package, extras = package_match.groups()
+            to_remove.append(package)
+            to_add.append(f"{package}{extras or ''}")
+        uv("remove", to_remove, group=group)
+        uv("add", to_add, group=group)
+    subprocess.check_call(["uv", "sync"])
+
+
+if __name__ == "__main__":
+    main()

+ 1 - 1
setup.sh

@@ -3,7 +3,7 @@
 # symlink dotfiles
 dir="$HOME/dotfiles"
 olddir="$HOME/dotfiles/bak"   # backup directory
-files=".zshrc .zshrc.d .rc.d .bashrc .vimrc .bash_logout .gitconfig .gitignore_global .gemrc .vim"    # list of files/folders to symlink in homedir
+files=".zshrc .zshrc.d .rc.d .bashrc .vimrc .bash_logout .gitconfig .gitignore_global .gemrc .vim .tmux.conf"    # list of files/folders to symlink in homedir
 
 ## create dotfiles_old in homedir
 mkdir -p $olddir