prompt.elv 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. use str
  2. use re
  3. fn nix-shell-prompt-string {
  4. put '['
  5. styled nix yellow
  6. if (has-env NIX_SHELL_NAME) {
  7. put ':'
  8. styled $E:NIX_SHELL_NAME green
  9. }
  10. put ']'
  11. }
  12. fn k8s-prompt-string {
  13. var k8s-config = (kubectl config view -o json | from-json)
  14. var k8s-context = $k8s-config[current-context]
  15. var k8s-namespace = (each { |ctx| if (eq $ctx[name] $k8s-context) { put $ctx[context][namespace] } } $k8s-config[contexts])
  16. put '['
  17. styled $k8s-context magenta
  18. put '|'
  19. styled $k8s-namespace blue
  20. put ']'
  21. }
  22. fn aws-prompt-string {
  23. put '['
  24. styled $E:AWS_PROFILE yellow
  25. put ']'
  26. }
  27. fn parse-git-branch {
  28. try {
  29. git symbolic-ref -q HEAD 2> /dev/null
  30. } catch e {
  31. try {
  32. git rev-parse --short HEAD 2> /dev/null
  33. } catch e {
  34. echo ""
  35. }
  36. }
  37. }
  38. fn resolve-symbolic {|ref|
  39. try {
  40. put (git rev-parse --symbolic-full-name $ref 2> /dev/null)
  41. } catch {
  42. put $nil
  43. }
  44. }
  45. fn parse-git-state {
  46. var git-revision = ''
  47. var git-branch = ''
  48. var git-changed = (num 0)
  49. var git-staged = (num 0)
  50. var git-conflicts = (num 0)
  51. var git-untracked = (num 0)
  52. var git-ahead-upstream = (num 0)
  53. var git-behind-upstream = (num 0)
  54. var git-ahead-push = (num 0)
  55. var git-behind-push = (num 0)
  56. git status --porcelain=v2 -b 2>/dev/null | each {|line|
  57. if (eq '#' $line[0]) {
  58. try {
  59. var match = (re:find '# branch.ab \+(\d+) -(\d+)' $line)
  60. set git-ahead-upstream = (num $match[groups][1][text])
  61. set git-behind-upstream = (num $match[groups][2][text])
  62. } catch e {
  63. # noop
  64. }
  65. if (str:has-prefix $line '# branch.head') {
  66. set git-branch = $line[14..]
  67. }
  68. if (str:has-prefix $line '# branch.oid') {
  69. set git-revision = $line[13..20]
  70. }
  71. } elif (eq u $line[0]) {
  72. set git-conflicts = (+ $git-conflicts 1)
  73. } elif (eq '?' $line[0]) {
  74. set git-untracked = (+ $git-untracked 1)
  75. } else {
  76. if (not-eq '.' $line[2]) {
  77. set git-staged = (+ $git-staged 1)
  78. }
  79. if (not-eq '.' $line[3]) {
  80. set git-changed = (+ $git-changed 1)
  81. }
  82. }
  83. }
  84. var git-ref = $git-branch
  85. var git-ref-prefix = ''
  86. if (eq $git-branch '(detached)') {
  87. try {
  88. var tag @rest = (git tag --points-at HEAD)
  89. set git-ref-prefix = '#'
  90. set git-ref = $tag
  91. } catch e {
  92. set git-ref-prefix = '@'
  93. set git-ref = $git-revision
  94. }
  95. } else {
  96. var git-push = (resolve-symbolic '@{push}')
  97. var git-upstream = (resolve-symbolic '@{upstream}')
  98. var git-origin-head = (resolve-symbolic origin/HEAD)
  99. if (not-eq $nil $git-push) {
  100. if (eq $git-push $git-upstream) {
  101. # if push is the same as upstream, use the values from git status
  102. set git-behind-push = $git-behind-upstream
  103. set git-ahead-push = $git-ahead-upstream
  104. } else {
  105. # else calculate it ourselves
  106. var behind ahead = (str:split "\t" (git rev-list --count --left-right '@{push}...HEAD'))
  107. set git-behind-push = (num $behind)
  108. set git-ahead-push = (num $ahead)
  109. }
  110. }
  111. # if upstream is nil or the same as push, use origin/HEAD instead if
  112. # present
  113. if (and ^
  114. (or (eq $git-push $git-upstream) (eq $nil $git-upstream)) ^
  115. (not-eq $nil $git-origin-head) ^
  116. ) {
  117. var behind ahead = (str:split "\t" (git rev-list --count --left-right origin/HEAD...HEAD))
  118. set git-behind-upstream = (num $behind)
  119. set git-ahead-upstream = (num $ahead)
  120. }
  121. }
  122. put '('
  123. put $git-ref-prefix
  124. styled $git-ref magenta bold
  125. if (> $git-ahead-push 0) {
  126. put '^'$git-ahead-push
  127. }
  128. if (> $git-behind-push 0) {
  129. put 'v'$git-behind-push
  130. }
  131. if (> $git-behind-upstream 0) {
  132. put '!'
  133. }
  134. put '|'
  135. if (> $git-staged 0) {
  136. styled +$git-staged green
  137. }
  138. if (> $git-conflicts 0) {
  139. styled x$git-conflicts red
  140. }
  141. if (> $git-changed 0) {
  142. styled '*'$git-changed red
  143. }
  144. if (> $git-untracked 0) {
  145. put '..'
  146. }
  147. if (== 0 $git-changed $git-staged $git-conflicts $git-untracked) {
  148. styled ok green bold
  149. }
  150. put ')'
  151. }
  152. fn git-prompt-string {
  153. try {
  154. parse-git-state
  155. } catch e {
  156. }
  157. }
  158. set edit:prompt = {
  159. put "\n"
  160. styled '['(date +%H:%M)']' bold bright-cyan
  161. put ' '
  162. styled (tilde-abbr $pwd) yellow
  163. put ' '
  164. git-prompt-string
  165. put "\n% "
  166. }
  167. set edit:rprompt = {
  168. put '['
  169. styled elv green
  170. put ']'
  171. if (has-env IN_NIX_SHELL) {
  172. nix-shell-prompt-string
  173. }
  174. if (has-env IN_K8S) {
  175. k8s-prompt-string
  176. }
  177. if (has-env AWS_PROFILE) {
  178. aws-prompt-string
  179. }
  180. }
  181. # when stale replace clock with --:--
  182. set edit:prompt-stale-transform = {|x|
  183. put $x[0] # newline
  184. styled '[--:--]' bright-cyan
  185. put $x[2..]
  186. }