fish/functions/fisher.fish 10.9 K raw
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