gregj529

zshrc

Jan 9th, 2024
1,280
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 12.15 KB | None | 0 0
  1. #===============================================================================
  2. #
  3. #          FILE: .zsh_prompt
  4. #
  5. #         USAGE: Sourced automatically in .zshrc
  6. #
  7. #   DESCRIPTION: In my opinion which I respect very much this may be one of the
  8. #                best zsh prompts on the planet.
  9. #
  10. #===============================================================================
  11.  
  12. autoload -U colors && colors && autoload -U promptinit && autoload -Uz vcs_info
  13.  
  14. # Make the colors easier to reference
  15. typeset -AHg FG BG
  16.  
  17. for color in {000..255}; do
  18.     FG[$color]="%{[38;5;${color}m%}"
  19.     BG[$color]="%{[48;5;${color}m%}"
  20. done
  21.  
  22. local reset white gray lightblue lightgray brightcyan green red yellow blue cyan lines_color git_repo working_dir pyenv_ver
  23. reset="%{${reset_color}%}"
  24. gray="%{$FG[239]%}"
  25. green="%{$FG[120]%}"
  26. red="%{$FG[196]%}"
  27. yellow="%{$FG[011]%}"
  28. cyan="%{$FG[066]%}"
  29. blue="%{$FG[033]%}"
  30. white="%{$FG[015]%}"
  31. orange=%{$FG[208]%}
  32. violet=%{$FG[135]%}
  33. lightblue="%{$FG[039]%}"
  34. lightgray="%{$FG[007]%}"
  35. brightcyan="%{$FG[087]%}"
  36. brightmagenta=%{$FG[198]%}
  37. brightgreen=%{$FG[082]%}
  38. testcolor=%{$FG[123]%}
  39.  
  40. #Global color scheme - Change these to the variables above to control your dotfiles environment colors.
  41. lines_color="$brightcyan"
  42. git_repo="$green"
  43. working_dir="$lightblue"
  44. pyenv_ver="$violet"
  45. # npm_ver="$brightcyan"
  46.  
  47. local -A pr_com            # Associative array
  48. local -a prompt_left_lines # Array parameters
  49.  
  50. zstyle ":pr_jrock:" mode full
  51. zstyle ':pr_jrock:*' hooks pwd usr vcs venv npm jobs prompt
  52. zstyle ':pr_jrock:*' pwd "%~"
  53.  
  54. # Set vcs_info options
  55. zstyle ':vcs_info:*' enable git                                           # We are only concerned with git VCS, so enable it
  56. zstyle ':vcs_info:(git*):*' check-for-changes true                        # We want to monitor changes to the repository's
  57. # Format of what we will display for the git repo information.
  58. # %s - The VCS in use (git, hg, svn, etc.).
  59. # %i - The current revision number or identifier. (SHA we only display 10 chars)
  60. # %c - The string from the stagedstr style if there are staged changes in the repository.
  61. # %u - The number of unapplied patches (unapplied-string).
  62. # %b - Information about the current branch.
  63. # %m - A "misc" replacement. It is at the discretion of the backend to decide what this replacement expands to.
  64. #      It is currently used by the hg and git backends to display patch information from the mq and stgit extensions.
  65. # Format of what we will display during a special action on the repo (Ex. Interactive rebase or merge conflict)
  66. zstyle ':vcs_info:(git*)' actionformats "(%b|${red}%a${lines_color}%m)"
  67. zstyle ':vcs_info:(git*)' formats "(%b%m)"
  68. zstyle ':vcs_info:git*+set-message:*' hooks git-statuses git-st
  69.  
  70. # Run all the prompt hook functions
  71. # (stolen, wholesale, from the excellent hook system in vcs_info)
  72. function pr_run_hooks() {
  73.     local hook func
  74.     local -a hooks
  75.  
  76.     zstyle -g hooks ":pr_jrock:*" hooks
  77.  
  78.     (( ${#hooks} == 0 )) && return 0
  79.  
  80.     for hook in ${hooks} ; do
  81.         func="+pr-${hook}"
  82.         if (( ${+functions[$func]} == 0 )); then
  83.             continue
  84.         fi
  85.         true
  86.         ${func} "$@"
  87.         case $? in
  88.             (0)
  89.                 ;;
  90.             (*)
  91.                 break
  92.                 ;;
  93.         esac
  94.     done
  95. }
  96.  
  97. # This is our prompt, this is a compressed example it will expand
  98. # to the width of the console
  99. # ┌──(~/src/dotfiles)v(dotfiles)──────(✔)─
  100. # ├──(master [origin/master ] Unstaged)
  101. # └───>
  102. function +pr-mode-full() {
  103.     local i info_line_width return_status_width filler venv_shim npm_shim
  104.  
  105.     infoline=( ${pr_com[pwd]} ${pr_com[usr]} )
  106.  
  107.     # # If we are in a directory that has a node_modules subdirectory we want to
  108.     # # display that on the info line
  109.     #  [[ -n ${pr_com[npm]} ]] && infoline[1]=(
  110.     #      ${infoline[1]}
  111.     #      "${lines_color}(${pr_com[npm]}${lines_color})${reset}"
  112.     #  )
  113.  
  114.     # # The prompt was not taking up the full width of the terminal when displaying npm info
  115.     # # So if we are in a npm directory then we add a one character shim to the width of the filler
  116.     #  npm_shim=0
  117.     #  if [[ -n ${pr_com[npm]} ]]; then
  118.     #      npm_shim+=1
  119.     #  fi
  120.  
  121.     # If we are in a virtualenv we want to display that on the info line
  122.     [[ -n ${pr_com[venv]} ]] && infoline[1]=(
  123.         ${infoline[1]}
  124.         "${lines_color}(${pr_com[venv]}${lines_color})${reset}"
  125.     )
  126.  
  127.     # The prompt was not taking up the full width of the terminal when in a virtualenv
  128.     # If we are in a virtualenv then we add a one character shim to the width of the filler
  129.     venv_shim=0
  130.     if [[ -n ${pr_com[venv]} ]]; then
  131.         venv_shim+=1 # Shim the filler to take up the entire width of the prompt
  132.     fi
  133.  
  134.     # Full-width filler; search/replace color wraps to find real text width
  135.     info_line_width=${(S)infoline//\%\{*\%\}} # search-and-replace color escapes
  136.     info_line_width=${#${(%)info_line_width}} # expand all escapes and count the chars
  137.     return_status_width=3 # We will take up three spaces to display the return code (✔)
  138.  
  139.     # Set the text string that will be used to fill the width of the terminal filler
  140.     # filler="${lines_color}${(l:$(( $COLUMNS - $info_line_width - $return_status_width + $venv_shim + $npm_shim))::─:)}${reset}"
  141.     filler="${lines_color}${(l:$(( $COLUMNS - $info_line_width - $return_status_width + $venv_shim))::─:)}${reset}"
  142.     infoline[-1]=( ${filler} ${infoline[-1]} )
  143.  
  144.     # --------------------------
  145.     # Assemble the prompt lines
  146.     # --------------------------
  147.     # Default we will always have a info line and a prompt line
  148.     lines=(
  149.         ${(j::)infoline}
  150.         ${pr_com[prompt]}
  151.     )
  152.  
  153.     # If we are in a git repo we will have three lines info, git_info, prompt
  154.     [[ -n ${pr_com[vcs]} ]] && lines[1]=(
  155.         ${lines[1]}
  156.         "${lines_color}${pr_com[vcs]}${reset}"
  157.  
  158.     )
  159.  
  160.     # Add some connecting lines to the beginning of our prompts
  161.     if [[ -n ${pr_com[vcs]} ]]; then
  162.         lines[1]="${lines_color}┌──${lines[1]}${lines_color}${reset}"
  163.         lines[2]="${lines_color}├──${lines[2]}${reset}"
  164.         lines[3]="${lines_color}└──➤${lines[3]}${reset}"
  165.     else
  166.         lines[1]="${lines_color}┌──${lines[1]}${lines_color}${reset}"
  167.         lines[2]="${lines_color}└──➤${lines[2]}${reset}"
  168.     fi
  169.  
  170.     # And we set the value for the prompt_left_lines
  171.     prompt_left_lines=( ${lines[@]} )
  172. }
  173.  
  174. # Show info collected from vcs_info
  175. function +pr-vcs() {
  176.     local -a v_vcs
  177.  
  178.     [[ -n ${vcs_info_msg_0_} ]] && v_vcs=(
  179.         ${git_repo}
  180.         ${vcs_info_msg_0_}
  181.         ${reset}
  182.     )
  183.  
  184.     pr_com[vcs]=${(j::)v_vcs}
  185. }
  186.  
  187. # Show virtualenv information
  188. function +pr-venv() {
  189.     local -a v_venv
  190.     python_version=$(python --version 2>&1)
  191.     pr_com[python_version]="${python_version}"
  192.  
  193.     if [[ -n ${VIRTUAL_ENV} ]]; then
  194.         v_venv=(
  195.             ${pyenv_ver}
  196.             "${pr_com[python_version]}"
  197.             ${reset}
  198.         )
  199.     else
  200.         v_venv=()
  201.     fi
  202.  
  203.     pr_com[venv]=${(j::)v_venv}
  204. }
  205.  
  206. # # Show npm information
  207. # function +pr-npm() {
  208. #     local -a v_npm
  209. #     npm_version=$(npm --version 2>&1)
  210. #     if [[ ${NODE_NAME}  != "" ]]; then
  211. #         v_npm=(
  212. #             ${npm_ver}
  213. #             ${NODE_NAME}
  214. #             ${reset}
  215. #         )
  216. #     fi
  217.  
  218. #     pr_com[npm]=${(j::)v_npm}
  219. # }
  220.  
  221. # Show number of background jobs, or hide if none
  222. function +pr-jobs() {
  223.     local -a v_jobs
  224.     v_jobs=( "%(1j.${lines_color}%j${reset}.)" )
  225.     pr_com[jobs]=${(j::)v_jobs}
  226. }
  227.  
  228. #AWS Granted Status
  229. _get_aws_account() {
  230.   aws_account_name="${AWS_PROFILE:u}"
  231.   if [[ -z "$aws_account_name" ]]; then
  232.     echo "${lines_color}${white}[NO-AUTH]${lines_color}─%{$reset%}"
  233.   elif [[ "$aws_account_name" == *"TEST"* ]]; then
  234.     echo "${lines_color}${green}[$aws_account_name]${lines_color}─%{$reset%}"
  235.   elif [[ "$aws_account_name" == *"QA"* ]]; then
  236.     echo "${lines_color}${yellow}[$aws_account_name]${lines_color}─%{$reset%}"
  237.   elif [[ "$aws_account_name" == *"PROD"* ]]; then
  238.     echo "${lines_color}${red%}[$aws_account_name]${lines_color}─%{$reset%}"
  239.   else
  240.     echo "${lines_color}${orange}[$aws_account_name]${lines_color}─%{$reset%}"
  241.   fi
  242. }
  243.  
  244. # Get pulumi backend account number
  245. _get_pulumi_backend_account(){
  246.   if [[ ! -z "$PULUMI_BACKEND_URL" ]]; then
  247.     PULUMI_ACCOUNT_NUMBER=$(echo $PULUMI_BACKEND_URL | cut -d '-' -f4)
  248.     echo $(jq -r ".accountList[] | select( .accountId == \"$PULUMI_ACCOUNT_NUMBER\" ) | .accountName" ~/.aws/sso_accounts.json | tr a-z A-Z)
  249.   fi
  250. }
  251.  
  252. # Check of Pulumi backend matches current AWS profile
  253. _compare_aws_pulumi_account(){
  254.   PULUMI=$( _get_pulumi_backend_account)
  255.   AWS_ACCOUNT_NAME=${AWS_PROFILE:u}
  256.   if [ ! -z ${AWS_PROFILE+x} ] && [ -n "$PULUMI" ]; then
  257.     if [[ "$AWS_ACCOUNT_NAME" =~ "$PULUMI" ]]; then
  258.       echo "${white}[PULUMI ${green}${white}]${lines_color}─%{$reset%}"
  259.     else
  260.       echo "${white}[PULUMI ${red}${white}]${lines_color}─%{$reset%}"
  261.     fi
  262.   fi
  263. }
  264.  
  265. function +pr-prompt() {
  266.     local -a v_pwd i_pwd
  267.     local -a exit_status i_usr i_host exit_status
  268.     account=$(_get_aws_account)
  269.     pulumi=$(_compare_aws_pulumi_account)
  270.  
  271.     # Add the print working directory logic
  272.     zstyle -g i_pwd ":pr_jrock:*" pwd
  273.     v_pwd+=( ${lines_color}\( )
  274.     [[ -w $PWD ]] && v_pwd+=( ${working_dir} ) || v_pwd+=( ${yellow} )
  275.     v_pwd+=( ${i_pwd} )
  276.     v_pwd+=( ${lines_color}\)${lightgray} )
  277.     v_pwd+=( ${account} )
  278.     v_pwd+=( ${pulumi} )
  279.     v_pwd+=( ${reset} )
  280.     pr_com[pwd]=${(j::)v_pwd}${reset}
  281.  
  282.  
  283.     # Add exit status check or x logic
  284.     exit_status=( ${lines_color}\( )
  285.     exit_status+="%(0?.${green}✔.${red}✘)"
  286.     exit_status+=( ${lines_color}\) )
  287.     exit_status+=( ${reset} )
  288.  
  289.     pr_com[usr]=${(j::)exit_status}
  290. }
  291.  
  292. # Show remote ref name and number of commits ahead-of or behind
  293. function +vi-git-st() {
  294.     local ahead behind remote
  295.     local -a gitstatus
  296.  
  297.     # Are we on a remote-tracking branch?
  298.     remote=${$(git rev-parse --verify ${hook_com[branch]}@{upstream} \
  299.         --symbolic-full-name --abbrev-ref 2>/dev/null)}
  300.  
  301.     if [[ -n ${remote} ]] ; then
  302.         ahead=$(git rev-list ${hook_com[branch]}@{upstream}..HEAD 2>/dev/null | wc -l | sed -e 's/^[ \t]*//')
  303.         (( $ahead )) && gitstatus+=( "${green}+${ahead}${lines_color}" )
  304.  
  305.         behind=$(git rev-list HEAD..${hook_com[branch]}@{upstream} 2>/dev/null | wc -l | sed -e 's/^[ \t]*//')
  306.         (( $behind )) && gitstatus+=( "${red}-${behind}${lines_color}" )
  307.  
  308.         user_data[gitstatus]=${gitstatus}
  309.         hook_com[branch]="${hook_com[branch]} [${remote}${(j:/:)gitstatus}]"
  310.     fi
  311. }
  312.  
  313. # Show the above/behind upstream counts more tersely for the compact display
  314. function +vi-git-st-compact() {
  315.     [[ -n ${user_data[gitstatus]} ]] \
  316.         && hook_com[misc]="@{u}${(j:/:)user_data[gitstatus]}"
  317. }
  318.  
  319. function +vi-git-statuses() {
  320.     git status -s >| /tmp/gitstatus.txt
  321.     staged=$( cat /tmp/gitstatus.txt | grep -c "^[MARCD]")
  322.     unstaged=$( cat /tmp/gitstatus.txt | grep -c "^.[MARCD]")
  323.     untracked=$( cat /tmp/gitstatus.txt | grep -c "^\?")
  324.     stashes=$(git stash list 2>/dev/null | wc -l | sed -e 's/^[ \t]*//')
  325.  
  326.     if [[ ${staged} != 0 ]] ; then
  327.         hook_com[misc]+=" ${green}${staged}${lines_color}"
  328.     fi
  329.  
  330.     if [[ ${unstaged} != 0 ]] ; then
  331.         hook_com[misc]+=" ${red}${unstaged}${lines_color}"
  332.     fi
  333.  
  334.     if [[ ${untracked} != 0 ]] ; then
  335.         hook_com[misc]+=" ${yellow}${untracked}${lines_color}"
  336.     fi
  337.  
  338.     if [[ ${stashes} != 0 ]] ; then
  339.         hook_com[misc]+=" ${lines_color}${stashes}${lines_color}"
  340.     fi
  341. }
  342.  
  343. # --------------------------
  344. # Finally we execute the above prompt functions
  345. # --------------------------
  346.  
  347. # To be added to the precmd_* array so it is executed before each prompt
  348. function precmd_prompt {
  349.     local func
  350.  
  351.     # Clear out old values
  352.     pr_com=()
  353.     prompt_left_lines=()
  354.  
  355.     # Collect needed data
  356.     vcs_info
  357.     pr_run_hooks
  358.  
  359.     # Use the above data and build the prompt arrays
  360.     func="+pr-mode-full"
  361.     ${func} "$@"
  362.  
  363.     # Set the prompts
  364.     PROMPT="${(F)prompt_left_lines} "
  365. }
  366.  
Advertisement
Add Comment
Please, Sign In to add comment