| 1 | function fisher --argument-names cmd --description "A plugin manager for Fish" |
| 2 | set --query fisher_path || set --local fisher_path $__fish_config_dir |
| 3 | set --local fisher_version 4.4.4 |
| 4 | set --local fish_plugins $__fish_config_dir/fish_plugins |
| 5 | |
| 6 | switch "$cmd" |
| 7 | case -v --version |
| 8 | echo "fisher, version $fisher_version" |
| 9 | case "" -h --help |
| 10 | echo "Usage: fisher install <plugins...> Install plugins" |
| 11 | echo " fisher remove <plugins...> Remove installed plugins" |
| 12 | echo " fisher update <plugins...> Update installed plugins" |
| 13 | echo " fisher update Update all installed plugins" |
| 14 | echo " fisher list [<regex>] List installed plugins matching regex" |
| 15 | echo "Options:" |
| 16 | echo " -v, --version Print version" |
| 17 | echo " -h, --help Print this help message" |
| 18 | echo "Variables:" |
| 19 | echo " \$fisher_path Plugin installation path. Default: $__fish_config_dir" | string replace --regex -- $HOME \~ |
| 20 | case ls list |
| 21 | string match --entire --regex -- "$argv[2]" $_fisher_plugins |
| 22 | case install update remove |
| 23 | isatty || read --local --null --array stdin && set --append argv $stdin |
| 24 | |
| 25 | set --local install_plugins |
| 26 | set --local update_plugins |
| 27 | set --local remove_plugins |
| 28 | set --local arg_plugins $argv[2..-1] |
| 29 | set --local old_plugins $_fisher_plugins |
| 30 | set --local new_plugins |
| 31 | |
| 32 | test -e $fish_plugins && set --local file_plugins (string match --regex -- '^[^\s]+$' <$fish_plugins) |
| 33 | |
| 34 | if ! set --query argv[2] |
| 35 | if test "$cmd" != update |
| 36 | echo "fisher: Not enough arguments for command: \"$cmd\"" >&2 && return 1 |
| 37 | else if ! set --query file_plugins |
| 38 | echo "fisher: \"$fish_plugins\" file not found: \"$cmd\"" >&2 && return 1 |
| 39 | end |
| 40 | set arg_plugins $file_plugins |
| 41 | end |
| 42 | |
| 43 | for plugin in $arg_plugins |
| 44 | set plugin (test -e "$plugin" && realpath $plugin || string lower -- $plugin) |
| 45 | contains -- "$plugin" $new_plugins || set --append new_plugins $plugin |
| 46 | end |
| 47 | |
| 48 | if set --query argv[2] |
| 49 | for plugin in $new_plugins |
| 50 | if contains -- "$plugin" $old_plugins |
| 51 | test "$cmd" = remove && |
| 52 | set --append remove_plugins $plugin || |
| 53 | set --append update_plugins $plugin |
| 54 | else if test "$cmd" = install |
| 55 | set --append install_plugins $plugin |
| 56 | else |
| 57 | echo "fisher: Plugin not installed: \"$plugin\"" >&2 && return 1 |
| 58 | end |
| 59 | end |
| 60 | else |
| 61 | for plugin in $new_plugins |
| 62 | contains -- "$plugin" $old_plugins && |
| 63 | set --append update_plugins $plugin || |
| 64 | set --append install_plugins $plugin |
| 65 | end |
| 66 | |
| 67 | for plugin in $old_plugins |
| 68 | contains -- "$plugin" $new_plugins || set --append remove_plugins $plugin |
| 69 | end |
| 70 | end |
| 71 | |
| 72 | set --local pid_list |
| 73 | set --local source_plugins |
| 74 | set --local fetch_plugins $update_plugins $install_plugins |
| 75 | set --local fish_path (status fish-path) |
| 76 | |
| 77 | echo (set_color --bold)fisher $cmd version $fisher_version(set_color normal) |
| 78 | |
| 79 | for plugin in $fetch_plugins |
| 80 | set --local source (command mktemp -d) |
| 81 | set --append source_plugins $source |
| 82 | |
| 83 | command mkdir -p $source/{completions,conf.d,themes,functions} |
| 84 | |
| 85 | $fish_path --command " |
| 86 | if test -e $plugin |
| 87 | command cp -Rf $plugin/* $source |
| 88 | else |
| 89 | set temp (command mktemp -d) |
| 90 | set repo (string split -- \@ $plugin) || set repo[2] HEAD |
| 91 | |
| 92 | if set path (string replace --regex -- '^(https://)?gitlab.com/' '' \$repo[1]) |
| 93 | set name (string split -- / \$path)[-1] |
| 94 | set url https://gitlab.com/\$path/-/archive/\$repo[2]/\$name-\$repo[2].tar.gz |
| 95 | else |
| 96 | set url https://api.github.com/repos/\$repo[1]/tarball/\$repo[2] |
| 97 | end |
| 98 | |
| 99 | echo Fetching (set_color --underline)\$url(set_color normal) |
| 100 | |
| 101 | if command curl -q --silent -L \$url | command tar -xzC \$temp -f - 2>/dev/null |
| 102 | command cp -Rf \$temp/*/* $source |
| 103 | else |
| 104 | echo fisher: Invalid plugin name or host unavailable: \\\"$plugin\\\" >&2 |
| 105 | command rm -rf $source |
| 106 | end |
| 107 | |
| 108 | command rm -rf \$temp |
| 109 | end |
| 110 | |
| 111 | set files $source/* && string match --quiet --regex -- .+\.fish\\\$ \$files |
| 112 | " & |
| 113 | |
| 114 | set --append pid_list (jobs --last --pid) |
| 115 | end |
| 116 | |
| 117 | wait $pid_list 2>/dev/null |
| 118 | |
| 119 | for plugin in $fetch_plugins |
| 120 | if set --local source $source_plugins[(contains --index -- "$plugin" $fetch_plugins)] && test ! -e $source |
| 121 | if set --local index (contains --index -- "$plugin" $install_plugins) |
| 122 | set --erase install_plugins[$index] |
| 123 | else |
| 124 | set --erase update_plugins[(contains --index -- "$plugin" $update_plugins)] |
| 125 | end |
| 126 | end |
| 127 | end |
| 128 | |
| 129 | for plugin in $update_plugins $remove_plugins |
| 130 | if set --local index (contains --index -- "$plugin" $_fisher_plugins) |
| 131 | set --local plugin_files_var _fisher_(string escape --style=var -- $plugin)_files |
| 132 | |
| 133 | if contains -- "$plugin" $remove_plugins |
| 134 | for name in (string replace --filter --regex -- '.+/conf\.d/([^/]+)\.fish$' '$1' $$plugin_files_var) |
| 135 | emit {$name}_uninstall |
| 136 | end |
| 137 | printf "%s\n" Removing\ (set_color red --bold)$plugin(set_color normal) " "$$plugin_files_var | string replace -- \~ ~ |
| 138 | set --erase _fisher_plugins[$index] |
| 139 | end |
| 140 | |
| 141 | command rm -rf (string replace -- \~ ~ $$plugin_files_var) |
| 142 | |
| 143 | functions --erase (string replace --filter --regex -- '.+/functions/([^/]+)\.fish$' '$1' $$plugin_files_var) |
| 144 | |
| 145 | for name in (string replace --filter --regex -- '.+/completions/([^/]+)\.fish$' '$1' $$plugin_files_var) |
| 146 | complete --erase --command $name |
| 147 | end |
| 148 | |
| 149 | set --erase $plugin_files_var |
| 150 | end |
| 151 | end |
| 152 | |
| 153 | if set --query update_plugins[1] || set --query install_plugins[1] |
| 154 | command mkdir -p $fisher_path/{functions,themes,conf.d,completions} |
| 155 | end |
| 156 | |
| 157 | for plugin in $update_plugins $install_plugins |
| 158 | set --local source $source_plugins[(contains --index -- "$plugin" $fetch_plugins)] |
| 159 | set --local files $source/{functions,themes,conf.d,completions}/* |
| 160 | |
| 161 | if set --local index (contains --index -- $plugin $install_plugins) |
| 162 | set --local user_files $fisher_path/{functions,themes,conf.d,completions}/* |
| 163 | set --local conflict_files |
| 164 | |
| 165 | for file in (string replace -- $source/ $fisher_path/ $files) |
| 166 | contains -- $file $user_files && set --append conflict_files $file |
| 167 | end |
| 168 | |
| 169 | if set --query conflict_files[1] && set --erase install_plugins[$index] |
| 170 | echo -s "fisher: Cannot install \"$plugin\": please remove or move conflicting files first:" \n" "$conflict_files >&2 |
| 171 | continue |
| 172 | end |
| 173 | end |
| 174 | |
| 175 | for file in (string replace -- $source/ "" $files) |
| 176 | command cp -RLf $source/$file $fisher_path/$file |
| 177 | end |
| 178 | |
| 179 | set --local plugin_files_var _fisher_(string escape --style=var -- $plugin)_files |
| 180 | |
| 181 | set --query files[1] && set --universal $plugin_files_var (string replace -- $source $fisher_path $files | string replace -- ~ \~) |
| 182 | |
| 183 | contains -- $plugin $_fisher_plugins || set --universal --append _fisher_plugins $plugin |
| 184 | contains -- $plugin $install_plugins && set --local event install || set --local event update |
| 185 | |
| 186 | printf "%s\n" Installing\ (set_color --bold)$plugin(set_color normal) " "$$plugin_files_var | string replace -- \~ ~ |
| 187 | |
| 188 | for file in (string match --regex -- '.+/[^/]+\.fish$' $$plugin_files_var | string replace -- \~ ~) |
| 189 | source $file |
| 190 | if set --local name (string replace --regex -- '.+conf\.d/([^/]+)\.fish$' '$1' $file) |
| 191 | emit {$name}_$event |
| 192 | end |
| 193 | end |
| 194 | end |
| 195 | |
| 196 | command rm -rf $source_plugins |
| 197 | |
| 198 | if set --query _fisher_plugins[1] |
| 199 | set --local commit_plugins |
| 200 | |
| 201 | for plugin in $file_plugins |
| 202 | contains -- (string lower -- $plugin) (string lower -- $_fisher_plugins) && set --append commit_plugins $plugin |
| 203 | end |
| 204 | |
| 205 | for plugin in $_fisher_plugins |
| 206 | contains -- (string lower -- $plugin) (string lower -- $commit_plugins) || set --append commit_plugins $plugin |
| 207 | end |
| 208 | |
| 209 | printf "%s\n" $commit_plugins >$fish_plugins |
| 210 | else |
| 211 | set --erase _fisher_plugins |
| 212 | command rm -f $fish_plugins |
| 213 | end |
| 214 | |
| 215 | set --local total (count $install_plugins) (count $update_plugins) (count $remove_plugins) |
| 216 | |
| 217 | test "$total" != "0 0 0" && echo (string join ", " ( |
| 218 | test $total[1] = 0 || echo "Installed $total[1]") ( |
| 219 | test $total[2] = 0 || echo "Updated $total[2]") ( |
| 220 | test $total[3] = 0 || echo "Removed $total[3]") |
| 221 | ) plugin/s |
| 222 | case \* |
| 223 | echo "fisher: Unknown command: \"$cmd\"" >&2 && return 1 |
| 224 | end |
| 225 | end |
| 226 | |
| 227 | if ! set --query _fisher_upgraded_to_4_4 |
| 228 | set --universal _fisher_upgraded_to_4_4 |
| 229 | if functions --query _fisher_list |
| 230 | set --query XDG_DATA_HOME[1] || set --local XDG_DATA_HOME ~/.local/share |
| 231 | command rm -rf $XDG_DATA_HOME/fisher |
| 232 | functions --erase _fisher_{list,plugin_parse} |
| 233 | fisher update >/dev/null 2>/dev/null |
| 234 | else |
| 235 | for var in (set --names | string match --entire --regex '^_fisher_.+_files$') |
| 236 | set $var (string replace -- ~ \~ $$var) |
| 237 | end |
| 238 | functions --erase _fisher_fish_postexec |
| 239 | end |
| 240 | end |