dotfiles

My dotfiles and configs
git clone https://git.dasho.dev/dotfiles.git
Log | Files | Refs | README

zshrc (11548B)


      1 # direnv integration (must be in interactive shells)
      2 if command -v direnv >/dev/null 2>&1; then
      3  eval "$(direnv hook zsh)"
      4 fi
      5 
      6 # Secret helpers
      7 if [[ -f "$HOME/.dotfiles/zsh/secrets.zsh" ]]; then
      8  source "$HOME/.dotfiles/zsh/secrets.zsh"
      9 fi
     10 
     11 # -----------------------------------------------------------------------------
     12 # commit: guided conventional commits with emojis via gum
     13 #
     14 # Usage:
     15 #   commit            # normal
     16 #   commit dotfiles   # prefixes subject with "[dotfiles] "
     17 #
     18 # Flow:
     19 #   - Choose type (emoji+type)
     20 #   - Choose scope (defaults or "other..." -> input)
     21 #   - Enter subject
     22 #   - Optional body (multiline)
     23 #   - Show status + diffstat + message preview
     24 #   - Confirm: run git commit
     25 #     If cancelled: copy the git commit command to clipboard
     26 # -----------------------------------------------------------------------------
     27 
     28 commit() {
     29  emulate -L zsh
     30  setopt localoptions pipefail
     31 
     32  command -v git >/dev/null 2>&1 || { echo "Missing: git" >&2; return 1; }
     33  command -v gum >/dev/null 2>&1 || { echo "Missing: gum" >&2; return 1; }
     34 
     35  git rev-parse --is-inside-work-tree >/dev/null 2>&1 || {
     36    echo "Not inside a git repository." >&2
     37    return 1
     38  }
     39 
     40  # Ensure there is something to commit
     41  if git diff --quiet && git diff --cached --quiet; then
     42    echo "No changes to commit." >&2
     43    return 1
     44  fi
     45 
     46  # Stage if needed
     47  if git diff --cached --quiet; then
     48    if gum confirm "No staged changes. Stage interactively (git add -p)?" ; then
     49      git add -p || return 1
     50      git diff --cached --quiet && { echo "Still nothing staged." >&2; return 1; }
     51    else
     52      echo "Aborted (nothing staged)." >&2
     53      return 1
     54    fi
     55  fi
     56 
     57  local project="${1:-}"
     58  local prefix=""
     59  [[ -n "$project" ]] && prefix="[$project] "
     60 
     61  # Types with emojis
     62  local -a types
     63  types=(
     64    "๐Ÿš€ feat"
     65    "๐Ÿ› fix"
     66    "๐Ÿ“ docs"
     67    "๐ŸŽจ style"
     68    "โ™ป๏ธ  refactor"
     69    "โœ… test"
     70    "๐Ÿ—๏ธ  build"
     71    "๐Ÿงน chore"
     72    "โช revert"
     73  )
     74 
     75  local type_choice emoji type
     76  type_choice="$(gum choose --header="Select commit type" "${types[@]}")" || return 1
     77  emoji="${type_choice%% *}"
     78  type="${type_choice#* }"
     79 
     80  # Scope (defaults + other)
     81  local -a scopes
     82  scopes=(api cli auth other...)
     83 
     84  local scope_choice scope
     85  scope_choice="$(gum choose --header="Select scope" "${scopes[@]}")" || return 1
     86  if [[ "$scope_choice" == "other..." ]]; then
     87    scope="$(gum input --prompt "scope: " --placeholder "e.g. infra, deps, ui")" || return 1
     88  else
     89    scope="$scope_choice"
     90  fi
     91 
     92  scope="${scope// /-}"
     93  scope="${scope//[^A-Za-z0-9_.-]/-}"
     94  [[ -z "$scope" ]] && scope="misc"
     95 
     96  # Subject (manual validation loop; compatible with older gum)
     97  local subject
     98  while true; do
     99    subject="$(gum input --prompt "subject: " --placeholder "short, imperative (<= 72 chars)")" || return 1
    100 
    101    # trim leading/trailing whitespace
    102    subject="${subject#"${subject%%[![:space:]]*}"}"
    103    subject="${subject%"${subject##*[![:space:]]}"}"
    104 
    105    if [[ -z "$subject" ]]; then
    106      gum style --border normal --padding "1" "Subject cannot be empty." >/dev/null
    107      continue
    108    fi
    109    if (( ${#subject} > 72 )); then
    110      gum style --border normal --padding "1" "Subject too long (${#subject}/72). Shorten it." >/dev/null
    111      continue
    112    fi
    113    break
    114  done
    115 
    116  # Optional body
    117  local body=""
    118  if gum confirm "Add body (multiline)?" ; then
    119    body="$(gum write --prompt "body: " --placeholder "Optional. Explain what/why.")" || return 1
    120    [[ -n "${body//[[:space:]]/}" ]] || body=""
    121  fi
    122 
    123  local subject_line="${prefix}${emoji} ${type}(${scope}): ${subject}"
    124 
    125  # Previews
    126  local status_summary diffstat
    127  status_summary="$(git status --porcelain=v1 2>/dev/null | sed -e 's/^/  /')"
    128  diffstat="$(git diff --cached --stat 2>/dev/null | sed -e 's/^/  /')"
    129 
    130  # Build safe clipboard command string
    131  local -a cmd
    132  cmd=(git commit -m "$subject_line")
    133  [[ -n "$body" ]] && cmd+=(-m "$body")
    134 
    135  local cmd_str="" arg
    136  for arg in "${cmd[@]}"; do
    137    cmd_str+="${(q)arg} "
    138  done
    139  cmd_str="${cmd_str% }"
    140 
    141  # Show summary + message preview
    142  {
    143    echo "Staged changes (status):"
    144    echo "${status_summary:-  (none)}"
    145    echo ""
    146    echo "Diffstat:"
    147    echo "${diffstat:-  (none)}"
    148    echo ""
    149    echo "Commit message preview:"
    150    echo "  $subject_line"
    151    if [[ -n "$body" ]]; then
    152      echo ""
    153      echo "  ---"
    154      echo "$body" | sed -e 's/^/  /'
    155    fi
    156  } | gum style --border normal --padding "1" --margin "1" >/dev/null
    157 
    158  if gum confirm "Run commit now?" ; then
    159    if [[ -n "$body" ]]; then
    160      git commit -m "$subject_line" -m "$body"
    161    else
    162      git commit -m "$subject_line"
    163    fi
    164    return $?
    165  fi
    166 
    167  # Cancel -> copy command
    168  if command -v pbcopy >/dev/null 2>&1; then
    169    print -r -- "$cmd_str" | pbcopy
    170    echo "Cancelled. Copied command to clipboard."
    171  elif command -v wl-copy >/dev/null 2>&1; then
    172    print -r -- "$cmd_str" | wl-copy
    173    echo "Cancelled. Copied command to clipboard."
    174  elif command -v xclip >/dev/null 2>&1; then
    175    print -r -- "$cmd_str" | xclip -selection clipboard
    176    echo "Cancelled. Copied command to clipboard."
    177  else
    178    echo "Cancelled. Clipboard tool not found. Here is the command:"
    179    echo "$cmd_str"
    180  fi
    181 }
    182 
    183 # Path to your Oh My Zsh installation.
    184 export ZSH_DISABLE_COMPFIX=true
    185 export ZSH="$HOME/.oh-my-zsh"
    186 eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
    187 #Set name of the theme to load --- if set to "random", it will
    188 # load a random theme each time Oh My Zsh is loaded, in which case,
    189 # to know which specific one was loaded, run: echo $RANDOM_THEME
    190 # See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
    191 ZSH_THEME="robbyrussell"
    192 
    193 # Uncomment one of the following lines to change the auto-update behavior
    194 # zstyle ':omz:update' mode disabled  # disable automatic updates
    195 # zstyle ':omz:update' mode auto      # update automatically without asking
    196 zstyle ':omz:update' mode reminder  # just remind me to update when it's time
    197 
    198 # Uncomment the following line to change how often to auto-update (in days).
    199 zstyle ':omz:update' frequency 1
    200 
    201 # Uncomment the following line if pasting URLs and other text is messed up.
    202 # DISABLE_MAGIC_FUNCTIONS="true"
    203 
    204 # Uncomment the following line to disable colors in ls.
    205 # DISABLE_LS_COLORS="true"
    206 
    207 # Uncomment the following line to disable auto-setting terminal title.
    208 # DISABLE_AUTO_TITLE="true"
    209 
    210 # Uncomment the following line to enable command auto-correction.
    211 # ENABLE_CORRECTION="true"
    212 
    213 # Uncomment the following line to display red dots whilst waiting for completion.
    214 # You can also set it to another string to have that shown instead of the default red dots.
    215 COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f"
    216 # Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765)
    217 # COMPLETION_WAITING_DOTS="true"
    218 
    219 # Uncomment the following line if you want to disable marking untracked files
    220 # under VCS as dirty. This makes repository status check for large repositories
    221 # much, much faster.
    222 # DISABLE_UNTRACKED_FILES_DIRTY="true"
    223 
    224 # Uncomment the following line if you want to change the command execution time
    225 # stamp shown in the history command output.
    226 # You can set one of the optional three formats:
    227 # "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
    228 # or set a custom format using the strftime function format specifications,
    229 # see 'man strftime' for details.
    230 # HIST_STAMPS="mm/dd/yyyy"
    231 
    232 # Would you like to use another custom folder than $ZSH/custom?
    233 # ZSH_CUSTOM=/path/to/new-custom-folder
    234 
    235 # Which plugins would you like to load?
    236 # Standard plugins can be found in $ZSH/plugins/
    237 # Custom plugins may be added to $ZSH_CUSTOM/plugins/
    238 # Example format: plugins=(rails git textmate ruby lighthouse)
    239 # Add wisely, as too many plugins slow down shell startup.
    240 plugins=(fzf zsh-vi-mode git)
    241 
    242 source $ZSH/oh-my-zsh.sh
    243 
    244 # User configuration
    245 
    246 # export MANPATH="/usr/local/man:$MANPATH"
    247 
    248 # You may need to manually set your language environment
    249 # export LANG=en_US.UTF-8
    250 
    251 # Preferred editor for local and remote sessions
    252 # if [[ -n $SSH_CONNECTION ]]; then
    253 #   export EDITOR='vim'
    254 # else
    255 #   export EDITOR='nvim'
    256 # fi
    257 
    258 # Compilation flags
    259 # export ARCHFLAGS="-arch $(uname -m)"
    260 
    261 # Set personal aliases, overriding those provided by Oh My Zsh libs,
    262 # plugins, and themes. Aliases can be placed here, though Oh My Zsh
    263 # users are encouraged to define aliases within a top-level file in
    264 # the $ZSH_CUSTOM folder, with .zsh extension. Examples:
    265 # - $ZSH_CUSTOM/aliases.zsh
    266 # - $ZSH_CUSTOM/macos.zsh
    267 # For a full list of active aliases, run `alias`.
    268 #
    269 # Example aliases
    270 # alias zshconfig="mate ~/.zshrc"
    271 # alias ohmyzsh="mate ~/.oh-my-zsh"
    272 autoload -U compinit; compinit
    273 eval "$(zoxide init zsh)"
    274 
    275 export EDITOR='nvim'
    276 # Aliases
    277 ## -- File Navigation --
    278 alias cd="z"
    279 alias ci="zi"
    280 alias ls="eza --icons"
    281 
    282 ## -- Applications --
    283 alias e="nvim"
    284 alias dotedit="chezmoi edit"
    285 alias dotfiles="chezmoi"
    286 alias py="python3"
    287 alias ipy="ipython3"
    288 alias ..="cd .."
    289 alias ...="cd ../.."
    290 
    291 alias bhcli="/home/dasho/dev/bhcli-new/target/release/bhcli --refresh-rate 2 --url http://blkhatjxlrvc5aevqzz5t6kxldayog6jlx5h7glnu44euzongl4fh5ad.onion --page-php chat.php -m"
    292 alias bhcli2="/home/dasho/dev/bhcli-new/target/release/bhcli --refresh-rate 2 --url http://blkh4ylofapg42tj6ht565klld5i42dhjtysvsnnswte4xt4uvnfj5qd.onion --page-php index.php -m"
    293 alias 404="/home/dasho/dev/bhcli-new/target/release/bhcli --refresh-rate 2 --url https://4-0-4.io/chat/min"
    294 alias 404tor="/home/dasho/dev/bhcli-new/target/release/bhcli --refresh-rate 2 --url http://4o4o4hn4hsujpnbsso7tqigujuokafxys62thulbk2k3mf46vq22qfqd.onion/chat/min"
    295 alias tb="cd /home/dasho/Downloads/tor-browser && ./start-tor-browser.desktop"
    296 
    297 alias slides="presenterm"
    298 
    299 alias -s md="glow"
    300 alias -s py="$EDITOR"
    301 alias -s txt="bat"
    302 alias -s log="bat"
    303 alias -s json="bat"
    304 alias -s xml="bat"
    305 alias -s csv="bat"
    306 alias -s yml="$EDITOR"
    307 alias -s yaml="$EDITOR"
    308 alias -s html="$EDITOR"
    309 alias -s js="$EDITOR"
    310 alias -s css="$EDITOR"
    311 # alias -s sh="$EDITOR"
    312 # alias -s zsh="$EDITOR"
    313 alias -s conf="bat"
    314 alias -s toml="bat"
    315 alias -s rs="$EDITOR"
    316 alias -s go="$EDITOR"
    317 alias -s c="$EDITOR"
    318 alias -s cpp="$EDITOR"
    319 alias -s h="$EDITOR"
    320 alias -s hpp="$EDITOR"
    321 alias -s mov="open"
    322 alias -s mp4="open"
    323 alias -s mkv="open"
    324 alias -s jpg="open"
    325 alias -s png="open"
    326 alias -s gif="open"
    327 
    328 alias -g NE="2>/dev/null"
    329 alias -g ND=">/dev/null"
    330 alias -g NULL=">/dev/null 2>1"
    331 alias -g F="| fzf"
    332 alias -g T="| tail"
    333 alias -g JQ="| jq"
    334 alias -g G="| grep"
    335 alias -g L="| less"
    336 alias -g H="| head"
    337 
    338 # Source and export variables from ~/.env
    339 if [ -f ~/.env ]; then
    340    set -a
    341    source ~/.env
    342    set +a
    343 fi
    344 
    345 # Add custom bin directories to PATH, starting with Gobin, then Emacs, Cargo, local bin, and finally Homebrew
    346 export PATH="$HOME/go/bin:$PATH"
    347 export PATH="$HOME/.config/emacs/bin:$PATH"
    348 export PATH="$HOME/.cargo/bin:$PATH"
    349 export PATH="$HOME/.local/bin:$PATH"
    350 export PATH="/home/linuxbrew/.linuxbrew/bin:$PATH"
    351 
    352 chpwd() {
    353    ls
    354 }
    355 
    356 clear_buffer_screen() {
    357  zle clear-screen
    358 }
    359 zle -N clear_buffer_screen
    360 bindkey '^Xl' clear_buffer_screen
    361 
    362 # --- Auto-start Zellij for interactive shells ---
    363 # if [[ -o interactive ]] && [[ -z "$ZELLIJ" ]] && command -v zellij >/dev/null 2>&1; then
    364  # Attach to "main" if it exists, otherwise create it
    365  # exec zellij attach --create main
    366 # fi
    367 # --- End Auto-start Zellij ---
    368 
    369 # Carapace setup
    370 autoload -U compinit && compinit
    371 export CARAPACE_BRIDGES='zsh,fish,bash,inshellisense' # optional
    372 zstyle ':completion:*' format $'\e[2;37mCompleting %d\e[m'
    373 source <(carapace _carapace)
    374 
    375 # OpenClaw Completion
    376 # source <(openclaw completion --shell zsh)