-
-
Notifications
You must be signed in to change notification settings - Fork 35
/
zap.zsh
194 lines (173 loc) Β· 6.68 KB
/
zap.zsh
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#!/usr/bin/env zsh
export ZSHRC="${ZDOTDIR:-$HOME}/.zshrc"
export ZAP_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/zap"
export ZAP_PLUGIN_DIR="$ZAP_DIR/plugins"
export -a ZAP_INSTALLED_PLUGINS=()
fpath+="$ZAP_DIR/completion"
function plug() {
function _try_source() {
if [[ "$plugin_name" == "*" ]]; then
# Treat * as a glob pattern
local -a initfiles=(
$plugin_dir/*.{plugin.,}{z,}sh{-theme,}(N)
)
for file in "${initfiles[@]}"; do
[[ -f "$file" ]] && source "$file"
done
else
# Use the specified plugin_name
local -a initfiles=(
$plugin_dir/${plugin_name}.{plugin.,}{z,}sh{-theme,}(N)
$plugin_dir/*.{plugin.,}{z,}sh{-theme,}(N)
)
(( $#initfiles )) && source $initfiles[1]
fi
}
# If the absolute is a directory then source as a local plugin
pushd -q "$ZAP_DIR"
local plugin_absolute="${1:A}"
popd -q
if [ -d "${plugin_absolute}" ]; then
local plugin="${plugin_absolute}"
local plugin_name="${plugin:t}"
local plugin_dir="${plugin_absolute}"
elif [ "${plugin_absolute:t}" = "*" ]; then
local plugin_name="${plugin_absolute:t}"
local plugin_dir="${plugin_absolute:h}"
else
# If the basename directory exists, then local source only
if [ -d "${plugin_absolute:h}" ]; then
[[ -f "${plugin_absolute}" ]] && source "${plugin_absolute}"
return
fi
local plugin="$1"
local plugin_name="${plugin:t}"
local plugin_dir="$ZAP_PLUGIN_DIR/$plugin_name"
fi
local git_ref="$2"
if [ ! -d "$plugin_dir" ]; then
echo "π Zap is installing $plugin_name..."
git clone --depth 1 "${ZAP_GIT_PREFIX:-"https://github.com/"}${plugin}.git" "$plugin_dir" > /dev/null 2>&1 || { echo -e "\e[1A\e[Kβ Failed to clone $plugin_name"; return 12 }
echo -e "\e[1A\e[Kβ‘ Zap installed $plugin_name"
fi
[[ -n "$git_ref" ]] && {
git -C "$plugin_dir" remote set-branches origin '*' > /dev/null 2>&1
git -C "$plugin_dir" pull --unshallow > /dev/null 2>&1
git -C "$plugin_dir" checkout "$git_ref" > /dev/null 2>&1 || { echo "β Failed to checkout $git_ref"; return 13 }
}
_try_source && { ZAP_INSTALLED_PLUGINS+="$plugin_name" && return 0 } || echo "β $plugin_name not activated" && return 1
}
function _pull() {
echo "π updating ${1:t}..."
git -C $1 pull > /dev/null 2>&1 && { echo -e "\e[1A\e[Kβ‘ ${1:t} updated!"; return 0 } || { echo -e "\e[1A\e[Kβ Failed to pull"; return 14 }
}
function _zap_clean() {
typeset -a unused_plugins=()
echo "β‘ Zap - Clean\n"
for plugin in "$ZAP_PLUGIN_DIR"/*; do
[[ "$ZAP_INSTALLED_PLUGINS[(Ie)${plugin:t}]" -eq 0 ]] && unused_plugins+=("${plugin:t}")
done
[[ ${#unused_plugins[@]} -eq 0 ]] && { echo "β
Nothing to remove"; return 15 }
for plug in ${unused_plugins[@]}; do
echo "β Remove: $plug? (y/N)"
read -qs answer
[[ "$answer" == "y" ]] && { rm -rf "$ZAP_PLUGIN_DIR/$plug" && echo -e "\e[1A\e[Kβ
Removed $plug" } || echo -e "\e[1A\e[Kβ skipped $plug"
done
}
function _zap_list() {
local _plugin
echo "β‘ Zap - List\n"
for _plugin in ${ZAP_INSTALLED_PLUGINS[@]}; do
printf '%4s π %s\n' $ZAP_INSTALLED_PLUGINS[(Ie)$_plugin] $_plugin
done
}
function _zap_update() {
local _plugin _plug _status
[[ $1 == "all" || $1 == "self" ]] && {
_pull $ZAP_DIR
[[ $1 == "self" ]] && return
}
[[ $1 == "all" || $1 == "plugins" ]] && {
echo "\nUpdating All Plugins\n"
for _plug in ${ZAP_INSTALLED_PLUGINS[@]}; do
_pull "$ZAP_PLUGIN_DIR/$_plug"
done
return
}
function _check() {
git -C "$1" remote update &> /dev/null
case $(LANG=en_US git -C "$1" status -uno | grep -Eo '(ahead|behind|up to date)') in
ahead)
_status='\033[1;34mLocal ahead remote\033[0m' ;;
behind)
_status='\033[1;33mOut of date\033[0m' ;;
'up to date')
_status='\033[1;32mUp to date\033[0m' ;;
*)
_status='\033[1;31mDiverged state\033[0m' ;;
esac
}
echo "β‘ Zap - Update\n"
_check "$ZAP_DIR"
printf ' 0 β‘ Zap (%b)\n' "$_status"
for _plugin in ${ZAP_INSTALLED_PLUGINS[@]}; do
_check "$ZAP_PLUGIN_DIR/$_plugin"
printf '%4s π %s (%b)\n' $ZAP_INSTALLED_PLUGINS[(Ie)$_plugin] $_plugin $_status
done
echo -n "\n π Plugin Number | (0) β‘ Zap Itself | (a) All Plugins | (β) Abort: " && read _plugin
case $_plugin in
[[:digit:]]*)
[[ $_plugin -gt ${#ZAP_INSTALLED_PLUGINS[@]} ]] && { echo "β Invalid option" && return 1 }
[[ $_plugin -eq 0 ]] && {
git -C "$ZAP_DIR" pull &> /dev/null && { echo -e "\e[1A\e[Kβ‘ Zap updated!"; return 0 } || { echo -e "\e[1A\e[Kβ Failed to pull"; return 14 }
} || { _pull "$ZAP_PLUGIN_DIR/$ZAP_INSTALLED_PLUGINS[$_plugin]" } ;;
'a'|'A')
echo "\nUpdating All Plugins\n"
for _plug in ${ZAP_INSTALLED_PLUGINS[@]}; do
_pull "$ZAP_PLUGIN_DIR/$_plug"
done ;;
*)
: ;;
esac
[[ $ZAP_CLEAN_ON_UPDATE == true ]] && _zap_clean || return 0
}
function _zap_help() {
echo "β‘ Zap - Help
Usage: zap <command> [options]
COMMANDS:
clean Remove unused plugins
help Show this help message
list List plugins
update Update plugins
version Show version information
OPTIONS:
update self Update Zap itself
update plugins Update all plugins
update all Update Zap and all plugins"
}
function _zap_version() {
local -Ar color=(BLUE "\033[0;34m" GREEN "\033[0;32m" RESET "\033[0m")
local _branch=$(git -C "$ZAP_DIR" branch --show-current)
local _version=$(git -C "$ZAP_DIR" describe --abbrev=0 --tags)
local _commit=$(git -C "$ZAP_DIR" log -1 --pretty="%h (%cr)")
echo "β‘ Zap - Version\n\nVersion: ${color[GREEN]}${_branch}/${_version}${color[RESET]}\nCommit Hash: ${color[BLUE]}${_commit}${color[RESET]}"
}
function zap() {
typeset -A subcmds=(
clean "_zap_clean"
help "_zap_help"
list "_zap_list"
update "_zap_update"
version "_zap_version"
)
emulate -L zsh
[[ -z "$subcmds[$1]" ]] && { _zap_help; return 1 } || ${subcmds[$1]} $2
}
# vim: ft=zsh ts=4 et
# Return codes:
# 0: Success
# 1: Invalid option
# 12: Failed to clone
# 13: Failed to checkout
# 14: Failed to pull
# 15: Nothing to remove