forked from nushell/nu_scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgit_status_prompt.nu
94 lines (83 loc) · 3.06 KB
/
git_status_prompt.nu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# Displays a prompt
def git-status-prompt [] {
let not_windows = ($nu.path | first | into string | str contains '/')
$"(ansi reset)(ansi green)(if $not_windows {$nu.env.USER} {$nu.env.USERNAME})(ansi reset)@(hostname | str trim):(ansi green_dimmed)(prompt-pwd)(ansi reset)(git-branch-icon)(ansi reset)(char newline)(char prompt) "
}
# Returns a shortened pwd for use in prompt
def prompt-pwd [] {
let not_windows = ($nu.path | first | into string | str contains '/')
let path = (pwd | if $not_windows { split row "/" } { split row "\" })
let home = (if $not_windows { ($nu.env.HOME | split row "/") } { (echo [$nu.env.HOMEDRIVE $nu.env.HOMEPATH] | path join | split row "\") })
if ($path | length) > 1 {
if ($home | reduce { $it in $path }) {
let path-without-home = ($path | skip ($home | length))
if ($path-without-home | wrap | compact | length) > 0 {
let parent = ($path | skip ($home | length) | drop)
if ($parent | wrap | compact | length) > 0 {
let short-part = ($parent | each { |part|
if ($part | str starts-with ".") {
$"($part | str substring [0 2])/"
} {
$"($part | str substring [0 1])/"
}
})
$"~/($short-part | str collect)($path | last)"
} {
$"~/($path | last)"
}
} {
"~"
}
} {
let parent = (echo $path | drop | str substring [0 1] | each { echo $it "/" })
$"/($parent)($path | last)"
}
} {
pwd
}
}
# Map of git status codes to ANSI colour codes
def git-prompt-map [] {
echo a m r c d "??" u |
rotate counter-clockwise |
reject Column0 | append (
echo (ansi green) (ansi yellow_bold) (ansi cyan) (ansi blue) (ansi red) (ansi red_dimmed) (ansi red) |
rotate counter-clockwise |
reject Column0
) | headers
}
# Gets an icon and a colour for a given git status code
def git-prompt-icons [k] {
let icns = ["✚ " "* " "➜ " "⇒ " "✖ " "? " "! "];
git-prompt-map |
pivot status colour | each --numbered { |icon|
let idx = $icon.index;
if $icon.item.status == $k {
$"($icon.item.colour)($icns | nth $idx)"
} {
= $nothing
}
} | compact
}
# Checks git status of current working directory and displays an icon
def git-branch-icon [] {
do -i {
let branch = (do -i { git rev-parse --abbrev-ref HEAD } | str trim)
if ($branch | str length) > 0 {
let modified = (do -i { git status --porcelain } | split row "\n" | str trim | split column " " status file);
if ($modified | get | first | empty?) {
$"|(ansi green)($branch)(ansi reset):(ansi green)✓(ansi reset)"
} {
let modified2 = (do -i { git status --porcelain } | split row "\n" | str substring [0 1])
let branch-colour = (if (echo $modified2 | each { $it in [A M R C D] } | reduce { $it || $acc }) {
"yellow"
} {
"red"
})
$"|(ansi $branch-colour)($branch)(ansi reset):($modified | get status | uniq | str downcase | each { git-prompt-icons $it })" | str collect
}
} {
""
}
}
}