]> arthur.barton.de Git - ax-zsh.git/blob - bin/axzshctl
Add axzshctl subcommand "list-enabled"
[ax-zsh.git] / bin / axzshctl
1 #!/usr/bin/env zsh
2 #
3 # AX-ZSH: Alex' Modular ZSH Configuration
4 # Copyright (c) 2015-2016 Alexander Barton <alex@barton.de>
5 #
6
7 # Include "ax-common.sh", if available:
8 for dir ("$HOME/lib" "$HOME/.ax" /usr/local /opt/ax /usr); do
9         [[ -z "$ax_common_sourced" ]] || break
10         ax_common="${dir}/lib/ax/ax-common.sh"
11         [[ -r "$ax_common" ]] && source "$ax_common"
12 done
13 if [[ -z "$ax_common_sourced" ]]; then
14         function ax_msg {
15                 shift
16                 echo "$@"
17         }
18 fi
19 unset dir ax_common ax_common_sourced
20
21 function Usage {
22         echo "Usage: $NAME <command> [...]"
23         echo
24         echo "  enable"
25         echo "    Enable AX-ZSH altogether."
26         echo "  disable"
27         echo "    Disable AX-ZSH altogether."
28         echo
29         echo "  enable-plugin <name|directory> [<name|directory> [...]]"
30         echo "    Enable plugin(s)."
31         echo "  disable-plugin <name> [<name> [...]]"
32         echo "    Disable plugin(s)."
33         echo "  list-enabled"
34         echo "    List enabled plugins."
35         echo
36         echo "  reset-plugins"
37         echo "    Reset active plugins to the default set."
38         echo "  enable-default-plugins"
39         echo "    Enable all default plugins."
40         echo "  check-plugins"
41         echo "    Detect plugins which are \"useful\" on this system."
42         echo
43         echo "  set-theme <name>|-"
44         echo "    Set active theme to <name>, or to the default."
45         echo
46         echo "  upgrade"
47         echo "    Upgrade AX-ZSH installation (requires Git)."
48         echo
49         exit 2
50 }
51
52 function NormalizedPluginName {
53         if [[ "$1" =~ "^[[:alnum:]-]+/[[:alnum:]_-]+$" ]]; then
54                 echo "${1:gs/\//#}"
55         elif [[ "$1" =~ "/" ]]; then
56                 echo "${1:t}"
57         else
58                 echo "$1"
59         fi
60 }
61
62 function EnableAXZSH {
63         for f (~/.zlogin ~/.zlogout ~/.zprofile ~/.zshrc); do
64                 ln -sv "$AXZSH/ax.zsh" "$f" \
65                         || ax_msg 2 "Failed to create symbolic link for \"$f\"!"
66         done
67 }
68
69 function DisableAXZSH {
70         for f (~/.zlogin ~/.zlogout ~/.zprofile ~/.zshrc); do
71                 if [ -h "$f" ]; then
72                         rm -v "$f" || ax_msg 2 "Failed to remove \"$f\"!"
73                 elif [ -e "$f" ]; then
74                         ax_msg 2 "Error: Not removing \"$f\", it is not a symbolic link!"
75                 else
76                         ax_msg 1 "Warning: \"$f\" already does not exist. Ok."
77                 fi
78         done
79 }
80
81 function EnablePlugin {
82         local plugin=$(NormalizedPluginName "$1")
83         local dir="$AXZSH/active_plugins"
84
85         if [[ -h "$dir/$plugin" ]]; then
86                 ax_msg 1 "Plugin \"$1\" already active!"
87                 return 1
88         fi
89
90         if [[ "$1" =~ "^[[:alnum:]-]+/[[:alnum:]_-]+$" ]]; then
91                 # GitHub plugin
92                 mkdir -p "$AXZSH/repos"
93                 if [[ ! -e "$AXZSH/repos/$plugin" ]]; then
94                         ax_msg - "Cloning plugin from GitHub ..."
95                         git clone "https://github.com/$1.git" \
96                          "$AXZSH/repos/$plugin"
97                 fi
98         fi
99
100         for dname (
101                 "$plugin:A"
102                 "$AXZSH_PLUGIN_D/$plugin"
103                 "$ZSH_CUSTOM/$plugin"
104                 "$AXZSH/custom_plugins/$plugin"
105                 "$AXZSH/repos/$plugin"
106                 "$AXZSH/plugins/$plugin"
107                 "$AXZSH/default_plugins/$plugin"
108                 "$AXZSH/core/$plugin"
109         ); do
110                 [[ ! -d "$dname" ]] && continue
111                 mkdir -p "$dir"
112                 (
113                         cd "$dir" || exit 9
114                         ln -sv "$dname" "$PWD"
115                 )
116                 return $?
117         done
118
119         ax_msg 2 "Plugin \"$1\" not found!"
120         return 1
121 }
122
123 function DisablePlugin {
124         local plugin=$(NormalizedPluginName "$1")
125         local dir="$AXZSH/active_plugins"
126
127         if [[ ! -h "$dir/$plugin" ]]; then
128                 ax_msg 1 "Plugin \"$1\" not active?"
129                 return 1
130         fi
131
132         rm -v "$dir/$plugin"; r=$?
133         [ $r -eq 0 ] && rm -fr "$AXZSH/repos/$plugin"
134         return $r
135 }
136
137 function ListEnabledPlugins {
138         for plugin ($AXZSH/active_plugins/*(N)); do
139                 print ${plugin:t:s/#/\//}
140         done
141         return 0
142 }
143
144 function ResetPlugins {
145         local dir="$AXZSH/active_plugins"
146         local r1=0, r2=0
147
148         if [[ -e "$dir" ]]; then
149                 ax_msg - "Removing all symbolic links in $dir ..."
150                 find "$dir" -type l -print -delete; r1=$?
151         fi
152
153         ax_msg - "Removing all external repositories in \"$AXZSH/repos\" ..."
154         rm -fr "$AXZSH/repos"; r2=$?
155
156         [[ $r1 == 0 && $r2 == 0 ]] && return 0 || return 1
157 }
158
159 function EnableDefaultPlugins {
160         local dir="$AXZSH/active_plugins"
161
162         ax_msg - "Activating (linking) default plugins ..."
163         mkdir -p "$dir"
164         (
165                 cd "$dir" || exit 9
166                 ln -sfv "$AXZSH/default_plugins/"* "$PWD"
167         )
168         return $?
169 }
170
171 function SetTheme {
172         local link_name="$AXZSH/active_theme"
173
174         if [ $# -ne 1 ]; then
175                 echo "Usage: axzsh_set_theme <name|->"
176                 return 1
177         fi
178
179         rm -f "$link_name" || return 1
180
181         if [ "$1" = "-" ]; then
182                 echo "Theme settings have been reset."
183                 return 0
184         fi
185
186         if [ -r "$1" ]; then
187                 theme="$1"
188         elif [ -r "$AXZSH/custom_themes/$1.axzshtheme" ]; then
189                 theme="$AXZSH/custom_themes/$1.axzshtheme"
190         elif [ -r "$AXZSH/themes/$1.axzshtheme" ]; then
191                 theme="$AXZSH/themes/$1.axzshtheme"
192         else
193                 echo "Theme \"$1\" not found!"
194                 return 1
195         fi
196         ln -sv "$theme" "$link_name" || return 1
197         return $?
198 }
199
200 function UpgradeAXZSH {
201         if [[ $+commands[git] -eq 0 ]]; then
202                 ax_msg 2 "The git(1) command is not available!"
203                 return 1
204         fi
205         if [[ ! -d "$AXZSH/.git" ]]; then
206                 ax_msg 2 "AX-ZSH seems not to be installed using Git. Can't upgrade!"
207                 return 1
208         fi
209
210         ax_msg - "Upgrading AX-ZSH in \"$AXZSH\" using git(1) ..."
211         ( cd "$AXZSH" && git pull --ff-only )
212 }
213
214 function UpgradeForeignPlugins {
215         if [[ $+commands[git] -eq 0 ]]; then
216                 ax_msg 2 "The git(1) command is not available!"
217                 return 1
218         fi
219
220         for dir ($AXZSH/repos/*(N)); do
221                 name=${dir:t:s/#/\//}
222                 if [ -d "$dir/.git" ]; then
223                         ax_msg - "Upgrading \"$name\" [git] ..."
224                         (
225                                 cd "$dir"
226                                 git pull --ff-only || ax_msg 2 "Pull failed!"
227                         )
228                 else
229                         ax_msg 2 "Unknown repository type!"
230                 fi
231         done
232 }
233
234 function CheckPlugins {
235         missing_plugins=()
236         invalid_plugins=()
237
238         ax_msg - "Checking plugins ..."
239         for dir ($AXZSH/plugins/*(N)); do
240                 plugin=${dir:t}
241
242                 # Test if plugin is already enabled
243                 [[ -e "$AXZSH/active_plugins/$plugin" ]] \
244                         && enabled=" (enabled)" \
245                         || unset enabled
246
247                 # Test plugin ...
248                 printf " - \"%s\"%s ... " "$plugin" "$enabled"
249                 new_plugin=""
250                 for script ($AXZSH/plugins/$plugin/$plugin.{zshrc,zprofile}); do
251                         [[ -r "$script" ]] || continue
252                         zsh -i -c "AXZSH_PLUGIN_CHECK=1 source $script"; r=$?
253                         if [[ $r -eq 0 ]]; then
254                                 new_plugin=$plugin
255                                 break
256                         fi
257                 done
258                 if [[ -n "$new_plugin" ]]; then
259                         detected_plugins+=($new_plugin)
260                         [[ -n "$enabled" ]] || missing_plugins+=($new_plugin)
261                         ax_msg 0 "OK."
262                 elif [[ $r -eq 91 ]]; then
263                         ax_msg 1 "ignored."
264                 elif [[ $r -eq 92 ]]; then
265                         ax_msg 1 "optional."
266                 else
267                         [[ -n "$enabled" ]] && invalid_plugins+=($plugin)
268                         ax_msg 2 "failed."
269                 fi
270         done
271         echo
272
273         result=0
274         if [[ -n "$missing_plugins" ]]; then
275                 ax_msg 1 "Run the following command to enable all missing plugins:"
276                 echo "$AXZSH/bin/axzshctl enable-plugin" $missing_plugins
277                 echo
278                 result=1
279         else
280                 ax_msg 0 "All detected plugins are already enabled."
281         fi
282
283         if [[ -n "$invalid_plugins" ]]; then
284                 ax_msg 1 "Run the following command to disable all failed plugins:"
285                 echo "$AXZSH/bin/axzshctl disable-plugin" $invalid_plugins
286                 result=1
287         else
288                 ax_msg 0 "No failed plugins are enabled."
289         fi
290
291         echo
292         return $result
293 }
294
295 NAME="$0:t"
296
297 [[ $# -gt 0 ]] || Usage
298
299 if [[ -z "$AXZSH" || ! -r "$AXZSH/ax.zsh" ]]; then
300         [[ -r "$HOME/.axzsh/ax.zsh" ]] && AXZSH="$HOME/.axzsh"
301         if [[ ! -r "$AXZSH/ax.zsh" ]]; then
302                 ax_msg 2 "Oops, \"AXZSH\" is not set or invalid and can't be autodetected!"
303                 exit 3
304         fi
305 fi
306
307 cmd="$1"
308 shift
309
310 case "$cmd" in
311         "enable")
312                 [[ $# -eq 0 ]] || Usage
313                 EnableAXZSH
314                 ;;
315         "disable")
316                 [[ $# -eq 0 ]] || Usage
317                 DisableAXZSH
318                 ;;
319         "enable-plugin")
320                 [[ $# -gt 0 ]] || Usage
321                 for plugin in "$@"; do
322                         EnablePlugin "$plugin"
323                 done
324                 ;;
325         "disable-plugin")
326                 [[ $# -gt 0 ]] || Usage
327                 for plugin in "$@"; do
328                         DisablePlugin "$plugin"
329                 done
330                 ;;
331         "list-enabled")
332                 [[ $# -eq 0 ]] || Usage
333                 ListEnabledPlugins
334                 ;;
335         "reset-plugins")
336                 [[ $# -eq 0 ]] || Usage
337                 ResetPlugins
338                 EnableDefaultPlugins
339                 ;;
340         "enable-default-plugins")
341                 [[ $# -eq 0 ]] || Usage
342                 EnableDefaultPlugins
343                 ;;
344         "check-plugins")
345                 [[ $# -eq 0 ]] || Usage
346                 CheckPlugins
347                 ;;
348         "set-theme")
349                 [[ $# -eq 1 ]] || Usage
350                 SetTheme "$1"
351                 ;;
352         "upgrade")
353                 [[ $# -eq 0 ]] || Usage
354                 UpgradeAXZSH
355                 UpgradeForeignPlugins
356                 ;;
357         *)
358                 Usage
359 esac