alias prompt "$SCR/helpers/prompt.py" function pcolor --description 'Colorize text using the repository prompt helper' "$SCR/helpers/prompt.py" (string join ' ' -- $argv) color end function prompt-reset --description 'Reset fish prompt state used by this rc' set -g __fishrc_proxy_segment '' git-id-prompt end function __fishrc_github_owner_from_url --description 'Print GitHub owner from a remote URL' set -l url $argv[1] test -n "$url"; or return 1 set -l owner (string replace -r '^https?://[^/]+/([^/]+)/.*$' '$1' -- "$url") if test "$owner" != "$url" printf '%s\n' "$owner" return 0 end set owner (string replace -r '^ssh://[^@]+@[^/]+/([^/]+)/.*$' '$1' -- "$url") if test "$owner" != "$url" printf '%s\n' "$owner" return 0 end set owner (string replace -r '^[^@]+@[^:]+:([^/]+)/.*$' '$1' -- "$url") if test "$owner" != "$url" printf '%s\n' "$owner" return 0 end return 1 end function __fishrc_git_remote_url --description 'Print a git remote URL from a remote name or URL' set -l remote $argv[1] test -n "$remote"; or return 1 if string match -qr '://|^[^@]+@[^:]+:' -- "$remote" printf '%s\n' "$remote" else command git remote get-url "$remote" 2>/dev/null end end function __fishrc_prompt_pr_by_head --description 'Print PR number and state for an exact GitHub head owner and branch' set -l head_owner $argv[1] set -l head_branch $argv[2] test -n "$head_owner"; and test -n "$head_branch"; or return 1 set -l pr_lines set -l jq 'map(select(.state == "OPEN" or .state == "MERGED")) | sort_by(.updatedAt) | reverse | .[] | [.number, .state, .headRepositoryOwner.login, .headRefName] | @tsv' if command -sq timeout set pr_lines (command timeout 1s gh pr list --head "$head_branch" --state all --limit 50 --json number,state,updatedAt,headRefName,headRepositoryOwner --jq "$jq" 2>/dev/null) else set pr_lines (command gh pr list --head "$head_branch" --state all --limit 50 --json number,state,updatedAt,headRefName,headRepositoryOwner --jq "$jq" 2>/dev/null) end set -l tab (printf '\t') for line in $pr_lines set -l fields (string split "$tab" -- "$line") if test "$fields[3]" = "$head_owner"; and test "$fields[4]" = "$head_branch" printf '%s\n%s\n' "$fields[1]" "$fields[2]" return 0 end end return 1 end function __fishrc_prompt_pr_state --description 'Set GitHub PR prompt state for a branch' set -l branch $argv[1] test -n "$branch"; or return 1 command -sq gh; or return 1 set -l repo_key (command git rev-parse --show-toplevel 2>/dev/null) if test -z "$repo_key" set repo_key (command jj root --ignore-working-copy 2>/dev/null) end set -l cache_key "$repo_key:$branch:pr-v2" set -l now (date +%s) if test "$__fishrc_prompt_pr_cache_key" = "$cache_key" if string match -qr '^[0-9]+$' -- "$__fishrc_prompt_pr_cache_time" set -l cache_age (math "$now - $__fishrc_prompt_pr_cache_time" 2>/dev/null) if string match -qr '^[0-9]+$' -- "$cache_age" if test "$cache_age" -lt 300 set -l cached_pr $__fishrc_prompt_pr_cache_value test "$cached_pr[1]" != __none; or return 1 if test -z "$cached_pr[2]" set cached_pr[2] green end set -g __fishrc_vcs_pr_number "$cached_pr[1]" set -g __fishrc_vcs_pr_color "$cached_pr[2]" return 0 end end end end set -l repo_owner if command -sq timeout set repo_owner (command timeout 1s gh repo view --json owner --jq '.owner.login' 2>/dev/null) else set repo_owner (command gh repo view --json owner --jq '.owner.login' 2>/dev/null) end set repo_owner (string trim -- "$repo_owner") test -n "$repo_owner"; or return 1 set -l pr_line set pr_line (__fishrc_prompt_pr_by_head "$repo_owner" "$branch") set -l branch_remote (command git config --get "branch.$branch.remote" 2>/dev/null) set -l branch_merge (command git config --get "branch.$branch.merge" 2>/dev/null) set -l branch_head (string replace -r '^refs/heads/' '' -- "$branch_merge") if test -z "$pr_line"; and test -n "$branch_remote"; and test -n "$branch_head"; and test "$branch_head" != "$branch_merge" set -l remote_url (__fishrc_git_remote_url "$branch_remote") set -l remote_owner (__fishrc_github_owner_from_url "$remote_url") if test -n "$remote_owner" set pr_line (__fishrc_prompt_pr_by_head "$remote_owner" "$branch_head") end end set -l pr_number (string trim -- "$pr_line[1]") set -l pr_state (string trim -- "$pr_line[2]") set -l pr_color green if test "$pr_state" = MERGED set pr_color purple end set -g __fishrc_prompt_pr_cache_key "$cache_key" set -g __fishrc_prompt_pr_cache_time "$now" if not string match -qr '^[0-9]+$' -- "$pr_number" set -g __fishrc_prompt_pr_cache_value __none return 1 end set -g __fishrc_prompt_pr_cache_value "$pr_number" "$pr_color" set -g __fishrc_vcs_pr_number "$pr_number" set -g __fishrc_vcs_pr_color "$pr_color" end function __fishrc_git_unpushed_count --description 'Print commits ahead of the git upstream' set -l upstream (command git rev-parse --abbrev-ref --symbolic-full-name '@{upstream}' 2>/dev/null) test -n "$upstream"; or return 1 command git rev-list --count "$upstream"..HEAD 2>/dev/null end function __fishrc_git_prompt_state --description 'Set compact git repository state for the prompt' command -sq git; or return 1 command git rev-parse --is-inside-work-tree >/dev/null 2>&1; or return 1 set -l branch (command git symbolic-ref --quiet --short HEAD 2>/dev/null) set -l pr_branch "$branch" if test -z "$branch" set branch (command git rev-parse --short HEAD 2>/dev/null) end test -n "$branch"; or return 1 set -l git_status (command git status --porcelain=v1 --branch 2>/dev/null) set -l flags set -l changed 0 set -l header $git_status[1] set -l behind (string match -r 'behind [0-9]+' -- "$header" | string replace 'behind ' 'v') set -l ahead_count (__fishrc_git_unpushed_count) if string match -qr '^[0-9]+$' -- "$ahead_count" if test "$ahead_count" -gt 0 set -a flags ^$ahead_count set changed 1 end end test -n "$behind"; and set -a flags $behind for line in $git_status[2..-1] set changed 1 set -l index (string sub -s 1 -l 1 -- "$line") set -l worktree (string sub -s 2 -l 1 -- "$line") switch "$line" case 'UU*' 'AA*' 'DD*' 'AU*' 'UA*' 'DU*' 'UD*' contains x $flags; or set -a flags x continue case '??*' contains '?' $flags; or set -a flags '?' continue end if test "$index" != ' ' contains + $flags; or set -a flags + end if test "$worktree" != ' ' contains '!' $flags; or set -a flags '!' end end set -l segment "git:$branch" if test (count $flags) -gt 0 set segment "$segment "(string join '' -- $flags) end set -g __fishrc_vcs_segment "$segment" set -g __fishrc_vcs_color 777777 if test "$changed" -eq 1 set -g __fishrc_vcs_color yellow end __fishrc_prompt_pr_state "$pr_branch" return 0 end function __fishrc_jj_prompt_state --description 'Set compact jj workspace state for the prompt' command -sq jj; or return 1 command jj root --ignore-working-copy >/dev/null 2>&1; or return 1 set -l info (command jj log --no-graph --ignore-working-copy --color=never -r @ --template 'separate(" ", change_id.shortest(8), bookmarks.join("|"), if(conflict, "x")) ++ "\n"' 2>/dev/null) test -n "$info"; or return 1 set -g __fishrc_vcs_segment "jj:$info" set -g __fishrc_vcs_color 777777 set -l diff_summary (command jj diff --summary --ignore-working-copy 2>/dev/null) if test -n "$diff_summary" set -g __fishrc_vcs_color yellow end set -l pr_branch (command jj log --no-graph --ignore-working-copy --color=never -r 'bookmarks() & @' --template 'bookmarks.join("\n") ++ "\n"' 2>/dev/null)[1] set pr_branch (string replace -r '\*$' '' -- "$pr_branch") __fishrc_prompt_pr_state "$pr_branch" return 0 end function __fishrc_vcs_prompt_state --description 'Set prompt VCS segment state' set -g __fishrc_vcs_segment '' set -g __fishrc_vcs_color 777777 set -g __fishrc_vcs_pr_number '' set -g __fishrc_vcs_pr_color green __fishrc_jj_prompt_state; or __fishrc_git_prompt_state end function fish_prompt --description 'Repository fish prompt' set -l host (prompt_hostname) set host (string replace -r '^HyDEV-' '' -- "$host") printf '\n' if test "$host" = HyDEV set_color magenta printf '%s ' (date '+%a %m-%d %H:%M') else set_color 55CDFC printf '%s ' (date '+%a') set_color F7A8B8 printf '%s' (date '+%m-') set_color FFFFFF printf '%s ' (date '+%d') set_color F7A8B8 printf '%s' (date '+%H:') set_color 55CDFC printf '%s ' (date '+%M') end set_color blue if test "$host" = HyDEV set_color 55CDFC printf H set_color F7A8B8 printf y set_color FFFFFF printf D set_color F7A8B8 printf E set_color 55CDFC printf 'V ' else printf '%s ' "$host" end set_color yellow if test -n "$__fishrc_git_id_segment" printf '%s' "$__fishrc_git_id_segment" else printf '%s ' "$USER" end set_color brgreen printf '%s' "$__fishrc_proxy_segment" set_color normal printf '%s' (prompt_pwd) __fishrc_vcs_prompt_state if test -n "$__fishrc_vcs_segment" printf ' ' set_color $__fishrc_vcs_color printf '[%s' "$__fishrc_vcs_segment" if test -n "$__fishrc_vcs_pr_number" printf ' ' set_color $__fishrc_vcs_pr_color printf '#%s' "$__fishrc_vcs_pr_number" set_color $__fishrc_vcs_color end printf ']' set_color normal end printf '\n> ' end