Ahoy! Fisherman and Happy New Year 2016.

pull/445/head
Jorge Bucaran 9 years ago
commit e4b455d4c3
No known key found for this signature in database
GPG Key ID: E54BA3C0E646DB30

@ -0,0 +1,7 @@
root = true
[*]
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

1
.gitignore vendored

@ -0,0 +1 @@
.DS_Store

@ -0,0 +1,7 @@
sudo: required
before_install:
- sudo add-apt-repository -y ppa:fish-shell/release-2
- sudo apt-get update
- sudo apt-get -y install fish
script:
- make && fish -c "fisher install fishtape; fishtape test/*.fish"

@ -0,0 +1,2 @@
# Authors
* Jorge Bucaran <[j@bucaran.me](mailto:j@bucaran.me)>

@ -0,0 +1,7 @@
# Changelog
* [0.1.0](#010)
## 0.1.0 - 2016-01-01
* Initial commit.

@ -0,0 +1,38 @@
# Contributing to Fisherman
You can start contributing right away:
* [Join][join] the community.
* [Spread][tweet] the voice.
* [Bugs][bugs]? :beetle:
If you are looking for other ways to help, peruse [open issues][issues]. If you are already working on something, feel free to send us a PR.
## Guidelines
* Fork the repo and create your feature branch from master.
* Test before you push. Get familiar with [Fishtape][fishtape].
* If you've changed APIs, update the documentation.
* Follow the [seven rules][seven-rules] of a great git commit message.
## Addons
Third-party plugins are essential for keeping this project exciting. To learn how to create your own plugins and other extensions see `fisher help plugins`.
To browse the available content use `fisher search` or see the [Fisherman Index][fisher-index].
<!-- -->
[org]: https://github.com/fisherman
[fishtape]: https://github.com/fisherman/fishtape
[join]: https://gitter.im/fisherman/wharf
[bugs]: https://github.com/fisherman/fisherman/issues
[issues]: https://github.com/fisherman/fisherman/issues?q=is%3Aopen+is%3Aissue
[fish-docs]: http://fishshell.com/docs/current/index.html
[seven-rules]: http://chris.beams.io/posts/git-commit/#seven-rules
[tweet]: https://twitter.com/intent/tweet?url=https%3A%2F%2Fgit.io%2Ffisher&via=jbucaran&text=Check+out+%23Fisherman+for+the+%23fishshell
[fisher-index]: https://github.com/fisherman/fisher-index

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Jorge Bucaran
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

@ -0,0 +1,72 @@
SHELL:=/bin/bash -O nullglob
XDG_CONFIG_HOME ?= $$HOME/.config
FISH_CONFIG := $(XDG_CONFIG_HOME)/fish/config.fish
FISHER_HOME := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
FISHER_CONFIG := $(XDG_CONFIG_HOME)/fisherman
FISHER_CACHE := $(FISHER_CONFIG)/cache
MAN := $(FISHER_HOME)/man
MAN1 := $(wildcard $(MAN)/man1/*.md)
MAN5 := $(wildcard $(MAN)/man5/*.md)
MAN7 := $(wildcard $(MAN)/man7/*.md)
DOCS := $(MAN1:%.md=%.1) $(MAN5:%.md=%.5) $(MAN7:%.md=%.7)
AUTHORS = $(FISHER_HOME)/AUTHORS.md
VERSION = `cat $(FISHER_HOME)/VERSION`
MSG = printf "\033[47m\033[30m%s\033[0m\n" $(1)
TILDEIFY = sed "s|$$HOME|~|"
.PHONY: all test flush uninstall release
all: $(FISH_CONFIG) $(FISHER_CACHE) $(AUTHORS) $(DOCS)
@$(call MSG,"Reset your shell to apply changes")
test:
@fish -c "fishtape test/*.fish"
flush:
@rm -rf $(FISHER_CONFIG)/*
uninstall:
@echo "Removing configuration from $(FISH_CONFIG)" | $(TILDEIFY)
@sed -E '/set (fisher_home|fisher_config) /d;/source \$$fisher_home/d' \
$(FISH_CONFIG) > $(FISH_CONFIG).tmp
@mv $(FISH_CONFIG).tmp $(FISH_CONFIG)
@$(call MSG,"Reset your shell to apply changes")
release: $(FISHER_HOME)
@if [ "`git -C $^ status --short --porcelain | xargs`" = "M VERSION" ]; then\
echo "`git -C $^ describe --abbrev=0 2>/dev/null || echo \*` -> $(VERSION)";\
sed "s/fisherman-v.\..\..-00B9FF/fisherman-v$(VERSION)-00B9FF/" $^/README.md > $^/README.md.swap;\
mv $^/README.md.swap $^/README.md;\
git -C $^ add README.md;\
git -C $^ add $^/VERSION;\
git -C $^ commit --quiet -m $(VERSION);\
git -C $^ tag $(VERSION) -m v$(VERSION) --force >/dev/null;\
else\
echo "Commit changes and update VERSION to tag a new release.";\
fi
$(FISH_CONFIG):
@echo "Adding configuration to $@" | $(TILDEIFY)
@mkdir -p $(dir $@) && touch $@
@echo "set fisher_home $(FISHER_HOME)" | sed "s|/$$||;s|$$HOME|~|" > $@.fisher
@echo "set fisher_config $(FISHER_CONFIG)" | sed "s|$$HOME|~|" >> $@.fisher
@echo "source \$$fisher_home/config.fish" >> $@.fisher
@awk '!config[$$0]++' $@.fisher $@ > $@.tmp
@mv $@.tmp $@ && rm $@.fisher
$(FISHER_CACHE):
@[ -d $@ ] || echo "Creating $@" | $(TILDEIFY)
@mkdir -p $@
$(AUTHORS): $(FISHER_HOME)
@echo "# Authors" > $@
@git -C $^ shortlog -sne | cut -f2- | \
sed -E 's/([^<>]+)<([^<>]*)>/* \1 \&lt;[\2](mailto:\2)\&gt;/' >> $@
%.1 %.5 %.7: %.md
@ronn --manual=fisherman --roff $? 2>&1 | sed 's/^ *roff: *//;s|//|/|g'

@ -0,0 +1,42 @@
<p align="center">
<a href="http://github.com/fisherman/fisherman">
<img alt="Fisherman" width=620px src="https://cloud.githubusercontent.com/assets/8317250/10865127/daa0e138-8044-11e5-91f9-f72228974552.png">
</a>
</p>
[![Build Status][travis-badge]][travis-link]
![Fisherman Version][fisherman-version]
## About
Fisherman is a shell manager for [fish][fish] that lets you share and reuse code, prompts and configurations easily. See [FAQ][faq].
## Install
```fish
git clone https://github.com/fisherman/fisherman
cd fisherman
make
```
## Contributing
Check out the [contribution](CONTRIBUTING.md) guidelines.
## Help
See [`fisherman(1)`][fisherman-1] and [`fisherman(7)`][fisherman-7] for usage and documentation. For support and feedback join the [Gitter room][wharf] or browse the [issues][issues].
<!-- Links -->
[fish]: https://github.com/fish-shell/fish-shell
[faq]: https://github.com/fisherman/fisherman/wiki/FAQ
[issues]: http://github.com/fisherman/fisherman/issues
[wharf]: https://gitter.im/fisherman/wharf
[fisherman-1]: man/man1/fisher.md
[fisherman-7]: man/man7/fisher.md
[travis-link]: https://travis-ci.org/fisherman/fisherman
[travis-badge]: https://img.shields.io/travis/fisherman/fisherman.svg?style=flat-square
[fisherman-version]: https://img.shields.io/badge/fisherman-v0.1.0-00B9FF.svg?style=flat-square

@ -0,0 +1 @@
0.0.0

@ -0,0 +1,46 @@
complete -c fisher -n "__fish_use_subcommand" -s v -l version -d "Show version information"
complete -c fisher -n "__fish_use_subcommand" -s h -l help -d "Display help"
complete -c fisher -n "__fish_use_subcommand" -s f -l file -d "Read fishfile"
if test -e $fisher_cache/.index
set -l cache (for file in $fisher_cache/*
if test -d $file
basename $file
end
end)
awk -v FS='\n' -v RS='' -v OFS=' ' '/^ *#/ { next } { print $1,$3 }' $fisher_cache/.index \
| while read -l name info
switch "$name"
case $cache
for cmd in update uninstall
complete -c fisher -n "__fish_seen_subcommand_from $cmd" -a "$name" -d "$info"
end
case \*
complete -c fisher -n "__fish_seen_subcommand_from install" -a "$name" -d "$info"
end
end
end
for option in commands guides
set -l IFS ";"
fisher help --$option=bare | sed -E 's/^ *([^ ]+) *(.*)/\1;\2/' | while read -l func info
complete -c fisher -n "__fish_seen_subcommand_from help" -a $func -d "$info"
if test $option = guides
continue
end
complete -c fisher -n "__fish_use_subcommand" -a $func -d "$info"
fisher_help --usage=$func | __fish_parse_usage OFS=';' | while read -l 1 2 3
complete -c fisher -n "__fish_seen_subcommand_from $func" -s "$3" -l "$2" -d "$1"
end
end
end
complete -c fisher -n "__fish_seen_subcommand_from search" -a "\t"
complete -xc fisher -d "Fisherman"

@ -0,0 +1 @@
complete -xc getopts -d "Parse CLI options" -a "\t"

@ -0,0 +1,10 @@
set -l spinners arc star pipe ball flip mixer caret bar1 bar2 bar3
complete -xc wait -n "__fish_seen_subcommand_from --spin" -a "$spinners"
complete -xc wait -d "Run commands and wait with a spin"
complete -xc wait -n "not __fish_seen_subcommand_from --spin" -a "\t"
set -l IFS \t
wait --help | __fish_parse_usage | while read -l 1 2 3
complete -c wait -s "$3" -l "$2" -d "$1"
end

@ -0,0 +1,11 @@
set fisher_cache $fisher_config/cache
set fisher_index https://raw.githubusercontent.com/fisherman/fisher-index/master/INDEX
set fisher_error_log $fisher_cache/.debug_log
set fish_function_path {$fisher_config,$fisher_home}/functions $fish_function_path
set fish_complete_path {$fisher_config,$fisher_home}/completions $fish_complete_path
for file in $fisher_config/functions/*.config.fish
source $file
end

@ -0,0 +1,43 @@
function __fish_parse_usage -d "Parse usage help output"
switch "$argv[1]"
case -h --help
printf "Usage\n"
printf " __fish_parse_usage [awk_var=value] [--help]\n\n"
printf "Example\n"
printf " set -l IFS \\\t\n"
printf " STDIN | __fish_parse_usage | while read -l d l s\n"
printf " complete -c <command> -s $s -l $l -d $d\n"
printf " end\n"
return
end
switch "$argv"
case \*OFS=\*
case \*
set argv $argv OFS=\t
end
awk (printf "-v\n%s\n" $argv) '
/^ *--?[A-Za-z0-9-]+[, ]?/ {
re = "[<=\\\[]"
for (n = 1; n <= NF; n++) {
if ($n ~ /^--/ && !long) {
long = substr($n, 3)
split(long, _, re)
long = substr(_[1], 1)
} else if ($n ~ /^-.,?$/ && !short) {
short = substr($n, 2, 1)
} else if ($n !~ re) {
info = (info ? info" " : info)$n
}
}
print info, long, short
info = short = long = ""
}
'
end

@ -0,0 +1,161 @@
function fisher -d "Fish Shell Manager"
if not set -q argv[1]
fisher --help
return 1
end
set -l option
set -l value
set -l quiet -E .
getopts $argv | while read -l 1 2
switch "$1"
case _
set option command
set value $2
break
case h help
set option help
set value $value $2
case path-in-cache
set option path-in-cache
set value $2
case f file
set option file
set value $2
case V validate
set option validate
set value $2
case v version
set option version
case q quiet
set quiet -q .
case \*
printf "fisher: '%s' is not a valid option\n" $1 >& 2
fisher --help >& 2
return 1
end
end
switch "$option"
case command
printf "%s\n" $fisher_alias | sed 's/[=,]/ /g' | while read -la alias
if set -q alias[2]
switch "$value"
case $alias[2..-1]
set value $alias[1]
break
end
end
end
if not functions -q "fisher_$value"
printf "fisher: '%s' is not a valid command\n" "$value" >& 2
fisher --help >& 2 | head -n1 >& 2
return 1
end
set -e argv[1]
if not eval "fisher_$value" (printf "%s\n" "'"$argv"'")
return 1
end
case validate
if not test -z "$value"
printf "%s\n" $value | fisher --validate | grep $quiet
return
end
if not set -q fisher_default_host
set fisher_default_host https://github.com
end
set -l id "[A-Za-z0-9_-]"
sed -En "
s#/\$##
s#\.git\$##
s#^(https?):*/* *(.*\$)#\1://\2#p
s#^(@|(gh:)|(github(.com)?[/:]))/?($id+)/($id+)\$#https://github.com/\5/\6#p
s#^(bb:)/?($id+)/($id+)\$#https://bitbucket.org/\2/\3#p
s#^(gl:)/?($id+)/($id+)\$#https://gitlab.com/\2/\3#p
s#^($id+)/($id+)\$#$fisher_default_host/\1/\2#p
/^file:\/\/\/.*/p
/^[a-z]+([._-]?[a-z0-9]+)*\$/p
" | grep $quiet
case path-in-cache
while read --prompt= -l item
switch "$item"
case \*/\*
for file in $fisher_cache/*
switch "$item"
case (git -C $file ls-remote --get-url | fisher --validate)
printf "%s\n" $file
break
end
end
case \*
printf "%s\n" $fisher_cache/$item
end
end
case file
switch "$value"
case "-"
set value /dev/stdin
case ""
set value $fisher_config/fishfile
end
awk '
!/^ *(#.*)*$/ {
gsub("#.*", "")
if (/^ *package .+/) {
$1 = $2
}
if (!k[$1]++) {
printf("%s\n", $1)
}
}
' $value
case version
sed 's/^/fisher version /;q' $fisher_home/VERSION
case help
if test -z "$value"
set value commands
end
printf "usage: fisher <command> [<options>] [--version] [--help]\n\n"
switch commands
case $value
printf "Available Fisherman commands:\n"
fisher_help --commands=bare
echo
end
switch guides
case $value
printf "Available Fisherman guides:\n"
fisher_help --guides=bare
echo
end
printf "Use 'fisher help -g' to list guides and other documentation.\n"
printf "See 'fisher help <command or concept>' to access a man page.\n"
end
end

@ -0,0 +1,109 @@
function fisher_help -d "Display Help Information"
if not set -q argv[1]
fisher --help
return 1
end
set -l option
set -l value
getopts $argv | while read -l 1 2
switch "$1"
case _
set option manual
set value $2
case a all
set option guides commands
set value $2
case g guides
set option $option guides
set value $2
case commands
set option $option commands
set value $2
case u usage
set option usage
set value $value $2
case h help
printf "usage: fisher help [<keyword>] [--all] [--guides]\n"
printf " [--usage[=<command>]] [--help]\n\n"
printf " -a --all List commands and guides \n"
printf " -g --guides List documentation guides \n"
printf " -u --usage[=<command>] Display command usage help \n"
printf " -h --help Show usage help \n"
return
case \*
printf "fisher: '%s' is not a valid option\n" $1 >& 2
fisher_help --help >& 2
return 1
end
end
if not set -q option[1]
set option commands
end
switch "$option"
case manual
switch "$value"
case fisherman
man $value 7
case fisher me @
man fisher
case \*
man fisher-$value
end
case usage
if test -z "$value"
sed -E 's/^ *([^ ]+).*/\1/' | while read -l value
if functions -q fisher_$value
fisher $value --help
end
end
else
printf "%s\n" $value | fisher_help --usage
end
case \*
switch "$value"
case bare
case \*
fisher --help=$option
return
end
switch commands
case $option
functions -a | grep '^fisher_[^_]*$' | while read -l f
functions $f | awk '
/^$/ { next }
{
printf(" %s\t", substr($2, 8))
gsub("\'","")
for (i=4; i<=NF && $i!~/^--.*/; i++) {
printf("%s ", $i)
}
print ""
exit
}'
end | column -ts\t
end
switch guides
case $option
sed -nE 's/(fisher-)?(.+)\([0-9]\) -- (.+)/ \2'\t'\3/p' \
{$fisher_home,$fisher_config}/man/man{5,7}/fisher*.md | sort -r
end | column -ts\t
end
end

@ -0,0 +1,159 @@
function fisher_install -d "Enable / Install Plugins"
set -l items
set -l error /dev/stderr
getopts $argv | while read -l 1 2
switch "$1"
case _
set items $items $2
case q quiet
set error /dev/null
case h help
printf "usage: fisher install [<name | url> ...] [--quiet] [--help]\n\n"
printf " -q --quiet Enable quiet mode\n"
printf " -h --help Show usage help\n"
return
case \*
printf "fisher: '%s' is not a valid option\n" $1 >& 2
fisher_install --help >& 2
return 1
end
end
set -l count 0
set -l duration (date +%s)
set -l total (count $items)
if set -q items[1]
printf "%s\n" $items
else
fisher --file=-
end | fisher --validate | while read -l item
switch "$item"
case \*/\*
printf "%s %s\n" $item (
if not fisher_search --url=$item --field=name
printf "%s" $item | sed -E '
s/.*\/(.*)/\1/
s/^(plugin|theme|pkg|fish)-//'
end)
case \*
if set -l url (fisher_search --name=$item --field=url)
printf "%s %s\n" $url $item
else if test -d $fisher_cache/$item
printf "%s %s\n" (git -C $fisher_cache/$item ls-remote --get-url) $item
else
printf "fisher: '%s' not found\n" $item > $error
end
end
end | while read -l url name
printf "Installing " > $error
switch $total
case 0 1
printf ">> %s\n" $name > $error
case \*
printf "(%s of %s) >> %s\n" (math 1 + $count) $total $name > $error
end
mkdir -p $fisher_config/{cache,functions,completions,man}
set -l path $fisher_cache/$name
if not test -e $path
if not wait --spin=pipe --log=$fisher_error_log "
git clone --quiet --depth 1 $url $path"
printf "fisher: Repository not found: '%s'\n" $url > $error
continue
end
end
set -l bundle $path/fishfile
if test -e $path/bundle
set bundle $path/bundle
end
if test -e $bundle
printf "Resolving dependencies in %s\n" $name/(basename $bundle) > $error
set -l deps (fisher --file=$bundle \
| fisher_install ^&1 | sed -En 's/([0-9]+) plugin\/s.*/\1/p')
set count (math $count + 0$deps)
end
if test -s $path/Makefile -o -s $path/makefile
pushd $path
if not make > /dev/null ^ $error
popd
printf "fisher: Can't make '%s'\n" $name > $error
continue
end
popd
end
if test -e $path/fish_prompt.fish -o -e $path/fish_right_prompt.fish
rm -f $fisher_config/functions/{fish_prompt,fish_right_prompt}.fish
end
for file in $path/{*,functions{/*,/**/*}}.fish
set -l base (basename $file)
switch $base
case {init,uninstall}.fish
set base $name.config.$base
end
cp -f $file $fisher_config/functions/$base
end
source $fisher_config/functions/$name.fish > /dev/null ^& 1
cp -f $path/completions/*.fish $fisher_config/completions/ ^ /dev/null
for n in (seq 9)
if test -d $path/man/man$n
mkdir -p $fisher_config/man/man$n
end
cp -f $path/man/man$n/*.$n $fisher_config/man/man$n/ ^ /dev/null
end
set count (math $count + 1)
set -l file $fisher_config/fishfile
if test -s $file
if fisher --file=$file | grep -Eq "^$name\$|^$url\$"
continue
end
end
touch $file
if not fisher_search --name=$name --field=name --quiet
set name $url
end
printf "%s\n" "$name" >> $file
end
printf "%d plugin/s installed (%0.fs)\n" (math $count) (
math (date +%s) - $duration) > $error
if not test $count -gt 0
return 1
end
end

@ -0,0 +1,173 @@
function fisher_search -d "Search Fisherman Index"
set -l index $fisher_cache/.index
set -l select all
set -l fields
set -l join "||"
set -l query
set -l quiet 0
getopts $argv | while read -l 1 2 3
switch "$1"
case _ name url info author tag{,s}
switch "$1"
case _
switch "$2"
case \*/\*
set 1 url
set -l url (fisher --validate=$2)
if not test -z "$url"
set 2 $url
end
case \*
set 1 name
end
case tag{,s}
set 1 "find(tags, \"$2\")"
if test -z "$2"
set 1 "show(tags)"
end
end
switch "$2"
case ""
set fields $fields $1
continue
case {~,!~}\*
set 2 "$3$2"
case \?\*
if test "$3" = !
set 2 "!=\"$2\""
else
set 2 "==\"$2\""
end
end
set query "$query$join$1$2"
case s select
set select $2
case f field{,s}
switch "$2"
case T tag{,s}
set 2 "show(tags)"
end
set fields $fields $2
case a and
set join "&&"
case o or
set join "||"
case Q query
set query $query $2
case q quiet
set quiet 1
case h help
printf "usage: fisher search [<name | url>] [--select=<source>] [--field=<field>]\n"
printf " [--or|--and] [--quiet] [--help]\n\n"
printf " -s --select=<source> Select all, cache or remote plugins \n"
printf " -f --field=<field> Filter by name, url, info, tag or author \n"
printf " -a --and Join query with AND operator \n"
printf " -o --or Join query with OR operator \n"
printf " -q --quiet Enable quiet mode \n"
printf " -h --help Show usage help \n"
return
case \*
printf "fisher: '%s' is not a valid option\n" $1 >& 2
fisher_search --help >& 2
return 1
end
end
if not set -q fields[1]
set fields '$0'
end
set fields (printf "%s\n" $fields | paste -sd, -)
set query (printf "%s\n" $query | sed -E 's/^[\|&]+//')
switch "$select"
case all
if not fisher_update --quiet --index
if test -s $fisher_index
set index $fisher_index
end
end
if not cat $index ^ /dev/null
printf "fisher: '%s' invalid path or url\n" $index >& 2
return 1
end
case remote
fisher_search -a --name!=(
fisher_search --field=name --select=cache)
case cache
set -l names (for file in $fisher_cache/*
if test -d $file
basename $file
end
end)
if test -z "$names"
return 1
end
fisher_search --select=all --name=$names
end | awk -F'\n' -v RS='' -v OFS=';' (
if test "$fields" = '$0'
printf "%s\nORS=%s" -v '\\n\\n'
end) "
function find(array, item) {
for (i in array) {
if (array[i] == item) {
return item
}
}
}
function show(array) {
for (i in array) {
printf(\"%s \", array[i])
}
}
/^ *#/ { next }
{
delete tags
if (\$4) {
split(\$4, tags, \" \")
}
name = \$1
url = \$2
info = \$3
author = \$5
}
$query {
print $fields
}
" | sed '${/^$/d;}' | awk -v q=$quiet '
!/^ *$/ { ret = 1 }
!q { print }
q && !ret { exit !ret }
END { exit !ret }
'
end

@ -0,0 +1,129 @@
function fisher_uninstall -d "Disable / Uninstall Plugins"
set -l option
set -l items
set -l error /dev/stderr
getopts $argv | while read -l 1 2
switch "$1"
case _
set items $items $2
case a all
set option $option all
case f force
set option $option force
case q quiet
set error /dev/null
case help h
printf "usage: fisher uninstall [<name | url> ...] [--all] [--force] [--quiet]\n"
printf " [--help]\n\n"
printf " -a --all Uninstall all plugins \n"
printf " -f --force Delete copy from cache \n"
printf " -q --quiet Enable quiet mode \n"
printf " -h --help Show usage help \n"
return
case \*
printf "fisher: '%s' is not a valid option\n" $1 >& 2
fisher_uninstall --help >& 2
return 1
end
end
set -l count 0
set -l duration (date +%s)
set -l total (count $items)
switch all
case $option
set -l cache (find $fisher_cache/* -maxdepth 0 -type d)
set total (count $cache)
printf "%s\n" $cache
case \*
if set -q items[1]
printf "%s\n" $items
else
fisher --file=-
end | fisher --validate | fisher --path-in-cache
end | while read -l path
if not test -d "$path"
printf "fisher: '%s' not found\n" $path > $error
continue
end
set -l name (basename $path)
printf "Uninstalling " > $error
switch $total
case 0 1
printf ">> %s\n" $name > $error
case \*
printf "(%s of %s) >> %s\n" (math 1 + $count) $total $name > $error
end
set count (math $count + 1)
functions -e $name
for file in $path/{*,functions{/*,/**/*}}.fish
set -l base (basename $file)
switch $base
case {init,before.init,uninstall}.fish
set base $name.$base
end
rm -f $fisher_config/functions/$base
end
for file in $path/completions/*.fish
rm -f $fisher_config/completions/(basename $file)
end
for n in (seq 9)
if test -d $path/man/man$n
for file in $path/man/man$n/*.$n
rm -f $fisher_config/man/man$n/(basename $file)
end
end
end
git -C $path ls-remote --get-url ^ /dev/null | fisher --validate | read -l url
switch force
case $option
rm -rf $path
end
set -l file $fisher_config/fishfile
if not fisher --file=$file | grep -Eq "^$name\$|^$url\$"
continue
end
set -l tmp (mktemp)
if not sed -E '/^ *'(printf "%s|%s" $name $url | sed 's|/|\\\/|g'
)'([ #].*)*$/d' < $file > $tmp
rm -f $tmp
printf "fisher: can't delete '%s' from %s\n" $name $file > $error
return 1
end
mv -f $tmp $file
end
printf "%d plugin/s uninstalled (%0.fs)\n" $count (math (date +%s) - $duration) > $error
test $count -gt 0
end

@ -0,0 +1,149 @@
function fisher_update -d "Fisherman Update Manager"
set -l option
set -l path
set -l items
set -l error /dev/stderr
getopts $argv | while read -l 1 2
switch "$1"
case _
set items $items $2
case index
set option $option index
case s {,it,my,one}self fisher{,man}
set option $option self
case c cache
set option $option cache
case path
set option path
set path $2
case q quiet
if test -z "$2"
set 2 /dev/null
end
set error $2
case help h
printf "usage: fisher update [<name | url> ...] [--self] [--cache]\n"
printf " [--path=<path>] [--quiet] [--help]\n\n"
printf " -s --self Update Fisherman \n"
printf " -c --cache Update cached plugins \n"
printf " --path=<path> Update repository at given path \n"
printf " -q --quiet Enable quiet mode \n"
printf " -h --help Show usage help \n"
return
case \*
printf "fisher: '%s' is not a valid option\n" $1 >& 2
fisher_update --help >& 2
return 1
end
end
switch path
case $option
if not test -d $path
printf "fisher: '%s' invalid path\n" $path > $error
return 1
end
wait --spin=pipe --log=$fisher_error_log "
git -C $path checkout --quiet master ^/dev/null
git -C $path pull --quiet --rebase origin master"
return
end
switch index
case $option
mkdir -p $fisher_cache
set -l index $fisher_cache/.(random)
if not wait --spin=pipe --log=$fisher_error_log "curl -sS $fisher_index > $index"
rm -f $index
cat $fisher_error_log > $error
return 1
end
mv -f $index $fisher_cache/.index
end
switch self
case $option
set -l elap (date +%s)
printf "Updating >> Fisherman\n" > $error
if not fisher_update --path=$fisher_home --quiet=$error
return 1
end
printf "Done without errors (%0.fs)\n" (math (date +%s) - $elap) > $error
end
set -l elap (date +%s)
set -l count 0
set -l total (count $items)
switch cache
case $option
set -l cache (find $fisher_cache/* -maxdepth 0 -type d)
set total (count $cache)
printf "%s\n" $cache
case \*
if set -q items[1]
printf "%s\n" $items
else
if contains -- $option self
return
end
if contains -- $option index
return
end
fisher --file=-
end | fisher --validate | fisher --path-in-cache
end | while read -l path
if not test -d "$path"
printf "fisher: '%s' not found\n" $path > $error
continue
end
set -l name (basename $path)
printf "Updating " > $error
switch $total
case 0 1
printf ">> %s\n" $name > $error
case \*
printf "(%s of %s) >> %s\n" (math 1 + $count) $total $name > $error
end
if not fisher_update --path=$path --quiet=$error
sed -nE 's/.*(error|fatal): (.*)/error: \2/p' $fisher_error_log > $error
continue
end
fisher install $name --quiet
set count (math $count + 1)
end
printf "%d plugin/s updated (%0.fs)\n" $count (math (date +%s) - $elap) > $error
test $count -gt 0
end

@ -0,0 +1,33 @@
function getopts -d "Parse CLI options"
if not set -q argv[1]
return 1
end
printf "%s\n" $argv | sed -E '
s/^-([A-Za-z]+)/- \1 /
s/^--([A-Za-z0-9_-]+)(!?)=?(.*)/-- \1 \3 \2 /' | \
awk '
function add(k, v) { if (seen[k v]++) return; print k (v == "" ? "" : " "v) }
function pop() { return size <= 0 ? "_" : stack[size--] }
function push(k) { stack[++size] = k }
function flush() { while (size) add(pop()) }
$0 == "" { next }
done { add("_" , $1$2$3); next }
$1 == "--" && !$2 { done = 1 ; next }
$1 !~ /^-|^--/ { add( pop(), $0 ) ; next }
size { flush() }
$3 { for (i = 4; i <= NF; i++) $3 = $3" "$i }
$1 == "--" { if ($3 == "") push($2); else add($2, $3) }
$1 == "-" {
if ($2 == "") { print $1; next } else n = split($2, keys, "")
if ($3 == "") push(keys[n]); else add(keys[n], $3)
for (i = 1; i < n; i++) add(keys[i])
}
END { flush() }
'
end

@ -0,0 +1,4 @@
function man -d "Format and display manual pages"
set -lx MANPATH {$__fish_datadir,$fisher_config,$fisher_home}/man $MANPATH ""
command man $argv
end

@ -0,0 +1,131 @@
function wait -d "Run commands and wait with a spin"
set -l commands
set -l spinners
set -l time 0.03
set -l log
set -l format "@\r"
getopts $argv | while read -l 1 2
switch "$1"
case -
case _
set commands $commands ";$2"
case s spin spinner{,s} style
set spinners $spinners $2
case t time
set time $2
case l log
set log $2
case f format
set format $2
case h help
printf "usage: wait <commands> [--spin=<style>] [--time=<delay>] [--log=<file>] \n"
printf " [--format=<format>] [--help]\n\n"
printf " -s --spin=<style> Set spinner style\n"
printf " -t --time=<delay> Set spinner transition time delay\n"
printf " -l --log=<file> Output standard error to <file>\n"
printf " -f --format=<format> Use given <format> to display spinner\n"
printf " -h --help Show usage help\n"
return
case \*
printf "wait: '%s' is not a valid option\n" $1 >& 2
wait --help >& 2
return 1
end
end
if not set -q commands[1]
return 1
end
switch "$spinners"
case arc star pipe ball flip mixer caret
set -l arc "◜◠◝◞◡◟"
set -l star "+x*"
set -l pipe "-\\|/"
set -l ball "▖▘▝▗"
set -l flip "___-``'´-___"
set -l mixer "⠄⠆⠇⠋⠙⠸⠰⠠⠰⠸⠙⠋⠇⠆"
set -l caret "II||"
set spinners "$$spinners"
case bar{1,2,3,\?\?\*}
set -l bar
set -l bar1 "[" "=" " " "]" "%"
set -l bar2 "[" "#" " " "]" "%"
set -l bar3 "." "." " " " " "%"
switch "$spinners"
case \*{1,2,3}
case \*
printf "%s\n" $spinners | sed -E 's/^bar.?//;s/./& /g' | read -az bar
set spinners bar
end
set -l IFS \t
printf "%s\t" $$spinners | read -l open fill void close symbol
set spinners
for i in (seq 5 5 100)
if test -n "$symbol"
set symbol "$i%"
end
set -l gap (printf "$void%.0s" (seq (math 100 - $i)))
if test $i -ge 100
set gap ""
end
set spinners $spinners "$open"(printf "$fill%.0s" (seq $i))"$gap$close $symbol"
end
end
set -l tmp (mktemp)
fish -c "$commands" ^ $tmp &
if not set -q spinners[2]
set spinners (printf "%s\n" "$spinners" | grep -o .)
end
while true
if status --is-interactive
for i in $spinners
printf "$format" | awk -v t=$time -v i=(printf "%s" $i | sed 's/=/\\\=/') '
{
system("tput civis")
gsub("@", i)
printf("%s", $0)
system("sleep "t";tput cnorm")
}
' > /dev/stderr
end
end
if test -z (jobs)
printf "$format" | tr @ "\0" > /dev/stderr
break
end
end
if test -s $tmp
if set -q log[1]
nl -n ln -- $tmp > $log
end
rm -f $tmp
return 1
end
rm -f $tmp
end

@ -0,0 +1,91 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "FISHER\-HELP" "1" "January 2016" "" "fisherman"
.
.SH "NAME"
\fBfisher\-help\fR \- Display Help Information
.
.SH "SYNOPSIS"
fisher \fBhelp\fR [\fIkeyword\fR] [\fB\-\-all\fR] [\fB\-\-guides\fR] [\fB\-\-usage\fR[=\fIcommand\fR]] [\fB\-\-help\fR]
.
.br
.
.SH "USAGE"
fisher \fBhelp\fR \fIcommand\fR
.
.br
fisher \fBhelp\fR \fIconcept\fR
.
.br
fisher \fBhelp\fR \fB\-\-usage\fR=[\fIcommand\fR]
.
.SH "DESCRIPTION"
Help displays \fIcommand\fR documentation, usage, guides and tutorials\.
.
.P
Help is based in \fBman\fR(1) pages\. To supply help with your own plugin or command, create one or more man\.\fB1~7\fR pages and add them to your project under the corresponding \fBman/man%\fR directory\.
.
.IP "" 4
.
.nf
my_plugin
|\-\- my_plugin\.fish
|\-\- man
|\-\- man1
|\-\- my_plugin\.1
.
.fi
.
.IP "" 0
.
.P
This will allow you to invoke \fBman\fR my_plugin\. To add documentation to a command, prepend the keyword \fBfisher\-\fR to the man file, e\.g\., \fBfisher\-\fRmy\-command\.1\. This will allow you to access the man page via \fBfisher help my\-command\fR\.
.
.P
There are utilities that can help you generate man pages from other text formats, such as Markdown\. One example is \fBronn\fR(1)\. For a standalone example see \fBfisher help plugins\fR#{\fBExample\fR}\.
.
.SH "OPTIONS"
.
.TP
\fB\-\-commands\fR[=\fIbare\fR]
List commands\. This is the default behavior of \fBfisher help\fR\. Use \fIbare\fR for easy to parse output\.
.
.TP
\fB\-a\fR \fB\-\-all\fR
List commands and guides\. Display all the available documentation\.
.
.TP
\fB\-g\fR \fB\-\-guides\fR[=\fIbare\fR]
List guides / tutorials\. Use \fIbare\fR for easy to parse output\.
.
.TP
\fB\-u\fR \fB\-\-usage\fR[=\fIcommand\fR]
Display usage help for \fIcommand\fR\. To supply usage help with a command, \fIcommand\fR must accept a \fB\-\-help\fR option\.
.
.TP
\fB\-h\fR \fB\-\-help\fR
Show usage help\.
.
.SH "EXAMPLES"
Display usage help for all Fisherman commands\.
.
.IP "" 4
.
.nf
fisher help \-\-commands=bare | fisher help \-\-usage
.
.fi
.
.IP "" 0
.
.SH "SEE ALSO"
\fBfisher\fR(1)
.
.br
\fBfisher help plugins\fR#{\fBExample\fR}
.
.br

@ -0,0 +1,60 @@
fisher-help(1) -- Display Help Information
==========================================
## SYNOPSIS
fisher `help` [*keyword*] [`--all`] [`--guides`] [`--usage`[=*command*]] [`--help`] <br>
## USAGE
fisher `help` *command*<br>
fisher `help` *concept*<br>
fisher `help` `--usage`=[*command*]
## DESCRIPTION
Help displays *command* documentation, usage, guides and tutorials.
Help is based in `man`(1) pages. To supply help with your own plugin or command, create one or more man.`1~7` pages and add them to your project under the corresponding `man/man%` directory.
```
my_plugin
|-- my_plugin.fish
|-- man
|-- man1
|-- my_plugin.1
```
This will allow you to invoke `man` my_plugin. To add documentation to a command, prepend the keyword `fisher-` to the man file, e.g., `fisher-`my-command.1. This will allow you to access the man page via `fisher help my-command`.
There are utilities that can help you generate man pages from other text formats, such as Markdown. One example is `ronn`(1). For a standalone example see `fisher help plugins`#{`Example`}.
## OPTIONS
* `--commands`[=*bare*]:
List commands. This is the default behavior of `fisher help`. Use *bare* for easy to parse output.
* `-a` `--all`:
List commands and guides. Display all the available documentation.
* `-g` `--guides`[=*bare*]:
List guides / tutorials. Use *bare* for easy to parse output.
* `-u` `--usage`[=*command*]:
Display usage help for *command*. To supply usage help with a command, *command* must accept a `--help` option.
* `-h` `--help`:
Show usage help.
## EXAMPLES
Display usage help for all Fisherman commands.
```
fisher help --commands=bare | fisher help --usage
```
## SEE ALSO
`fisher`(1)<br>
`fisher help plugins`#{`Example`}<br>

@ -0,0 +1,136 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "FISHER\-INSTALL" "1" "January 2016" "" "fisherman"
.
.SH "NAME"
\fBfisher\-install\fR \- Enable / Install plugins
.
.SH "SYNOPSIS"
fisher \fBinstall\fR [\fIname\fR or \fIurl\fR \.\.\.] [\fB\-\-quiet\fR] [\fB\-\-help\fR]
.
.SH "USAGE"
fisher \fBinstall\fR \fIplugin\fR \.\.\.
.
.br
fisher \fBinstall\fR \fIowner/repo\fR \.\.\.
.
.br
.
.SH "DESCRIPTION"
Install one or \fImore\fR plugins by \fIname\fR, searching \fB$fisher_index\fR or by \fIurl\fR\. If no arguments are given, read the standard input\.
.
.P
If a copy of the plugin already exists in \fB$fisher_cache\fR, the relevant files are copied to \fB$fisher_config\fR/functions, otherwise the plugin repository is first downloaded\. If you wish to update a plugin, use \fBfisher update\fR instead\.
.
.P
If the plugin declares any dependencies, they will be installed as well\. If any dependencies are already installed they will not be updated in order to prevent mismatching version issues\. See \fBfisher help fishfile\fR#{\fBPlugins\fR}\.
.
.P
If a plugin includes either a fish_prompt\.\fBfish\fR or fish_right_prompt\.\fBfish\fR, both files are first removed from \fB$fisher_config\fR/functions and then the new one\fIs\fR are copied\.
.
.SH "OPTIONS"
.
.TP
\fB\-q\fR \fB\-\-quiet\fR
Enable quiet mode\.
.
.TP
\fB\-h\fR \fB\-\-help\fR
Show usage help\.
.
.SH "PROCESS"
Here is a typical install process breakdown for \fIplugin\fR:
.
.IP "1." 4
Check if \fIplugin\fR exists in \fB$fisher_index\fR\. Fail otherwise\.
.
.IP "2." 4
Download \fIplugin\fR to \fB$fisher_cache\fR if it is not there already\.
.
.IP "3." 4
Copy all \fB*\.fish\fR and functions/\fB*\.fish\fR files to \fB$fisher_config\fR/functions\.
.
.IP "4." 4
Copy all completions/\fB*\.fish\fR to \fB$fisher_config\fR/completions\.
.
.IP "5." 4
Copy all man/man[\fB1\-7\fR] to \fB$fisher_config\fR/man/man\fB%\fR
.
.IP "" 0
.
.P
Here is the \fIplugin\fR tree inside the cache:
.
.P
\fB$fisher_cache\fR/\fIplugin\fR
.
.br
|\-\- README\.md
.
.br
|\-\- \fIplugin\fR\.fish
.
.br
|\-\- functions
.
.br
| |\-\- plugin_helper\.fish
.
.br
|\-\- completions
.
.br
| |\-\- \fIplugin\fR\.fish
.
.br
|\-\- test
.
.br
| |\-\- \fIplugin\fR\.fish
.
.br
|\-\- man
.
.br
|\-\- man1
.
.br
|\-\- \fIplugin\fR\.1
.
.br
.
.P
And here is how files are copied from \fB$fisher_cache\fR/plugin to \fB$fisher_config\fR:
.
.IP "1." 4
\fIplugin\fR\.fish \fB\->\fR $fisher_config/functions
.
.IP "2." 4
functions/plugin_helper\.fish \fB\->\fR $fisher_config/functions
.
.IP "3." 4
completions/\fIplugin\fR\.fish \fB\->\fR $fisher_config/completions
.
.IP "4." 4
man/man1/\fIplugin\fR\.1 \fB\->\fR $fisher_config/man/man1
.
.IP "" 0
.
.SH "SEE ALSO"
\fBfisher\fR(1)
.
.br
\fBfisher help config\fR
.
.br
\fBfisher help update\fR
.
.br
\fBfisher help uninstall\fR
.
.br
\fBfisher help fishfile\fR#{\fBPlugins\fR}
.
.br

@ -0,0 +1,71 @@
fisher-install(1) -- Enable / Install plugins
=============================================
## SYNOPSIS
fisher `install` [*name* or *url* ...] [`--quiet`] [`--help`]
## USAGE
fisher `install` *plugin* ...<br>
fisher `install` *owner/repo* ...<br>
## DESCRIPTION
Install one or *more* plugins by *name*, searching `$fisher_index` or by *url*. If no arguments are given, read the standard input.
If a copy of the plugin already exists in `$fisher_cache`, the relevant files are copied to `$fisher_config`/functions, otherwise the plugin repository is first downloaded. If you wish to update a plugin, use `fisher update` instead.
If the plugin declares any dependencies, they will be installed as well. If any dependencies are already installed they will not be updated in order to prevent mismatching version issues. See `fisher help fishfile`#{`Plugins`}.
If a plugin includes either a fish_prompt.`fish` or fish_right_prompt.`fish`, both files are first removed from `$fisher_config`/functions and then the new one*s* are copied.
## OPTIONS
* `-q` `--quiet`:
Enable quiet mode.
* `-h` `--help`:
Show usage help.
## PROCESS
Here is a typical install process breakdown for *plugin*:
1. Check if *plugin* exists in `$fisher_index`. Fail otherwise.
2. Download *plugin* to `$fisher_cache` if it is not there already.
3. Copy all `*.fish` and functions/`*.fish` files to `$fisher_config`/functions.
4. Copy all completions/`*.fish` to `$fisher_config`/completions.
5. Copy all man/man[`1-7`] to `$fisher_config`/man/man`%`
Here is the *plugin* tree inside the cache:
`$fisher_cache`/*plugin*<br>
|-- README.md<br>
|-- *plugin*.fish<br>
|-- functions<br>
| |-- plugin_helper.fish<br>
|-- completions<br>
| |-- *plugin*.fish<br>
|-- test<br>
| |-- *plugin*.fish<br>
|-- man<br>
|-- man1<br>
|-- *plugin*.1<br>
And here is how files are copied from `$fisher_cache`/plugin to `$fisher_config`:
1. *plugin*.fish `->` $fisher_config/functions
2. functions/plugin_helper.fish `->` $fisher_config/functions
3. completions/*plugin*.fish `->` $fisher_config/completions
4. man/man1/*plugin*.1 `->` $fisher_config/man/man1
## SEE ALSO
`fisher`(1)<br>
`fisher help config`<br>
`fisher help update`<br>
`fisher help uninstall`<br>
`fisher help fishfile`#{`Plugins`}<br>

@ -0,0 +1,249 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "FISHER\-SEARCH" "1" "January 2016" "" "fisherman"
.
.SH "NAME"
\fBfisher\-search\fR \- Search Fisherman Index
.
.SH "SYNOPSIS"
fisher \fBsearch\fR [\fIname\fR or \fIurl\fR]
.
.br
fisher \fBsearch\fR [\fB\-\-select\fR=\fIall\fR|\fIcache\fR|\fIremote\fR]
.
.br
fisher \fBsearch\fR [\fB\-\-field\fR=\fIname\fR|\fIurl\fR|\fIinfo\fR|\fItag\fR|\fIauthor\fR]
.
.br
fisher \fBsearch\fR [\fB\-\-\fR\fIfield\fR=\fImatch\fR]
.
.br
fisher \fBsearch\fR [\fB\-\-\fR\fIfield\fR~\fB/\fR\fIregex\fR\fB/\fR]
.
.br
fisher \fBsearch\fR [\fB\-\-query\fR=\fIfield\fR[\fB&&\fR,\fB||\fR]\fIfield\fR\.\.\.]
.
.br
fisher \fBsearch\fR [\fB\-\-and\fR] [\fB\-\-or\fR] [\fB\-\-quiet\fR] [\fB\-\-help\fR]
.
.br
.
.SH "USAGE"
fisher \fBsearch\fR \fIplugin\fR
.
.br
fisher \fBsearch\fR \fIowner/repo\fR
.
.br
fisher \fBsearch\fR \-\-field=\fIname\fR \-\-select=all | column
.
.br
fisher \fBsearch\fR \-\-tag=tag1 \-\-and \-\-tag=tag2
.
.SH "DESCRIPTION"
Search the Fisherman index database\. You can use a custom index file by setting \fB$fisher_index\fR to your preferred url or file\. See \fBfisher help config\fR and \fBfisher\fR(7)#{\fBIndex\fR}\.
.
.P
A copy of the index is downloaded each time a search query happens, keeping the index up to date all the time\.
.
.P
The index file consists of records separated by blank lines \fB\'\en\en\'\fR and each record consists of fields separated by a single line \fB\'\en\'\fR\.
.
.IP "" 4
.
.nf
name
url
info | description
tag1 tag2 \.\.\.
author
.
.fi
.
.IP "" 0
.
.P
See #{\fBOutput\fR} for more information\.
.
.SH "OPTIONS"
.
.TP
\fB\-s\fR \fB\-\-select\fR[=\fIall\fR|\fIcache\fR|\fIremote\fR]
Select record set\. \-\-select=\fIcache\fR queries only local plugins, i\.e\., those inside \fB$fisher_cache\fR\. \-\-select=\fIremote\fR queries all plugins not in the cache\. \-\-select=\fIall\fR queries everything\.
.
.TP
\fB\-f\fR \fB\-\-field\fR=\fIname\fR|\fIurl\fR|\fIinfo\fR|\fItag\fR|\fIauthor\fR
Display only given fields from the result record set\. Use \fB\-\-select\fR to filter the record set\. Use \-\-\fIfield\fR instead as a shortcut, i\.e\., \fB\-\-name\fR is equivalent to \fB\-\-field\fR=name\.
.
.TP
\-\-\fIfield\fR[=\fImatch\fR]
Filter the result set by \fIfield\fR=\fImatch\fR, where \fIfield\fR can be any of \fBname\fR, \fBurl\fR, \fBinfo\fR, \fBtag\fR or \fBauthor\fR\. If \fImatch\fR is not given, this is equivalent to \fB\-\-select\fR=\fIfield\fR\. Use \fB!=\fR to negate the query\.
.
.TP
\-\-\fIfield\fR[~\fB/\fR\fIregex\fR\fB/\fR]
Essentially the same as \-\-\fIfield\fR=\fImatch\fR, but with Regular Expression support\. \-\-\fIfield\fR~\fB/\fR\fIregex\fR\fB/\fR filters the result set using the given \fB/\fR\fIregex\fR\fB/\fR\. For example, \-\-name=\fB/\fR^\fImatch\fR$\fB/\fR is essentially the same as \-\-\fIfield\fR=\fImatch\fR and \-\-url~\fB/\fRoh\-my\-fish\fB/\fR selects only Oh My Fish! plugins\. Use \fB!~\fR to negate the query\.
.
.TP
\fB\-a\fR \fB\-\-and\fR
Join query with a logical AND operator\.
.
.TP
\fB\-o\fR \fB\-\-or\fR
Join query with a logical OR operator\. This the default operator for each query operation\.
.
.TP
\fB\-Q\fR \fB\-\-query\fR=\fIfield\fR[\fB&&\fR,\fB||\fR]\fIfield\fR\.\.\.
Use a custom search expression\. For example, \-\-query=\'name~\fB/\fR[0\-9]\fB/\fR||name~\fB/\fR^[xyz]\fB/\fR\' selects all plugins that contain numbers in their name \fIor\fR begin with the characters \fIx\fR, \fIy\fR or \fIz\fR\.
.
.TP
\fB\-q\fR \fB\-\-quiet\fR
Enable quiet mode\.
.
.TP
\fB\-h\fR \fB\-\-search\fR
Show usage search\.
.
.SH "OUTPUT"
The default behavior is to print the result set to standard output in its original format\.
.
.IP "" 4
.
.nf
fisher search bobthefish shark
.
.fi
.
.IP "" 0
.
.P
\fB\.\.\.\fR
.
.IP "" 4
.
.nf
bobthefish
https://github\.com/oh\-my\-fish/theme\-bobthefish
A Powerline\-style, Git\-aware fish theme optimized for awesome
theme powerline awesome
bobthecow
shark
https://github\.com/bucaran/shark
Sparklines for your Fish
chart tool
bucaran
.
.fi
.
.IP "" 0
.
.P
Search is optimized for parsing when using filters: \fB\-\-name\fR, \fB\-\-url\fR, \fB\-\-info\fR, \fB\-\-tags\fR, \fB\-\-author\fR or \fB\-\-field\fR=\fIname\fR|\fIurl\fR|\fIinfo\fR|\fItag\fR|\fIauthor\fR\.
.
.IP "" 4
.
.nf
fisher search bobthefish shark \-\-name \-\-url
.
.fi
.
.IP "" 0
.
.P
\fB\.\.\.\fR
.
.IP "" 4
.
.nf
bobthefish;https://github\.com/oh\-my\-fish/theme\-bobthefish
shark;https://github\.com/bucaran/shark
.
.fi
.
.IP "" 0
.
.P
The result set above consists of single line \fB\'\en\'\fR separated records where each record consists of one or more of the given fields separated by a semicolon \fB\';\'\fR\.
.
.SH "EXAMPLES"
Display all plugins by name and format into multiple columns\.
.
.IP "" 4
.
.nf
fisher search \-\-name | column
.
.fi
.
.IP "" 0
.
.P
Display all plugins by url, sans \fIhttps://github\.com/\fR and format into multiple columns\.
.
.IP "" 4
.
.nf
fisher search \-\-field=url \-\-select=all | sed \'s|https://github\.com/||\' | column
.
.fi
.
.IP "" 0
.
.P
Display all remote plugins by name tagged as \fIa\fR or \fIb\fR\.
.
.IP "" 4
.
.nf
fisher search \-\-select=remote \-\-name \-\-tag=github \-\-or \-\-tag=tool
.
.fi
.
.IP "" 0
.
.P
Search plugins from a list of one or more urls and / or names and display their authors\.
.
.IP "" 4
.
.nf
fisher search $urls $names \-\-url
.
.fi
.
.IP "" 0
.
.P
Search all plugins in the cache whose name does not start with the letter \fBs\fR\.
.
.IP "" 4
.
.nf
fisher search \-\-select=cache \-\-name~/^[^s]/
.
.fi
.
.IP "" 0
.
.SH "SEE ALSO"
\fBfisher\fR(1)
.
.br
\fBfisher\fR(7){\fBIndex\fR}
.
.br
\fBfisher help plugins\fR
.
.br

@ -0,0 +1,143 @@
fisher-search(1) -- Search Fisherman Index
==========================================
## SYNOPSIS
fisher `search` [*name* or *url*]<br>
fisher `search` [`--select`=*all*|*cache*|*remote*]<br>
fisher `search` [`--field`=*name*|*url*|*info*|*tag*|*author*]<br>
fisher `search` [`--`*field*=*match*] <br>
fisher `search` [`--`*field*~`/`*regex*`/`] <br>
fisher `search` [`--query`=*field*[`&&`,`||`]*field*...]<br>
fisher `search` [`--and`] [`--or`] [`--quiet`] [`--help`]<br>
## USAGE
fisher `search` *plugin*<br>
fisher `search` *owner/repo*<br>
fisher `search` --field=*name* --select=all | column<br>
fisher `search` --tag=tag1 --and --tag=tag2
## DESCRIPTION
Search the Fisherman index database. You can use a custom index file by setting `$fisher_index` to your preferred url or file. See `fisher help config` and `fisher`(7)#{`Index`}.
A copy of the index is downloaded each time a search query happens, keeping the index up to date all the time.
The index file consists of records separated by blank lines `'\n\n'` and each record consists of fields separated by a single line `'\n'`.
```
name
url
info | description
tag1 tag2 ...
author
```
See #{`Output`} for more information.
## OPTIONS
* `-s` `--select`[=*all*|*cache*|*remote*]:
Select record set. --select=*cache* queries only local plugins, i.e., those inside `$fisher_cache`. --select=*remote* queries all plugins not in the cache. --select=*all* queries everything.
* `-f` `--field`=*name*|*url*|*info*|*tag*|*author*:
Display only given fields from the result record set. Use `--select` to filter the record set. Use --*field* instead as a shortcut, i.e., `--name` is equivalent to `--field`=name.
* --*field*[=*match*]:
Filter the result set by *field*=*match*, where *field* can be any of `name`, `url`, `info`, `tag` or `author`. If *match* is not given, this is equivalent to `--select`=*field*. Use `!=` to negate the query.
* --*field*[~`/`*regex*`/`]:
Essentially the same as --*field*=*match*, but with Regular Expression support. --*field*~`/`*regex*`/` filters the result set using the given `/`*regex*`/`. For example, --name=`/`^*match*$`/` is essentially the same as --*field*=*match* and --url~`/`oh-my-fish`/` selects only Oh My Fish! plugins. Use `!~` to negate the query.
* `-a` `--and`:
Join query with a logical AND operator.
* `-o` `--or`:
Join query with a logical OR operator. This the default operator for each query operation.
* `-Q` `--query`=*field*[`&&`,`||`]*field*...:
Use a custom search expression. For example, --query='name~`/`[0-9]`/`||name~`/`^[xyz]`/`' selects all plugins that contain numbers in their name *or* begin with the characters *x*, *y* or *z*.
* `-q` `--quiet`:
Enable quiet mode.
* `-h` `--search`:
Show usage search.
## OUTPUT
The default behavior is to print the result set to standard output in its original format.
```
fisher search bobthefish shark
```
`...`
```
bobthefish
https://github.com/oh-my-fish/theme-bobthefish
A Powerline-style, Git-aware fish theme optimized for awesome
theme powerline awesome
bobthecow
shark
https://github.com/bucaran/shark
Sparklines for your Fish
chart tool
bucaran
```
Search is optimized for parsing when using filters: `--name`, `--url`, `--info`, `--tags`, `--author` or `--field`=*name*|*url*|*info*|*tag*|*author*.
```
fisher search bobthefish shark --name --url
```
`...`
```
bobthefish;https://github.com/oh-my-fish/theme-bobthefish
shark;https://github.com/bucaran/shark
```
The result set above consists of single line `'\n'` separated records where each record consists of one or more of the given fields separated by a semicolon `';'`.
## EXAMPLES
Display all plugins by name and format into multiple columns.
```
fisher search --name | column
```
Display all plugins by url, sans *https://github.com/* and format into multiple columns.
```
fisher search --field=url --select=all | sed 's|https://github.com/||' | column
```
Display all remote plugins by name tagged as *a* or *b*.
```
fisher search --select=remote --name --tag=github --or --tag=tool
```
Search plugins from a list of one or more urls and / or names and display their authors.
```
fisher search $urls $names --url
```
Search all plugins in the cache whose name does not start with the letter `s`.
```
fisher search --select=cache --name~/^[^s]/
```
## SEE ALSO
`fisher`(1)<br>
`fisher`(7){`Index`}<br>
`fisher help plugins`<br>

@ -0,0 +1,72 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "FISHER\-UNINSTALL" "1" "January 2016" "" "fisherman"
.
.SH "NAME"
\fBfisher\-uninstall\fR \- Disable / Uninstall Plugins
.
.SH "SYNOPSIS"
fisher \fBuninstall\fR [\fIname\fR or \fIurl\fR \.\.\.]
.
.br
fisher \fBuninstall\fR [\fB\-\-all\fR] [\fB\-\-force\fR] [\fB\-\-quiet\fR] [\fB\-\-help\fR]
.
.br
.
.SH "USAGE"
fisher \fBuninstall\fR \fIplugin\fR \.\.\.
.
.br
fisher \fBuninstall\fR \fIowner/repo\fR \.\.\.
.
.br
.
.SH "DESCRIPTION"
Uninstall one or \fImore\fR plugins by \fIname\fR, searching \fB$fisher_index\fR or by \fIurl\fR\. If no arguments are given, read the standard input\. This process is the inverse of Install\. See \fBfisher help install\fR\.
.
.P
Uninstall does not remove any copies of the given plugin in \fB$fisher_cache\fR\. To erase the copy from the cache, use the \fB\-\-force\fR option\.
.
.P
Uninstall does not remove dependencies installed along with other plugins\. This behavior prevents breaking plugins that share the same dependency\. See \fBfisher\fR(7){\fBFlat Tree\fR}\.
.
.SH "OPTIONS"
.
.TP
\fB\-a\fR \fB\-\-all\fR
Uninstall all plugins\.
.
.TP
\fB\-f\fR \fB\-\-force\fR
Delete copy from cache\.
.
.TP
\fB\-q\fR \fB\-\-quiet\fR
Enable quiet mode\.
.
.TP
\fB\-h\fR \fB\-\-help\fR
Show usage help\.
.
.SH "EXAMPLES"
Uninstall all installed plugins and flushing the cache as well\.
.
.IP "" 4
.
.nf
fisher uninstall \-\-all \-\-force
.
.fi
.
.IP "" 0
.
.SH "SEE ALSO"
\fBfisher\fR(1)
.
.br
\fBfisher help plugins\fR
.
.br

@ -0,0 +1,48 @@
fisher-uninstall(1) -- Disable / Uninstall Plugins
==================================================
## SYNOPSIS
fisher `uninstall` [*name* or *url* ...] <br>
fisher `uninstall` [`--all`] [`--force`] [`--quiet`] [`--help`] <br>
## USAGE
fisher `uninstall` *plugin* ...<br>
fisher `uninstall` *owner/repo* ...<br>
## DESCRIPTION
Uninstall one or *more* plugins by *name*, searching `$fisher_index` or by *url*. If no arguments are given, read the standard input. This process is the inverse of Install. See `fisher help install`.
Uninstall does not remove any copies of the given plugin in `$fisher_cache`. To erase the copy from the cache, use the `--force` option.
Uninstall does not remove dependencies installed along with other plugins. This behavior prevents breaking plugins that share the same dependency. See `fisher`(7){`Flat Tree`}.
## OPTIONS
* `-a` `--all`:
Uninstall all plugins.
* `-f` `--force`:
Delete copy from cache.
* `-q` `--quiet`:
Enable quiet mode.
* `-h` `--help`:
Show usage help.
## EXAMPLES
Uninstall all installed plugins and flushing the cache as well.
```
fisher uninstall --all --force
```
## SEE ALSO
`fisher`(1)<br>
`fisher help plugins`<br>

@ -0,0 +1,66 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "FISHER\-UPDATE" "1" "January 2016" "" "fisherman"
.
.SH "NAME"
\fBfisher\-update\fR \- Fisherman Update Manager
.
.SH "SYNOPSIS"
fisher \fBupdate\fR [\fIname\fR or \fIurl\fR \.\.\.]
.
.br
fisher \fBupdate\fR [\fB\-\-self\fR] [\fB\-\-cache\fR] [\fB\-\-quiet\fR] [\fB\-\-help\fR]
.
.br
fisher \fBupdate\fR [\fB\-\-path\fR=\fIpath\fR]
.
.br
.
.SH "USAGE"
fisher \fBupdate\fR \fIplugin\fR \.\.\.
.
.br
fisher \fBupdate\fR \fIowner/repo\fR \.\.\.
.
.br
.
.SH "DESCRIPTION"
Update one or \fImore\fR plugins by \fIname\fR, searching \fB$fisher_index\fR or by \fIurl\fR\. If no arguments are given, read the standard input\. If you try to update a plugin that is currently disabled, but available in the cache, it will be updated and then enabled\.
.
.P
If a plugin is missing dependencies, they will be installed\. If any dependencies are already installed they will not be updated in order to prevent mismatching version issues\. See \fBfisher help fishfile\fR#{\fBPlugins\fR}\.
.
.SH "OPTIONS"
.
.TP
\fB\-s\fR \fB\-\-self\fR
Update Fisherman\.
.
.TP
\fB\-c\fR \fB\-\-cache\fR
Update all plugins in the cache\. Updates plugins that are currently disabled and enables them\.
.
.TP
\fB\-\-path\fR=\fIpath\fR
Update repository at given path\. The update mechanism is based in Git, via \fBgit pull \-\-rebase\fR\.
.
.TP
\fB\-q\fR \fB\-\-quiet\fR
Enable quiet mode\.
.
.TP
\fB\-h\fR \fB\-\-help\fR
Show usage help\.
.
.SH "SEE ALSO"
\fBfisher\fR(1)
.
.br
\fBfisher help fishfile\fR#{\fBPlugins\fR}
.
.br
\fBfisher help plugins\fR
.
.br

@ -0,0 +1,42 @@
fisher-update(1) -- Fisherman Update Manager
============================================
## SYNOPSIS
fisher `update` [*name* or *url* ...] <br>
fisher `update` [`--self`] [`--cache`] [`--quiet`] [`--help`] <br>
fisher `update` [`--path`=*path*] <br>
## USAGE
fisher `update` *plugin* ...<br>
fisher `update` *owner/repo* ...<br>
## DESCRIPTION
Update one or *more* plugins by *name*, searching `$fisher_index` or by *url*. If no arguments are given, read the standard input. If you try to update a plugin that is currently disabled, but available in the cache, it will be updated and then enabled.
If a plugin is missing dependencies, they will be installed. If any dependencies are already installed they will not be updated in order to prevent mismatching version issues. See `fisher help fishfile`#{`Plugins`}.
## OPTIONS
* `-s` `--self`:
Update Fisherman.
* `-c` `--cache`:
Update all plugins in the cache. Updates plugins that are currently disabled and enables them.
* `--path`=*path*:
Update repository at given path. The update mechanism is based in Git, via `git pull --rebase`.
* `-q` `--quiet`:
Enable quiet mode.
* `-h` `--help`:
Show usage help.
## SEE ALSO
`fisher`(1)<br>
`fisher help fishfile`#{`Plugins`}<br>
`fisher help plugins`<br>

@ -0,0 +1,135 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "FISHER" "1" "January 2016" "" "fisherman"
.
.SH "NAME"
\fBfisher\fR \- fish shell manager
.
.SH "SYNOPSIS"
\fBfisher\fR \fIcommand\fR [\fIoptions\fR] [\fB\-\-version\fR] [\fB\-\-help\fR]
.
.br
\fBfisher\fR \fB\-\-file\fR=\fIfishfile\fR
.
.br
\fBfisher\fR \fB\-\-validate\fR=\fIname\fR or \fIurl\fR
.
.br
.
.SH "DESCRIPTION"
Fisherman is a shell manager for \fBfish\fR(1) that lets you share and reuse code, prompts and configurations easily\.
.
.P
The following commands: \fIinstall\fR, \fIuninstall\fR, \fIupdate\fR, \fIsearch\fR and \fIhelp\fR are available by default\. See \fBfisher\fR help \fIcommand\fR for information about each command\.
.
.SH "OPTIONS"
.
.TP
\fB\-f\fR \fB\-\-file\fR=\fIfishfile\fR
Read \fIfishfile\fR and write contents to standard output\. If \fIfishfile\fR is null or an empty string, your user \fIfishfile\fR in \fB$fisher_config\fR/fishfile will be used instead\. Use a dash \fB\-\fR to force reading from the standard input\. Oh My Fish! bundle files are supported too\.
.
.TP
\fB\-V\fR, \fB\-\-validate\fR=\fIkeyword\fR
Validate a \fIname\fR or \fIurl\fR\. If \fIkeyword\fR resembles a url, the algorithm will attempt to normalize the url by adding / removing missing components\. Otherwise, it will assume \fIkeyword\fR is a potential plugin name and use the following regex \fB^[a\-z]+[\._\-]?[a\-z0\-9]+\fR to validate the string\. This method is used internally to validate user input and support url variations such as \fIowner/repo\fR, \fIgh:owner/repo\fR, \fIbb:owner/repo\fR, etc\. See \fBfisher\fR(7)#{\fBPlugins\fR}\.
.
.IP
If \fIkeyword\fR is null or an empty string, \fB\-\-validate\fR reads keyword\fIs\fR from the standard input\.
.
.TP
\fB\-v\fR \fB\-\-version\fR
Show version information\. Fisherman\'s current version can be found in the VERSION file at the root of the project\. The version scheme is based in \fBSemantic Versioning\fR and uses Git annotated tags to track releases\.
.
.TP
\fB\-h\fR \fB\-\-help\fR
Show usage help\.
.
.SH "CUSTOM COMMANDS"
A Fisherman command is a function that you can invoke using \fBfisher\fR \fIcommand\fR [\fIoptions\fR]\. By convention, any function of the form \fBfisher_<my_command>\fR is registered as Fisherman command\. You can create plugins that add new commands as well as regular utilities\. See \fBfisher help commands\fR and \fBfisher help plugins\fR for more information\.
.
.SH "EXAMPLES"
.
.IP "\(bu" 4
Install a plugin\.
.
.IP "" 0
.
.IP "" 4
.
.nf
fisher install fishtape
fishtape \-\-help
.
.fi
.
.IP "" 0
.
.TP
Install plugins from fishfile or bundle:
.
.IP "" 4
.
.nf
fisher \-\-file=path/to/shared/fishfile | fisher install
.
.fi
.
.IP "" 0
.
.IP "\(bu" 4
Validate an url\.
.
.IP "" 0
.
.IP "" 4
.
.nf
echo a/b | fisher \-V
> https://github\.com/a/b
.
.fi
.
.IP "" 0
.
.SH "AUTHORS"
Fisherman was created and it is currently maintained by Jorge Bucaran \fIj@bucaran\.me\fR\.
.
.P
See AUTHORS file for a more complete list of contributors\.
.
.SH "SEE ALSO"
\fBfisher\fR(7)
.
.br
\fBfisher\fR help \fIhelp\fR
.
.br
\fBfisher\fR help \fIupdate\fR
.
.br
\fBfisher\fR help \fIsearch\fR
.
.br
\fBfisher\fR help \fIconfig\fR
.
.br
\fBfisher\fR help \fIinstall\fR
.
.br
\fBfisher\fR help \fIplugins\fR
.
.br
\fBfisher\fR help \fIcommands\fR
.
.br
\fBfisher\fR help \fIfishfile\fR
.
.br
\fBfisher\fR help \fIuninstall\fR
.
.br

@ -0,0 +1,75 @@
fisher(1) -- fish shell manager
===============================
## SYNOPSIS
`fisher` *command* [*options*] [`--version`] [`--help`]<br>
`fisher` `--file`=*fishfile*<br>
`fisher` `--validate`=*name* or *url*<br>
## DESCRIPTION
Fisherman is a shell manager for `fish`(1) that lets you share and reuse code, prompts and configurations easily.
The following commands: *install*, *uninstall*, *update*, *search* and *help* are available by default. See `fisher` help *command* for information about each command.
## OPTIONS
* `-f` `--file`=*fishfile*:
Read *fishfile* and write contents to standard output. If *fishfile* is null or an empty string, your user *fishfile* in `$fisher_config`/fishfile will be used instead. Use a dash `-` to force reading from the standard input. Oh My Fish! bundle files are supported too.
* `-V`, `--validate`=*keyword*:
Validate a *name* or *url*. If *keyword* resembles a url, the algorithm will attempt to normalize the url by adding / removing missing components. Otherwise, it will assume *keyword* is a potential plugin name and use the following regex `^[a-z]+[._-]?[a-z0-9]+` to validate the string. This method is used internally to validate user input and support url variations such as *owner/repo*, *gh:owner/repo*, *bb:owner/repo*, etc. See `fisher`(7)#{`Plugins`}.
If *keyword* is null or an empty string, `--validate` reads keyword*s* from the standard input.
* `-v` `--version`:
Show version information. Fisherman's current version can be found in the VERSION file at the root of the project. The version scheme is based in `Semantic Versioning` and uses Git annotated tags to track releases.
* `-h` `--help`:
Show usage help.
## CUSTOM COMMANDS
A Fisherman command is a function that you can invoke using `fisher` *command* [*options*]. By convention, any function of the form `fisher_<my_command>` is registered as Fisherman command. You can create plugins that add new commands as well as regular utilities. See `fisher help commands` and `fisher help plugins` for more information.
## EXAMPLES
* Install a plugin.
```
fisher install fishtape
fishtape --help
```
* Install plugins from fishfile or bundle:
```
fisher --file=path/to/shared/fishfile | fisher install
```
* Validate an url.
```
echo a/b | fisher -V
> https://github.com/a/b
```
## AUTHORS
Fisherman was created and it is currently maintained by Jorge Bucaran *j@bucaran.me*.
See AUTHORS file for a more complete list of contributors.
## SEE ALSO
`fisher`(7)<br>
`fisher` help *help*<br>
`fisher` help *update*<br>
`fisher` help *search*<br>
`fisher` help *config*<br>
`fisher` help *install*<br>
`fisher` help *plugins*<br>
`fisher` help *commands*<br>
`fisher` help *fishfile*<br>
`fisher` help *uninstall*<br>

@ -0,0 +1,145 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "GETOPTS" "1" "January 2016" "" "fisherman"
.
.SH "NAME"
\fBgetopts\fR \- Parse CLI options
.
.SH "SYNOPSIS"
\fBgetopts\fR [\fIoptions\fR \.\.\.]
.
.br
\fBgetopts\fR [\fIoptions\fR \.\.\.] \fB|\fR \fBwhile\fR read \-l key value; \.\.\.; \fBend\fR
.
.br
.
.SH "DESCRIPTION"
getopts is a tool to help parsing command\-line arguments\. It is designed to process command line arguments that follow the POSIX Utility Syntax Guidelines\. If no arguments are given it returns \fB1\fR\.
.
.SH "USAGE"
In the following example:
.
.IP "" 4
.
.nf
getopts \-ab1 \-\-foo=bar baz
.
.fi
.
.IP "" 0
.
.P
And its output:
.
.IP "" 4
.
.nf
a
b 1
foo bar
_ baz
.
.fi
.
.IP "" 0
.
.P
The items on the left represent the option flags or \fIkeys\fR associated with the CLI\. The items on the right are the option \fIvalues\fR\. The underscore \fB_\fR character is the default \fIkey\fR for arguments without a key\.
.
.P
Use \fBread\fR(1) to process the generated stream and \fBswitch\fR(1) to match patterns:
.
.IP "" 4
.
.nf
getopts \-ab1 \-\-foo=bar baz | while read \-l key option
switch $key
case _
case a
case b
case foo
end
end
.
.fi
.
.IP "" 0
.
.SH "OPTIONS"
None\.
.
.SH "EXAMPLES"
The following is a mock of \fBfish\fR(1) CLI missing the implementation:
.
.IP "" 4
.
.nf
function fish
set \-l mode
set \-l flags
set \-l commands
set \-l debug_level
getopts $argv | while read \-l key value
switch $key
case c command
set commands $commands $value
case d debug\-level
set debug_level $value
case i interactive
set mode $value
case l login
set mode $value
case n no\-execute
set mode $value
case p profile
set flags $flags $value
case h help
printf "usage: $_ [OPTIONS] [\-c command] [FILE [ARGUMENTS\.\.\.]]\en"
return
case \e*
printf "$_: \'%s\' is not a valid option\.\en" $key
return 1
end
end
# Implementation
end
.
.fi
.
.IP "" 0
.
.SH "BUGS"
.
.IP "\(bu" 4
getopts does \fInot\fR read the standard input\. Use getopts to collect options and the standard input to process a stream of data relevant to your program\.
.
.IP "\(bu" 4
A double dash, \fB\-\-\fR, marks the end of options\. Arguments after this sequence are placed in the default underscore key, \fB_\fR\.
.
.IP "\(bu" 4
The getopts described in this document is \fInot\fR equivalent to the getopts \fIbuiltin\fR found in other shells\. This tool is only available for \fBfish\fR(1)\.
.
.IP "" 0
.
.SH "AUTHORS"
Jorge Bucaran \fIj@bucaran\.me\fR\.
.
.SH "SEE ALSO"
POSIX Utility Syntax Guidelines [goo\.gl/yrgQn9]
.
.br

@ -0,0 +1,108 @@
getopts(1) -- Parse CLI options
===============================
## SYNOPSIS
`getopts` [*options* ...]<br>
`getopts` [*options* ...] `|` `while` read -l key value; ...; `end`<br>
## DESCRIPTION
getopts is a tool to help parsing command-line arguments. It is designed to process command line arguments that follow the POSIX Utility Syntax Guidelines. If no arguments are given it returns `1`.
## USAGE
In the following example:
```
getopts -ab1 --foo=bar baz
```
And its output:
```
a
b 1
foo bar
_ baz
```
The items on the left represent the option flags or *keys* associated with the CLI. The items on the right are the option *values*. The underscore `_` character is the default *key* for arguments without a key.
Use `read`(1) to process the generated stream and `switch`(1) to match patterns:
```
getopts -ab1 --foo=bar baz | while read -l key option
switch $key
case _
case a
case b
case foo
end
end
```
## OPTIONS
None.
## EXAMPLES
The following is a mock of `fish`(1) CLI missing the implementation:
```
function fish
set -l mode
set -l flags
set -l commands
set -l debug_level
getopts $argv | while read -l key value
switch $key
case c command
set commands $commands $value
case d debug-level
set debug_level $value
case i interactive
set mode $value
case l login
set mode $value
case n no-execute
set mode $value
case p profile
set flags $flags $value
case h help
printf "usage: $_ [OPTIONS] [-c command] [FILE [ARGUMENTS...]]\n"
return
case \*
printf "$_: '%s' is not a valid option.\n" $key
return 1
end
end
# Implementation
end
```
## BUGS
* getopts does *not* read the standard input. Use getopts to collect options and the standard input to process a stream of data relevant to your program.
* A double dash, `--`, marks the end of options. Arguments after this sequence are placed in the default underscore key, `_`.
* The getopts described in this document is *not* equivalent to the getopts *builtin* found in other shells. This tool is only available for `fish`(1).
## AUTHORS
Jorge Bucaran <j@bucaran.me>.
## SEE ALSO
POSIX Utility Syntax Guidelines [goo.gl/yrgQn9]<br>

@ -0,0 +1,137 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "WAIT" "1" "January 2016" "" "fisherman"
.
.SH "NAME"
\fBwait\fR \- Run commands and wait with a spin
.
.SH "SYNOPSIS"
\fBwait\fR \fIcommands\fR [\fB\-\-spin\fR=\fIarc\fR|\fIstar\fR|\fIpipe\fR|\fIball\fR|\fIflip\fR|\fImixer\fR|\fIcaret\fR|\fIbar1~3\fR]
.
.br
\fBwait\fR \fIcommands\fR [\fB\-\-time\fR=interval] [\fB\-\-log\fR=file] [\fB\-\-format\fR=format] [\fB\-\-help\fR]
.
.SH "DESCRIPTION"
Run \fIcommands\fR as a background process and wait until the job has finished\. Any output to standard error indicates \fBwait\fR to return \fB1\fR once is done\. While it waits, a customizable spinner is displayed in the command line\.
.
.SH "OPTIONS"
.
.TP
\fB\-s\fR, \fB\-\-spin\fR=\fIstyle\fR|\fIstring\fR
Set spinner style\. See #{Styles} for a list of styles and instructions on how to use your own character sequences, progress bar usage, etc\.
.
.TP
\fB\-t\fR \fB\-\-time\fR=\fIinterval\fR
Set spinner transition time delay in \fIseconds\fR\. A large value will refresh the spinner more slowly\. You may use decimal numbers to represent smaller numbers\.
.
.TP
\fB\-l\fR \fB\-\-log\fR=\fIfile\fR
Output standard error to given \fIfile\fR\.
.
.TP
\fB\-f\fR \fB\-\-format\fR=\fIformat\fR
Use given \fIformat\fR to display the spinner\. The default format is \fB"\er@"\fR where \fB@\fR represents the spinner token and \fB\er\fR a carriage return, used to refresh / erase the line\.
.
.TP
\fB\-h\fR \fB\-\-help\fR
Show usage help\.
.
.SH "STYLES"
The following styles are supported via \fB\-\-spin=\fR\fIstyle\fR:
.
.IP "\(bu" 4
arc, star, pipe, ball, flip, mixer, caret
.
.IP "\(bu" 4
bar1~3
.
.IP "" 0
.
.SS "CUSTOMIZATION"
In addition to the default styles, you can specify a string of character tokens to be used each per spinner refresh cycle\.
.
.P
For example \fB\-\-spin=12345\fR will display the numbers from 1 to 5, and \fB\-\-spin=\. \-\-format=@\fR an increasing sequence of dots\.
.
.SS "PROGRESS BARS"
Display a progress bar with a percent indicator using \fB\-\-spin\fR=\fIbar1~3\fR:
.
.IP "\(bu" 4
bar1: [=====] \fInum\fR%
.
.IP "\(bu" 4
bar2: [#####] \fInum\fR%
.
.IP "\(bu" 4
bar3: \.\.\.\.\.\.\. \fInum\fR%
.
.IP "" 0
.
.P
You can customize the appearance as follows:
.
.IP "" 4
.
.nf
\-\-spin=bar:<opening token><fill token><empty slot token><closing token>[%]
.
.fi
.
.IP "" 0
.
.P
For example:
.
.IP "" 4
.
.nf
\-\-spin="bar:[+\-]%"
\-\-spin="bar:(@o)"
\-\-spin="bar:||_|"
.
.fi
.
.IP "" 0
.
.SH "EXAMPLES"
Run a lengthy operation as a background job and display a spinning pipe character until it is finished\.
.
.IP "" 4
.
.nf
wait \-\-spin=pipe "curl \-sS $url"
.
.fi
.
.IP "" 0
.
.P
Output any errors to \fIdebug\.txt\fR\.
.
.IP "" 4
.
.nf
if not wait \-\-spin=pipe \-\-log=debug\.txt "curl \-sS $url"
return 1
end
.
.fi
.
.IP "" 0
.
.SH "AUTHORS"
Jorge Bucaran \fIj@bucaran\.me\fR\.
.
.SH "SEE ALSO"
\fBsleep\fR(1)
.
.br
\fBhelp introduction\fR#{\fBBackground Jobs\fR}
.
.br

@ -0,0 +1,89 @@
wait(1) -- Run commands and wait with a spin
============================================
## SYNOPSIS
`wait` *commands* [`--spin`=*arc*|*star*|*pipe*|*ball*|*flip*|*mixer*|*caret*|*bar1~3*]<br>
`wait` *commands* [`--time`=interval] [`--log`=file] [`--format`=format] [`--help`]
## DESCRIPTION
Run *commands* as a background process and wait until the job has finished. Any output to standard error indicates `wait` to return `1` once is done. While it waits, a customizable spinner is displayed in the command line.
## OPTIONS
* `-s`, `--spin`=*style*|*string*:
Set spinner style. See #{Styles} for a list of styles and instructions on how to use your own character sequences, progress bar usage, etc.
* `-t` `--time`=*interval*:
Set spinner transition time delay in *seconds*. A large value will refresh the spinner more slowly. You may use decimal numbers to represent smaller numbers.
* `-l` `--log`=*file*:
Output standard error to given *file*.
* `-f` `--format`=*format*:
Use given *format* to display the spinner. The default format is `"\r@"` where `@` represents the spinner token and `\r` a carriage return, used to refresh / erase the line.
* `-h` `--help`:
Show usage help.
## STYLES
The following styles are supported via `--spin=`*style*:
* arc, star, pipe, ball, flip, mixer, caret
* bar1~3
### CUSTOMIZATION
In addition to the default styles, you can specify a string of character tokens to be used each per spinner refresh cycle.
For example `--spin=12345` will display the numbers from 1 to 5, and `--spin=. --format=@` an increasing sequence of dots.
### PROGRESS BARS
Display a progress bar with a percent indicator using `--spin`=*bar1~3*:
* bar1: [=====] *num*%
* bar2: [#####] *num*%
* bar3: ....... *num*%
You can customize the appearance as follows:
```
--spin=bar:<opening token><fill token><empty slot token><closing token>[%]
```
For example:
```
--spin="bar:[+-]%"
--spin="bar:(@o)"
--spin="bar:||_|"
```
## EXAMPLES
Run a lengthy operation as a background job and display a spinning pipe character until it is finished.
```
wait --spin=pipe "curl -sS $url"
```
Output any errors to *debug.txt*.
```
if not wait --spin=pipe --log=debug.txt "curl -sS $url"
return 1
end
```
## AUTHORS
Jorge Bucaran *j@bucaran.me*.
## SEE ALSO
`sleep`(1)<br>
`help introduction`#{`Background Jobs`}<br>

@ -0,0 +1,61 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "FISHER\-FISHFILE" "5" "January 2016" "" "fisherman"
.
.SH "NAME"
\fBfisher\-fishfile\fR \- Fishfile Format
.
.SH "SYNOPSIS"
A fishfile lets you share plugin configurations across multiple installations, allows plugins to declare dependencies, and prevent information loss in case of system failure\.
.
.P
Fisherman also keeps a user \fIfishfile\fR in \fB$fisher_config\fR/fishfile which is automatically updated as you install or uninstall plugins\.
.
.SH "USAGE"
Fishfiles are plain text, manifest files that list one or more plugins by their name, url or short url \fBowner/repo\fR\.
.
.P
Here is an example:
.
.IP "" 4
.
.nf
# my plugins
gitio
fishtape
# other links
oh\-my\-fish/bobthefish
.
.fi
.
.IP "" 0
.
.P
To read fishfiles use \fBfisher \-\-file\fR=\fIfishfile\fR\. This utility reads fishfiles sequentially, writing them to standard output\. Oh My Fish! bundle files are supported too\.
.
.P
If \fIfishfile\fR is null or an empty string, the global \fIfishfile\fR in \fB$fisher_config\fR/fishfile is used instead\. Use a dash \fB\-\fR to force read from standard input\.
.
.SH "PLUGINS"
Plugins may declare any number of dependencies to other plugins in a fishfile at the root of their project\.
.
.P
By default, when Fisherman installs a plugin, it will also fetch and install its dependencies\. If a dependency is already installed, it will not be updated as this could potentially break other plugins using an older version\. For the same reason, uninstalling a plugin does not remove its dependencies\.
.
.P
To understand this behavior, it helps to recall the shell\'s single scope for functions\. The lack of private functions means that, it is \fInot\fR possible to single\-lock a specific dependency version\. See also \fBfisher\fR(7)#{\fBFlat Tree\fR}\.
.
.SH "SEE ALSO"
\fBfisher\fR(1)
.
.br
\fBfisher help config\fR
.
.br
\fBfisher\fR(7) #{\fBFlat Tree\fR}
.
.br

@ -0,0 +1,41 @@
fisher-fishfile(5) -- Fishfile Format
=====================================
## SYNOPSIS
A fishfile lets you share plugin configurations across multiple installations, allows plugins to declare dependencies, and prevent information loss in case of system failure.
Fisherman also keeps a user *fishfile* in `$fisher_config`/fishfile which is automatically updated as you install or uninstall plugins.
## USAGE
Fishfiles are plain text, manifest files that list one or more plugins by their name, url or short url `owner/repo`.
Here is an example:
```
# my plugins
gitio
fishtape
# other links
oh-my-fish/bobthefish
```
To read fishfiles use `fisher --file`=*fishfile*. This utility reads fishfiles sequentially, writing them to standard output. Oh My Fish! bundle files are supported too.
If *fishfile* is null or an empty string, the global *fishfile* in `$fisher_config`/fishfile is used instead. Use a dash `-` to force read from standard input.
## PLUGINS
Plugins may declare any number of dependencies to other plugins in a fishfile at the root of their project.
By default, when Fisherman installs a plugin, it will also fetch and install its dependencies. If a dependency is already installed, it will not be updated as this could potentially break other plugins using an older version. For the same reason, uninstalling a plugin does not remove its dependencies.
To understand this behavior, it helps to recall the shell's single scope for functions. The lack of private functions means that, it is *not* possible to single-lock a specific dependency version. See also `fisher`(7)#{`Flat Tree`}.
## SEE ALSO
`fisher`(1)<br>
`fisher help config`<br>
`fisher`(7) #{`Flat Tree`}<br>

@ -0,0 +1,82 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "FISHER\-COMMANDS" "7" "January 2016" "" "fisherman"
.
.SH "NAME"
\fBfisher\-commands\fR \- Creating Fisherman Commands
.
.SH "SYNOPSIS"
This document describes how to add new commands to Fisherman\. A Fisherman command is a function that you can invoke like \fBfisher command\fR [\fIoptions\fR]\.
.
.SH "DESCRIPTION"
To add a command, create a function \fBfisher_<my_command>\fR:
.
.IP "" 4
.
.nf
function fisher_hello \-d "Friendly command"
echo hello
end
.
.fi
.
.IP "" 0
.
.P
Make sure it works: \fBfisher hello\fR\.
.
.P
To make this function available to the current and future fish sessions, add it to \fB$XDG_CONFIG_HOME\fR/fish/functions:
.
.IP "" 4
.
.nf
funcsave fisher_hello
.
.fi
.
.IP "" 0
.
.P
You may also choose to save this function to \fB$fisher_config\fR/functions\.
.
.SH "EXAMPLES"
The following example implements a command to retrieve plugin information and format the output into columns\.
.
.IP "" 4
.
.nf
function fisher_info \-d "Display information about plugins"
switch "$argv"
case \-h \-\-help
printf "usage: fisher info name | url [\.\.\.]\en\en"
printf " \-h \-\-help Show usage help\en"
return
end
for item in $argv
fisher search $item \-\-name \-\-info
end | sed \-E \'s/;/: /\' | column
end
.
.fi
.
.IP "" 0
.
.SH "SEE ALSO"
\fBfisher\fR(1)
.
.br
\fBfisher\fR(7)
.
.br
\fBfuncsave\fR(1)
.
.br
\fBfisher help plugins\fR
.
.br

@ -0,0 +1,52 @@
fisher-commands(7) -- Creating Fisherman Commands
=================================================
## SYNOPSIS
This document describes how to add new commands to Fisherman. A Fisherman command is a function that you can invoke like `fisher command` [*options*].
## DESCRIPTION
To add a command, create a function `fisher_<my_command>`:
```
function fisher_hello -d "Friendly command"
echo hello
end
```
Make sure it works: `fisher hello`.
To make this function available to the current and future fish sessions, add it to `$XDG_CONFIG_HOME`/fish/functions:
```
funcsave fisher_hello
```
You may also choose to save this function to `$fisher_config`/functions.
## EXAMPLES
The following example implements a command to retrieve plugin information and format the output into columns.
```
function fisher_info -d "Display information about plugins"
switch "$argv"
case -h --help
printf "usage: fisher info name | url [...]\n\n"
printf " -h --help Show usage help\n"
return
end
for item in $argv
fisher search $item --name --info
end | sed -E 's/;/: /' | column
end
```
## SEE ALSO
`fisher`(1)<br>
`fisher`(7)<br>
`funcsave`(1)<br>
`fisher help plugins`<br>

@ -0,0 +1,80 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "FISHER\-CONFIG" "7" "January 2016" "" "fisherman"
.
.SH "NAME"
\fBfisher\-config\fR \- Fisherman Configuration
.
.SH "SYNOPSIS"
This document describes how to use the available configuration options to customize Fisherman\.
.
.SH "DESCRIPTION"
Your fish user configuration, usually located in \fB$XDG_CONFIG_HOME\fR/fish/config\.fish is updated after installing Fisherman to add the global variables \fB$fisher_home\fR and \fB$fisher_config\fR\.
.
.P
\fB$fisher_home\fR is the location where Fisherman was downloaded\. This location can be anywhere you like\. If you changed this location after installing Fisherman, you need to update \fB$fisher_home\fR as well\.
.
.P
\fB$fisher_config\fR is the user configuration directory and the location of your user \fIfishfile\fR, \fIcache\fR directory and where plugins get installed to\. This location must be different from \fB$fisher_home\fR\. The default location is \fB$XDG_CONFIG_HOME\fR/fisherman\.
.
.P
You can also customize the debug log path, cache location, index source url, command aliases, and other options via \fB$fisher_*\fR variables\.
.
.SH "VARIABLES"
.
.IP "\(bu" 4
\fB$fisher_home\fR: The home directory\. This is the path where you downloaded Fisherman\.
.
.IP "\(bu" 4
\fB$fisher_config\fR: The user configuration directory\. \fB$XDG_CONFIG_HOME\fR/fisherman by default\. This directory is where the \fIcache\fR, \fIfunctions\fR and \fIcompletions\fR directories are located\.
.
.IP "\(bu" 4
\fB$fisher_cache\fR: The cache directory\. Plugins are first downloaded here and installed to \fB$fisher_config/functions\fR afterwards\. The cache is \fB$fisher_config\fR/cache by default\.
.
.IP "\(bu" 4
\fB$fisher_index\fR: Index source url or file\. To use a different index set this to a file or url\. Redirect urls are not supported due to security and performance concerns\. The underlying request and fetch mechanism is based in \fBcurl\fR(1)\. See also \fBfisher\fR(7)#{\fBIndex\fR}\.
.
.IP "\(bu" 4
\fB$fisher_error_log\fR: This file keeps a log of the most recent crash stack trace\. \fB$fisher_cache\fR/\.debug_log by default\.
.
.IP "\(bu" 4
\fB$fisher_alias\fR \fIcommand\fR=\fIalias\fR[,\.\.\.] [\fIcommand2\fR=\fIalias\fR[,\.\.\.]]: Use this variable to define custom aliases for fisher commands\. See #{\fBExamples\fR} below\.
.
.IP "\(bu" 4
\fB$fisher_default_host\fR \fIhost\fR Use this variable to define your preferred git host\. Fisherman uses this value to convert short urls like \fBowner/repo\fR to \fBhttps://host/owner/repo\fR\. The default host is \fIgithub\.com\fR\.
.
.IP "" 0
.
.SH "EXAMPLES"
Create aliases for fisher \fBinstall\fR to \fIi\fR, \fIin\fR and \fIinst\fR; and for fisher \fBupdate\fR to \fIup\fR\.
.
.IP "" 4
.
.nf
set fisher_alias install=i,in,inst update=up
.
.fi
.
.IP "" 0
.
.P
Set \fB$fisher_index\fR and \fB$fisher_default_host\fR\.
.
.IP "" 4
.
.nf
set fisher_index https://raw\.\.\./owner/repo/master/index2\.txt
set fisher_default_host bitbucket\.org
.
.fi
.
.IP "" 0
.
.SH "SEE ALSO"
\fBfisher\fR(7)#{\fBIndex\fR}
.
.br

@ -0,0 +1,58 @@
fisher-config(7) -- Fisherman Configuration
===========================================
## SYNOPSIS
This document describes how to use the available configuration options to customize Fisherman.
## DESCRIPTION
Your fish user configuration, usually located in `$XDG_CONFIG_HOME`/fish/config.fish is updated after installing Fisherman to add the global variables `$fisher_home` and `$fisher_config`.
`$fisher_home` is the location where Fisherman was downloaded. This location can be anywhere you like. If you changed this location after installing Fisherman, you need to update `$fisher_home` as well.
`$fisher_config` is the user configuration directory and the location of your user *fishfile*, *cache* directory and where plugins get installed to. This location must be different from `$fisher_home`. The default location is `$XDG_CONFIG_HOME`/fisherman.
You can also customize the debug log path, cache location, index source url, command aliases, and other options via `$fisher_*` variables.
## VARIABLES
* `$fisher_home`:
The home directory. This is the path where you downloaded Fisherman.
* `$fisher_config`:
The user configuration directory. `$XDG_CONFIG_HOME`/fisherman by default. This directory is where the *cache*, *functions* and *completions* directories are located.
* `$fisher_cache`:
The cache directory. Plugins are first downloaded here and installed to `$fisher_config/functions` afterwards. The cache is `$fisher_config`/cache by default.
* `$fisher_index`:
Index source url or file. To use a different index set this to a file or url. Redirect urls are not supported due to security and performance concerns. The underlying request and fetch mechanism is based in `curl`(1). See also `fisher`(7)#{`Index`}.
* `$fisher_error_log`:
This file keeps a log of the most recent crash stack trace. `$fisher_cache`/.debug_log by default.
* `$fisher_alias` *command*=*alias*[,...] [*command2*=*alias*[,...]]:
Use this variable to define custom aliases for fisher commands. See #{`Examples`} below.
* `$fisher_default_host` *host*
Use this variable to define your preferred git host. Fisherman uses this value to convert short urls like `owner/repo` to `https://host/owner/repo`. The default host is *github.com*.
## EXAMPLES
Create aliases for fisher `install` to *i*, *in* and *inst*; and for fisher `update` to *up*.
```
set fisher_alias install=i,in,inst update=up
```
Set `$fisher_index` and `$fisher_default_host`.
```
set fisher_index https://raw.../owner/repo/master/index2.txt
set fisher_default_host bitbucket.org
```
## SEE ALSO
`fisher`(7)#{`Index`}<br>

@ -0,0 +1,189 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "FISHER\-FAQ" "7" "January 2016" "" "fisherman"
.
.SH "NAME"
\fBfisher\-faq\fR \- Fisherman Frequently Asked Questions
.
.SH "SYNOPSIS"
This document attempts to answer some of Fisherman most frequently asked questions\. Feel free to create a new issue in the Fisherman issue tracker if your question is not answered here\.
.
.SS "What is Fisherman?"
Fisherman is a shell manager for fish that lets you share and reuse code, prompts and configurations easily\.
.
.SS "What do I need to know to use Fisherman?"
Nothing\. You can continue using your shell as usual\. When you are ready to learn more just type \fBman fisher\fR or \fBman 7 fisher\fR\.
.
.SS "How do I access other Fisherman documentation?"
Fisherman documentation is based in UNIX \fBman\fR(1) pages\. See \fBman fisher\fR and \fBman 7 fisher\fR to get started\. You can also access any documentation using the \fBfisher help\fR command\.
.
.SS "What are Fisherman plugins?"
Plugins are written in fish and extend the shell core functionality, run initialization code, add completions or documentations to other commands, etc\. See \fBfisher help plugins\fR\.
.
.P
Plugins may list any number of dependencies to other plugins using a \fIfishfile\fR\.
.
.SS "What is a Fishfile?"
A plain text file that lists what plugins you have installed or a plugin\'s dependencies to other plugins\.
.
.P
Fishfiles let you share plugin configurations across multiple installations, allow plugins to declare dependencies, and prevent information loss in case of system failure\. See also \fBfisher help fishfile\fR\.
.
.SS "What kind of Fisherman plugins are there?"
There is no technical distinction between plugins, themes, commands, etc\., but there is a \fIconceptual\fR difference\.
.
.IP "\(bu" 4
\fBStandalone Utilities\fR: Plugins that define one or more functions, meant to be used at the command line\.
.
.IP "\(bu" 4
\fBPrompts / Themes\fR: Plugins that modify the appearance of the fish prompt by defining a \fBfish_prompt\fR and / or \fBfish_right_prompt\fR functions\.
.
.IP "\(bu" 4
\fBExtension Commands\fR: Plugins that extend Fisherman default commands\. An extension plugin must define one or more functions like \fBfisher_<my_command>\fR\. For specific information about commands, see \fBfisher help commands\fR and then return to this guide\.
.
.IP "\(bu" 4
\fBConfiguration Plugins\fR: Plugins that include one or more \fBmy_plugin\fR\.config\.fish files\. Files that follow this convention are evaluated at the start of the session\.
.
.IP "" 0
.
.P
See \fBfisher help plugins\fR and \fBfisher help commands\fR\.
.
.SS "Does Fisherman support Oh My Fish plugins and themes?"
Yes\. To install either a plugin or theme use their URL:
.
.IP "" 4
.
.nf
fisher install oh\-my\-fish/{rbenv,hub,bobthefish}
.
.fi
.
.IP "" 0
.
.P
You can use the same mechanism to install a Wahoo package or a plugin in a any given URL\. See also \fBfisher\fR(7)#{\fBCompatibility\fR}\.
.
.SS "What does Fisherman do exactly every time I create a new shell session?"
Essentially, add Fisherman functions and completions to the \fB$fish_{function,complete}_path\fR and evaluate files that follow the convention \fB*\.config\.fish\fR\.
.
.IP "" 4
.
.nf
set fish_function_path {$fisher_config,$fisher_home}/functions $fish_function_path
set fish_complete_path {$fisher_config,$fisher_home}/completions $fish_complete_path
for file in $fisher_config/functions/*\.config\.fish
source $file
end
.
.fi
.
.IP "" 0
.
.P
See \fB$fisher_home/config\.fish\fR for the full code\.
.
.SS "How is Fisherman faster than Oh My Fish!, Wahoo, etc?"
Fisherman ameliorates the slow shell start problem using a flat dependency tree instead of loading a directory hierarchy per plugin\. This also means that Fisherman performance does not decline depending on the number of plugins installed\. See also \fBfisher\fR(7)#{\fBFlat Tree\fR}\.
.
.SS "Why don\'t you contribute your improvements back to Oh My Fish! instead of creating a new project?"
Already done that\. See Oh My Fish! history for August 27, 2015\. The project was then called Wahoo and it was entirely merged with Oh My Fish!\.
.
.P
Fisherman was built from the ground up using a completely different design, implementation and set of principles\.
.
.P
Some features include: UNIX familiarity, minimalistic design, flat tree structure, unified plugin system, external self\-managed database, cache mechanism, dependency manifest file and compatibility with Oh My Fish!, etc\. See \fBfisher\fR(7)\.
.
.SS "How can I upgrade from an existing Oh My Fish! or Wahoo installation?"
Install Fisherman\.
.
.IP "" 4
.
.nf
git clone https://github\.com/fisherman/fisherman
cd fisherman
make
.
.fi
.
.IP "" 0
.
.P
You can now safely remove Oh My Fish! \fB$OMF_PATH\fR and \fB$OMF_CONFIG\fR\.
.
.P
Backup dotfiles and other sensitive data first\.
.
.IP "" 4
.
.nf
rm \-rf {$OMF_PATH,$OMF_CONFIG}
.
.fi
.
.IP "" 0
.
.SS "I changed my prompt with <code>fish_config</code> and now I can\'t use any Fisherman theme, what do I do?"
\fBfish_config\fR persists the prompt to \fBXDG_CONFIG_HOME/fish/functions\fR/fish_prompt\.fish\. That file takes precedence over Fisherman prompts that install to \fB$fisher_config\fR/functions/\. To use Fisherman prompts remove the \fBfish_promt\.fish\fR inside \fBXDG_CONFIG_HOME/fish/functions/\fR\.
.
.P
Assuming \fBXDG_CONFIG_HOME\fR is \fB~/\.config\fR in your system:
.
.IP "" 4
.
.nf
rm ~/\.config/fish/functions/fish_prompt\.fish
.
.fi
.
.IP "" 0
.
.SS "How do I use fish as my default shell?"
Add Fish to \fB/etc/shells\fR:
.
.IP "" 4
.
.nf
echo "/usr/local/bin/fish" | sudo tee \-a /etc/shells
.
.fi
.
.IP "" 0
.
.P
Make Fish your default shell:
.
.IP "" 4
.
.nf
chsh \-s /usr/local/bin/fish
.
.fi
.
.IP "" 0
.
.P
To switch back to another shell\.
.
.IP "" 4
.
.nf
chsh \-s /bin/another/shell
.
.fi
.
.IP "" 0
.
.SS "Why is this FAQ similar to the Oh My Fish! FAQ?"
Because it was written by the same author of Fisherman and Wahoo and some of the questions and answers simply overlap\.

@ -0,0 +1,146 @@
fisher-faq(7) -- Fisherman Frequently Asked Questions
=====================================================
## SYNOPSIS
This document attempts to answer some of Fisherman most frequently asked questions. Feel free to create a new issue in the Fisherman issue tracker if your question is not answered here.
### What is Fisherman?
Fisherman is a shell manager for fish that lets you share and reuse code, prompts and configurations easily.
### What do I need to know to use Fisherman?
Nothing. You can continue using your shell as usual. When you are ready to learn more just type `man fisher` or `man 7 fisher`.
### How do I access other Fisherman documentation?
Fisherman documentation is based in UNIX `man`(1) pages. See `man fisher` and `man 7 fisher` to get started. You can also access any documentation using the `fisher help` command.
### What are Fisherman plugins?
Plugins are written in fish and extend the shell core functionality, run initialization code, add completions or documentations to other commands, etc. See `fisher help plugins`.
Plugins may list any number of dependencies to other plugins using a *fishfile*.
### What is a Fishfile?
A plain text file that lists what plugins you have installed or a plugin's dependencies to other plugins.
Fishfiles let you share plugin configurations across multiple installations, allow plugins to declare dependencies, and prevent information loss in case of system failure. See also `fisher help fishfile`.
### What kind of Fisherman plugins are there?
There is no technical distinction between plugins, themes, commands, etc., but there is a *conceptual* difference.
* `Standalone Utilities`: Plugins that define one or more functions, meant to be used at the command line.
* `Prompts / Themes`: Plugins that modify the appearance of the fish prompt by defining a `fish_prompt` and / or `fish_right_prompt` functions.
* `Extension Commands`: Plugins that extend Fisherman default commands. An extension plugin must define one or more functions like `fisher_<my_command>`. For specific information about commands, see `fisher help commands` and then return to this guide.
* `Configuration Plugins`: Plugins that include one or more `my_plugin`.config.fish files. Files that follow this convention are evaluated at the start of the session.
See `fisher help plugins` and `fisher help commands`.
### Does Fisherman support Oh My Fish plugins and themes?
Yes. To install either a plugin or theme use their URL:
```
fisher install oh-my-fish/{rbenv,hub,bobthefish}
```
You can use the same mechanism to install a Wahoo package or a plugin in a any given URL. See also `fisher`(7)#{`Compatibility`}.
### What does Fisherman do exactly every time I create a new shell session?
Essentially, add Fisherman functions and completions to the `$fish_{function,complete}_path` and evaluate files that follow the convention `*.config.fish`.
```fish
set fish_function_path {$fisher_config,$fisher_home}/functions $fish_function_path
set fish_complete_path {$fisher_config,$fisher_home}/completions $fish_complete_path
for file in $fisher_config/functions/*.config.fish
source $file
end
```
See `$fisher_home/config.fish` for the full code.
### How is Fisherman faster than Oh My Fish!, Wahoo, etc?
Fisherman ameliorates the slow shell start problem using a flat dependency tree instead of loading a directory hierarchy per plugin. This also means that Fisherman performance does not decline depending on the number of plugins installed. See also `fisher`(7)#{`Flat Tree`}.
### Why don't you contribute your improvements back to Oh My Fish! instead of creating a new project?
Already done that. See Oh My Fish! history for August 27, 2015. The project was then called Wahoo and it was entirely merged with Oh My Fish!.
Fisherman was built from the ground up using a completely different design, implementation and set of principles.
Some features include: UNIX familiarity, minimalistic design, flat tree structure, unified plugin system, external self-managed database, cache mechanism, dependency manifest file and compatibility with Oh My Fish!, etc. See `fisher`(7).
### How can I upgrade from an existing Oh My Fish! or Wahoo installation?
Install Fisherman.
```
git clone https://github.com/fisherman/fisherman
cd fisherman
make
```
You can now safely remove Oh My Fish! `$OMF_PATH` and `$OMF_CONFIG`.
Backup dotfiles and other sensitive data first.
```fish
rm -rf {$OMF_PATH,$OMF_CONFIG}
```
### I changed my prompt with `fish_config` and now I can't use any Fisherman theme, what do I do?
`fish_config` persists the prompt to `XDG_CONFIG_HOME/fish/functions`/fish_prompt.fish. That file takes precedence over Fisherman prompts that install to `$fisher_config`/functions/. To use Fisherman prompts remove the `fish_promt.fish` inside `XDG_CONFIG_HOME/fish/functions/`.
Assuming `XDG_CONFIG_HOME` is `~/.config` in your system:
```
rm ~/.config/fish/functions/fish_prompt.fish
```
### How do I use fish as my default shell?
Add Fish to `/etc/shells`:
```sh
echo "/usr/local/bin/fish" | sudo tee -a /etc/shells
```
Make Fish your default shell:
```sh
chsh -s /usr/local/bin/fish
```
To switch back to another shell.
```sh
chsh -s /bin/another/shell
```
### Why is this FAQ similar to the Oh My Fish! FAQ?
Because it was written by the same author of Fisherman and Wahoo and some of the questions and answers simply overlap.

@ -0,0 +1,215 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "FISHER\-PLUGINS" "7" "January 2016" "" "fisherman"
.
.SH "NAME"
\fBfisher\-plugins\fR \- Creating Fisherman Plugins
.
.SH "DESCRIPTION"
This document describes how to create Fisherman plugins\. This includes stand\-alone utilities, prompts, extension commands and configuration plugins\.
.
.P
There is no technical distinction between any of the terms aforementioned, but there is a \fIconceptual\fR difference\.
.
.SH "DEFINITIONS"
.
.IP "\(bu" 4
\fBStandalone Utilities\fR: Plugins that define one or more functions, meant to be used at the command line\.
.
.IP "\(bu" 4
\fBPrompts / Themes\fR: Plugins that modify the appearance of the fish prompt by defining a \fBfish_prompt\fR and / or \fBfish_right_prompt\fR functions\.
.
.IP "\(bu" 4
\fBExtension Commands\fR: Plugins that extend Fisherman default commands\. An extension plugin must define one or more functions like \fBfisher_<my_command>\fR\. For specific information about commands, see \fBfisher help commands\fR and then return to this guide\.
.
.IP "\(bu" 4
\fBConfiguration Plugins\fR: Plugins that include one or more \fBmy_plugin\fR\.config\.fish files\. Files that follow this convention are evaluated at the start of the session\.
.
.IP "" 0
.
.P
The following tree is that of a plugin that displays the characteristics of all the plugins described above\.
.
.IP "" 4
.
.nf
my_plugin
|\-\- fisher_my_plugin\.fish
|\-\- my_plugin\.fish
|\-\- fish_prompt\.fish
|\-\- fish_right_prompt\.fish
|\-\- my_plugin\.config\.fish
|\-\- functions/
| |\-\- my_plugin_helper\.fish
|\-\- completions/
| |\-\- my_plugin\.fish
|\-\- man/
|\-\- man1/
|\-\- my_plugin\.1
.
.fi
.
.IP "" 0
.
.P
Plugins may list any number of dependencies to other plugins using a \fIfishfile\fR, see \fBfisher help fishfile\fR\.
.
.P
Plugins may also define completions using \fBcomplete\fR(1) and provide documentation in the form of \fBman\fR(1) pages\.
.
.SH "EXAMPLE"
This section walks you through creating \fIwtc\fR, a stand\-alone plugin based in \fIgithub\.com/ngerakines/commitment\fR random commit message generator\.
.
.IP "\(bu" 4
Navigate to your preferred workspace and create the plugin\'s directory and Git repository:
.
.IP
\fBmkdir\fR \-p my/workspace/wtc; and \fBcd\fR my/workspace/wtc
.
.br
\fBgit\fR init
.
.br
\fBgit\fR remote add origin https://github\.com/\fIowner\fR/wtc
.
.br
.
.IP "\(bu" 4
Add the implementation\.
.
.IP
\fBcat\fR > wtc\.fish
.
.IP "" 0
.
.IP "" 4
.
.nf
function wtc \-d "Generate a random commit message"
switch "$argv"
case \-h \-\-help
printf "usage: wtc [\-\-help]\en\en"
printf " \-h \-\-help Show usage help\en"
return
end
curl \-s whatthecommit\.com/index\.txt
end
^C
.
.fi
.
.IP "" 0
.
.IP "\(bu" 4
Add completions\. \fIwtc\fR is simple enough that you could get away without \fB__fish_parse_usage\fR, but more complex utilities, or utilities whose CLI evolves over time, can benefit using automatic completion generation\. Note that in order to use \fB__fish_parse_usage\fR, your command must provide a \fB\-\-help\fR option that prints usage information to standard output\.
.
.IP
\fBmkdir\fR completions
.
.br
\fBcat\fR > completions/wtc\.fish
.
.IP "" 0
.
.IP "" 4
.
.nf
set \-l IFS ";"
wtc \-\-help | __fish_parse_usage | while read \-l info long short
complete \-c wtc \-s "$short" \-l "$long" \-d "$info"
end
^C
.
.fi
.
.IP "" 0
.
.IP "\(bu" 4
Add basic documentation\. Fisherman uses standard manual pages for displaying help information\. There are utilities that can help you generate man pages from other text formats, such as Markdown\. One example is \fBronn\fR(1)\. For this example, type will do:
.
.IP
\fBmkdir\fR \-p man/man1
.
.br
\fBcat\fR > man/man1/wtc\.1
.
.IP "" 4
.
.nf
\.TH man 1 "Today" "1\.0" "wtc man page"
\.SH NAME
wtc \e\- Generate a random commit message
\.SH SYNOPSIS
wtc [\-\-help]
\.SH OPTIONS
\-h, \-\-help: Display help information\.
\.SH SEE ALSO
https://github\.com/ngerakines/commitment
^C
.
.fi
.
.IP "" 0
.
.IP "\(bu" 4
Commit changes and push to remote repository\.
.
.IP
\fBgit\fR add \-\-all
.
.br
\fBgit\fR commit \-m "What the commit? 1\.0"
.
.br
\fBgit\fR push origin master
.
.br
.
.IP "\(bu" 4
Install with Fisherman\. If you would like to submit your package for registration install the \fBsubmit\fR plugin or send a pull request to the main index repository in \fIhttps://github\.com/fisherman/index\fR\. See \fBfisher\fR(7)#{\fBIndex\fR} for details\.
.
.IP
fisher install github/\fIowner\fR/wtc
.
.br
wtc
.
.br
(\e /)
.
.br
(O\.o)
.
.br
(> <) Bunny approves these changes\.
.
.br
.
.IP "" 0
.
.SH "SEE ALSO"
\fBman\fR(1)
.
.br
\fBcomplete\fR(1)
.
.br
\fBfisher help commands\fR
.
.br
\fBfisher help fishfile\fR
.
.br
\fBfisher\fR(7)#{\fBIndex\fR}
.
.br

@ -0,0 +1,126 @@
fisher-plugins(7) -- Creating Fisherman Plugins
===============================================
## DESCRIPTION
This document describes how to create Fisherman plugins. This includes stand-alone utilities, prompts, extension commands and configuration plugins.
There is no technical distinction between any of the terms aforementioned, but there is a *conceptual* difference.
## DEFINITIONS
* `Standalone Utilities`: Plugins that define one or more functions, meant to be used at the command line.
* `Prompts / Themes`: Plugins that modify the appearance of the fish prompt by defining a `fish_prompt` and / or `fish_right_prompt` functions.
* `Extension Commands`: Plugins that extend Fisherman default commands. An extension plugin must define one or more functions like `fisher_<my_command>`. For specific information about commands, see `fisher help commands` and then return to this guide.
* `Configuration Plugins`: Plugins that include one or more `my_plugin`.config.fish files. Files that follow this convention are evaluated at the start of the session.
The following tree is that of a plugin that displays the characteristics of all the plugins described above.
```
my_plugin
|-- fisher_my_plugin.fish
|-- my_plugin.fish
|-- fish_prompt.fish
|-- fish_right_prompt.fish
|-- my_plugin.config.fish
|-- functions/
| |-- my_plugin_helper.fish
|-- completions/
| |-- my_plugin.fish
|-- man/
|-- man1/
|-- my_plugin.1
```
Plugins may list any number of dependencies to other plugins using a *fishfile*, see `fisher help fishfile`.
Plugins may also define completions using `complete`(1) and provide documentation in the form of `man`(1) pages.
## EXAMPLE
This section walks you through creating *wtc*, a stand-alone plugin based in *github.com/ngerakines/commitment* random commit message generator.
* Navigate to your preferred workspace and create the plugin's directory and Git repository:
`mkdir` -p my/workspace/wtc; and `cd` my/workspace/wtc<br>
`git` init<br>
`git` remote add origin https://github.com/*owner*/wtc<br>
* Add the implementation.
`cat` > wtc.fish
```
function wtc -d "Generate a random commit message"
switch "$argv"
case -h --help
printf "usage: wtc [--help]\n\n"
printf " -h --help Show usage help\n"
return
end
curl -s whatthecommit.com/index.txt
end
^C
```
* Add completions. *wtc* is simple enough that you could get away without `__fish_parse_usage`, but more complex utilities, or utilities whose CLI evolves over time, can benefit using automatic completion generation. Note that in order to use `__fish_parse_usage`, your command must provide a `--help` option that prints usage information to standard output.
`mkdir` completions<br>
`cat` > completions/wtc.fish
```
set -l IFS ";"
wtc --help | __fish_parse_usage | while read -l info long short
complete -c wtc -s "$short" -l "$long" -d "$info"
end
^C
```
* Add basic documentation. Fisherman uses standard manual pages for displaying help information. There are utilities that can help you generate man pages from other text formats, such as Markdown. One example is `ronn`(1). For this example, type will do:
`mkdir` -p man/man1<br>
`cat` > man/man1/wtc.1
```
.TH man 1 "Today" "1.0" "wtc man page"
.SH NAME
wtc \- Generate a random commit message
.SH SYNOPSIS
wtc [--help]
.SH OPTIONS
-h, --help: Display help information.
.SH SEE ALSO
https://github.com/ngerakines/commitment
^C
```
* Commit changes and push to remote repository.
`git` add --all<br>
`git` commit -m "What the commit? 1.0"<br>
`git` push origin master<br>
* Install with Fisherman. If you would like to submit your package for registration install the `submit` plugin or send a pull request to the main index repository in *https://github.com/fisherman/index*. See `fisher`(7)#{`Index`} for details.
fisher install github/*owner*/wtc<br>
wtc<br>
(\ /)<br>
(O.o)<br>
(> <) Bunny approves these changes.<br>
## SEE ALSO
`man`(1)<br>
`complete`(1)<br>
`fisher help commands`<br>
`fisher help fishfile`<br>
`fisher`(7)#{`Index`}<br>

@ -0,0 +1,329 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "FISHER" "7" "January 2016" "" "fisherman"
.
.SH "NAME"
\fBfisher\fR \- An Introduction to Fisherman
.
.SH "DESCRIPTION"
Fisherman is a shell manager for \fBfish\fR(1) that lets you share and reuse code, prompts and configurations easily\.
.
.P
Some features include: minimalistic design, flat tree structure, unified plugin system, external self\-managed database, cache mechanism, dependency manifest file and compatibility with Oh My Fish! and other frameworks\.
.
.P
This document describes Fisherman main features and their implementation details\. For usage and command help see \fBfisher\fR(1)\.
.
.SH "FLAT TREE"
The configuration directory structure is optimized to help fish start new sessions as quickly as possible, regardless of the numbers of plugins or prompts enabled at any given time\.
.
.P
To explain how this is possible, we need to make a digression and discuss function scope first\. In fish, all functions share the same scope and you can use only one name per function\.
.
.P
In the following example:
.
.IP "" 4
.
.nf
function foo
echo $_
function bar
end
end
function bar
echo $_
end
.
.fi
.
.IP "" 0
.
.P
\fIfoo\fR and \fIbar\fR are available immediately at the command line prompt and both print their names\. But there is a catch, calling \fIfoo\fR at least once will create a new \fIbar\fR function, effectively erasing the previous \fIbar\fR definition\. Subsequent calls to \fIbar\fR will print nothing\.
.
.P
By convention, functions that start with any number of underscores are \fIintentionally\fR private, but there is no mechanism that prevents you from calling them at any time once loaded\.
.
.P
With this in mind, it\'s possible to improve the slow shell start problem using a \fIflat\fR tree structure whose path is loaded only once\.
.
.P
The overhead of juggling multiple path hierarchies in a per\-plugin basis yields no benefits as everything is shared in the same scope\.
.
.P
Loading a path simply means adding the desired location to the \fB$fish_function_path\fR array\. See also \fBfunctions\fR(1)\.
.
.P
Here is a snapshot of a typical configuration path with a single plugin and prompt:
.
.IP "" 4
.
.nf
$fisher_config
|\-\- cache/
|\-\- functions/
| |\-\- my_plugin\.fish
| |\-\- fish_prompt\.fish
| |\-\- fish_right_prompt\.fish
|\-\- completions/
| |\-\- my_plugin\.fish
|\-\- man/
|\-\- man1/
|\-\- my_plugin\.1
.
.fi
.
.IP "" 0
.
.P
If you are already familiar in the way fish handles your user configuration, you will find the above structure similar to \fB$XDG_CONFIG_HOME/fish\fR\. See \fBhelp fish\fR#{\fBInitialization Files\fR} to learn more about fish configuration\.
.
.SS "PLUGINS"
Plugins are components that extend and add features to your shell\. To see what plugins are available use \fBfisher search\fR\. You can also type \fBfisher install\fR and hit \fItab\fR once to get full name completions and plugin information\. The same works for \fBfisher update\fR and \fBfisher uninstall\fR\.
.
.P
To learn how to create plugins, see \fBfisher help plugins\fR\.
.
.P
To install a plugin, you can use their \fIname\fR if they are listed in \fB$fisher_index\fR\.
.
.IP "" 4
.
.nf
fisher install shark
.
.fi
.
.IP "" 0
.
.P
Otherwise, you can use the repository remote \fIurl\fR\.
.
.IP "" 4
.
.nf
fisher install oh\-my\-fish/bobthefish
.
.fi
.
.IP "" 0
.
.P
If the domain or host is not provided, Fisherman will use any value in \fB$fisher_default_host\fR\. The default value is \fBhttps://github\.com\fR\.
.
.P
In addition, all of the following variations are accepted:
.
.IP "\(bu" 4
\fBgithub\fR/owner/repo \fB\->\fR https://github\.com/owner/repo
.
.br
.
.IP "\(bu" 4
\fBgh:\fRowner/repo \fB\->\fR https://github\.com/owner/repo
.
.br
.
.IP "" 0
.
.P
Shortcuts for other common Git repository hosting services are also available:
.
.IP "\(bu" 4
\fBbb:\fR/owner/repo \fB\->\fR https://bitbucket\.org/owner/repo
.
.br
.
.IP "\(bu" 4
\fBgl:\fR/owner/repo \fB\->\fR https://gitlab\.com/owner/repo
.
.br
.
.IP "" 0
.
.P
A flat tree model means there is no technical distinction between plugins or prompts\. Installing a prompt is equivalent to switching themes in other systems\. The interface is always \fIinstall\fR, \fIupdate\fR or \fIuninstall\fR\.
.
.P
Throughout this document and other Fisherman manuals you will find the term prompt when referring to the \fIconcept\fR of a theme, i\.e\., a plugin that defines a \fBfish_prompt\fR and / or \fBfish_right_prompt\fR functions\.
.
.SS "INDEX"
You can install, update and uninstall plugins by name, querying the Fisherman index, or by url using several of the variations described in #{\fBPlugins\fR}\. The index is a plain text flat database \fIindependent\fR from Fisherman\. You can use a custom index file by setting \fB$fisher_index\fR to your own file or url\. Redirection urls are not supported due to security and performance concerns\. See \fBfisher help config\fR\.
.
.P
A copy of the index is downloaded each time a query happens\. This keeps the index up to date and allows you to search the database offline\.
.
.P
The index is a list of records, each consisting of the following fields:
.
.IP "\(bu" 4
\fBname\fR, \fBurl\fR, \fBinfo\fR, \fBauthor\fR and one or more \fBtags\fR\.
.
.IP "" 0
.
.P
Fields are separated by a new line \fB\'\en\'\fR\. Tags are separated by one \fIspace\fR\. Here is a sample record:
.
.IP "" 4
.
.nf
shark
https://github\.com/bucaran/shark
Sparklines for your Fish
graph spark data
bucaran
.
.fi
.
.IP "" 0
.
.P
To submit a new plugin for registration install the \fBsubmit\fR plugin:
.
.IP "" 4
.
.nf
fisher install submit
.
.fi
.
.IP "" 0
.
.P
For usage see the bundled documentation \fBfisher help submit\fR\.
.
.P
You can also submit a new plugin manually and create a pull request\.
.
.IP "" 4
.
.nf
git clone https://github\.com/fisherman/fisher\-index
cd index
echo "$name\en$url\en$info\en$author\en$tags\en\en" >> index
git push origin master
open http://github\.com
.
.fi
.
.IP "" 0
.
.P
Now you can create a new pull request in the upstream repository\.
.
.SS "CACHE"
Downloaded plugins are tracked as Git repositories under \fB$fisher_cache\fR\. See \fBfisher help config\fR to find out about other Fisherman configuration variables\.
.
.P
When you install or uninstall a plugin, Fisherman downloads the repository to the cache and copies only the relevant files from the cache to the loaded function and / or completion path\. In addition, man pages are added to the corresponding man directory and if a Makefile is detected, the command \fBmake\fR is run\.
.
.P
The cache also provides a location for a local copy of the Index\.
.
.SS "FISHFILES"
Dependency manifest file, or fishfiles for short, let you share plugin configurations across multiple installations, allow plugins to declare dependencies, and prevent information loss in case of system failure\. See \fBfisher help fishfile\fR\.
.
.P
Here is an example fishfile inside \fB$fisher_config\fR:
.
.IP "" 4
.
.nf
# my plugins
gitio
fishtape
# my links
github/bucaran/shark
.
.fi
.
.IP "" 0
.
.P
The fishfile updates as you install / uninstall plugins\. See also \fBfisher help install\fR or \fBfisher help uninstall\fR\.
.
.P
Plugins may list any number of dependencies to other plugins in a fishfile at the root of each project\. By default, when Fisherman installs a plugin, it will also fetch and install its dependencies\. If a dependency is already installed, it will not be updated as this could potentially break other plugins using an older version\. For the same reasons, uninstalling a plugin does not remove its dependencies\. See \fBfisher help update\fR\.
.
.SS "CONFIGURATION"
Fisherman allows a high level of configuration using \fB$fisher_*\fR variables\. You can customize the home and configuration directories, debug log file, cache location, index source url, command aliases, etc\. See \fBfisher help config\fR\.
.
.P
You can also extend Fisherman by adding new commands and ship them as plugins as well\. Fisherman automatically adds completions to \fIcommands\fR based in the function \fIdescription\fR and usage help if provided\. See \fBfisher help help\fR and \fBfisher help commands\fR\.
.
.P
To add completions to standalone utility plugins, use \fBcomplete\fR(1)\.
.
.SS "CLI"
If you are already familiar with other UNIX tools, you\'ll find Fisherman commands behave intuitively\.
.
.P
Most commands read the standard input by default when no options are given and produce easy to parse output, making Fisherman commands ideal for plumbing and building upon each other\.
.
.P
Fisherman also ships with a CLI options parser and a background job wait spinner that you can use to implement your own commands CLI\. See \fBgetopts\fR(1) and \fBwait\fR(1)\.
.
.SH "COMPATIBILITY"
Fisherman supports Oh My Fish! (Wahoo) themes and plugins by default, but some features are turned off due to performance considerations\.
.
.P
Oh My Fish! evaluates every \fI\.fish\fR file inside the root directory of every plugin during initialization\. This is necessary in order to register any existing \fBinit\fR events and invoke them using fish \fBemit\fR(1)\.
.
.P
Since it is not possible to determine whether a file defines an initialization event without evaluating its contents first, Oh My Fish! sources all \fI\.fish\fR files and then emits events for each plugin\.
.
.P
Not all plugins opt in the initialization mechanism, therefore support for this behavior is turned off by default\. If you would like Fisherman to behave like Oh My Fish! at the start of each session, install the \fBomf\fR compatibility plugin\.
.
.IP "" 4
.
.nf
fisher install omf
.
.fi
.
.IP "" 0
.
.P
This plugin also adds definitions for some of Oh My Fish! Core Library functions\.
.
.SH "SEE ALSO"
\fBfisher\fR(1)
.
.br
\fBfisher help\fR
.
.br
\fBfisher help config\fR
.
.br
\fBfisher help plugins\fR
.
.br
\fBfisher help commands\fR
.
.br
\fBwait\fR(1)
.
.br
\fBgetopts\fR(1)
.
.br

@ -0,0 +1,199 @@
fisher(7) -- An Introduction to Fisherman
=========================================
## DESCRIPTION
Fisherman is a shell manager for `fish`(1) that lets you share and reuse code, prompts and configurations easily.
Some features include: minimalistic design, flat tree structure, unified plugin system, external self-managed database, cache mechanism, dependency manifest file and compatibility with Oh My Fish! and other frameworks.
This document describes Fisherman main features and their implementation details. For usage and command help see `fisher`(1).
## FLAT TREE
The configuration directory structure is optimized to help fish start new sessions as quickly as possible, regardless of the numbers of plugins or prompts enabled at any given time.
To explain how this is possible, we need to make a digression and discuss function scope first. In fish, all functions share the same scope and you can use only one name per function.
In the following example:
```
function foo
echo $_
function bar
end
end
function bar
echo $_
end
```
*foo* and *bar* are available immediately at the command line prompt and both print their names. But there is a catch, calling *foo* at least once will create a new *bar* function, effectively erasing the previous *bar* definition. Subsequent calls to *bar* will print nothing.
By convention, functions that start with any number of underscores are *intentionally* private, but there is no mechanism that prevents you from calling them at any time once loaded.
With this in mind, it's possible to improve the slow shell start problem using a *flat* tree structure whose path is loaded only once.
The overhead of juggling multiple path hierarchies in a per-plugin basis yields no benefits as everything is shared in the same scope.
Loading a path simply means adding the desired location to the `$fish_function_path` array. See also `functions`(1).
Here is a snapshot of a typical configuration path with a single plugin and prompt:
$fisher_config
|-- cache/
|-- functions/
| |-- my_plugin.fish
| |-- fish_prompt.fish
| |-- fish_right_prompt.fish
|-- completions/
| |-- my_plugin.fish
|-- man/
|-- man1/
|-- my_plugin.1
If you are already familiar in the way fish handles your user configuration, you will find the above structure similar to `$XDG_CONFIG_HOME/fish`. See `help fish`#{`Initialization Files`} to learn more about fish configuration.
### PLUGINS
Plugins are components that extend and add features to your shell. To see what plugins are available use `fisher search`. You can also type `fisher install` and hit *tab* once to get full name completions and plugin information. The same works for `fisher update` and `fisher uninstall`.
To learn how to create plugins, see `fisher help plugins`.
To install a plugin, you can use their *name* if they are listed in `$fisher_index`.
```
fisher install shark
```
Otherwise, you can use the repository remote *url*.
```
fisher install oh-my-fish/bobthefish
```
If the domain or host is not provided, Fisherman will use any value in `$fisher_default_host`. The default value is `https://github.com`.
In addition, all of the following variations are accepted:
* `github`/owner/repo `->` https://github.com/owner/repo<br>
* `gh:`owner/repo `->` https://github.com/owner/repo<br>
Shortcuts for other common Git repository hosting services are also available:
* `bb:`/owner/repo `->` https://bitbucket.org/owner/repo<br>
* `gl:`/owner/repo `->` https://gitlab.com/owner/repo<br>
A flat tree model means there is no technical distinction between plugins or prompts. Installing a prompt is equivalent to switching themes in other systems. The interface is always *install*, *update* or *uninstall*.
Throughout this document and other Fisherman manuals you will find the term prompt when referring to the *concept* of a theme, i.e., a plugin that defines a `fish_prompt` and / or `fish_right_prompt` functions.
### INDEX
You can install, update and uninstall plugins by name, querying the Fisherman index, or by url using several of the variations described in #{`Plugins`}. The index is a plain text flat database *independent* from Fisherman. You can use a custom index file by setting `$fisher_index` to your own file or url. Redirection urls are not supported due to security and performance concerns. See `fisher help config`.
A copy of the index is downloaded each time a query happens. This keeps the index up to date and allows you to search the database offline.
The index is a list of records, each consisting of the following fields:
* `name`, `url`, `info`, `author` and one or more `tags`.
Fields are separated by a new line `'\n'`. Tags are separated by one *space*. Here is a sample record:
```
shark
https://github.com/bucaran/shark
Sparklines for your Fish
graph spark data
bucaran
```
To submit a new plugin for registration install the `submit` plugin:
```
fisher install submit
```
For usage see the bundled documentation `fisher help submit`.
You can also submit a new plugin manually and create a pull request.
```
git clone https://github.com/fisherman/fisher-index
cd index
echo "$name\n$url\n$info\n$author\n$tags\n\n" >> index
git push origin master
open http://github.com
```
Now you can create a new pull request in the upstream repository.
### CACHE
Downloaded plugins are tracked as Git repositories under `$fisher_cache`. See `fisher help config` to find out about other Fisherman configuration variables.
When you install or uninstall a plugin, Fisherman downloads the repository to the cache and copies only the relevant files from the cache to the loaded function and / or completion path. In addition, man pages are added to the corresponding man directory and if a Makefile is detected, the command `make` is run.
The cache also provides a location for a local copy of the Index.
### FISHFILES
Dependency manifest file, or fishfiles for short, let you share plugin configurations across multiple installations, allow plugins to declare dependencies, and prevent information loss in case of system failure. See `fisher help fishfile`.
Here is an example fishfile inside `$fisher_config`:
```
# my plugins
gitio
fishtape
# my links
github/bucaran/shark
```
The fishfile updates as you install / uninstall plugins. See also `fisher help install` or `fisher help uninstall`.
Plugins may list any number of dependencies to other plugins in a fishfile at the root of each project. By default, when Fisherman installs a plugin, it will also fetch and install its dependencies. If a dependency is already installed, it will not be updated as this could potentially break other plugins using an older version. For the same reasons, uninstalling a plugin does not remove its dependencies. See `fisher help update`.
### CONFIGURATION
Fisherman allows a high level of configuration using `$fisher_*` variables. You can customize the home and configuration directories, debug log file, cache location, index source url, command aliases, etc. See `fisher help config`.
You can also extend Fisherman by adding new commands and ship them as plugins as well. Fisherman automatically adds completions to *commands* based in the function *description* and usage help if provided. See `fisher help help` and `fisher help commands`.
To add completions to standalone utility plugins, use `complete`(1).
### CLI
If you are already familiar with other UNIX tools, you'll find Fisherman commands behave intuitively.
Most commands read the standard input by default when no options are given and produce easy to parse output, making Fisherman commands ideal for plumbing and building upon each other.
Fisherman also ships with a CLI options parser and a background job wait spinner that you can use to implement your own commands CLI. See `getopts`(1) and `wait`(1).
## COMPATIBILITY
Fisherman supports Oh My Fish! (Wahoo) themes and plugins by default, but some features are turned off due to performance considerations.
Oh My Fish! evaluates every *.fish* file inside the root directory of every plugin during initialization. This is necessary in order to register any existing `init` events and invoke them using fish `emit`(1).
Since it is not possible to determine whether a file defines an initialization event without evaluating its contents first, Oh My Fish! sources all *.fish* files and then emits events for each plugin.
Not all plugins opt in the initialization mechanism, therefore support for this behavior is turned off by default. If you would like Fisherman to behave like Oh My Fish! at the start of each session, install the `omf` compatibility plugin.
```
fisher install omf
```
This plugin also adds definitions for some of Oh My Fish! Core Library functions.
## SEE ALSO
`fisher`(1)<br>
`fisher help`<br>
`fisher help config`<br>
`fisher help plugins`<br>
`fisher help commands`<br>
`wait`(1)<br>
`getopts`(1)<br>

@ -0,0 +1,42 @@
{
"name": "fisherman",
"version": "0.1.0",
"description": "fish shell manager",
"main": "index.js",
"directories": {
"man": "man",
"test": "test"
},
"scripts": {
"install": "make",
"test": "make test"
},
"repository": {
"type": "git",
"url": "git+https://github.com/fisherman/fisherman.git"
},
"keywords": [
"fish-shell",
"shell",
"fisherman",
"theme",
"prompt",
"shell",
"manager",
"package",
"package manager",
"git",
"framework",
"fast",
"light",
"pretty",
"minimal"
],
"author": "Jorge Bucaran",
"license": "MIT",
"bugs": {
"url": "https://github.com/fisherman/fisherman/issues"
},
"homepage": "https://github.com/fisherman/fisherman#readme",
"dependencies": {}
}

@ -0,0 +1,50 @@
set -l cmd awk
set -l fishfile $DIRNAME/fixtures/fishfile
function -S setup
set -g fisher_alias "$cmd=A,B"
function fisher_$cmd
if not set -q argv[1]
echo usage:...
return 1
end
awk $argv
end
end
function -S teardown
functions -e fisher_$cmd
end
test "read a fishfile using --file"
(fisher --file=$fishfile) = foo bar baz github/foo/bar
end
test "evaluate commands"
(fisher $cmd) = usage:...
end
test "evaluate commands w/ standard input"
(echo "foo bar baz" | fisher $cmd '{ print $2 }' | xargs) = "bar"
end
test "display version information"
(fisher --version | cut -d " " -f3) = (sed 1q $fisher_home/VERSION)
end
test "evaluate \$fisher_alias=<command=alias[,...]> as aliases"
(fisher A; fisher B) = (fisher $cmd; fisher $cmd)
end
test "display usage"
(fisher | sed 1q) = "usage: fisher <command> [<options>] [--version] [--help]"
end
test "display help information about 'help' at the bottom"
(fisher | tail -n2 | xargs) = "Use fisher help -g to list guides and other documentation. See fisher help <command or concept> to access a man page."
end
test "display basic help information about available commands"
(fisher | sed -E 's/ +//' | grep "^$cmd\$")
end

@ -0,0 +1,8 @@
# fishfile example
###################
foo
bar
package baz # omf
# comment
# comment
github/foo/bar

@ -0,0 +1,112 @@
test "only bare"
"_ beer" = (getopts beer)
end
test "bare and bare"
"_ bar" "_ beer" = (getopts bar beer)
end
test "bare first"
"foo" "_ beer" = (getopts beer --foo)
end
test "bare sequence"
"_ foo" "_ bar" "_ baz" "_ quux" = (getopts foo bar baz quux)
end
test "bare does not end opts"
"a" "b 42" "_ beer" "foo" "bar" = (getopts -ab42 beer --foo --bar)
end
test "only single"
"f" "o" "o 42" = (getopts -foo42)
end
test "single and single"
"a" "b" "c" "x" "y" "z" = (getopts -abc -xyz)
end
test "single and bare"
"a" "b" "c bar" = (getopts -abc bar)
end
test "single and value"
"a bar" = (getopts -a bar)
end
test "single w/ value and bare"
"a" "b" "c ./" "_ bar" = (getopts -abc./ bar)
end
test "single and double"
"a" "b" "c" "foo" = (getopts -abc --foo)
end
test "double"
"foo" = (getopts --foo)
end
test "double w/ value"
"foo bar" = (getopts --foo=bar)
end
test "double w/ negated value"
"foo bar !" = (getopts --foo!=bar)
end
test "double w/ value group"
"foo bar" "bar foo" = (getopts --foo=bar --bar=foo)
end
test "double w/ value and bare"
"foo bar" "_ beer" = (getopts --foo=bar beer)
end
test "double double"
"foo" "bar" = (getopts --foo --bar)
end
test "double w/ inner dashes"
"foo-bar-baz" = (getopts --foo-bar-baz)
end
test "double and single"
"foo" "a" "b" "c" = (getopts --foo -abc)
end
test "multiple double sequence"
"foo" "bar" "secret 42" "_ baz" = (getopts --foo --bar --secret=42 baz)
end
test "single double single w/ remaining bares"
"f" "o" "o" "bar" "b" "a" "r norf" "_ baz" "_ quux" = (
getopts -foo --bar -bar norf baz quux)
end
test "double dash"
"_ --foo" "_ bar" = (getopts -- --foo bar)
end
test "single double dash"
"a" "_ --foo" "_ bar" = (getopts -a -- --foo bar)
end
test "bare and double dash"
"foo bar" "_ baz" "_ foo" "_ --foo" = (getopts --foo=bar baz -- foo --foo)
end
test "long string as a value"
"f Fee fi fo fum" = (getopts -f "Fee fi fo fum")
end
test "single and empty string"
"f" = (getopts -f "")
end
test "double and empty string"
"foo" = (getopts --foo "")
end
test "ignore repeated options"
"x" = (getopts -xxx | xargs)
end

@ -0,0 +1,40 @@
set -l name foo
set -l path $DIRNAME/.$TESTNAME.test
set -l sections 1 5 7
function -S setup
set -gx MANPATH $path/man
for i in $sections
if not mkdir -p $MANPATH/man$i
return
end
echo $name > $MANPATH/man$i/fisher-$name.$i
end
end
function -S teardown
rm -rf $path
end
test "help wraps `fisher` w/o arguments"
(fisher help) = (fisher)
end
test "help --all shows commands and guides"
! -z (fisher help --all | grep -E 'Fisherman commands:$|Fisherman guides:$' | xargs)
end
test "help --guides shows guides"
! -z (fisher help --guides | grep -E 'Fisherman guides:$' | xargs)
end
test "help --usage shows command usage info"
(fisher help --usage=help) = (fisher help --help)
end
for i in $sections
test "read fisher-<name> man pages"
(fisher help $name | xargs) = $name
end
end

@ -0,0 +1,28 @@
function create_mock_source -a path
set -e argv[1]
for name in $argv
if not mkdir -p $path/$name/{,functions,completions,man}
return 1
end
echo "function $name; end;" >> $path/$name/$name.fish
echo > $path/$name/functions/$name.func.fish
echo > $path/$name/completions/$name.fish
for n in (seq 9)
mkdir -p $path/$name/man/man$n
echo $name >> $path/$name/man/man$n/$name.$n
end
git -C $path/$name init --quiet
git -C $path/$name config user.email "man@fisher"
git -C $path/$name config user.name "fisherman"
git -C $path/$name add -A > /dev/null
git -C $path/$name commit -m "add $name.fish" > /dev/null
printf "$name\nfile://$path/$name\n$name's plugin\nt a g s\n@$name\n\n"
end
end

@ -0,0 +1,66 @@
source $DIRNAME/helpers/create_mock_source.fish
set -l path $DIRNAME/$TESTNAME.test(random)
set -l source $path/source
set -l index $path/index
set -l names foo bar
function -S setup
if not mkdir -p $path
return 1
end
set -g fisher_config $path/config
set -g fisher_cache $fisher_config/cache
set -g fisher_index "file://$index"
create_mock_source $source $names > $index
end
function -S teardown
rm -rf $path
end
for name in $names
test "install by name:<$name>" (
fisher install $name --quiet
ls $fisher_cache
) = $name
end
test "install by url:<file://$source/$name>" (
fisher install file://$source/$name --quiet
ls $fisher_cache
) = $name
end
end
test "install several"
(printf "%s\n" $names) = (
fisher install $names --quiet
ls $fisher_cache)
end
test "install from <stdin>"
(printf "%s\n" $names) = (
printf "%s\n" $names | fisher install --quiet
ls $fisher_cache)
end
test "install updates fishfile"
"$names" = (
fisher install $names --quiet
xargs < $fisher_config/fishfile)
end
test "fail install package by name"
"fisher: 'what' not found" = (
fisher install "what" ^&1
echo $status)
end

@ -0,0 +1,19 @@
test "display help help"
(fisher help --help | xargs) = "usage: fisher help [<keyword>] [--all] [--guides] [--usage[=<command>]] [--help] -a --all List commands and guides -g --guides List documentation guides -u --usage[=<command>] Display command usage help -h --help Show usage help"
end
test "display install help"
(fisher install --help | xargs) = "usage: fisher install [<name | url> ...] [--quiet] [--help] -q --quiet Enable quiet mode -h --help Show usage help"
end
test "display search help"
(fisher search --help | xargs) = "usage: fisher search [<name | url>] [--select=<source>] [--field=<field>] [--or|--and] [--quiet] [--help] -s --select=<source> Select all, cache or remote plugins -f --field=<field> Filter by name, url, info, tag or author -a --and Join query with AND operator -o --or Join query with OR operator -q --quiet Enable quiet mode -h --help Show usage help"
end
test "display uninstall help"
(fisher uninstall --help | xargs) = "usage: fisher uninstall [<name | url> ...] [--all] [--force] [--quiet] [--help] -a --all Uninstall all plugins -f --force Delete copy from cache -q --quiet Enable quiet mode -h --help Show usage help"
end
test "display update help"
(fisher update --help | xargs) = "usage: fisher update [<name | url> ...] [--self] [--cache] [--path=<path>] [--quiet] [--help] -s --self Update Fisherman -c --cache Update cached plugins --path=<path> Update repository at given path -q --quiet Enable quiet mode -h --help Show usage help"
end

@ -0,0 +1,141 @@
set -l path $DIRNAME/$TESTNAME.test(random)
set -l index $path/index
set -l names foo bar baz #norf
set -l cache foo bar
set -l url https://hoge.com
set -l info info
function -S search_make_record
awk -v url=$url -v info=$info -v author=Mr. '
{
printf("%s\n%s\n%s\n%s\nMr.%s\n\n", $0, url"/"$0, info, "t a g s", $0)
}
'
end
function -S setup
if not mkdir -p $path
return 1
end
set -g fisher_cache $path/cache
set -g fisher_index "file://$index"
printf "%s\n" $names | search_make_record > $index
for i in $cache
mkdir -p $fisher_cache/$i
end
end
function -S teardown
rm -rf $path
end
test "use \$fisher_cache for local cache and \$fisher_index for data source"
(fisher search --name --select=all) = $names
end
test "--select=cache shows names packages also in the cache"
(fisher search --select=cache | xargs) = (printf "%s\n" $cache | search_make_record | xargs)
end
test "--select=remote shows names packages sans local cache"
(fisher search --select=remote) = (
for i in $names
if not contains -- $i $cache
printf "%s\n" $i | search_make_record
end
end)
end
test "--field=name filters data by name field"
(fisher search --field=name) = $names
end
test "--field=url filters data by url field"
(fisher search --field=url) = (
for i in $names
printf "%s\n" $url/$i
end)
end
test "--field=info filters data by info field"
(fisher search --field=info) = (
printf "$info\n%.0s" (seq (count $names)))
end
test "--field=author filters data by author field"
(fisher search --field=author) = (printf "Mr.%s\n" $names)
end
for field in name url info author
test "--$field is a shorthand for --field=$field"
(fisher search --$field) = (fisher search --field=$field)
end
end
test "--name=<name> finds given record"
(fisher search --name=foo) = (echo foo | search_make_record)
end
test "--author=<author> finds given record"
(fisher search --author=Mr.foo) = (printf "%s\n" foo | search_make_record)
end
test "search <name> finds given record by name"
(fisher search bar) = (printf "%s\n" bar | search_make_record)
end
test "search <u/r/l> finds given record by url"
(fisher search $url/bar) = (printf "%s\n" bar | search_make_record)
end
test "search non-matches with --<field>!=<value>"
(fisher search --name!=foo --field=name) = (
printf "%s\n" $names | while read -l name
if not test $name = foo
echo $name
end
end)
end
test "search for regex matches with --<field>~/regex/"
(fisher search --name~/..../ --field=name) = (
printf "%s\n" $names | awk 'length($0) == 4 { print }')
end
test "search for regex non-matches with --<field>!~/regex/"
(fisher search --name!~/..../ --field=name) = (
printf "%s\n" $names | awk 'length($0) != 4 { print }')
end
test "use --and operator to join a query w/ the default search query"
(fisher search bar --or --name=baz) = (printf "%s\n" bar baz | search_make_record)
end
test "use --or operator to join two queries"
(fisher search --name=baz --or --name=foo --field=name) = (echo baz\nfoo)
end
test "use --query=<query> to specify any search query"
(fisher search --query="name!~/^[fb]/") = (
printf "%s\n" $names | awk '$0!~/^[fb]/ { print }' | search_make_record)
end
test "use --query=<query> to specify any search query and filter with --field"
(fisher search --query="name~/^[fb]/" --field=name) = (
printf "%s\n" $names | awk '$0~/^[fb]/ { print }')
end
test "use --quiet to enable quiet mode"
(fisher search --quiet --name=%%%; echo $status) = 1
end

@ -0,0 +1,120 @@
source $DIRNAME/helpers/create_mock_source.fish
set -l path $DIRNAME/$TESTNAME.test(random)
set -l source $path/source
set -l index $path/index
set -l names foo bar
function -S setup
if not mkdir -p $path
return 1
end
set -g fisher_config $path/config
set -g fisher_cache $fisher_config/cache
set -g fisher_index "file://$index"
create_mock_source $source $names > $index
fisher install $names --quiet
end
function -S teardown
rm -rf $path
end
for name in $names
test "uninstall <$name> does not clear cache"
(printf "%s\n" $names) = (
fisher uninstall $name --quiet
ls $fisher_cache)
end
test "uninstall --force clears package <$name> from cache"
(for _name in $names
if test $_name != $name
printf "%s\n" $_name
end
end) = (
fisher uninstall $name --quiet --force
ls $fisher_cache)
end
test "uninstall <$name> removes functions/$name.fish"
(
echo 0
echo 1
) = (
builtin test -f $fisher_config/functions/$name.fish
echo $status
fisher uninstall $name --quiet
builtin test -f $fisher_config/functions/$name.fish
echo $status)
end
test "uninstall <$name> removes completions/$name.fish"
(
echo 0
echo 1
) = (
builtin test -f $fisher_config/completions/$name.fish
echo $status
fisher uninstall $name --quiet
builtin test -f $fisher_config/completions/$name.fish
echo $status)
end
test "uninstall <$name> removes man/man.../$name..."
(
for n in (seq 9)
echo 0
end
for n in (seq 9)
echo 1
end
) = (
for n in (seq 9)
builtin test -f $fisher_config/man/man$n/$name.$n
echo $status
end
fisher uninstall $name --quiet
for n in (seq 9)
builtin test -f $fisher_config/man/man$n/$name.$n
echo $status
end)
end
end
test "remove all installed/enabled plugins"
-z (
fisher uninstall --all --quiet
ls $fisher_config/functions
ls $fisher_config/completions)
end
test "remove all installed plugins flushing cache"
-z (
fisher uninstall --all --force --quiet
ls $fisher_cache)
end
test "uninstall updates fishfile"
"$names[2..-1]" = (
fisher uninstall $names[1] --quiet
cat $fisher_config/fishfile | xargs)
end

@ -0,0 +1,36 @@
source $DIRNAME/helpers/create_mock_source.fish
set -l path $DIRNAME/$TESTNAME.test(random)
set -l server $path/server
set -l home fisherman
function -S setup
set -g fisher_home $path/home
if not mkdir -p $fisher_home
return 1
end
create_mock_source $server $home > /dev/null
git -C $fisher_home init --quiet
git -C $fisher_home remote add origin $server/$home/.git
end
function -S teardown
rm -rf $path
end
test "update itself w/ --self"
(ls $server/$home) = (
fisher update --self --quiet ^/dev/null
ls $fisher_home)
end
test "update repo at given path via git pull"
(ls $server/$home) = (
fisher update --path=$fisher_home --quiet ^/dev/null
ls $fisher_home)
end

@ -0,0 +1,64 @@
source $DIRNAME/helpers/create_mock_source.fish
set -l path $DIRNAME/$TESTNAME.test(random)
set -l source $path/source
set -l index $path/index
set -l names foo
set -l extra norf
function -S setup
if not mkdir -p $path
return 1
end
set -g fisher_config $path/config
set -g fisher_cache $fisher_config/cache
set -g fisher_index "file://$index"
create_mock_source $source $names > $index
fisher install $names --quiet
# Updates the source repos duplicating the original content.
# See helpers/create_mock_source.fish
create_mock_source $source $names $extra > $index
end
function -S teardown
rm -rf $path
end
for name in $names
test "update <$name> package copy in cache"
(functions $name $name | xargs) = (
fisher update $name --quiet
fish_indent < $fisher_cache/$name/$name.fish | xargs)
end
test "install <$name> if update is successful"
(functions $name $name | xargs) = (
fisher update $name --quiet
fish_indent < $fisher_config/functions/$name.fish | xargs)
end
end
test "update packages via <stdin>"
(functions $names $names | xargs) = (
printf "%s\n" $names | fisher update --quiet
cat $fisher_config/functions/{$names}.fish | fish_indent | xargs)
end
test "update cache"
(functions $names $names | xargs) = (
fisher update --cache --quiet
cat $fisher_config/functions/{$names}.fish | fish_indent | xargs)
end
test "update index with --index using contents in \$fisher_index" (
fisher update --index --quiet
awk -F'\n' -v RS='' '{ print $1 }' $fisher_cache/.index) = $names $extra
end

@ -0,0 +1,63 @@
set -l id foo bar
set -l host baz
set -l tld org
function -S setup
set -g fisher_default_host https://$host.$tld
end
test "validate names"
$id[1] = (fisher --validate=$id[1])
end
test "validate uris"
$fisher_default_host/$id[1]/$id[2] = (fisher --validate=$id[1]/$id[2])
end
test "validate names may end with a number"
"a0" = (fisher --validate=a0)
end
test "validate names may start in uppercase"
-z (fisher --validate=A)
end
test "validate names may not start with a number"
-z (fisher --validate=0abc)
end
test "supress validation output"
-z (fisher -q --validate=$id[1])
end
test "remove `/' from uris"
$fisher_default_host/$id[1]/$id[2] = (fisher --validate=$id[1]/$id[2]/)
end
test "remove `.git' from uris"
$fisher_default_host/$id[1]/$id[2] = (fisher --validate=$id[1]/$id[2].git)
end
test "file:/// uris"
! -z (fisher --validate=file:///$id[1]/$id[2].git)
end
test "id/id uris"
! -z (fisher --validate=$id[1]/$id[2].git)
end
test "short owner/repo uris"
https://github.com/$id[1]/$id[2] = (fisher --validate=github/$id[1]/$id[2])
end
test "short $short:owner/repo uris"
https://github.com/$id[1]/$id[2] = (fisher --validate=gh:$id[1]/$id[2])
end
test "short bitbucket urls uris"
https://bitbucket.org/$id[1]/$id[2] = (fisher --validate=bb:$id[1]/$id[2])
end
test "short gitlab urls uris"
https://gitlab.com/$id[1]/$id[2] = (fisher --validate=gl:$id[1]/$id[2])
end

@ -0,0 +1,37 @@
set -l path $DIRNAME/$TESTNAME.test(random)
function -S setup
if not mkdir -p $path
return 1
end
pushd $path
end
function -S teardown
popd
rm -rf $path
end
test "fail if no commands are given" (
wait
echo $status) = 1
end
test "do not redirect standard output"
(wait "echo output") = output
end
test "fail if there is any output to standard error" (
wait "echo output > &2"
echo $status) = 1
end
test "log standard error to log if <file> is given" (
wait "printf '%s\n' a b c d >&2" --log=$path/log
cat $path/log | xargs) = "1 a 2 b 3 c 4 d"
end
test "display help"
(wait --help | xargs) = "usage: wait <commands> [--spin=<style>] [--time=<delay>] [--log=<file>] [--format=<format>] [--help] -s --spin=<style> Set spinner style -t --time=<delay> Set spinner transition time delay -l --log=<file> Output standard error to <file> -f --format=<format> Use given <format> to display spinner -h --help Show usage help"
end
Loading…
Cancel
Save