prompt.elv 4.7 KB

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