# fzf https://github.com/junegunn/fzf https://github.com/junegunn/fzf/wiki https://sim590.github.io/fr/outils/fzf/#extension-de-la-complétion https://github.com/junegunn/fzf/wiki/examples https://github.com/junegunn/fzf/blob/master/ADVANCED.md ### Installation: ```bash $ brew install fzf # To install useful key bindings and fuzzy completion: $ $(brew --prefix)/opt/fzf/install ``` ##### Syntaxe: | Token | Match type | Description | | --------- | -------------------------- | ------------------------------------ | | `sbtrkt` | fuzzy-match | Items that match `sbtrkt` | | `'wild` | exact-match (quoted) | Items that include `wild` | | `^music` | prefix-exact-match | Items that start with `music` | | `.mp3$` | suffix-exact-match | Items that end with `.mp3` | | `!fire` | inverse-exact-match | Items that do not include `fire` | | `!^music` | inverse-prefix-exact-match | Items that do not start with `music` | | `!.mp3$` | inverse-suffix-exact-match | Items that do not end with `.mp3` | Options Search mode -e, --exact Enable exact-match -i Case-insensitive match (default: smart-case match) +i Case-sensitive match ### Utilisation 1: ```bash ~/Documents/Scripts_Raspberry master* 19s 17:46:16 $ find . | fzf ``` puis on entre des mots-clé pour affiner la recherche. fzf2 ### Utilisation 2: ```bash ~/Documents/Scripts_Raspberry master* $ nano $(fzf) ``` On filtre: 'led fzf **Return** ouvre le fichier dans nano. On peut ouvrir plusieurs fichiers dans nano: ```bash ~/Documents/Scripts_Raspberry master* $ nano $(fzf -m) ``` puis **Tab** pour sélectionner plusieurs fichiers et **Return** pour les ouvrir. ### Fuzzy completion Déclencheur: ** puis ##### Utilisation 3 (complétion de cd): ```bash ~/Documents/Scripts_Raspberry master* 18:00:32 $ cd ** ``` Puis **Tab** fzf3 Puis **Return** ```bash ~/Documents/Scripts_Raspberry master* $ cd SiriControl/ ~/Documents/Scripts_Raspberry/SiriControl master* $ ``` La complétion marche aussi avec la commande ssh: les serveurs sont tirés de /etc/hosts et de ssh/config. ### Utilisation 4 (kill): Taper **kill** puis **Espace** puis **Tab** ```bash $ kill ``` fzf4 **Tab** pour sélectionner les process à tuer puis **Return**: ```bash ~/Documents/Scripts_Raspberry/SiriControl master* $ kill 266 311 ``` ### Utilisation 5 (complétion de cat): ```bash ~/Documents/Scripts_Raspberry master* $ cat ** ``` Puis **Tab** fzf5 Puis **Return** ```bash ~/Documents/Scripts_Raspberry master* $ cat pir/pir2.py ``` La complétion marche aussi avec les variables d'environnement. ```bash $ unset ** $ unalias ** $ export ** ``` ### Utilisation 6 (complétion de nano): ```bash ~/Documents/Scripts_Raspberry master* $ nano /opt/** ``` Puis **Tab** fzf6 Puis **Return** ```bash ~/Documents/Scripts_Raspberry master* $ nano /opt/homebrew/etc/httpd/httpd.conf ``` Lancer la fuzzy recherche dans le répertoire parent: ```bash ~/Documents/Scripts_Raspberry master* $ nano ../** ``` ### Options: ```bash fzf --height 40% --layout reverse --info inline --border \ --preview 'bat --style=numbers --color=always --line-range :500 {}' --preview-window right \ --color 'fg:#bbccdd,fg+:#ddeeff,bg:#334455,preview-bg:#223344,border:#778899' ``` ```bash # .zshrc export FZF_ALT_C_OPTS="--preview 'tree -C {} | head -200'" #export FZF_DEFAULT_COMMAND="find ." export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow' # --preview "bat --style=numbers --color=always --line-range :500 {}" --preview="head -$LINES {}" export FZF_DEFAULT_OPTS='--height 40% --layout=reverse --border' ``` https://bluz71.github.io/2018/11/26/fuzzy-finding-in-bash-with-fzf.html https://curatedgo.com/r/fzf-is-a-junegunnfzf/index.html https://thevaluable.dev/practical-guide-fzf-example/ https://pragmaticpineapple.com/four-useful-fzf-tricks-for-your-terminal/ https://reposhub.com/linux/shell-applications/lincheney-fzf-tab-completion.html ### Python #### Activer un venv: ```bash function activate-venv() { local selected_env selected_env=$(ls ~/.venv/ | fzf) if [ -n "$selected_env" ]; then source "$HOME/.venv/$selected_env/bin/activate" fi } ``` ### Git #### Git commit history ```bash git log --oneline | fzf --preview 'git show --name-only {1}' ``` ### Navigateurs #### Recherche dans l'historique de Firefox: ```bash cd ~/Library/Application\ Support/Firefox/Profiles/*.default-release sqlite3 places.sqlite "SELECT url FROM moz_places" | fzf ``` #### Recherche dans les bookmarks de chrome: ```bash b() { bookmarks_path=~/Library/Application\ Support/Google/Chrome/Default/Bookmarks jq_script=' def ancestors: while(. | length >= 2; del(.[-1,-2])); . as $in | paths(.url?) as $key | $in | getpath($key) | {name,url, path: [$key[0:-2] | ancestors as $a | $in | getpath($a) | .name?] | reverse | join("/") } | .path + "/" + .name + "\t" + .url' jq -r "$jq_script" < "$bookmarks_path" \ | sed -E $'s/(.*)\t(.*)/\\1\t\x1b[36m\\2\x1b[m/g' \ | fzf --ansi \ | cut -d$'\t' -f2 \ | xargs open } ``` #### Recherche dans l'historique de Safari: ```bash function sbh() { local cols sep cols=$(( COLUMNS / 3 )) sep='{::}' cp -f ~/Library/Safari/History.db /tmp/h sqlite3 -separator $sep /tmp/h \ "select substr(id, 1, $cols), url from history_items order by visit_count_score desc" | awk -F $sep '{printf "%-'$cols's \x1b[36m%s\x1b[m\n", $1, $2}' | fzf --ansi --multi | sed 's#.*\(https*://\)#\1#' | xargs open } fzf-safari-browser-history() { local cols sep columns=$(( COLUMNS / 3 )) separator='{::}' sqlite3 -separator $separator $HOME/Library/Safari/History.db \ "select distinct substr(title, 1, $columns), url from history_items inner join history_visits on history_items.id = history_visits.history_item order by history_visits.visit_time desc;" | awk -F $separator '{printf "%-'$columns's \x1b[36m%s\x1b[m\n", $1, $2}' | fzf --ansi --multi | sed 's#.*\(https*://\)#\1#' | xargs open -a safari } ``` ### Terminal #### Kill process: ```bash kill -9 $(ps aux | fzf | awk '{print $2}') ``` #### File preview ```bash fzf --preview 'bat --style=numbers --color=always --line-range :500 {}' ``` ```bash fd . '/opt/homebrew' | fzf --height=90% --reverse --preview 'cat {}' --query '_log' ``` ### Docker ```bash # Select a docker container to start and attach to function da() { local cid cid=$(docker ps -a | sed 1d | fzf -1 -q "$1" | awk '{print $1}') [ -n "$cid" ] && docker start "$cid" && docker attach "$cid" } ``` ```bash # Select a running docker container to stop function ds() { local cid cid=$(docker ps | sed 1d | fzf -q "$1" | awk '{print $1}') [ -n "$cid" ] && docker stop "$cid" } ``` ```bash # Select a docker container to remove function drm() { local cid cid=$(docker ps -a | sed 1d | fzf -q "$1" | awk '{print $1}') [ -n "$cid" ] && docker rm "$cid" } # Same as above, but allows multi selection: function drm() { docker ps -a | sed 1d | fzf -q "$1" --no-sort -m --tac | awk '{ print $1 }' | xargs -r docker rm } ``` ```bash # Select a docker image or images to remove function drmi() { docker images | sed 1d | fzf -q "$1" --no-sort -m --tac | awk '{ print $3 }' | xargs -r docker rmi } ``` ### Homebrew Cask ```bash # Install or open the webpage for the selected application # using brew cask search as input source # and display a info quickview window for the currently marked application install() { local token token=$(brew search --casks "$1" | fzf-tmux --query="$1" +m --preview 'brew info {}') if [ "x$token" != "x" ] then echo "(I)nstall or open the (h)omepage of $token" read input if [ $input = "i" ] || [ $input = "I" ]; then brew install --cask $token fi if [ $input = "h" ] || [ $input = "H" ]; then brew home $token fi fi } ``` #### fzf-brew ```bash antigen bundle thirteen37/fzf-brew fbi: Fuzzy brew install fbui: Fuzzy brew uninstall fci: Fuzzy cask install fcui: Fuzzy cask uninstall ``` https://github.com/thirteen37/fzf-brew?tab=readme-ov-file