Improve fzf commands with fd, bat or lesspipe

This commit is contained in:
Jeremy Gardais 2022-02-18 15:34:03 +01:00
parent fe655567b0
commit e115b1875d
Signed by: jegardai
GPG Key ID: E759BAA22501AF32
1 changed files with 329 additions and 104 deletions

433
zshrc
View File

@ -1430,7 +1430,6 @@ else ## Simple utilisateur
export PS1="$heure $host $repertoire_courant$noroot $normal" export PS1="$heure $host $repertoire_courant$noroot $normal"
fi fi
# Prise en charge des touches [début], [fin] et autres # Prise en charge des touches [début], [fin] et autres
typeset -A key typeset -A key
@ -1806,7 +1805,7 @@ setopt extendedglob
if [ -d ~/.fzf ]; then if [ -d ~/.fzf ]; then
if [[ ! "$PATH" == *"${HOME}"/.fzf/bin* ]]; then if [[ ! "$PATH" == *"${HOME}"/.fzf/bin* ]]; then
export PATH="$PATH:${HOME}/.fzf/bin" export PATH="$PATH:${HOME}/.fzf/bin"
fi fi
if [ -f ~/bin/fd ]; then if [ -f ~/bin/fd ]; then
@ -1821,157 +1820,326 @@ fi
# ------------ # ------------
source "${HOME}/.fzf/shell/key-bindings.zsh" source "${HOME}/.fzf/shell/key-bindings.zsh"
# ff - cd to selected directory (exclude hidden directories # ff - cd to selected directory exclude hidden directories and their content {{{
# Search with find (fd|fdfind overkill the CPU for few benefits on small tree)
# Check for symlinked directories too
# Allow to give arguments to prefill fzf request
# Display a preview tree of the directory
# Move to the selected directory
ff() { ff() {
local dir local dir
dir=$(find ${1:-.} -path '*/\.*' -prune \
-o -type d -print 2> /dev/null | fzf +m) &&
cd "$dir"
}
# ffh - hidden directories only ## Manage argument {{{
if [ "${#}" -eq "0" ]; then
## Default command without args
dir=$(find . -xtype d -not -path "*/.*" | fzf --height=50% --preview 'exa --tree --level 2 {} | head --lines=20' --no-multi) &&
else
## If at least one argument was given, add it to fzf query
dir=$(find . -xtype d -not -path "*/.*" | fzf --height=50% --preview 'exa --tree --level 2 {} | head --lines=20' --no-multi --query "${*} ") &&
fi
## }}}
cd -- "${dir}"
}
# }}}
# ffh - cd to selected directory (hidden only) {{{
# Search with find (fd|fdfind overkill the CPU for few benefits on small tree)
# Check for symlinked directories too
# Allow to give arguments to prefill fzf request
# Display a preview tree of the directory
# Move to the selected directory
ffh() { ffh() {
local dir local dir
dir=$(find ${1:-.} -type d 2> /dev/null | fzf +m) && cd "$dir"
## Manage argument {{{
if [ "${#}" -eq "0" ]; then
## Default command without args
dir=$(find . -xtype d -path "*/.*" | fzf --height=50% --preview 'exa --tree --level 2 {} | head --lines=20' --no-multi) &&
else
## If at least one argument was given, add it to fzf query
dir=$(find . -xtype d -path "*/.*" | fzf --height=50% --preview 'exa --tree --level 2 {} | head --lines=20' --no-multi --query "${*} ") &&
fi
## }}}
cd -- "${dir}"
} }
# }}}
# ffa - cd to any directory from / {{{
# Search with fd (fdfind is perfect to search on /)
# Check for symlinked directories too
# Allow to give arguments to prefill fzf request
# Display a preview tree of the directory
# Move to the selected directory
ffa() {
local dir
# ffa - all directories ## Manage argument {{{
if [ "${#}" -eq "0" ]; then
## Default command without args
dir=$(fd -uu --search-path / --type d --type symlink | fzf --height=50% --preview 'exa --tree --level 1 {} | head --lines=20' --no-multi) &&
else
## If at least one argument was given, add it to fzf query
dir=$(fd -uu --search-path / --type d --type symlink | fzf --height=50% --preview 'exa --tree --level 1 {} | head --lines=20' --no-multi --query "${*} ") &&
fi
## }}}
# ffr - cd to selected parent directory cd -- "${dir}"
ffr() { }
# }}}
# ffu - cd to selected parent directory {{{
ffu() {
local declare dirs=() local declare dirs=()
local dir
## Function to list parents of the given directory {{{
get_parent_dirs() { get_parent_dirs() {
if [[ -d "${1}" ]]; then dirs+=("$1"); else return; fi if [[ -d "${1}" ]]; then dirs+=("$1"); else return; fi
if [[ "${1}" == '/' ]]; then if [[ "${1}" == '/' ]]; then
for _dir in "${dirs[@]}"; do echo $_dir; done for _dir in "${dirs[@]}"; do echo $_dir; done
else else
get_parent_dirs $(dirname "$1") get_parent_dirs $(dirname "${1}")
fi fi
} }
local DIR=$(get_parent_dirs $(realpath "${1:-$PWD}") | fzf-tmux --tac) ## }}}
cd "$DIR" ## Manage argument {{{
} if [ "${#}" -eq "0" ]; then
## Default command without args
dir=$(get_parent_dirs $(realpath "${PWD}") | fzf --tac --height=50% --no-multi) &&
else
## If at least one argument was given, add it to fzf query
dir=$(get_parent_dirs $(realpath "${PWD}") | fzf --tac --height=50% --no-multi --query "${*} ") &&
fi
## }}}
# fff - cd into the directory of the selected file cd -- "${dir}"
}
# }}}
# fff - cd to the directory of the selected file {{{
# Search with find (fd|fdfind overkill the CPU for few benefits on small tree)
# Check for symlinked files too
# Allow to give arguments to prefill fzf request
# Display a directory preview tree of the selected file with exa
# Move to the directory of the selected file
fff() { fff() {
local file local file
local dir local dir
file=$(fzf +m -q "$1") && dir=$(dirname "$file") && cd "$dir"
}
# cf - fuzzy cd from anywhere ## Manage argument {{{
# ex: cf word1 word2 ... (even part of a file name) if [ "${#}" -eq "0" ]; then
# zsh autoload function ## Default command without args
file=$(find . -xtype f | fzf --height=50% --preview 'exa --tree --level 2 $(dirname {}) | head --lines=20' --no-multi) &&
else
## If at least one argument was given, add it to fzf query
file=$(find . -xtype f | fzf --height=50% --preview 'exa --tree --level 2 $(dirname {}) | head --lines=20' --no-multi --query "${*} ") &&
fi
## }}}
dir=$(dirname "${file}")
cd -- "${dir}"
}
# }}}
# cf - fuzzy cd from anywhere {{{
# Search with fd (fdfind is perfect to search on /)
# Allow to give arguments to prefill fzf request
# Display a directory preview tree of the selected file with exa
# Move to the directory of the selected file
cf() { cf() {
local file local file
file="$(locate -Ai -0 $@ | grep -z -vE '~$' | fzf --read0 -0 -1)" ## Manage argument {{{
if [ "${#}" -eq "0" ]; then
## Default command without args
#file="$(locate -Ai -0 $@ | grep -z -vE '~$' | fzf --read0 -0 -1)"
file=$(fd -uu --search-path / | fzf --height=50% --preview 'exa --tree --level 1 $(dirname {}) | head --lines=20' --no-multi) &&
else
## If at least one argument was given, add it to fzf query
file=$(fd -uu --search-path / | fzf --height=50% --preview 'exa --tree --level 1 $(dirname {}) | head --lines=20' --no-multi --query "${*} ") &&
fi
## }}}
if [[ -n $file ]] if [[ -n "${file}" ]]
then then
if [[ -d $file ]] if [[ -d "${file}" ]]
then then
cd -- $file ### If it's a directory, cd
cd -- "${file}"
else else
cd -- ${file:h} ### If it's a file, cd to the directory
cd -- "${file:h}"
fi fi
fi fi
} }
# }}}
fi # v - fuzzy open file with vi from current directory {{{
# Search with fd (fdfind is perfect to search more than ~200k files)
# v - fuzzy open with vi from current directory # Check for symlinked files too
# cd into the directory of the selected file # Allow to give arguments to prefill fzf request
# open the selected file with vi # Display the 50 first lines of the selected file with bat (batcat)
# Move to the directory of the selected file
# Open the selected file with vi
v() { v() {
local files local files
local dir
local file
files=$(find ${1:-.} -path '*/\.*' -prune \ ## Manage argument {{{
-o -print 2> /dev/null | fzf +m) && if [ "${#}" -eq "0" ]; then
## Default command without args
files=$(fd -uu --type file --type symlink | fzf --preview 'bat --color=always --line-range 0:50 {}' --no-multi) &&
else
## If at least one argument was given, add it to fzf query
files=$(fd -uu --type file --type symlink | fzf --preview 'bat --color=always --line-range 0:50 {}' --no-multi --query "${*} ") &&
fi
## }}}
if [[ -n $files ]] ## Move to the directory and open the file {{{
if [[ -n "${files}" ]]
then then
dir=$(dirname "${files}") dir=$(dirname "${files}")
cd "${dir}" cd -- "${dir}"
file=$(basename "${files}") file=$(basename "${files}")
vi -- "${file}" vi -- "${file}"
fi fi
## }}}
} }
# }}}
# Try to give the real creation time of a file fi
xstat() {
for target in "${@}"; do
inode=$(ls -di "${target}" | cut -d ' ' -f 1)
fs=$(df "${target}" | tail -1 | awk '{print $1}')
crtime=$(sudo debugfs -R 'stat <'"${inode}"'>' "${fs}" 2>/dev/null |
grep -oP 'crtime.*--\s*\K.*')
printf "%s\t%s\n" "${crtime}" "${target}"
done
}
# PDF with fzf {{{ # pdf fuzzy open PDF file with "${PDF_VIEWER}" from current directory {{{
# pdf - fuzzy open with "${PDF_VIEWER}" from current directory # Search with fd (fdfind is better than find with a pattern)
# cd into the directory of the selected file # Allow to give arguments to prefill fzf request
# open the selected file with "${PDF_VIEWER}" # Display a preview of selected file with lesspipe
# Move to the directory of the selected file
# Open the selected file with "${PDF_VIEWER}"
pdf() { pdf() {
local files local files
local dir
local file
files=$(find ${1:-.} -iname "*.pdf" 2> /dev/null | fzf +m) && ## Manage argument {{{
if [ "${#}" -eq "0" ]; then
## Default command without args
files=$(fd --unrestricted --type file --type symlink "\.pdf$" | fzf --preview 'lesspipe {} | less' --no-multi) &&
else
## If at least one argument was given, add it to fzf query
files=$(fd --unrestricted --type file --type symlink "\.pdf$" | fzf --preview 'lesspipe {} | less' --no-multi --query "${*} ") &&
fi
## }}}
## Move to the directory and open the file {{{
if [[ -n $files ]] if [[ -n $files ]]
then then
dir=$(dirname "${files}") dir=$(dirname "${files}")
cd "${dir}" cd -- "${dir}"
file=$(basename "${files}") file=$(basename "${files}")
"${PDF_VIEWER}" -- "${file}" "${PDF_VIEWER}" -- "${file}"
fi fi
} ## }}}
# pdfe - fuzzy open with evince from current directory
# cd into the directory of the selected file
# open the selected file with evince
pdfe() {
local files
files=$(find ${1:-.} -iname "*.pdf" 2> /dev/null | fzf +m) &&
if [[ -n $files ]]
then
dir=$(dirname "${files}")
cd "${dir}"
file=$(basename "${files}")
evince -- "${file}"
fi
}
# pdfz - fuzzy open with zathura from current directory
# cd into the directory of the selected file
# open the selected file with zathura
pdfz() {
local files
files=$(find ${1:-.} -iname "*.pdf" 2> /dev/null | fzf +m) &&
if [[ -n $files ]]
then
dir=$(dirname "${files}")
cd "${dir}"
file=$(basename "${files}")
zathura -- "${file}"
fi
} }
# }}} # }}}
# LibreOffice with fzf {{{ # pdfe fuzzy open PDF file with evince from current directory {{{
# Search with fd (fdfind is better than find with a pattern)
# Allow to give arguments to prefill fzf request
# Display a preview of selected file with lesspipe
# Move to the directory of the selected file
# Open the selected file with evince (default rollback to "${PDF_VIEWER}")
pdfe() {
local files
local dir
local file
local evince_bin
# odt - fuzzy open wordprocessor related files ## If evince is available {{{
# Look for some known extensions (odt, rtf, doc,…). if [ $(command -v evince) ]; then
# cd into the directory of the selected file. evince_bin=$(command -v evince)
# Open in background the selected file with libreoffice-writer. else
evince_bin="${PDF_VIEWER}"
fi
## }}}
## Manage argument {{{
if [ "${#}" -eq "0" ]; then
## Default command without args
files=$(fd --unrestricted --type file --type symlink "\.pdf$" | fzf --preview 'lesspipe {} | less' --no-multi) &&
else
## If at least one argument was given, add it to fzf query
files=$(fd --unrestricted --type file --type symlink "\.pdf$" | fzf --preview 'lesspipe {} | less' --no-multi --query "${*} ") &&
fi
## }}}
## Move to the directory and open the file {{{
if [[ -n $files ]]
then
dir=$(dirname "${files}")
cd "${dir}"
file=$(basename "${files}")
"${evince_bin}" -- "${file}"
fi
## }}}
}
# }}}
# pdfz - fuzzy open with zathura from current directory {{{
# Search with fd (fdfind is better than find with a pattern)
# Allow to give arguments to prefill fzf request
# Display a preview of selected file with lesspipe
# Move to the directory of the selected file
# Open the selected file with zathura (default rollback to "${PDF_VIEWER}")
pdfz() {
local files
local dir
local file
local zathura_bin
## If zathura is available {{{
if [ $(command -v zathura) ]; then
zathura_bin=$(command -v zathura)
else
zathura_bin="${PDF_VIEWER}"
fi
## }}}
## Manage argument {{{
if [ "${#}" -eq "0" ]; then
## Default command without args
files=$(fd --unrestricted --type file --type symlink "\.pdf$" | fzf --preview 'lesspipe {} | less' --no-multi) &&
else
## If at least one argument was given, add it to fzf query
files=$(fd --unrestricted --type file --type symlink "\.pdf$" | fzf --preview 'lesspipe {} | less' --no-multi --query "${*} ") &&
fi
## }}}
## Move to the directory and open the file {{{
if [[ -n $files ]]
then
dir=$(dirname "${files}")
cd "${dir}"
file=$(basename "${files}")
"${zathura_bin}" -- "${file}"
fi
## }}}
}
# }}}
# odt fuzzy open text document file with LibreOffice from current directory {{{
# Search with fd (fdfind is better than find with a pattern)
# Search for odt|rtf|doc|docx files
# Allow to give arguments to prefill fzf request
# Move to the directory of the selected file
# Open the selected file with libreoffice --writer
odt() { odt() {
local files local files
files=$(find ${1:-.} -regextype posix-extended -regex ".*\.(odt|rtf|doc|docx)" 2> /dev/null | fzf +m) && ## Manage argument {{{
if [ "${#}" -eq "0" ]; then
## Default command without args
files=$(fd --unrestricted --type file --type symlink "\.(odt|rtf|doc|docx)" | fzf --no-multi) &&
else
## If at least one argument was given, add it to fzf query
files=$(fd --unrestricted --type file --type symlink "\.(odt|rtf|doc|docx)" | fzf --no-multi --query "${*} ") &&
fi
## }}}
## Move to the directory and open the file {{{
if [[ -n $files ]] if [[ -n $files ]]
then then
dir=$(dirname "${files}") dir=$(dirname "${files}")
@ -1979,17 +2147,29 @@ odt() {
file=$(basename "${files}") file=$(basename "${files}")
command libreoffice --writer "${file}" & command libreoffice --writer "${file}" &
fi fi
## }}}
} }
# }}}
# ods - fuzzy open spreadsheet related files # ods fuzzy open calc document file with LibreOffice from current directory {{{
# Look for some known extensions (ods, xls,…). # Search with fd (fdfind is better than find with a pattern)
# cd into the directory of the selected file. # Search for ods|xls|xlsx files
# Open in background the selected file with libreoffice-calc. # Allow to give arguments to prefill fzf request
# Move to the directory of the selected file
# Open the selected file with libreoffice --calc
ods() { ods() {
local files local files
files=$(find ${1:-.} -regextype posix-extended -regex ".*\.(ods|xls|xlsx)" 2> /dev/null | fzf +m) && ## Manage argument {{{
if [ "${#}" -eq "0" ]; then
## Default command without args
files=$(fd --unrestricted --type file --type symlink "\.(ods|xls|xlsx)" | fzf --no-multi) &&
else
## If at least one argument was given, add it to fzf query
files=$(fd --unrestricted --type file --type symlink "\.(ods|xls|xlsx)" | fzf --no-multi --query "${*} ") &&
fi
## }}}
## Move to the directory and open the file {{{
if [[ -n $files ]] if [[ -n $files ]]
then then
dir=$(dirname "${files}") dir=$(dirname "${files}")
@ -1997,17 +2177,29 @@ ods() {
file=$(basename "${files}") file=$(basename "${files}")
command libreoffice --calc "${file}" & command libreoffice --calc "${file}" &
fi fi
## }}}
} }
# }}}
# odp - fuzzy open presentation related files # odp fuzzy open presentation document file with LibreOffice from current directory {{{
# Look for some known extensions (odp, ppt,…). # Search with fd (fdfind is better than find with a pattern)
# cd into the directory of the selected file. # Search for odp|ppt|pptx files
# Open in background the selected file with libreoffice-impress. # Allow to give arguments to prefill fzf request
# Move to the directory of the selected file
# Open the selected file with libreoffice --impress
odp() { odp() {
local files local files
files=$(find ${1:-.} -regextype posix-extended -regex ".*\.(odp|ppt|pptx)" 2> /dev/null | fzf +m) && ## Manage argument {{{
if [ "${#}" -eq "0" ]; then
## Default command without args
files=$(fd --unrestricted --type file --type symlink "\.(odp|ppt|pptx)" | fzf --no-multi) &&
else
## If at least one argument was given, add it to fzf query
files=$(fd --unrestricted --type file --type symlink "\.(odp|ppt|pptx)" | fzf --no-multi "${*} ") &&
fi
## }}}
## Move to the directory and open the file {{{
if [[ -n $files ]] if [[ -n $files ]]
then then
dir=$(dirname "${files}") dir=$(dirname "${files}")
@ -2015,7 +2207,40 @@ odp() {
file=$(basename "${files}") file=$(basename "${files}")
command libreoffice --impress "${file}" & command libreoffice --impress "${file}" &
fi fi
## }}}
} }
# }}}
# fopen fuzzy open file with xdg-open from current directory {{{
# Search with fd (fdfind is better than find with a pattern)
# Use first argument as fd pattern
# Other arguments will prefill fzf request
# Move to the directory of the selected file
# Open the selected file with xdg-open
fopen() {
local files
## Manage argument {{{
if [ "${#}" -le "1" ]; then
## Default command with one argument or default value
files=$(fd --unrestricted --type file --type symlink "${1:-.}" | fzf --no-multi) &&
else
## If at least one argument was given, add it to fzf query
files=$(fd --unrestricted --type file --type symlink "${1:-.}" | fzf --no-multi --query "${*} ") &&
fi
## }}}
## Move to the directory and open the file {{{
if [[ -n $files ]]
then
dir=$(dirname "${files}")
cd -- "${dir}"
file=$(basename "${files}")
command xdg-open "${file}" &
fi
## }}}
}
# }}}
# }}} # }}}
# zsh-syntax-highlighting {{{ # zsh-syntax-highlighting {{{