diff --git a/Brewfile b/Brewfile index dca6856..ac5906a 100644 --- a/Brewfile +++ b/Brewfile @@ -24,6 +24,7 @@ brew "bat" # cat with syntax highlighting brew "eza" # modern ls brew "jq" # JSON on the command line brew "mise" # Node/Python/Java/... version manager +brew "pam-reattach" # Touch ID for sudo inside herdr and tmux (see macos-defaults.sh) # --- Containers (pick one) --- brew "colima" # open-source Docker runtime (CLI only) diff --git a/README.md b/README.md index 8f31db1..1d14362 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ My recommended developer setup for a new Mac (Apple Silicon or Intel), installab ./setup.sh ``` -3. Optional: apply developer-friendly macOS settings (read [the script](macos-defaults.sh) first, it's short): +3. Optional: apply developer-friendly macOS settings, including Touch ID for `sudo` (read [the script](macos-defaults.sh) first, it's short): ```sh ./macos-defaults.sh @@ -64,15 +64,16 @@ zsh is already the default shell on macOS, so there's nothing to install for it. | [git](https://git-scm.com/) | Newer than the version Apple ships | | [gh](https://cli.github.com/) | GitHub from the terminal: PRs, issues, `gh auth login` | | [delta](https://github.com/dandavison/delta) | Readable, syntax-highlighted `git diff` and `git log -p` | -| [fzf](https://github.com/junegunn/fzf) | Fuzzy finder. **Ctrl-R** searches history, **Ctrl-T** finds files | +| [fzf](https://github.com/junegunn/fzf) | Fuzzy finder. **Ctrl-R** searches history, **Ctrl-T** finds files (with a preview), **Option-C** jumps to a folder. Uses fd, so it skips files your `.gitignore` lists | | [zoxide](https://github.com/ajeetdsouza/zoxide) | A smarter `cd`: jump with `z `, or pick interactively with `zi` | | [btop](https://github.com/aristocratos/btop) | A better `top` | | [ripgrep](https://github.com/BurntSushi/ripgrep) | Very fast code search: `rg` | | [fd](https://github.com/sharkdp/fd) | A simpler, faster `find` | -| [bat](https://github.com/sharkdp/bat) | `cat` with syntax highlighting | +| [bat](https://github.com/sharkdp/bat) | `cat` with syntax highlighting. Also colors `man` pages | | [eza](https://github.com/eza-community/eza) | Modern `ls` (`ls`, `ll` and `la` use it) | | [jq](https://jqlang.org/) | Query and format JSON | | [mise](https://mise.jdx.dev/) | Installs and switches Node, Python, Java and other runtime versions per project: `mise use node@22` | +| [pam-reattach](https://github.com/fabianishere/pam_reattach) | Lets Touch ID approve `sudo` inside herdr and tmux too. [`macos-defaults.sh`](macos-defaults.sh) turns Touch ID for `sudo` on | ### Containers diff --git a/dotfiles/zshrc b/dotfiles/zshrc index 801b65e..9290e7c 100644 --- a/dotfiles/zshrc +++ b/dotfiles/zshrc @@ -19,6 +19,22 @@ setopt SHARE_HISTORY HIST_IGNORE_ALL_DUPS HIST_IGNORE_SPACE HIST_REDUCE_BLANKS autoload -Uz compinit && compinit zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}' # case-insensitive +# Defaults, so anything you set before this file is loaded still wins +export EDITOR="${EDITOR:-vim}" # git commit messages, crontab -e +if command -v bat >/dev/null; then + export MANPAGER="${MANPAGER:-sh -c 'col -bx | bat -l man -p'}" # colored man pages +fi + +# fzf: list files with fd (skips what .gitignore lists) and preview them with bat +if command -v fd >/dev/null; then + export FZF_DEFAULT_COMMAND="${FZF_DEFAULT_COMMAND:-fd --type f --hidden --exclude .git}" + export FZF_CTRL_T_COMMAND="${FZF_CTRL_T_COMMAND:-$FZF_DEFAULT_COMMAND}" + export FZF_ALT_C_COMMAND="${FZF_ALT_C_COMMAND:-fd --type d --hidden --exclude .git}" +fi +if command -v bat >/dev/null && [[ -z "$FZF_CTRL_T_OPTS" ]]; then + export FZF_CTRL_T_OPTS="--preview 'bat --color=always --style=numbers --line-range=:500 {}'" +fi + # Tools command -v starship >/dev/null && eval "$(starship init zsh)" command -v mise >/dev/null && eval "$(mise activate zsh)" diff --git a/macos-defaults.sh b/macos-defaults.sh index f46443e..364d7fa 100755 --- a/macos-defaults.sh +++ b/macos-defaults.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash # Optional macOS settings that suit development. Read through and delete what you don't want. -# Some settings (key repeat) only apply after you log out and back in. +# Some settings (key repeat) only apply after you log out and back in. Turning on +# Touch ID for sudo asks for your password. set -euo pipefail if [[ "$(uname -s)" != "Darwin" ]]; then @@ -35,5 +36,34 @@ defaults write com.apple.dock show-recents -bool false mkdir -p "$HOME/Screenshots" defaults write com.apple.screencapture location -string "$HOME/Screenshots" +# Touch ID for sudo. sudo_local survives macOS updates, unlike /etc/pam.d/sudo. pam-reattach, from the Brewfile, makes it work inside herdr and tmux. +SUDO_LOCAL=/etc/pam.d/sudo_local +REATTACH="" +for prefix in "${HOMEBREW_PREFIX:-}" /opt/homebrew /usr/local; do + if [[ -n "$prefix" && -f "$prefix/lib/pam/pam_reattach.so" ]]; then + REATTACH="$prefix/lib/pam/pam_reattach.so" + break + fi +done +if ! grep -qs sudo_local /etc/pam.d/sudo; then + echo "Touch ID for sudo needs macOS 14 (Sonoma) or newer, skipped." +else + if ! grep -qsE '^[[:space:]]*auth.*pam_tid\.so' "$SUDO_LOCAL"; then + echo 'auth sufficient pam_tid.so' | sudo tee -a "$SUDO_LOCAL" >/dev/null + echo "sudo now accepts Touch ID." + fi + if [[ -z "$REATTACH" ]]; then + echo "For Touch ID inside herdr and tmux: brew install pam-reattach, then re-run this script." + elif ! grep -qsE '^[[:space:]]*auth.*pam_reattach\.so' "$SUDO_LOCAL"; then + # It has to come before pam_tid.so, so it goes at the top. + tmp="$(mktemp)" + { printf 'auth optional %s ignore_ssh\n' "$REATTACH"; cat "$SUDO_LOCAL"; } > "$tmp" + # shellcheck disable=SC2024 # only the write needs sudo; the temp file is ours + sudo tee "$SUDO_LOCAL" < "$tmp" >/dev/null + rm -f "$tmp" + echo "Touch ID for sudo now works inside herdr and tmux too." + fi +fi + killall Finder Dock SystemUIServer 2>/dev/null || true echo "Done. Log out and back in for the keyboard settings to take effect."