dotfiles

My personal dotfiles 💠️

fisher.fish (15914B)

      1 set -g fisher_version 3.2.11
      2 
      3 function fisher -a cmd -d "fish package manager"
      4     set -q XDG_CACHE_HOME; or set XDG_CACHE_HOME ~/.cache
      5     set -q XDG_CONFIG_HOME; or set XDG_CONFIG_HOME ~/.config
      6     set -q XDG_DATA_HOME; or set XDG_DATA_HOME ~/.local/share
      7 
      8     set -g fish_config $XDG_CONFIG_HOME/fish
      9     set -g fisher_cache $XDG_CACHE_HOME/fisher
     10     set -g fisher_data $XDG_DATA_HOME/fisher
     11 
     12     set -q fisher_path; or set -g fisher_path $fish_config
     13     set -g fishfile $fish_config/fishfile
     14 
     15     for path in {$fish_config,$fisher_path}/{functions,completions,conf.d} $fisher_cache
     16         if test ! -d $path
     17             command mkdir -p $path
     18         end
     19     end
     20 
     21     if test ! -e $fisher_path/completions/fisher.fish
     22         echo "fisher complete" >$fisher_path/completions/fisher.fish
     23         _fisher_complete
     24     end
     25 
     26     if test -e $fisher_path/conf.d/fisher.fish
     27         switch "$version"
     28             case \*-\*
     29                 command rm -f $fisher_path/conf.d/fisher.fish
     30             case 2\*
     31             case \*
     32                 command rm -f $fisher_path/conf.d/fisher.fish
     33         end
     34     else
     35         switch "$version"
     36             case \*-\*
     37             case 2\*
     38                 echo "fisher copy-user-key-bindings" >$fisher_path/conf.d/fisher.fish
     39         end
     40     end
     41 
     42     # 2019-10-22: temp code, migrates fishfile from old path back to $fish_config
     43     if test -e "$fisher_path/fishfile"; and test ! -e "$fishfile"
     44         command mv -f "$fisher_path/fishfile" "$fishfile"
     45     end
     46 
     47     # 2020-06-23: temp code, migrates fisher data from XDG_CONFIG_HOME to XDG_DATA_HOME
     48     set -l fisher_config $XDG_CONFIG_HOME/fisher
     49     if test -d $fisher_config
     50         echo "migrating local data from $fisher_config to $fisher_data"
     51         command rm -rf $fisher_data
     52         command mv -f $fisher_config $fisher_data
     53     end
     54 
     55     switch "$cmd"
     56         case {,self-}complete
     57             _fisher_complete
     58         case copy-user-key-bindings
     59             _fisher_copy_user_key_bindings
     60         case ls
     61             set -e argv[1]
     62             if test -s "$fishfile"
     63                 set -l file (_fisher_fmt <$fishfile | _fisher_parse -R | command sed "s|@.*||")
     64                 _fisher_ls | _fisher_fmt | command awk -v FILE="$file" "
     65                     BEGIN { for (n = split(FILE, f); ++i <= n;) file[f[i]] } \$0 in file && /$argv[1]/
     66                 " | command sed "s|^$HOME|~|"
     67             end
     68         case self-update
     69             _fisher_self_update (status -f)
     70         case self-uninstall
     71             _fisher_self_uninstall
     72         case {,-}-v{ersion,}
     73             echo "fisher version $fisher_version" (status -f | command sed "s|^$HOME|~|")
     74         case {,-}-h{elp,}
     75             _fisher_help
     76         case ""
     77             _fisher_commit --
     78         case add rm
     79             if not isatty
     80                 while read -l arg
     81                     set argv $argv $arg
     82                 end
     83             end
     84 
     85             if test (count $argv) = 1
     86                 echo "fisher: invalid number of arguments" >&2
     87                 _fisher_help >&2
     88                 return 1
     89             end
     90 
     91             _fisher_commit $argv
     92         case \*
     93             echo "fisher: unknown flag or command \"$cmd\"" >&2
     94             _fisher_help >&2
     95             return 1
     96     end
     97 end
     98 
     99 function _fisher_complete
    100     complete -ec fisher
    101     complete -xc fisher -n __fish_use_subcommand -a add -d "Add packages"
    102     complete -xc fisher -n __fish_use_subcommand -a rm -d "Remove packages"
    103     complete -xc fisher -n __fish_use_subcommand -a ls -d "List installed packages matching REGEX"
    104     complete -xc fisher -n __fish_use_subcommand -a --help -d "Show usage help"
    105     complete -xc fisher -n __fish_use_subcommand -a --version -d "$fisher_version"
    106     complete -xc fisher -n __fish_use_subcommand -a self-update -d "Update to the latest version"
    107     for pkg in (fisher ls)
    108         complete -xc fisher -n "__fish_seen_subcommand_from rm" -a $pkg
    109     end
    110 end
    111 
    112 function _fisher_copy_user_key_bindings
    113     if functions -q fish_user_key_bindings
    114         functions -c fish_user_key_bindings fish_user_key_bindings_copy
    115     end
    116     function fish_user_key_bindings
    117         for file in $fisher_path/conf.d/*_key_bindings.fish
    118             source $file >/dev/null 2>/dev/null
    119         end
    120         if functions -q fish_user_key_bindings_copy
    121             fish_user_key_bindings_copy
    122         end
    123     end
    124 end
    125 
    126 function _fisher_ls
    127     for pkg in $fisher_data/*/*/*
    128         command readlink $pkg; or echo $pkg
    129     end
    130 end
    131 
    132 function _fisher_fmt
    133     command sed "s|^[[:space:]]*||;s|^$fisher_data/||;s|^~|$HOME|;s|^\.\/*|$PWD/|;s|^https*:/*||;s|^github\.com/||;s|/*\$||"
    134 end
    135 
    136 function _fisher_help
    137     echo "usage: fisher add <package...>     Add packages"
    138     echo "       fisher rm  <package...>     Remove packages"
    139     echo "       fisher                      Update all packages"
    140     echo "       fisher ls  [<regex>]        List installed packages matching <regex>"
    141     echo "       fisher --help               Show this help"
    142     echo "       fisher --version            Show the current version"
    143     echo "       fisher self-update          Update to the latest version"
    144     echo "       fisher self-uninstall       Uninstall from your system"
    145     echo "examples:"
    146     echo "       fisher add jethrokuan/z rafaelrinaldi/pure"
    147     echo "       fisher add gitlab.com/foo/bar@v2"
    148     echo "       fisher add ~/path/to/local/pkg"
    149     echo "       fisher add <file"
    150     echo "       fisher rm rafaelrinaldi/pure"
    151     echo "       fisher ls | fisher rm"
    152     echo "       fisher ls fish-\*"
    153 end
    154 
    155 function _fisher_self_update -a file
    156     set -l url "https://raw.githubusercontent.com/jorgebucaran/fisher/master/fisher.fish"
    157     echo "fetching $url" >&2
    158     command curl -s "$url?nocache" >$file.
    159 
    160     set -l next_version (command awk '{ print $4 } { exit }' <$file.)
    161     switch "$next_version"
    162         case "" $fisher_version
    163             command rm -f $file.
    164             if test -z "$next_version"
    165                 echo "fisher: cannot update fisher -- are you offline?" >&2
    166                 return 1
    167             end
    168             echo "fisher is already up-to-date" >&2
    169         case \*
    170             echo "linking $file" | command sed "s|$HOME|~|" >&2
    171             command mv -f $file. $file
    172             source $file
    173             echo "updated to fisher $fisher_version -- hooray!" >&2
    174             _fisher_complete
    175     end
    176 end
    177 
    178 function _fisher_self_uninstall
    179     for pkg in (_fisher_ls)
    180         _fisher_rm $pkg
    181     end
    182 
    183     for file in $fisher_cache $fisher_data $fisher_path/{functions,completions,conf.d}/fisher.fish $fishfile
    184         echo "removing $file"
    185         command rm -Rf $file 2>/dev/null
    186     end | command sed "s|$HOME|~|" >&2
    187 
    188     for name in (set -n | command awk '/^fisher_/')
    189         set -e "$name"
    190     end
    191 
    192     functions -e (functions -a | command awk '/^_fisher/') fisher
    193     complete -c fisher --erase
    194 end
    195 
    196 function _fisher_commit -a cmd
    197     set -e argv[1]
    198     set -l elapsed (_fisher_now)
    199 
    200     if test ! -e "$fishfile"
    201         command touch $fishfile
    202         echo "created new fishfile in $fishfile" | command sed "s|$HOME|~|" >&2
    203     end
    204 
    205     set -l old_pkgs (_fisher_ls | _fisher_fmt)
    206     for pkg in (_fisher_ls)
    207         _fisher_rm $pkg
    208     end
    209     command rm -Rf $fisher_data
    210     command mkdir -p $fisher_data
    211 
    212     set -l next_pkgs (_fisher_fmt <$fishfile | _fisher_parse -R $cmd (printf "%s\n" $argv | _fisher_fmt))
    213     set -l actual_pkgs (_fisher_fetch $next_pkgs)
    214     set -l updated_pkgs
    215     for pkg in $old_pkgs
    216         if contains -- $pkg $actual_pkgs
    217             set updated_pkgs $updated_pkgs $pkg
    218         end
    219     end
    220 
    221     if test -z "$actual_pkgs$updated_pkgs$old_pkgs$next_pkgs"
    222         echo "fisher: nothing to commit -- try adding some packages" >&2
    223         return 1
    224     end
    225 
    226     set -l out_pkgs
    227     if test "$cmd" = "rm"
    228         set out_pkgs $next_pkgs
    229     else
    230         for pkg in $next_pkgs
    231             if contains -- (echo $pkg | command sed "s|@.*||") $actual_pkgs
    232                 set out_pkgs $out_pkgs $pkg
    233             end
    234         end
    235     end
    236 
    237     printf "%s\n" (_fisher_fmt <$fishfile | _fisher_parse -W $cmd $out_pkgs | command sed "s|^$HOME|~|") >$fishfile
    238 
    239     _fisher_complete
    240 
    241     command awk -v A=(count $actual_pkgs) -v U=(count $updated_pkgs) -v O=(count $old_pkgs) -v E=(_fisher_now $elapsed) '
    242         BEGIN {
    243             res = fmt("removed", O - U, fmt("updated", U, fmt("added", A - U)))
    244             printf((res ? res : "done") " in %.2fs\n", E / 1000)
    245         }
    246         function fmt(action, n, s) {
    247             return n ? (s ? s ", " : s) action " " n " package" (n > 1 ? "s" : "") : s
    248         }
    249     ' >&2
    250 end
    251 
    252 function _fisher_parse -a mode cmd
    253     set -e argv[1..2]
    254     command awk -v FS="[[:space:]]*#+" -v MODE="$mode" -v CMD="$cmd" -v ARGSTR="$argv" '
    255         BEGIN {
    256             for (n = split(ARGSTR, a, " "); i++ < n;) pkgs[getkey(a[i])] = a[i]
    257         }
    258         !NF { next } { k = getkey($1) }
    259         MODE == "-R" && !(k in pkgs) && ($0 = $1)
    260         MODE == "-W" && (/^#/ || k in pkgs || CMD != "rm") { print pkgs[k] (sub($1, "") ? $0 : "") }
    261         MODE == "-W" || CMD == "rm" { delete pkgs[k] }
    262         END {
    263             for (k in pkgs) {
    264                 if (CMD != "rm" || MODE == "-W") print pkgs[k]
    265                 else print "fisher: cannot remove \""k"\" -- package is not in fishfile" > "/dev/stderr"
    266             }
    267         }
    268         function getkey(s,  a) {
    269             return (split(s, a, /@+|:/) > 2) ? a[2]"/"a[1]"/"a[3] : a[1]
    270         }
    271     '
    272 end
    273 
    274 function _fisher_fetch
    275     set -l pkg_jobs
    276     set -l out_pkgs
    277     set -l next_pkgs
    278     set -l local_pkgs
    279     set -q fisher_user_api_token; and set -l curl_opts -u $fisher_user_api_token
    280 
    281     for pkg in $argv
    282         switch $pkg
    283             case \~\* /\*
    284                 set -l path (echo "$pkg" | command sed "s|^~|$HOME|")
    285                 if test -e "$path"
    286                     set local_pkgs $local_pkgs $path
    287                 else
    288                     echo "fisher: cannot add \"$pkg\" -- is this a valid file?" >&2
    289                 end
    290                 continue
    291         end
    292 
    293         command awk -v PKG="$pkg" -v FS=/ '
    294             BEGIN {
    295                 if (split(PKG, tmp, /@+|:/) > 2) {
    296                     if (tmp[4]) sub("@"tmp[4], "", PKG)
    297                     print PKG "\t" tmp[2]"/"tmp[1]"/"tmp[3] "\t" (tmp[4] ? tmp[4] : "master")
    298                 } else {
    299                     pkg = split(PKG, _, "/") <= 2 ? "github.com/"tmp[1] : tmp[1]
    300                     tag = tmp[2] ? tmp[2] : "master"
    301                     print (\
    302                         pkg ~ /^github/ ? "https://codeload."pkg"/tar.gz/"tag : \
    303                         pkg ~ /^gitlab/ ? "https://"pkg"/-/archive/"tag"/"tmp[split(pkg, tmp, "/")]"-"tag".tar.gz" : \
    304                         pkg ~ /^bitbucket/ ? "https://"pkg"/get/"tag".tar.gz" : pkg \
    305                     ) "\t" pkg
    306                 }
    307             }
    308         ' | read -l url pkg branch
    309 
    310         if test ! -d "$fisher_data/$pkg"
    311             fish -c "
    312                 echo fetching $url >&2
    313                 command mkdir -p $fisher_data/$pkg $fisher_cache/(command dirname $pkg)
    314                 if test ! -z \"$branch\"
    315                      command git clone $url $fisher_data/$pkg --branch $branch --depth 1 2>/dev/null
    316                      or echo fisher: cannot clone \"$url\" -- is this a valid url\? >&2
    317                 else if command curl $curl_opts -Ss -w \"\" $url 2>&1 | command tar -xzf- -C $fisher_data/$pkg 2>/dev/null
    318                     command rm -Rf $fisher_cache/$pkg
    319                     command mv -f $fisher_data/$pkg/* $fisher_cache/$pkg
    320                     command rm -Rf $fisher_data/$pkg
    321                     command cp -Rf {$fisher_cache,$fisher_data}/$pkg
    322                 else if test -d \"$fisher_cache/$pkg\"
    323                     echo fisher: cannot connect to server -- looking in \"$fisher_cache/$pkg\" | command sed 's|$HOME|~|' >&2
    324                     command cp -Rf $fisher_cache/$pkg $fisher_data/$pkg/..
    325                 else
    326                     command rm -Rf $fisher_data/$pkg
    327                     echo fisher: cannot add \"$pkg\" -- is this a valid package\? >&2
    328                 end
    329             " >/dev/null &
    330             set pkg_jobs $pkg_jobs (_fisher_jobs --last)
    331             set next_pkgs $next_pkgs "$fisher_data/$pkg"
    332         end
    333     end
    334 
    335     if set -q pkg_jobs[1]
    336         while for job in $pkg_jobs
    337                 contains -- $job (_fisher_jobs); and break
    338             end
    339         end
    340         for pkg in $next_pkgs
    341             if test -d "$pkg"
    342                 set out_pkgs $out_pkgs $pkg
    343                 _fisher_add $pkg
    344             end
    345         end
    346     end
    347 
    348     set -l local_prefix $fisher_data/local/$USER
    349     if test ! -d "$local_prefix"
    350         command mkdir -p $local_prefix
    351     end
    352     for pkg in $local_pkgs
    353         set -l target $local_prefix/(command basename $pkg)
    354         if test ! -L "$target"
    355             command ln -sf $pkg $target
    356             set out_pkgs $out_pkgs $pkg
    357             _fisher_add $pkg --link
    358         end
    359     end
    360 
    361     if set -q out_pkgs[1]
    362         _fisher_fetch (
    363             for pkg in $out_pkgs
    364                 if test -s "$pkg/fishfile"
    365                     _fisher_fmt <$pkg/fishfile | _fisher_parse -R
    366                 end
    367             end)
    368         printf "%s\n" $out_pkgs | _fisher_fmt
    369     end
    370 end
    371 
    372 function _fisher_add -a pkg opts
    373     for src in $pkg/{functions,completions,conf.d}/**.* $pkg/*.fish
    374         set -l target (command basename $src)
    375         switch $src
    376             case $pkg/conf.d\*
    377                 set target $fisher_path/conf.d/$target
    378             case $pkg/completions\*
    379                 set target $fisher_path/completions/$target
    380             case $pkg/{functions,}\*
    381                 switch $target
    382                     case uninstall.fish
    383                         continue
    384                     case {init,key_bindings}.fish
    385                         set target $fisher_path/conf.d/(command basename $pkg)\_$target
    386                     case \*
    387                         set target $fisher_path/functions/$target
    388                 end
    389         end
    390         echo "linking $target" | command sed "s|$HOME|~|" >&2
    391         if set -q opts[1]
    392             command ln -sf $src $target
    393         else
    394             command cp -f $src $target
    395         end
    396         switch $target
    397             case \*.fish
    398                 source $target >/dev/null 2>/dev/null
    399         end
    400     end
    401 end
    402 
    403 function _fisher_rm -a pkg
    404     for src in $pkg/{conf.d,completions,functions}/**.* $pkg/*.fish
    405         set -l target (command basename $src)
    406         set -l filename (command basename $target .fish)
    407         switch $src
    408             case $pkg/conf.d\*
    409                 test "$filename.fish" = "$target"; and emit "$filename"_uninstall
    410                 set target conf.d/$target
    411             case $pkg/completions\*
    412                 test "$filename.fish" = "$target"; and complete -ec $filename
    413                 set target completions/$target
    414             case $pkg/{,functions}\*
    415                 test "$filename.fish" = "$target"; and functions -e $filename
    416                 switch $target
    417                     case uninstall.fish
    418                         source $src
    419                         continue
    420                     case {init,key_bindings}.fish
    421                         set target conf.d/(command basename $pkg)\_$target
    422                     case \*
    423                         set target functions/$target
    424                 end
    425         end
    426         command rm -f $fisher_path/$target
    427     end
    428     if not functions -q fish_prompt
    429         source "$__fish_datadir$__fish_data_dir/functions/fish_prompt.fish"
    430     end
    431 end
    432 
    433 function _fisher_jobs
    434     jobs $argv | command awk '/^[0-9]+\t/ { print $1 }'
    435 end
    436 
    437 function _fisher_now -a elapsed
    438     switch (command uname)
    439         case Darwin \*BSD
    440             command perl -MTime::HiRes -e 'printf("%.0f\n", (Time::HiRes::time() * 1000) - $ARGV[0])' $elapsed
    441         case \*
    442             math (command date "+%s%3N") - "0$elapsed"
    443     end
    444 end