From e115b1875d04951a6cbb87203ea19efd65a72838 Mon Sep 17 00:00:00 2001 From: Gardouille Date: Fri, 18 Feb 2022 15:34:03 +0100 Subject: [PATCH] Improve fzf commands with fd, bat or lesspipe --- zshrc | 433 ++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 329 insertions(+), 104 deletions(-) diff --git a/zshrc b/zshrc index f2b604c..f68cdbc 100644 --- a/zshrc +++ b/zshrc @@ -1430,7 +1430,6 @@ else ## Simple utilisateur export PS1="$heure $host $repertoire_courant$noroot $normal" fi - # Prise en charge des touches [début], [fin] et autres typeset -A key @@ -1806,7 +1805,7 @@ setopt extendedglob if [ -d ~/.fzf ]; then if [[ ! "$PATH" == *"${HOME}"/.fzf/bin* ]]; then - export PATH="$PATH:${HOME}/.fzf/bin" + export PATH="$PATH:${HOME}/.fzf/bin" fi if [ -f ~/bin/fd ]; then @@ -1821,157 +1820,326 @@ fi # ------------ 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() { 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() { 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 -ffr() { + cd -- "${dir}" +} +# }}} +# ffu - cd to selected parent directory {{{ +ffu() { local declare dirs=() + local dir + + ## Function to list parents of the given directory {{{ get_parent_dirs() { if [[ -d "${1}" ]]; then dirs+=("$1"); else return; fi if [[ "${1}" == '/' ]]; then for _dir in "${dirs[@]}"; do echo $_dir; done else - get_parent_dirs $(dirname "$1") + get_parent_dirs $(dirname "${1}") 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() { local file local dir - file=$(fzf +m -q "$1") && dir=$(dirname "$file") && cd "$dir" -} -# cf - fuzzy cd from anywhere -# ex: cf word1 word2 ... (even part of a file name) -# zsh autoload function + ## Manage argument {{{ + if [ "${#}" -eq "0" ]; then + ## 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() { 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 - if [[ -d $file ]] + if [[ -d "${file}" ]] then - cd -- $file + ### If it's a directory, cd + cd -- "${file}" else - cd -- ${file:h} + ### If it's a file, cd to the directory + cd -- "${file:h}" fi fi } +# }}} -fi - -# v - fuzzy open with vi from current directory -# cd into the directory of the selected file -# open the selected file with vi +# v - fuzzy open file with vi from current directory {{{ +# Search with fd (fdfind is perfect to search more than ~200k files) +# Check for symlinked files too +# Allow to give arguments to prefill fzf request +# 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() { local files + local dir + local file - files=$(find ${1:-.} -path '*/\.*' -prune \ - -o -print 2> /dev/null | fzf +m) && + ## Manage argument {{{ + 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 dir=$(dirname "${files}") - cd "${dir}" + cd -- "${dir}" file=$(basename "${files}") vi -- "${file}" fi + ## }}} } +# }}} -# Try to give the real creation time of a file -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 -} +fi -# PDF with fzf {{{ -# pdf - fuzzy open with "${PDF_VIEWER}" from current directory -# cd into the directory of the selected file -# open the selected file with "${PDF_VIEWER}" +# pdf − fuzzy open PDF file with "${PDF_VIEWER}" 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 "${PDF_VIEWER}" pdf() { 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 ]] then dir=$(dirname "${files}") - cd "${dir}" + cd -- "${dir}" file=$(basename "${files}") "${PDF_VIEWER}" -- "${file}" 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 -# Look for some known extensions (odt, rtf, doc,…). -# cd into the directory of the selected file. -# Open in background the selected file with libreoffice-writer. + ## If evince is available {{{ + if [ $(command -v evince) ]; then + evince_bin=$(command -v evince) + 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() { 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 ]] then dir=$(dirname "${files}") @@ -1979,17 +2147,29 @@ odt() { file=$(basename "${files}") command libreoffice --writer "${file}" & fi + ## }}} } - -# ods - fuzzy open spreadsheet related files -# Look for some known extensions (ods, xls,…). -# cd into the directory of the selected file. -# Open in background the selected file with libreoffice-calc. +# }}} +# ods − fuzzy open calc document file with LibreOffice from current directory {{{ +# Search with fd (fdfind is better than find with a pattern) +# Search for ods|xls|xlsx files +# Allow to give arguments to prefill fzf request +# Move to the directory of the selected file +# Open the selected file with libreoffice --calc ods() { 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 ]] then dir=$(dirname "${files}") @@ -1997,17 +2177,29 @@ ods() { file=$(basename "${files}") command libreoffice --calc "${file}" & fi + ## }}} } - -# odp - fuzzy open presentation related files -# Look for some known extensions (odp, ppt,…). -# cd into the directory of the selected file. -# Open in background the selected file with libreoffice-impress. +# }}} +# odp − fuzzy open presentation document file with LibreOffice from current directory {{{ +# Search with fd (fdfind is better than find with a pattern) +# Search for odp|ppt|pptx files +# Allow to give arguments to prefill fzf request +# Move to the directory of the selected file +# Open the selected file with libreoffice --impress odp() { 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 ]] then dir=$(dirname "${files}") @@ -2015,7 +2207,40 @@ odp() { file=$(basename "${files}") command libreoffice --impress "${file}" & 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 {{{