Implement bash auto-completion with fzf

This commit is contained in:
Junegunn Choi 2013-11-20 01:29:36 +09:00
parent e52a1d5fad
commit fa5617e076
4 changed files with 224 additions and 20 deletions

View File

@ -16,8 +16,24 @@ fzf requires Ruby (>= 1.8.5).
Installation
------------
Download [fzf executable](https://raw.github.com/junegunn/fzf/master/fzf) and
put it somewhere in your search $PATH.
### Using install script
Clone this repository and run
[install](https://github.com/junegunn/fzf/blob/master/install) script.
```sh
git clone https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install
```
The script will add an alias to fzf and auto-completion support to your
`.bashrc` and `.zshrc`.
### Manual installation
Or you can just download
[fzf executable](https://raw.github.com/junegunn/fzf/master/fzf) and put it
somewhere in your search $PATH.
```sh
mkdir -p ~/bin
@ -25,20 +41,6 @@ wget https://raw.github.com/junegunn/fzf/master/fzf -O ~/bin/fzf
chmod +x ~/bin/fzf
```
Or you can just clone this repository and run
[install](https://github.com/junegunn/fzf/blob/master/install) script.
```sh
git clone https://github.com/junegunn/fzf.git
fzf/install
```
Make sure that ~/bin is included in $PATH.
```sh
export PATH=$PATH:~/bin
```
### Install as Ruby gem
fzf can be installed as a Ruby gem
@ -215,7 +217,7 @@ zsh widgets
-----------
```sh
# CTRL-T - Paste the selected file(s) path into the command line
# CTRL-T - Paste the selected file path(s) into the command line
fzf-file-widget() {
local FILES
local IFS="
@ -250,6 +252,36 @@ zle -N fzf-history-widget
bindkey '^R' fzf-history-widget
```
Auto-completion (experimental)
------------------------------
Disclaimer: *Auto-completion feature is currently experimental, it can change
over time*
### bash
fuzzy-finder-completion can be triggered if you type in a directory name
followed by the trigger sequence which is by default `**`.
```sh
vim **<TAB>
vim ..**<TAB>
vim ~/**<TAB>
cd **<TAB>
cd ../<TAB>
```
You can use different trigger sequence by setting `FZF_COMPLETION_TRIGGER`
```sh
export FZF_COMPLETION_TRIGGER='~~'
```
### zsh
TODO
Tips
----
@ -269,6 +301,9 @@ Define fzf alias with the option as follows:
alias fzf='ruby --disable-gems ~/bin/fzf'
```
This is automatically set up in your .bashrc and .zshrc if you use the bundled
[install](https://github.com/junegunn/fzf/blob/master/install) script.
### Incorrect display on Ruby 1.8
It is reported that the output of fzf can become unreadable on some terminals

95
fzf-completion.bash Normal file
View File

@ -0,0 +1,95 @@
#!/bin/bash
# ____ ____
# / __/___ / __/
# / /_/_ / / /_
# / __/ / /_/ __/
# /_/ /___/_/-completion.bash
#
# - $FZF_COMPLETION_TRIGGER (default '**')
# - $FZF_COMPLETION_OPTS
_fzf_opts_completion() {
local cur prev opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts="-m --multi -x --extended -s --sort +s +i +c --no-color"
case "${prev}" in
--sort|-s)
COMPREPLY=( $(compgen -W "$(seq 2000 1000 10000)" -- ${cur}) )
return 0
;;
esac
if [[ ${cur} =~ ^-|\+ ]]; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
fi
return 0
}
_fzf_generic_completion() {
local cur prev opts base matches ignore
COMPREPLY=()
FZF_COMPLETION_TRIGGER=${FZF_COMPLETION_TRIGGER:-**}
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
if [[ ${cur} == *"$FZF_COMPLETION_TRIGGER" ]]; then
base=${cur:0:${#cur}-${#FZF_COMPLETION_TRIGGER}}
base=${base%/}
eval base=$base
ignore=${FZF_COMPLETION_IGNORE:-*/.git/*}
find_opts="-name .git -prune -o -name .svn -prune -o"
if [ -z "$base" -o -d "$base" ]; then
matches=$(find ${base:-*} $1 2> /dev/null | fzf $FZF_COMPLETION_OPTS $2 | while read item; do
if [[ ${item} =~ \ ]]; then
echo -n "\"$item\" "
else
echo -n "$item "
fi
done)
matches=${matches% }
if [ -n "$matches" ]; then
COMPREPLY=( "$matches" )
return 0
fi
fi
fi
}
_fzf_all_completion() {
_fzf_generic_completion \
"-name .git -prune -o -name .svn -prune -o -type f -print -o -type l -print" \
"-m"
}
_fzf_dir_completion() {
_fzf_generic_completion \
"-name .git -prune -o -name .svn -prune -o -type d -print" \
""
}
complete -F _fzf_opts_completion fzf
for cmd in "cd pushd rmdir"; do
complete -F _fzf_dir_completion -o default $cmd
done
FZF_COMPLETION_COMMANDS=${FZF_COMPLETION_COMMANDS:-
awk basename bunzip2 bzip2 curl diff diff3 dirname du emacs ex file find ftp
g++ gcc git grep gunzip gvim gzip head hg jar java javac jps ld less ls more
mvim open patch perl python rsync ruby scp sed sftp sort svn tail tar tee
uniq unzip vi view vim wc zip
}
for cmd in $FZF_COMPLETION_COMMANDS; do
complete -F _fzf_all_completion -o default $cmd
done
bind '"\e\e": complete'
bind '"\er": redraw-current-line'
bind '"\C-i": "\e\e\er"'

9
fzf-completion.zsh Normal file
View File

@ -0,0 +1,9 @@
#!/bin/zsh
# ____ ____
# / __/___ / __/
# / /_/_ / / /_
# / __/ / /_/ __/
# /_/ /___/_/-completion.zsh
#
# TODO

71
install
View File

@ -1,7 +1,72 @@
#!/bin/bash
cd `dirname $BASH_SOURCE`
mkdir -p ~/bin
ln -sf `pwd`/fzf ~/bin/fzf
chmod +x ~/bin/fzf
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
echo "OK"
# Curses-support
echo -n "Checking Curses support ... "
/usr/bin/env ruby -e "begin; require 'curses'; rescue Exception; exit 1; end"
if [ $? -ne 0 ]; then
echo "Your ruby does not support 'curses'"
exit 1
fi
echo "OK"
# Ruby version
echo -n "Checking Ruby version ... "
/usr/bin/env ruby -e 'exit RUBY_VERSION >= "1.9"'
if [ $? -eq 0 ]; then
echo ">= 1.9"
FZF_ALIAS="alias fzf='$RUBY --disable-gems $FZF_BASE/fzf'"
else
echo "< 1.9"
FZF_ALIAS="alias fzf='$RUBY $FZF_BASE/fzf' # fzf"
fi
# Auto-completion
read -p "Do you want to add auto-completion support? (y/n) " -n 1 -r
echo
[[ ! $REPLY =~ ^[Nn]$ ]]
AUTO_COMPLETION=$?
echo
for shell in bash zsh; do
rc=~/.${shell}rc
echo "Update $rc:"
# Install fzf alias
echo "- Add fzf alias:"
echo " - $FZF_ALIAS"
if [ $(grep "alias fzf=" $rc | wc -l) -gt 0 ]; then
echo " - (X) fzf alias already exists"
else
echo $FZF_ALIAS >> $rc
echo " - Added."
fi
# Install auto-completion support
if [ $AUTO_COMPLETION -eq 0 ]; then
FZF_COMPLETION="source $FZF_BASE/fzf-completion.${shell}"
echo "- Add auto-completion support"
echo " - $FZF_COMPLETION"
if [ $(grep "source.*fzf-completion" $rc | wc -l) -gt 0 ]; then
echo " - (X) fzf-completion.${shell} already being sourced"
else
echo $FZF_COMPLETION >> $rc
echo " - Added."
fi
fi
echo
done
echo "Finished. Remove the added lines to uninstall fzf."