2014-11-30 20:02:34 +00:00
|
|
|
#!/usr/bin/env bash
|
2013-10-23 01:26:55 +00:00
|
|
|
|
2015-10-23 05:56:27 +00:00
|
|
|
set -u
|
|
|
|
|
2015-11-03 14:03:49 +00:00
|
|
|
[[ "$@" =~ --pre ]] && version=0.10.9 pre=1 ||
|
|
|
|
version=0.10.9 pre=0
|
2015-01-04 17:17:26 +00:00
|
|
|
|
2015-10-23 05:56:27 +00:00
|
|
|
auto_completion=
|
|
|
|
key_bindings=
|
|
|
|
update_config=1
|
|
|
|
|
|
|
|
help() {
|
|
|
|
cat << EOF
|
|
|
|
usage: $0 [OPTIONS]
|
|
|
|
|
|
|
|
--help Show this message
|
|
|
|
--bin Download fzf binary only
|
|
|
|
--all Download fzf binary and update configuration files
|
|
|
|
to enable key bindings and fuzzy completion
|
|
|
|
--[no-]key-bindings Enable/disable key bindings (CTRL-T, CTRL-R, ALT-C)
|
|
|
|
--[no-]completion Enable/disable fuzzy completion (bash & zsh)
|
|
|
|
--[no-]update-rc Whether or not to update shell configuration files
|
|
|
|
|
|
|
|
EOF
|
|
|
|
}
|
|
|
|
|
|
|
|
for opt in $@; do
|
|
|
|
case $opt in
|
|
|
|
--help)
|
|
|
|
help
|
|
|
|
exit 0
|
|
|
|
;;
|
|
|
|
--all)
|
|
|
|
auto_completion=1
|
|
|
|
key_bindings=1
|
|
|
|
update_config=1
|
|
|
|
;;
|
|
|
|
--key-bindings) key_bindings=1 ;;
|
|
|
|
--no-key-bindings) key_bindings=0 ;;
|
|
|
|
--completion) auto_completion=1 ;;
|
|
|
|
--no-completion) auto_completion=0 ;;
|
|
|
|
--update-rc) update_config=1 ;;
|
|
|
|
--no-update-rc) update_config=0 ;;
|
2015-10-23 08:43:34 +00:00
|
|
|
--bin) ;;
|
2015-10-23 05:56:27 +00:00
|
|
|
*)
|
|
|
|
echo "unknown option: $opt"
|
|
|
|
help
|
|
|
|
exit 1
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
2015-01-05 03:21:26 +00:00
|
|
|
cd $(dirname $BASH_SOURCE)
|
2015-10-23 05:56:27 +00:00
|
|
|
fzf_base="$(pwd)"
|
2013-11-19 16:29:36 +00:00
|
|
|
|
2015-04-14 00:05:45 +00:00
|
|
|
# If stdin is a tty, we are "interactive".
|
2015-10-23 06:07:16 +00:00
|
|
|
interactive=
|
2015-04-14 00:05:45 +00:00
|
|
|
[ -t 0 ] && interactive=yes
|
|
|
|
|
2015-01-04 05:29:42 +00:00
|
|
|
ask() {
|
2015-04-14 00:05:45 +00:00
|
|
|
# non-interactive shell: wait for a linefeed
|
|
|
|
# interactive shell: continue after a single keypress
|
|
|
|
[ -n "$interactive" ] && read_n='-n 1' || read_n=
|
|
|
|
|
|
|
|
read -p "$1 ([y]/n) " $read_n -r
|
2015-01-04 05:29:42 +00:00
|
|
|
echo
|
2015-10-23 05:56:27 +00:00
|
|
|
[[ $REPLY =~ ^[Nn]$ ]]
|
2015-01-04 05:29:42 +00:00
|
|
|
}
|
|
|
|
|
2015-01-05 03:21:26 +00:00
|
|
|
check_binary() {
|
2015-01-07 11:08:05 +00:00
|
|
|
echo -n " - Checking fzf executable ... "
|
2015-08-19 10:42:06 +00:00
|
|
|
local output
|
|
|
|
output=$("$fzf_base"/bin/fzf --version 2>&1)
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
echo "Error: $output"
|
|
|
|
binary_error="Invalid binary"
|
|
|
|
elif [ "$version" != "$output" ]; then
|
|
|
|
echo "$output != $version"
|
|
|
|
binary_error="Invalid version"
|
|
|
|
else
|
2015-01-13 14:46:38 +00:00
|
|
|
echo "$output"
|
2015-01-17 11:40:00 +00:00
|
|
|
binary_error=""
|
2015-08-19 10:42:06 +00:00
|
|
|
return 0
|
2015-01-05 03:21:26 +00:00
|
|
|
fi
|
2015-08-19 10:42:06 +00:00
|
|
|
rm -f "$fzf_base"/bin/fzf
|
|
|
|
return 1
|
2015-01-05 03:21:26 +00:00
|
|
|
}
|
|
|
|
|
2015-01-07 11:08:05 +00:00
|
|
|
symlink() {
|
|
|
|
echo " - Creating symlink: bin/$1 -> bin/fzf"
|
2015-01-13 03:29:12 +00:00
|
|
|
(cd "$fzf_base"/bin &&
|
2015-01-17 11:40:00 +00:00
|
|
|
rm -f fzf &&
|
2015-01-13 03:29:12 +00:00
|
|
|
ln -sf $1 fzf)
|
2015-01-17 11:40:00 +00:00
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
binary_error="Failed to create symlink"
|
|
|
|
return 1
|
|
|
|
fi
|
2015-01-07 11:08:05 +00:00
|
|
|
}
|
|
|
|
|
2015-01-01 19:49:30 +00:00
|
|
|
download() {
|
2015-01-13 14:46:38 +00:00
|
|
|
echo "Downloading bin/fzf ..."
|
2015-08-02 06:09:57 +00:00
|
|
|
if [ $pre = 0 ]; then
|
|
|
|
if [ -x "$fzf_base"/bin/fzf ]; then
|
|
|
|
echo " - Already exists"
|
|
|
|
check_binary && return
|
2015-10-26 03:31:43 +00:00
|
|
|
fi
|
|
|
|
if [ -x "$fzf_base"/bin/$1 ]; then
|
2015-08-02 06:09:57 +00:00
|
|
|
symlink $1 && check_binary && return
|
|
|
|
fi
|
2015-10-26 03:31:43 +00:00
|
|
|
if which_fzf="$(which fzf 2> /dev/null)"; then
|
|
|
|
echo " - Found in \$PATH"
|
|
|
|
echo " - Creating symlink: $which_fzf -> bin/fzf"
|
|
|
|
(cd "$fzf_base"/bin && rm -f fzf && ln -sf "$which_fzf" fzf)
|
|
|
|
check_binary && return
|
|
|
|
fi
|
2015-01-04 05:29:42 +00:00
|
|
|
fi
|
2015-01-03 17:42:58 +00:00
|
|
|
mkdir -p "$fzf_base"/bin && cd "$fzf_base"/bin
|
|
|
|
if [ $? -ne 0 ]; then
|
2015-01-05 03:21:26 +00:00
|
|
|
binary_error="Failed to create bin directory"
|
|
|
|
return
|
2015-01-03 17:42:58 +00:00
|
|
|
fi
|
|
|
|
|
2015-01-06 15:24:05 +00:00
|
|
|
local url=https://github.com/junegunn/fzf-bin/releases/download/$version/${1}.tgz
|
2015-01-03 17:42:58 +00:00
|
|
|
if which curl > /dev/null; then
|
|
|
|
curl -fL $url | tar -xz
|
|
|
|
elif which wget > /dev/null; then
|
|
|
|
wget -O - $url | tar -xz
|
2014-06-20 16:43:25 +00:00
|
|
|
else
|
2015-01-05 03:21:26 +00:00
|
|
|
binary_error="curl or wget not found"
|
|
|
|
return
|
2015-01-03 17:42:58 +00:00
|
|
|
fi
|
|
|
|
|
|
|
|
if [ ! -f $1 ]; then
|
2015-01-05 03:21:26 +00:00
|
|
|
binary_error="Failed to download ${1}"
|
|
|
|
return
|
2014-06-20 16:43:25 +00:00
|
|
|
fi
|
2015-01-03 17:42:58 +00:00
|
|
|
|
2015-09-19 13:51:12 +00:00
|
|
|
chmod +x $1 && symlink $1 && check_binary
|
2015-01-01 19:49:30 +00:00
|
|
|
}
|
|
|
|
|
2015-01-03 17:42:58 +00:00
|
|
|
# Try to download binary executable
|
2015-01-04 16:25:54 +00:00
|
|
|
archi=$(uname -sm)
|
2015-01-05 03:21:26 +00:00
|
|
|
binary_available=1
|
|
|
|
binary_error=""
|
2015-01-05 17:04:06 +00:00
|
|
|
case "$archi" in
|
2015-01-06 15:24:05 +00:00
|
|
|
Darwin\ x86_64) download fzf-$version-darwin_amd64 ;;
|
|
|
|
Darwin\ i*86) download fzf-$version-darwin_386 ;;
|
|
|
|
Linux\ x86_64) download fzf-$version-linux_amd64 ;;
|
|
|
|
Linux\ i*86) download fzf-$version-linux_386 ;;
|
2015-03-12 01:06:15 +00:00
|
|
|
*) binary_available=0 binary_error=1 ;;
|
2015-01-05 17:04:06 +00:00
|
|
|
esac
|
2015-01-03 17:42:58 +00:00
|
|
|
|
2015-01-05 03:21:26 +00:00
|
|
|
cd "$fzf_base"
|
|
|
|
if [ -n "$binary_error" ]; then
|
2015-01-03 17:42:58 +00:00
|
|
|
if [ $binary_available -eq 0 ]; then
|
2015-01-05 03:21:26 +00:00
|
|
|
echo "No prebuilt binary for $archi ... "
|
2015-01-03 17:42:58 +00:00
|
|
|
else
|
2015-01-07 11:08:05 +00:00
|
|
|
echo " - $binary_error !!!"
|
2015-08-07 18:53:46 +00:00
|
|
|
exit 1
|
2015-01-03 17:42:58 +00:00
|
|
|
fi
|
|
|
|
echo "Installing legacy Ruby version ..."
|
2015-01-01 19:49:30 +00:00
|
|
|
|
|
|
|
# ruby executable
|
|
|
|
echo -n "Checking Ruby executable ... "
|
|
|
|
ruby=`which ruby`
|
2013-12-25 16:06:46 +00:00
|
|
|
if [ $? -ne 0 ]; then
|
2015-01-07 11:08:05 +00:00
|
|
|
echo "ruby executable not found !!!"
|
2013-12-25 16:06:46 +00:00
|
|
|
exit 1
|
|
|
|
fi
|
2013-11-19 16:29:36 +00:00
|
|
|
|
2015-01-01 19:49:30 +00:00
|
|
|
# System ruby is preferred
|
|
|
|
system_ruby=/usr/bin/ruby
|
|
|
|
if [ -x $system_ruby -a $system_ruby != "$ruby" ]; then
|
|
|
|
$system_ruby --disable-gems -rcurses -e0 2> /dev/null
|
|
|
|
[ $? -eq 0 ] && ruby=$system_ruby
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo "OK ($ruby)"
|
|
|
|
|
|
|
|
# Curses-support
|
|
|
|
echo -n "Checking Curses support ... "
|
|
|
|
"$ruby" -rcurses -e0 2> /dev/null
|
2013-12-25 16:39:17 +00:00
|
|
|
if [ $? -eq 0 ]; then
|
2015-01-01 19:49:30 +00:00
|
|
|
echo "OK"
|
2013-12-25 16:39:17 +00:00
|
|
|
else
|
2015-01-01 19:49:30 +00:00
|
|
|
echo "Not found"
|
|
|
|
echo "Installing 'curses' gem ... "
|
|
|
|
if (( EUID )); then
|
|
|
|
/usr/bin/env gem install curses --user-install
|
|
|
|
else
|
|
|
|
/usr/bin/env gem install curses
|
|
|
|
fi
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
echo
|
|
|
|
echo "Failed to install 'curses' gem."
|
|
|
|
if [[ $(uname -r) =~ 'ARCH' ]]; then
|
|
|
|
echo "Make sure that base-devel package group is installed."
|
|
|
|
fi
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Ruby version
|
|
|
|
echo -n "Checking Ruby version ... "
|
|
|
|
"$ruby" -e 'exit RUBY_VERSION >= "1.9"'
|
|
|
|
if [ $? -eq 0 ]; then
|
|
|
|
echo ">= 1.9"
|
|
|
|
"$ruby" --disable-gems -rcurses -e0 2> /dev/null
|
|
|
|
if [ $? -eq 0 ]; then
|
|
|
|
fzf_cmd="$ruby --disable-gems $fzf_base/fzf"
|
|
|
|
else
|
|
|
|
fzf_cmd="$ruby $fzf_base/fzf"
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
echo "< 1.9"
|
2013-12-25 16:39:17 +00:00
|
|
|
fzf_cmd="$ruby $fzf_base/fzf"
|
|
|
|
fi
|
2015-03-13 04:08:42 +00:00
|
|
|
|
|
|
|
# Create fzf script
|
|
|
|
echo -n "Creating wrapper script for fzf ... "
|
|
|
|
rm -f "$fzf_base"/bin/fzf
|
|
|
|
echo "#!/bin/sh" > "$fzf_base"/bin/fzf
|
|
|
|
echo "$fzf_cmd \"\$@\"" >> "$fzf_base"/bin/fzf
|
|
|
|
chmod +x "$fzf_base"/bin/fzf
|
|
|
|
echo "OK"
|
2013-11-19 16:29:36 +00:00
|
|
|
fi
|
|
|
|
|
2015-04-16 12:58:41 +00:00
|
|
|
[[ "$*" =~ "--bin" ]] && exit 0
|
|
|
|
|
2013-11-19 16:29:36 +00:00
|
|
|
# Auto-completion
|
2015-10-23 05:56:27 +00:00
|
|
|
if [ -z "$auto_completion" ]; then
|
|
|
|
ask "Do you want to enable fuzzy auto-completion?"
|
|
|
|
auto_completion=$?
|
|
|
|
fi
|
2013-11-19 16:29:36 +00:00
|
|
|
|
2013-12-21 15:18:41 +00:00
|
|
|
# Key-bindings
|
2015-10-23 05:56:27 +00:00
|
|
|
if [ -z "$key_bindings" ]; then
|
|
|
|
ask "Do you want to enable key bindings?"
|
|
|
|
key_bindings=$?
|
|
|
|
fi
|
2013-12-21 15:18:41 +00:00
|
|
|
|
2013-11-19 16:29:36 +00:00
|
|
|
echo
|
|
|
|
for shell in bash zsh; do
|
2013-11-26 10:01:01 +00:00
|
|
|
echo -n "Generate ~/.fzf.$shell ... "
|
|
|
|
src=~/.fzf.${shell}
|
2013-11-19 16:29:36 +00:00
|
|
|
|
2015-10-01 19:18:10 +00:00
|
|
|
fzf_completion="[[ \$- == *i* ]] && source \"$fzf_base/shell/completion.${shell}\" 2> /dev/null"
|
2015-10-23 05:56:27 +00:00
|
|
|
if [ $auto_completion -eq 0 ]; then
|
2013-11-26 10:01:01 +00:00
|
|
|
fzf_completion="# $fzf_completion"
|
2013-11-19 16:29:36 +00:00
|
|
|
fi
|
|
|
|
|
2015-03-13 04:08:42 +00:00
|
|
|
fzf_key_bindings="source \"$fzf_base/shell/key-bindings.${shell}\""
|
2015-10-23 05:56:27 +00:00
|
|
|
if [ $key_bindings -eq 0 ]; then
|
2015-03-13 04:08:42 +00:00
|
|
|
fzf_key_bindings="# $fzf_key_bindings"
|
|
|
|
fi
|
2015-01-12 17:39:00 +00:00
|
|
|
|
2015-03-13 04:08:42 +00:00
|
|
|
cat > $src << EOF
|
2015-01-12 17:39:00 +00:00
|
|
|
# Setup fzf
|
|
|
|
# ---------
|
2015-10-01 19:18:10 +00:00
|
|
|
if [[ ! "\$PATH" == *$fzf_base/bin* ]]; then
|
2015-03-25 18:44:18 +00:00
|
|
|
export PATH="\$PATH:$fzf_base/bin"
|
2015-01-01 19:49:30 +00:00
|
|
|
fi
|
2013-12-21 15:18:41 +00:00
|
|
|
|
2015-03-25 18:06:31 +00:00
|
|
|
# Man path
|
|
|
|
# --------
|
2015-10-01 19:18:10 +00:00
|
|
|
if [[ ! "\$MANPATH" == *$fzf_base/man* && -d "$fzf_base/man" ]]; then
|
2015-03-25 18:11:08 +00:00
|
|
|
export MANPATH="\$MANPATH:$fzf_base/man"
|
|
|
|
fi
|
2015-03-25 18:06:31 +00:00
|
|
|
|
2013-12-21 15:18:41 +00:00
|
|
|
# Auto-completion
|
|
|
|
# ---------------
|
2014-05-03 15:49:29 +00:00
|
|
|
$fzf_completion
|
2013-11-26 10:01:01 +00:00
|
|
|
|
2013-12-21 15:18:41 +00:00
|
|
|
# Key bindings
|
|
|
|
# ------------
|
2015-03-13 04:08:42 +00:00
|
|
|
$fzf_key_bindings
|
2013-12-21 15:18:41 +00:00
|
|
|
|
2015-03-13 04:08:42 +00:00
|
|
|
EOF
|
2013-11-26 10:01:01 +00:00
|
|
|
echo "OK"
|
|
|
|
done
|
|
|
|
|
2014-05-02 02:27:32 +00:00
|
|
|
# fish
|
|
|
|
has_fish=0
|
2015-03-13 04:08:42 +00:00
|
|
|
if [ -n "$(which fish 2> /dev/null)" ]; then
|
2014-05-02 02:27:32 +00:00
|
|
|
has_fish=1
|
2015-03-13 04:08:42 +00:00
|
|
|
echo -n "Update fish_user_paths ... "
|
|
|
|
fish << EOF
|
|
|
|
echo \$fish_user_paths | grep $fzf_base/bin > /dev/null
|
|
|
|
or set --universal fish_user_paths \$fish_user_paths $fzf_base/bin
|
|
|
|
EOF
|
|
|
|
[ $? -eq 0 ] && echo "OK" || echo "Failed"
|
|
|
|
|
2014-05-02 02:27:32 +00:00
|
|
|
mkdir -p ~/.config/fish/functions
|
2015-03-13 04:08:42 +00:00
|
|
|
if [ -e ~/.config/fish/functions/fzf.fish ]; then
|
|
|
|
echo -n "Remove unnecessary ~/.config/fish/functions/fzf.fish ... "
|
|
|
|
rm -f ~/.config/fish/functions/fzf.fish && echo "OK" || echo "Failed"
|
2015-01-04 05:35:13 +00:00
|
|
|
fi
|
2014-05-02 02:27:32 +00:00
|
|
|
|
2015-10-23 05:56:27 +00:00
|
|
|
fish_binding=~/.config/fish/functions/fzf_key_bindings.fish
|
|
|
|
if [ $key_bindings -ne 0 ]; then
|
|
|
|
echo -n "Symlink $fish_binding ... "
|
|
|
|
ln -sf "$fzf_base/shell/key-bindings.fish" \
|
|
|
|
"$fish_binding" && echo "OK" || echo "Failed"
|
|
|
|
else
|
|
|
|
echo -n "Removing $fish_binding ... "
|
|
|
|
rm -f "$fish_binding"
|
|
|
|
echo "OK"
|
2014-05-02 02:27:32 +00:00
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
append_line() {
|
2015-09-24 01:51:05 +00:00
|
|
|
set -e
|
2015-10-23 05:56:27 +00:00
|
|
|
|
|
|
|
local skip line file pat lno
|
|
|
|
skip="$1"
|
|
|
|
line="$2"
|
|
|
|
file="$3"
|
|
|
|
pat="${4:-}"
|
|
|
|
|
|
|
|
echo "Update $file:"
|
|
|
|
echo " - $line"
|
|
|
|
[ -f "$file" ] || touch "$file"
|
|
|
|
if [ $# -lt 4 ]; then
|
|
|
|
lno=$(\grep -nF "$line" "$file" | sed 's/:.*//' | tr '\n' ' ')
|
2014-09-18 03:55:28 +00:00
|
|
|
else
|
2015-10-23 05:56:27 +00:00
|
|
|
lno=$(\grep -nF "$pat" "$file" | sed 's/:.*//' | tr '\n' ' ')
|
2014-09-18 03:55:28 +00:00
|
|
|
fi
|
2015-10-23 05:56:27 +00:00
|
|
|
if [ -n "$lno" ]; then
|
|
|
|
echo " - Already exists: line #$lno"
|
2013-11-26 10:01:01 +00:00
|
|
|
else
|
2015-10-23 05:56:27 +00:00
|
|
|
if [ $skip -eq 1 ]; then
|
|
|
|
echo >> "$file"
|
|
|
|
echo "$line" >> "$file"
|
|
|
|
echo " + Added"
|
|
|
|
else
|
|
|
|
echo " ~ Skipped"
|
|
|
|
fi
|
2013-11-19 16:29:36 +00:00
|
|
|
fi
|
|
|
|
echo
|
2015-09-24 01:51:05 +00:00
|
|
|
set +e
|
2014-05-02 02:27:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
echo
|
|
|
|
for shell in bash zsh; do
|
2015-11-08 16:48:55 +00:00
|
|
|
[ $shell = zsh ] && dest=${ZDOTDIR:-~}/.zshrc || dest=~/.bashrc
|
|
|
|
append_line $update_config "[ -f ~/.fzf.${shell} ] && source ~/.fzf.${shell}" "$dest" "~/.fzf.${shell}"
|
2013-11-19 16:29:36 +00:00
|
|
|
done
|
|
|
|
|
2015-10-23 05:56:27 +00:00
|
|
|
if [ $key_bindings -eq 1 -a $has_fish -eq 1 ]; then
|
2014-05-02 02:27:32 +00:00
|
|
|
bind_file=~/.config/fish/functions/fish_user_key_bindings.fish
|
2015-10-23 05:56:27 +00:00
|
|
|
append_line $update_config "fzf_key_bindings" "$bind_file"
|
2014-05-02 02:27:32 +00:00
|
|
|
fi
|
|
|
|
|
2013-11-29 04:42:13 +00:00
|
|
|
cat << EOF
|
2014-05-02 02:27:32 +00:00
|
|
|
Finished. Restart your shell or reload config file.
|
2013-12-25 16:54:29 +00:00
|
|
|
source ~/.bashrc # bash
|
2015-11-08 16:48:55 +00:00
|
|
|
source ${ZDOTDIR:-~}/.zshrc # zsh
|
2014-05-02 02:27:32 +00:00
|
|
|
EOF
|
|
|
|
[ $has_fish -eq 1 ] && echo " fzf_key_bindings # fish"; cat << EOF
|
2013-11-29 04:42:13 +00:00
|
|
|
|
2014-05-20 16:14:21 +00:00
|
|
|
Use uninstall script to remove fzf.
|
2014-03-30 15:53:35 +00:00
|
|
|
|
|
|
|
For more information, see: https://github.com/junegunn/fzf
|
2013-11-29 04:42:13 +00:00
|
|
|
EOF
|
2013-10-23 01:26:55 +00:00
|
|
|
|