-
Notifications
You must be signed in to change notification settings - Fork 154
/
powerline_git.lua
137 lines (121 loc) · 3.8 KB
/
powerline_git.lua
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
-- Constants
local segmentColors = {
clean = {
fill = colorGreen,
text = colorWhite
},
dirty = {
fill = colorYellow,
text = colorBlack
},
conflict = {
fill = colorRed,
text = colorWhite
}
}
---
-- Finds out the name of the current branch
-- @return {nil|git branch name}
---
function get_git_branch(git_dir)
git_dir = git_dir or get_git_dir()
-- If git directory not found then we're probably outside of repo
-- or something went wrong. The same is when head_file is nil
local head_file = git_dir and io.open(git_dir..'/HEAD')
if not head_file then return end
local HEAD = head_file:read()
head_file:close()
-- if HEAD matches branch expression, then we're on named branch
-- otherwise it is a detached commit
local branch_name = HEAD:match('ref: refs/heads/(.+)')
return branch_name or 'HEAD detached at '..HEAD:sub(1, 7)
end
---
-- Gets the .git directory
-- copied from clink.lua
-- clink.lua is saved under %CMDER_ROOT%\vendor
-- @return {bool} indicating there's a git directory or not
---
-- function get_git_dir(path)
-- MOVED INTO CORE
---
-- Gets the status of working dir
-- @return {bool} indicating true for clean, false for dirty
---
function get_git_status()
local file = io.popen("git --no-optional-locks status --porcelain 2>nul")
for line in file:lines() do
file:close()
return false
end
file:close()
return true
end
---
-- Gets the conflict status
-- @return {bool} indicating true for conflict, false for no conflicts
---
function get_git_conflict()
local file = io.popen("git diff --name-only --diff-filter=U 2>nul")
for line in file:lines() do
file:close()
return true;
end
file:close()
return false
end
-- * Segment object with these properties:
---- * isNeeded: sepcifies whether a segment should be added or not. For example: no Git segment is needed in a non-git folder
---- * text
---- * textColor: Use one of the color constants. Ex: colorWhite
---- * fillColor: Use one of the color constants. Ex: colorBlue
local segment = {
isNeeded = false,
text = "",
textColor = 0,
fillColor = 0
}
---
-- Sets the properties of the Segment object, and prepares for a segment to be added
---
local function init()
segment.isNeeded = get_git_dir()
if segment.isNeeded then
-- if we're inside of git repo then try to detect current branch
local branch = get_git_branch(git_dir)
if branch then
-- Has branch => therefore it is a git folder, now figure out status
local gitStatus = get_git_status()
local gitConflict = get_git_conflict()
segment.text = " "..plc_git_branchSymbol.." "..branch.." "
if gitConflict then
segment.textColor = segmentColors.conflict.text
segment.fillColor = segmentColors.conflict.fill
if plc_git_conflictSymbol then
segment.text = segment.text..plc_git_conflictSymbol
end
return
end
if gitStatus then
segment.textColor = segmentColors.clean.text
segment.fillColor = segmentColors.clean.fill
segment.text = segment.text..""
return
end
segment.textColor = segmentColors.dirty.text
segment.fillColor = segmentColors.dirty.fill
segment.text = segment.text.."± "
end
end
end
---
-- Uses the segment properties to add a new segment to the prompt
---
local function addAddonSegment()
init()
if segment.isNeeded then
addSegment(segment.text, segment.textColor, segment.fillColor)
end
end
-- Register this addon with Clink
clink.prompt.register_filter(addAddonSegment, 61)