aboutsummaryrefslogtreecommitdiff
path: root/linux/home/.config/zsh/user/prompt.zsh
diff options
context:
space:
mode:
authorsrdusr <trevorgray@srdusr.com>2025-09-24 00:51:52 +0200
committersrdusr <trevorgray@srdusr.com>2025-09-24 00:51:52 +0200
commit88370cd83f13c30d68119cbe3b229a1ab559cf55 (patch)
tree59697e6b3a229726ed1ee876b00d889ff7d0c38a /linux/home/.config/zsh/user/prompt.zsh
parenta70909b2057bf8d5923241d53e8ef3daef328458 (diff)
downloaddotfiles-88370cd83f13c30d68119cbe3b229a1ab559cf55.tar.gz
dotfiles-88370cd83f13c30d68119cbe3b229a1ab559cf55.zip
Zsh config changes
Diffstat (limited to 'linux/home/.config/zsh/user/prompt.zsh')
-rw-r--r--linux/home/.config/zsh/user/prompt.zsh678
1 files changed, 0 insertions, 678 deletions
diff --git a/linux/home/.config/zsh/user/prompt.zsh b/linux/home/.config/zsh/user/prompt.zsh
deleted file mode 100644
index b8b1b97..0000000
--- a/linux/home/.config/zsh/user/prompt.zsh
+++ /dev/null
@@ -1,678 +0,0 @@
-#!/bin/zsh
-
-########## Prompt(s) ##########
-
-# Autoload necessary functions for vcs_info and coloring
-autoload -Uz vcs_info
-autoload -Uz add-zsh-hook
-autoload -U colors && colors
-
-# Enable prompt substitution
-setopt prompt_subst
-
-# Display git branch status and color
-precmd_vcs_info() { vcs_info }
-
-# Add vcs_info to precmd functions
-precmd_functions+=( precmd_vcs_info )
-
-# Manipulates cursor position: moves down by 2 lines, saves position, and restores cursor after an operation.
-terminfo_down_sc=$terminfo[cud1]$terminfo[cuu1]$terminfo[sc]$terminfo[cud1]
-
-# Track last executed command for exit code display
-typeset -g _last_executed_command=""
-typeset -g _cmd_start_time=0
-typeset -g _cmd_end_time=0
-typeset -g _cmd_duration=0
-typeset -g _spinner_idx=0
-typeset -ga _spinner_frames=('⣾' '⣽' '⣻' '⢿' '⡿' '⣟' '⣯' '⣷')
-typeset -g _cmd_is_running=0
-typeset -g _show_spinner=0
-typeset -g _SPINNER_DELAY=5 # Only show spinner after 5 seconds
-typeset -g _FINISHED_DELAY=10 # Only show finished message after 10 seconds
-
-# Register the ZLE widget for spinner updates - do this early
-zle -N update_spinner
-
-# Cache git information to avoid repeated expensive operations
-typeset -g _git_cached_info=""
-typeset -g _git_cache_timestamp=0
-typeset -g _git_cache_lifetime=2 # seconds before cache expires
-
-# Calculate how much space is available for the prompt components
-function available_space() {
- local width=${COLUMNS:-80}
- echo $width
-}
-
-# Check if we need to abbreviate git info
-function need_to_abbreviate_git() {
- local available=$(available_space)
- local vi_mode_len=13 # Length of "-- INSERT --"
- local prompt_base_len=20 # Base prompt elements length
- local path_len=${#${PWD/#$HOME/\~}}
- local git_full_len=0
-
- # Try to estimate git info length if available
- if git rev-parse --is-inside-work-tree &>/dev/null; then
- local branch=$(git symbolic-ref --short HEAD 2>/dev/null)
- git_full_len=${#branch}
-
- # Add length for status indicators
- if [[ -n "$(git status --porcelain)" ]]; then
- # Rough estimate for status text
- git_full_len=$((git_full_len + 20))
- fi
- fi
-
- # Calculate total space needed
- local total_needed=$((vi_mode_len + prompt_base_len + path_len + git_full_len))
-
- # Determine if we need to abbreviate
- if [[ $total_needed -gt $available ]]; then
- return 0 # Need to abbreviate
- else
- return 1 # Don't need to abbreviate
- fi
-}
-
-# Custom git branch coloring based on status
-git_branch_test_color() {
- local now=$(date +%s)
- local cache_age=$((now - _git_cache_timestamp))
-
- # Use cached value if available and not expired
- if [[ -n "$_git_cached_info" && $cache_age -lt $_git_cache_lifetime ]]; then
- echo "$_git_cached_info"
- return
- fi
-
- local ref=$(git symbolic-ref --short HEAD 2> /dev/null)
- if [ -n "${ref}" ]; then
- if [ -n "$(git status --porcelain)" ]; then
- local gitstatuscolor='%F{green}'
- else
- local gitstatuscolor='%F{82}'
- fi
- _git_cached_info="${gitstatuscolor}${ref}"
- _git_cache_timestamp=$now
- echo "$_git_cached_info"
- else
- _git_cached_info=""
- _git_cache_timestamp=$now
- echo ""
- fi
-}
-
-# Git branch with dynamic abbreviation
-git_branch_dynamic() {
- local now=$(date +%s)
- local cache_age=$((now - _git_cache_timestamp))
-
- # Only query git if cache is expired
- if [[ $cache_age -ge $_git_cache_lifetime ]]; then
- local ref=$(git symbolic-ref --short HEAD 2> /dev/null)
- if [ -n "${ref}" ]; then
- if need_to_abbreviate_git; then
- # Abbreviated version for small terminals
- case "${ref}" in
- "main") _git_cached_info="m" ;;
- "master") _git_cached_info="m" ;;
- "development") _git_cached_info="d" ;;
- "develop") _git_cached_info="d" ;;
- "feature/"*) _git_cached_info="f/${ref#feature/}" | cut -c 1-4 ;;
- "release/"*) _git_cached_info="r/${ref#release/}" | cut -c 1-4 ;;
- "hotfix/"*) _git_cached_info="h/${ref#hotfix/}" | cut -c 1-4 ;;
- *) _git_cached_info="${ref}" | cut -c 1-5 ;; # Truncate to first 5 chars for other branches
- esac
- else
- # Full branch name when there's room
- _git_cached_info="${ref}"
- fi
- _git_cache_timestamp=$now
- echo "$_git_cached_info"
- else
- _git_cached_info=""
- _git_cache_timestamp=$now
- echo ""
- fi
- else
- echo "$_git_cached_info"
- fi
-}
-
-# VCS info styles (e.g., git)
-zstyle ':vcs_info:*' check-for-changes true
-zstyle ':vcs_info:*' enable git
-
-# Dynamically configure vcs_info formats based on available space
-function configure_vcs_styles() {
- if need_to_abbreviate_git; then
- # Abbreviated versions
- zstyle ':vcs_info:*' stagedstr ' +%F{15}s%f'
- zstyle ':vcs_info:*' unstagedstr ' -%F{15}u%f'
- else
- # Full versions
- zstyle ':vcs_info:*' stagedstr ' +%F{15}staged%f'
- zstyle ':vcs_info:*' unstagedstr ' -%F{15}unstaged%f'
- fi
-
- zstyle ':vcs_info:*' actionformats '%F{5}%F{2}%b%F{3}|%F{1}%a%F{5}%f '
- zstyle ':vcs_info:*' formats '%F{208} '$'\uE0A0'' %f$(git_branch_test_color)%f%F{76}%c%F{3}%u%f '
- zstyle ':vcs_info:git*+set-message:*' hooks git-untracked git-dynamic
-}
-
-# Show "untracked" status in git - with conditional abbreviation
-+vi-git-untracked() {
- if [[ $(git rev-parse --is-inside-work-tree 2> /dev/null) == 'true' ]] && \
- git status --porcelain | grep '??' &> /dev/null ; then
-
- if need_to_abbreviate_git; then
- hook_com[unstaged]+='%F{196} !%f%F{15}u%f'
- else
- hook_com[unstaged]+='%F{196} !%f%F{15}untracked%f'
- fi
- fi
-}
-
-# Dynamic git branch hook
-+vi-git-dynamic() {
- hook_com[branch]=$(git_branch_dynamic)
-}
-
-# SSH info with conditional abbreviation
-ssh_name() {
- if [[ -n $SSH_CONNECTION ]]; then
- local ssh_info
-
- if need_to_abbreviate_git; then
- # Abbreviated SSH info
- ssh_info="ssh:%F{green}%n$nc%f"
- else
- ssh_info="ssh:%F{green}%n$nc%f"
- if [[ -n $SSH_CONNECTION ]]; then
- local ip_address
- ip_address=$(echo $SSH_CONNECTION | awk '{print $3}')
- ssh_info="$ssh_info@%F{green}$ip_address%f"
- fi
- fi
- echo " ${ssh_info}"
- fi
-}
-
-# Job names (for job control) with conditional abbreviation
-function job_name() {
- job_name=""
- job_length=0
- local available=$(available_space)
-
- # Only show jobs if we have reasonable space
- if [ "${available}" -gt 60 ]; then
- local job_count=$(jobs | wc -l)
- if [ "${job_count}" -gt 0 ]; then
- if need_to_abbreviate_git; then
- job_name+="%F{green}j:${job_count}%f"
- else
- local title_jobs="jobs:"
- job_name="${title_jobs}"
- job_length=$((${available}-70))
- [ "${job_length}" -lt "0" ] && job_length=0
-
- if [ "${job_length}" -gt 0 ]; then
- job_name+="%F{green}$(jobs | grep + | tr -s " " | cut -d " " -f 4- | cut -b 1-${job_length} | sed "s/\(.*\)/\1/")%f"
- else
- job_name+="%F{green}${job_count}%f"
- fi
- fi
- fi
- fi
-
- echo "${job_name}"
-}
-
-# Check if we should show the spinner based on elapsed time
-function should_show_spinner() {
- if [[ $_cmd_is_running -eq 1 ]]; then
- local current_time=$(date +%s)
- local elapsed=$((current_time - _cmd_start_time))
-
- # Show spinner only after delay threshold
- if [[ $elapsed -ge $_SPINNER_DELAY ]]; then
- _show_spinner=1
- return 0 # Yes, show spinner
- fi
- fi
-
- _show_spinner=0
- return 1 # No, don't show spinner
-}
-
-# Update spinner animation - simplified version
-function update_spinner() {
- # This function is now just a ZLE widget placeholder
- # The actual spinner updates happen in the TRAPALRM handler
- :
-}
-
-# Start spinner timer when command runs longer than threshold
-function start_spinner_timer() {
- _spinner_idx=0
- _cmd_is_running=1
- _show_spinner=0 # Start with spinner hidden until delay passes
-
- # Set up the TRAPALRM for periodic updates - CRITICAL FIX
- TMOUT=0.5 # Update spinner every 0.5 seconds
-
- # Define TRAPALRM function - this is key to the spinner working
- TRAPALRM() {
- if [[ $_cmd_is_running -eq 1 ]]; then
- local current_time=$(date +%s)
- local elapsed=$((current_time - _cmd_start_time))
-
- # Show spinner only after delay threshold
- if [[ $elapsed -ge $_SPINNER_DELAY ]]; then
- _show_spinner=1
- _spinner_idx=$(( (_spinner_idx + 1) % ${#_spinner_frames[@]} ))
-
- # Force prompt refresh - critical for updating the spinner
- if [[ -o zle ]]; then
- zle reset-prompt 2>/dev/null || true
- zle -R
- fi
- fi
- fi
- }
-}
-
-# Stop spinner when command finishes
-function stop_spinner_timer() {
- _cmd_is_running=0
- _show_spinner=0
-
- # Disable the alarm trap and timer
- TRAPALRM() { : }
- TMOUT=0
-
- # Force prompt refresh to clear spinner
- if [[ -o zle ]]; then
- zle reset-prompt 2>/dev/null || true
- zle -R
- fi
-}
-
-# Format time in a human-readable way
-function format_time() {
- local seconds=$1
- local result=""
-
- # Format time as hours:minutes:seconds for long durations
- if [[ $seconds -ge 3600 ]]; then
- local hours=$((seconds / 3600))
- local minutes=$(( (seconds % 3600) / 60 ))
- local secs=$((seconds % 60))
- result="${hours}h${minutes}m${secs}s"
- elif [[ $seconds -ge 60 ]]; then
- local minutes=$((seconds / 60))
- local secs=$((seconds % 60))
- result="${minutes}m${secs}s"
- else
- result="${seconds}s"
- fi
-
- echo "$result"
-}
-
-# Error code display for RPROMPT with spinner - fixed version
-function exit_code_info() {
- local exit_code=$?
-
- # If a command is running and we should show spinner
- if [[ $_cmd_is_running -eq 1 && $_show_spinner -eq 1 ]]; then
- local spinner=${_spinner_frames[$_spinner_idx]}
- local current_time=$(date +%s)
- local elapsed=$((current_time - _cmd_start_time))
- echo "%F{yellow}${spinner} ${elapsed}s%f"
- return
- fi
-
- # Don't show error code when line editor is active (user is typing)
- if [[ -o zle ]]; then
- echo ""
- return
- fi
-
- # Show command finished message for completed commands that took longer than threshold
- if [[ -n "$_last_executed_command" && $_cmd_duration -ge $_FINISHED_DELAY ]]; then
- local duration_formatted=$(format_time $_cmd_duration)
-
- # Show error code along with finished message if there was an error
- if [[ $exit_code -ne 0 ]]; then
- # Show TSTP (148) as a suspension indicator instead of error
- if [[ $exit_code -eq 148 ]]; then
- echo "%F{cyan}finished ${duration_formatted}%f %F{yellow}⏸ TSTP%f"
- return
- fi
-
- local signal_name=""
- # Check if it's a signal
- if [[ $exit_code -gt 128 && $exit_code -le 165 ]]; then
- local signal_num=$((exit_code - 128))
- signal_name=$(kill -l $signal_num 2>/dev/null)
- if [[ -n "$signal_name" ]]; then
- signal_name=" ($signal_name)"
- fi
- fi
-
- # Return formatted error code with finished message
- echo "%F{cyan}finished ${duration_formatted}%f %F{red}✘ $exit_code$signal_name%f"
- else
- echo "%F{cyan}finished ${duration_formatted}%f %F{green}✓%f"
- fi
- return
- fi
-
- # Don't show anything for exit code 0 (success) if this is first command
- if [[ -z "$_last_executed_command" && $exit_code -eq 0 ]]; then
- echo ""
- return
- fi
-
- # Show TSTP (148) as a suspension indicator instead of error
- if [[ $exit_code -eq 148 ]]; then
- echo "%F{yellow}⏸ TSTP%f"
- return
- fi
-
- if [[ $exit_code -ne 0 ]]; then
- local signal_name=""
-
- # Check if it's a signal
- if [[ $exit_code -gt 128 && $exit_code -le 165 ]]; then
- local signal_num=$((exit_code - 128))
- signal_name=$(kill -l $signal_num 2>/dev/null)
- if [[ -n "$signal_name" ]]; then
- signal_name=" ($signal_name)"
- fi
- fi
-
- # Return formatted error code
- echo "%F{red}✘ $exit_code$signal_name%f"
- else
- echo "%F{green}✓%f" # Success indicator
- fi
-}
-
-abbreviated_path() {
- local full_path="${PWD/#$HOME/~}" # Replace $HOME with ~
- local available=$(available_space)
-
- # If path is root
- if [[ "$full_path" == "/" ]]; then
- echo "%F{4}/%f"
- return
- fi
-
- # If path is just ~
- if [[ "$full_path" == "~" ]]; then
- echo "%F{4}~%f"
- return
- fi
-
- # If extremely small terminal, show nothing to avoid breaking prompt
- if (( available < 20 )); then
- echo ""
- return
- fi
-
- # For very narrow terminals, just show the current dir
- if (( available < 30 )); then
- echo "%F{4}%1~%f"
- return
- fi
-
- # For moderately narrow terminals, show last two components
- if (( available < 40 )); then
- echo "%F{4}%2~%f"
- return
- fi
-
- # For wide terminals, show full path
- if (( available > 70 )); then
- echo "%F{4}${full_path}%f"
- return
- fi
-
- # Otherwise, show abbreviated path (e.g. ~/d/p/n)
- local parts=("${(s:/:)full_path}")
- local result=""
- local last_index=${#parts[@]}
-
- for i in {1..$((last_index - 1))}; do
- [[ -n ${parts[i]} ]] && result+="/${parts[i]:0:1}"
- done
-
- result+="/${parts[last_index]}"
- echo "%F{4}${result}%f"
-}
-
-
-# Prompt variables
-user="%n"
-at="%F{15}at%{$reset_color%}"
-machine="%F{4}%m%{$reset_color%}"
-relative_home="%F{4}%~%{$reset_color%}"
-carriage_return=""$'\n'""
-empty_line_bottom=""
-chevron_right=""
-color_reset="%{$(tput sgr0)%}"
-color_yellow="%{$(tput setaf 226)%}"
-color_blink="%{$(tput blink)%}"
-prompt_symbol="$"
-dollar_sign="${color_yellow}${color_blink}${prompt_symbol}${color_reset}"
-dollar="%(?:%F{2}${dollar_sign}:%F{1}${dollar_sign})"
-space=" "
-#thin_space=$'\u2009'
-thin_space=$'\u202F'
-cmd_prompt="%(?:%F{2}${chevron_right} :%F{1}${chevron_right} )"
-git_info="\$vcs_info_msg_0_"
-v1="%{┌─[%}"
-v2="%{]%}"
-v3="└─["
-v4="]"
-newline=$'\n'
-
-# Indicate INSERT mode for vi - NEVER truncate this
-function insert-mode () {
- echo "-- INSERT --"
-}
-
-# Indicate NORMAL mode for vi - NEVER truncate this
-function normal-mode () {
- echo "-- NORMAL --"
-}
-
-# Vi mode indicator
-vi-mode-indicator () {
- if [[ ${KEYMAP} == vicmd || ${KEYMAP} == vi-cmd-mode ]]; then
- echo -ne '\e[1 q'
- vi_mode=$(normal-mode)
- elif [[ ${KEYMAP} == main || ${KEYMAP} == viins || ${KEYMAP} == '' ]]; then
- echo -ne '\e[5 q'
- vi_mode=$(insert-mode)
- fi
-}
-
-# Prompt function to ensure the prompt stays on one line, even in narrow terminals
-function set-prompt() {
- vi-mode-indicator
- configure_vcs_styles # Dynamically set vcs styles based on available space
- vcs_info # Refresh vcs info with new styles
-
- local available=$(available_space)
- if (( available < 14 )); then
- # Extremely narrow terminal — use minimal prompt
- PS1="${carriage_return}${dollar}${space}${empty_line_bottom}"
- #RPROMPT='$(exit_code_info)'
-
- else
- # Path display - always show something for path, but adapt based on space
- local path_display="$(abbreviated_path)"
-
- # Git info - omit entirely if not enough space
- local gitinfo=""
- if [[ $available -gt 40 ]]; then
- gitinfo="${vcs_info_msg_0_}"
- fi
-
- # Jobs info
- local jobs=" $(job_name)"
-
- # SSH info
- local sshinfo="$(ssh_name)"
-
- # Vi mode is priority 1 - ALWAYS show it
- mode="%F{145}%{$terminfo_down_sc$vi_mode$terminfo[rc]%f%}"
-
- # Right prompt for error codes or spinner
- #RPROMPT='$(exit_code_info)'
-
- PS1="${newline}${v1}${user}${v2} ${path_display}${gitinfo}${jobs}${sshinfo}${carriage_return}${mode}${v3}${dollar}${v4}${empty_line_bottom}"
- fi
-}
-
-# Pre-command hook to set prompt
-my_precmd() {
- # Calculate command duration if a command was run
- if [[ -n "$_last_executed_command" && $_cmd_start_time -gt 0 ]]; then
- _cmd_end_time=$(date +%s)
- _cmd_duration=$((_cmd_end_time - _cmd_start_time))
- else
- _cmd_duration=0
- fi
-
- stop_spinner_timer # Make sure spinner is stopped
- vcs_info
- set-prompt
- vi-mode-indicator
-}
-add-zsh-hook precmd my_precmd
-
-# Update mode file based on current mode
-update-mode-file() {
- set-prompt
- local current_mode=$(cat ~/.vi-mode 2>/dev/null || echo "")
- local new_mode="$vi_mode"
-
- if [[ "$new_mode" != "$current_mode" ]]; then
- echo "$new_mode" >| ~/.vi-mode
- fi
-
- # Ensure we're in an interactive shell and ZLE is active
- if [[ -o zle ]] && zle -l &>/dev/null; then
- zle reset-prompt 2>/dev/null || true
- else
- # If ZLE is not active, fallback and print the prompt manually
- set-prompt
- print -Pn "$PS1"
- fi
-
- # Refresh tmux client if tmux is running
- if command -v tmux &>/dev/null && [[ -n "$TMUX" ]]; then
- tmux refresh-client -S
- fi
-}
-
-# Check if nvim is running and update mode
-function check-nvim-running() {
- if pgrep -x "nvim" > /dev/null; then
- vi_mode=""
- update-mode-file
- if command -v tmux &>/dev/null && [[ -n "$TMUX" ]]; then
- tmux refresh-client -S
- fi
- else
- if [[ ${KEYMAP} == vicmd || ${KEYMAP} == vi-cmd-mode ]]; then
- vi_mode=$(normal-mode)
- elif [[ ${KEYMAP} == main || ${KEYMAP} == viins || ${KEYMAP} == '' ]]; then
- vi_mode=$(insert-mode)
- fi
- update-mode-file
- if command -v tmux &>/dev/null && [[ -n "$TMUX" ]]; then
- tmux refresh-client -S
- fi
- fi
-}
-
-# ZLE line initialization hook
-function zle-line-init() {
- zle reset-prompt
- vi-mode-indicator
- case "${KEYMAP}" in
- vicmd)
- echo -ne '\e[1 q'
- ;;
- main|viins|*)
- echo -ne '\e[5 q'
- ;;
- esac
-}
-
-# ZLE keymap select hook
-function zle-keymap-select() {
- update-mode-file
- zle reset-prompt
- zle -R
- vi-mode-indicator
- case "${KEYMAP}" in
- vicmd)
- echo -ne '\e[1 q'
- ;;
- main|viins|*)
- echo -ne '\e[5 q'
- ;;
- esac
-}
-
-# Safer version of zle reset-prompt
-function safe_reset_prompt() {
- # Only reset if ZLE is active
- if [[ -o zle ]] && zle -l &>/dev/null; then
- zle reset-prompt 2>/dev/null || true
- fi
-}
-
-# Preexec hook for command execution - NO BACKGROUND JOBS VERSION
-function preexec() {
- # Store the command being executed
- _last_executed_command=$1
- _cmd_start_time=$(date +%s)
- _cmd_is_running=1
- _show_spinner=0 # Reset spinner flag
-
- # Start the spinner timer immediately
- start_spinner_timer
-
- print -rn -- $terminfo[el]
- echo -ne '\e[5 q'
- vi-mode-indicator
-}
-
-# Terminal resizing: resets the prompt if ZLE is active, updates the mode file.
-TRAPWINCH() {
- if [[ -o zle ]] && zle -l &>/dev/null; then
- zle -R
- zle reset-prompt 2>/dev/null || true
- fi
- update-mode-file 2>/dev/null
-}
-
-# Register ZLE hooks
-zle -N zle-line-init
-zle -N zle-keymap-select
-zle -N update_spinner
-
-# Register hooks
-add-zsh-hook preexec preexec
-add-zsh-hook precmd my_precmd
-
-set-prompt