mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2024-12-23 03:19:01 +00:00
3827a1b09e
Aliases are expanded in shell scripts, and one may have an alias for the `find` command that conflicts with fzf. So make sure fzf is using real find command rather than the alias.
353 lines
8.4 KiB
Bash
Executable File
353 lines
8.4 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
cd `dirname $BASH_SOURCE`
|
|
fzf_base=`pwd`
|
|
|
|
# ruby executable
|
|
echo -n "Checking Ruby executable ... "
|
|
ruby=`which ruby`
|
|
if [ $? -ne 0 ]; then
|
|
echo "ruby executable not found!"
|
|
exit 1
|
|
fi
|
|
|
|
# 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
|
|
if [ $? -eq 0 ]; then
|
|
echo "OK"
|
|
else
|
|
echo "Not found"
|
|
echo "Installing 'curses' gem ... "
|
|
/usr/bin/env gem install curses -v 1.0.0 --user-install
|
|
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"
|
|
fzf_cmd="$ruby $fzf_base/fzf"
|
|
fi
|
|
|
|
# Auto-completion
|
|
read -p "Do you want to add auto-completion support? ([y]/n) " -n 1 -r
|
|
echo
|
|
[[ ! $REPLY =~ ^[Nn]$ ]]
|
|
auto_completion=$?
|
|
|
|
# Key-bindings
|
|
read -p "Do you want to add key bindings? ([y]/n) " -n 1 -r
|
|
echo
|
|
[[ ! $REPLY =~ ^[Nn]$ ]]
|
|
key_bindings=$?
|
|
|
|
echo
|
|
for shell in bash zsh; do
|
|
echo -n "Generate ~/.fzf.$shell ... "
|
|
src=~/.fzf.${shell}
|
|
|
|
fzf_completion="[[ \$- =~ i ]] && source $fzf_base/fzf-completion.${shell}"
|
|
if [ $auto_completion -ne 0 ]; then
|
|
fzf_completion="# $fzf_completion"
|
|
fi
|
|
|
|
cat > $src << EOF
|
|
# Setup fzf function
|
|
# ------------------
|
|
unalias fzf 2> /dev/null
|
|
fzf() {
|
|
$fzf_cmd "\$@"
|
|
}
|
|
export -f fzf > /dev/null
|
|
|
|
# Auto-completion
|
|
# ---------------
|
|
$fzf_completion
|
|
|
|
EOF
|
|
|
|
if [ $key_bindings -eq 0 ]; then
|
|
if [ $shell = bash ]; then
|
|
cat >> $src << "EOFZF"
|
|
# Key bindings
|
|
# ------------
|
|
__fsel() {
|
|
command find * -path '*/\.*' -prune \
|
|
-o -type f -print \
|
|
-o -type d -print \
|
|
-o -type l -print 2> /dev/null | fzf -m | while read item; do
|
|
printf '%q ' "$item"
|
|
done
|
|
echo
|
|
}
|
|
|
|
if [[ $- =~ i ]]; then
|
|
|
|
__fsel_tmux() {
|
|
local height
|
|
height=${FZF_TMUX_HEIGHT:-40%}
|
|
if [[ $height =~ %$ ]]; then
|
|
height="-p ${height%\%}"
|
|
else
|
|
height="-l $height"
|
|
fi
|
|
tmux split-window $height "bash -c 'source ~/.fzf.bash; tmux send-keys -t $TMUX_PANE \"\$(__fsel)\"'"
|
|
}
|
|
|
|
__fcd() {
|
|
local dir
|
|
dir=$(command find ${1:-*} -path '*/\.*' -prune -o -type d -print 2> /dev/null | fzf +m) && printf 'cd %q' "$dir"
|
|
}
|
|
|
|
__use_tmux=0
|
|
[ -n "$TMUX_PANE" -a ${FZF_TMUX:-1} -ne 0 -a ${LINES:-40} -gt 15 ] && __use_tmux=1
|
|
|
|
if [ -z "$(set -o | grep '^vi.*on')" ]; then
|
|
# Required to refresh the prompt after fzf
|
|
bind '"\er": redraw-current-line'
|
|
|
|
# CTRL-T - Paste the selected file path into the command line
|
|
if [ $__use_tmux -eq 1 ]; then
|
|
bind '"\C-t": " \C-u \C-a\C-k$(__fsel_tmux)\e\C-e\C-y\C-a\C-d\C-y\ey\C-h"'
|
|
else
|
|
bind '"\C-t": " \C-u \C-a\C-k$(__fsel)\e\C-e\C-y\C-a\C-y\ey\C-h\C-e\er \C-h"'
|
|
fi
|
|
|
|
# CTRL-R - Paste the selected command from history into the command line
|
|
bind '"\C-r": " \C-e\C-u$(HISTTIMEFORMAT= history | fzf +s +m -n..,1,2.. | sed \"s/ *[0-9]* *//\")\e\C-e\er"'
|
|
|
|
# ALT-C - cd into the selected directory
|
|
bind '"\ec": " \C-e\C-u$(__fcd)\e\C-e\er\C-m"'
|
|
else
|
|
bind '"\C-x\C-e": shell-expand-line'
|
|
bind '"\C-x\C-r": redraw-current-line'
|
|
|
|
# CTRL-T - Paste the selected file path into the command line
|
|
# - FIXME: Selected items are attached to the end regardless of cursor position
|
|
if [ $__use_tmux -eq 1 ]; then
|
|
bind '"\C-t": "\e$a \eddi$(__fsel_tmux)\C-x\C-e\e0P$xa"'
|
|
else
|
|
bind '"\C-t": "\e$a \eddi$(__fsel)\C-x\C-e\e0Px$a \C-x\C-r\exa "'
|
|
fi
|
|
|
|
# CTRL-R - Paste the selected command from history into the command line
|
|
bind '"\C-r": "\eddi$(HISTTIMEFORMAT= history | fzf +s +m -n..,1,2.. | sed \"s/ *[0-9]* *//\")\C-x\C-e\e$a\C-x\C-r"'
|
|
|
|
# ALT-C - cd into the selected directory
|
|
bind '"\ec": "\eddi$(__fcd)\C-x\C-e\C-x\C-r\C-m"'
|
|
fi
|
|
|
|
unset __use_tmux
|
|
|
|
fi
|
|
EOFZF
|
|
else
|
|
cat >> $src << "EOFZF"
|
|
# Key bindings
|
|
# ------------
|
|
# CTRL-T - Paste the selected file path(s) into the command line
|
|
__fsel() {
|
|
set -o nonomatch
|
|
command find * -path '*/\.*' -prune \
|
|
-o -type f -print \
|
|
-o -type d -print \
|
|
-o -type l -print 2> /dev/null | fzf -m | while read item; do
|
|
printf '%q ' "$item"
|
|
done
|
|
echo
|
|
}
|
|
|
|
if [[ $- =~ i ]]; then
|
|
|
|
if [ -n "$TMUX_PANE" -a ${FZF_TMUX:-1} -ne 0 -a ${LINES:-40} -gt 15 ]; then
|
|
fzf-file-widget() {
|
|
local height
|
|
height=${FZF_TMUX_HEIGHT:-40%}
|
|
if [[ $height =~ %$ ]]; then
|
|
height="-p ${height%\%}"
|
|
else
|
|
height="-l $height"
|
|
fi
|
|
tmux split-window $height "zsh -c 'source ~/.fzf.zsh; tmux send-keys -t $TMUX_PANE \"\$(__fsel)\"'"
|
|
}
|
|
else
|
|
fzf-file-widget() {
|
|
LBUFFER="${LBUFFER}$(__fsel)"
|
|
zle redisplay
|
|
}
|
|
fi
|
|
zle -N fzf-file-widget
|
|
bindkey '^T' fzf-file-widget
|
|
|
|
# ALT-C - cd into the selected directory
|
|
fzf-cd-widget() {
|
|
cd "${$(set -o nonomatch; command find * -path '*/\.*' -prune \
|
|
-o -type d -print 2> /dev/null | fzf):-.}"
|
|
zle reset-prompt
|
|
}
|
|
zle -N fzf-cd-widget
|
|
bindkey '\ec' fzf-cd-widget
|
|
|
|
# CTRL-R - Paste the selected command from history into the command line
|
|
fzf-history-widget() {
|
|
LBUFFER=$(fc -l 1 | fzf +s +m -n..,1,2.. | sed "s/ *[0-9*]* *//")
|
|
zle redisplay
|
|
}
|
|
zle -N fzf-history-widget
|
|
bindkey '^R' fzf-history-widget
|
|
|
|
fi
|
|
EOFZF
|
|
fi
|
|
fi
|
|
|
|
echo "OK"
|
|
done
|
|
|
|
# fish
|
|
has_fish=0
|
|
if [ -n "$(which fish)" ]; then
|
|
has_fish=1
|
|
echo -n "Generate ~/.config/fish/functions/fzf.fish ... "
|
|
mkdir -p ~/.config/fish/functions
|
|
cat > ~/.config/fish/functions/fzf.fish << EOFZF
|
|
function fzf
|
|
$fzf_cmd \$argv
|
|
end
|
|
EOFZF
|
|
echo "OK"
|
|
|
|
if [ $key_bindings -eq 0 ]; then
|
|
echo -n "Generate ~/.config/fish/functions/fzf_key_bindings.fish ... "
|
|
cat > ~/.config/fish/functions/fzf_key_bindings.fish << "EOFZF"
|
|
function fzf_key_bindings
|
|
function __fzf_select
|
|
command find * -path '*/\.*' -prune \
|
|
-o -type f -print \
|
|
-o -type d -print \
|
|
-o -type l -print 2> /dev/null | fzf -m | while read item
|
|
echo -n (echo -n "$item" | sed 's/ /\\\\ /g')' '
|
|
end
|
|
echo
|
|
end
|
|
|
|
function __fzf_ctrl_t
|
|
if [ -n "$TMUX_PANE" -a "$FZF_TMUX" != "0" ]
|
|
tmux split-window (__fzf_tmux_height) "fish -c 'fzf_key_bindings; __fzf_ctrl_t_tmux \\$TMUX_PANE'"
|
|
else
|
|
__fzf_select > $TMPDIR/fzf.result
|
|
and commandline -i (cat $TMPDIR/fzf.result)
|
|
rm -f $TMPDIR/fzf.result
|
|
end
|
|
end
|
|
|
|
function __fzf_ctrl_t_tmux
|
|
__fzf_select > $TMPDIR/fzf.result
|
|
and tmux send-keys -t $argv[1] (cat $TMPDIR/fzf.result)
|
|
rm -f $TMPDIR/fzf.result
|
|
end
|
|
|
|
function __fzf_ctrl_r
|
|
if history | fzf +s +m > $TMPDIR/fzf.result
|
|
commandline (cat $TMPDIR/fzf.result)
|
|
else
|
|
commandline -f repaint
|
|
end
|
|
rm -f $TMPDIR/fzf.result
|
|
end
|
|
|
|
function __fzf_alt_c
|
|
command find * -path '*/\.*' -prune -o -type d -print 2> /dev/null | fzf +m > $TMPDIR/fzf.result
|
|
if [ (cat $TMPDIR/fzf.result | wc -l) -gt 0 ]
|
|
cd (cat $TMPDIR/fzf.result)
|
|
end
|
|
commandline -f repaint
|
|
rm -f $TMPDIR/fzf.result
|
|
end
|
|
|
|
function __fzf_tmux_height
|
|
if set -q FZF_TMUX_HEIGHT
|
|
set height $FZF_TMUX_HEIGHT
|
|
else
|
|
set height 40%
|
|
end
|
|
if echo $height | grep -q -E '%$'
|
|
echo "-p "(echo $height | sed 's/%$//')
|
|
else
|
|
echo "-l $height"
|
|
end
|
|
set -e height
|
|
end
|
|
|
|
bind \ct '__fzf_ctrl_t'
|
|
bind \cr '__fzf_ctrl_r'
|
|
bind \ec '__fzf_alt_c'
|
|
end
|
|
EOFZF
|
|
echo "OK"
|
|
fi
|
|
fi
|
|
|
|
append_line() {
|
|
echo "Update $2:"
|
|
echo " - $1"
|
|
[ -f "$2" ] || touch "$2"
|
|
line=$(grep -nF "$1" "$2" | sed 's/:.*//')
|
|
if [ -n "$line" ]; then
|
|
echo " - Already exists (line #$line)"
|
|
else
|
|
echo "$1" >> "$2"
|
|
echo " - Added"
|
|
fi
|
|
echo
|
|
}
|
|
|
|
echo
|
|
for shell in bash zsh; do
|
|
append_line "source ~/.fzf.${shell}" ~/.${shell}rc
|
|
done
|
|
|
|
if [ $key_bindings -eq 0 -a $has_fish -eq 1 ]; then
|
|
bind_file=~/.config/fish/functions/fish_user_key_bindings.fish
|
|
append_line "fzf_key_bindings" "$bind_file"
|
|
fi
|
|
|
|
cat << EOF
|
|
Finished. Restart your shell or reload config file.
|
|
source ~/.bashrc # bash
|
|
source ~/.zshrc # zsh
|
|
EOF
|
|
[ $has_fish -eq 1 ] && echo " fzf_key_bindings # fish"; cat << EOF
|
|
|
|
Use uninstall script to remove fzf.
|
|
|
|
For more information, see: https://github.com/junegunn/fzf
|
|
EOF
|
|
|