Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions home/zshrc.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,18 @@ _DOTFILES_SHELL_DIR="${${(%):-%N}:A:h:h}/shell"

# Source order matters: env.zsh first (PATH, EDITOR, XDG vars), then
# everything else.
#
# Note: do NOT name the loop var `module_path` -- that's a reserved zsh
# special parameter (the array tied to MODULE_PATH used to locate
# loadable .so modules). Overwriting and then unsetting it breaks
# zmodload for the rest of the session, which produces errors from
# fzf's completion.zsh (zsh/regex), compinit (zsh/complete), and
# Ghostty's shell integration (zsh/zleparameter).
for module in env aliases functions prompt fzf; do
module_path="${_DOTFILES_SHELL_DIR}/${module}.zsh"
[[ -r $module_path ]] && source "$module_path"
module_file="${_DOTFILES_SHELL_DIR}/${module}.zsh"
[[ -r $module_file ]] && source "$module_file"
done
unset module module_path
unset module module_file

# Machine-local override (gitignored). Sourced last so it can override
# anything above.
Expand Down
24 changes: 22 additions & 2 deletions shell/local.zsh.example
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,25 @@
# export SOMETHING=value

# --- Per-machine secrets ---
# Prefer 1Password CLI, AWS Secrets Manager, etc. over plaintext here.
# export GITHUB_TOKEN=...
# Never put plaintext secrets here. Prefer a secret manager (1Password CLI,
# AWS Secrets Manager, etc.) and load secrets lazily so they are fetched
# only when needed -- not on every shell startup.
#
# Example: load GITHUB_TOKEN from 1Password the first time you run `gh`.
# The token lives in 1Password (op://<vault>/<item>/<field>); it is cached
# in $GITHUB_TOKEN for the rest of the session after one fetch. Requires the
# 1Password CLI (`brew install 1password-cli`) with desktop-app integration.
#
# _OP_GITHUB_TOKEN_ACCOUNT="my.1password.com" # omit --account if single-account
# _OP_GITHUB_TOKEN_REF="op://Private/GitHub CLI token/credential"
#
# _load_github_token() {
# [[ -n $GITHUB_TOKEN ]] && return 0
# command -v op >/dev/null 2>&1 || { print -u2 "op (1Password CLI) not found"; return 1; }
# local _tok
# _tok="$(op read --account "$_OP_GITHUB_TOKEN_ACCOUNT" "$_OP_GITHUB_TOKEN_REF" 2>/dev/null)" \
# || { print -u2 "failed to read GITHUB_TOKEN from 1Password"; return 1; }
# export GITHUB_TOKEN="$_tok"
# }
#
# gh() { _load_github_token || return 1; command gh "$@"; }
38 changes: 35 additions & 3 deletions shell/prompt.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,18 @@ TRAPUSR1() {
dir=${content%%$'\t'*}
rendered=${content#*$'\t'}
if [[ $dir == $PWD ]]; then
_PROMPT_GIT_STATUS=$rendered
zle && zle reset-prompt
# Only redraw if the rendered status actually changed. zle
# reset-prompt has geometry quirks when the prompt wraps (long
# branch names in big repos), and the redraw can clobber the
# blank line above the prompt. Most consecutive commands in
# the same repo produce identical status -- skipping the
# redraw for those avoids the issue entirely. Only the first
# command after chpwd will trigger a redraw and possibly hit
# the glitch.
if [[ $_PROMPT_GIT_STATUS != $rendered ]]; then
_PROMPT_GIT_STATUS=$rendered
zle && zle reset-prompt
fi
else
# Result is for an old PWD; kick a fresh compute for the current dir.
_prompt_git_kick
Expand All @@ -156,6 +166,26 @@ autoload -Uz add-zsh-hook
add-zsh-hook precmd _prompt_git_kick
add-zsh-hook chpwd _prompt_git_chpwd

# Print a blank line before each prompt for visual separation between
# commands. This was previously done with a leading $'\n' inside PS1,
# but that put the recorded prompt-start position one line above the
# actual prompt content. Combined with Ghostty's OSC 133;A;cl=line
# fresh-line behavior, `zle reset-prompt` from TRAPUSR1 would clear
# into the previous command's output. Printing the blank line here,
# outside PS1, keeps the prompt-start position on the user-info line
# so reset-prompt can never touch the command output above.
_prompt_blank_line() { print; }
add-zsh-hook precmd _prompt_blank_line

# The default accept-line widget skips precmd when the buffer is
# empty, which means _prompt_blank_line above never runs for a bare
# Enter and there's no visual separation between successive prompts.
# Wrapping accept-line (even with a no-op body) forces the full
# command cycle including precmd, so _prompt_blank_line fires and we
# get the same blank line we get after a real command.
_prompt_accept_line() { zle .accept-line; }
zle -N accept-line _prompt_accept_line

# Backwards compat: anything else that calls prompt_git just gets the cached
# value. The PS1 below references $_PROMPT_GIT_STATUS directly.
function prompt_git() {
Expand All @@ -181,8 +211,10 @@ else
fi;

# Set the terminal title and prompt.
# The blank line above the prompt is printed by the _prompt_blank_line
# precmd hook above -- do NOT add a leading $'\n' to PS1 (see comment
# there for why).
PS1="${bold}";
PS1+=$'\n';
PS1+="${userStyle}%n"; # username
PS1+='${blue} (aws: $(aws_profile))';
PS1+="${white} at ";
Expand Down
Loading