Skip to content

Instantly share code, notes, and snippets.

@DanielFGray
Last active March 2, 2016 23:44
Show Gist options
  • Save DanielFGray/a94b6c063595d0aaac89 to your computer and use it in GitHub Desktop.
Save DanielFGray/a94b6c063595d0aaac89 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
has() {
command -v $1 &> /dev/null
}
err() {
echo -e "\e[31m$1\e[0m" >&2
}
die() {
[[ -n "$1" ]] && err "$1"
exit 1
}
usage() {
more <<'HELP'
fv [OPTIONS] [SEARCH]
fuzzy file filtering and command executing
-c command to execute [defaults to vim]
-a search all dirs and hidden files (still quirky)
-d detach from terminal via nohup
HELP
}
setCmd() {
if has $1; then
cmd="$1"
else
die "$1 is not a valid command"
fi
}
cmd='vim'
searchstr=''
searchcmd=''
searchopts=()
allfiles=false
while getopts "hadc:" opt; do
case "$opt" in
h) usage; exit 0 ;;
a) allfiles=true ;;
c) setCmd "$OPTARG" ;;
esac
done
shift "$((OPTIND-1))"
has 'fzf' || die 'fzf not found'
if [[ "$cmd" == 'vim' && -n "$DISPLAY" ]] && has v; then
cmd='v'
fi
for c in 'ag' 'ack' 'grep'; do
if has "$c"; then
searchcmd="$c"
break
fi
done
if [[ $searchcmd == 'grep' ]]; then
err 'grep is slow, you should strongly consider installing ag or ack'
sleep .5
fi
if [[ -n "$1" ]]; then
if [[ -d "$1" ]]; then
searchopts+=( "$1" )
else
searchstr="$1"
fi
shift
fi
case "$searchcmd" in
'ag')
searchopts+=( '--color' )
# searchopts+=( '-l' )
if [[ "$allfiles" == true ]]; then
searchopts+=( '-u' '--hidden' )
fi
if [[ "$searchstr" == '' ]]; then
searchopts+=( '-l' )
fi
;;
'ack')
if [[ "$searchstr" == '' ]]; then
if [[ "$allfiles" == false ]]; then
searchopts+=( '-g' '^[^\.]' )
else
searchopts+=( '-f' )
fi
else
searchopts+=( '-l' )
# searchopts+=( '--match' )
fi
;;
'grep')
searchopts+=( '-l' '-r' '-I' )
if [[ "$allfiles" == false ]]; then
searchopts+=( '--exclude-dir=bower_components' )
searchopts+=( '--exclude-dir=node_modules' )
searchopts+=( '--exclude-dir=jspm_packages' )
searchopts+=( '--exclude-dir=.cvs' )
searchopts+=( '--exclude-dir=.git' )
searchopts+=( '--exclude-dir=.hg' )
searchopts+=( '--exclude-dir=.svn' )
fi
if [[ "$searchstr" == '' ]]; then
searchopts+=( '' )
fi
;;
esac
if [[ "$searchstr" != '' ]]; then
searchopts+=( "$searchstr" )
fi
choices=$($searchcmd "${searchopts[@]}" 2> /dev/null |
fzf --ansi --cycle --multi) || exit 1
if [[ "$searchstr" != '' ]]; then
if [[ $searchcmd == 'ag' ]]; then
choices=$(cut -d: -f1 <<< "$choices")
fi
fi
mapfile -t choices <<< "$choices"
$cmd "${choices[@]}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment