devops
Last updated
Was this helpful?
Last updated
Was this helpful?
references:
others
fuzzy completion in bash
$ cat **<tab>
$ unset **<tab>
$ unalias **<tab>
$ export **<tab>
$ ssh **<tab>
$ kill -9 **<tab>
[!NOTE|label:references:]
fzf basics:
usage
more tools
vim
" fzf.vim now supports this command out of the box " so this code is no longer needed. command! -bang -nargs=* Rg \ call fzf#vim#grep( \ 'rg --column --line-number --hidden --ignore-case --no-heading --color=always '.shellescape(<q-args>), 1, \ <bang>0 ? fzf#vim#with_preview({'options': '--delimiter : --nth 4..'}, 'up:60%') \ : fzf#vim#with_preview({'options': '--delimiter : --nth 4..'}, 'right:50%:hidden', '?'), \ <bang>0)
customize
[!NOTE|label:references:]
$ brew install fzf fd
$ ln -sf $(brew --prefix fd)/share/bash-completion/completions/fd /usr/local/etc/bash_completion.d/fd
# debine
$ sudo apt install fd
$ FZF_DEFAULT_OPTS="${FZF_DEFAULT_OPTS:+$FZF_DEFAULT_OPTS} "
$ FZF_DEFAULT_OPTS+="--height 35% --min-height 8+ " # https://github.com/junegunn/fzf/issues/4226
$ FZF_DEFAULT_OPTS+="--layout=reverse --multi --cycle --ansi "
$ FZF_DEFAULT_OPTS+="--marker=' ' --pointer='▌' "
$ FZF_DEFAULT_OPTS+="--prompt=' ' --info='inline: ' "
$ FZF_DEFAULT_OPTS+="--info-command='echo \"\x1b[33;1m\$FZF_POS\x1b[m ~ \$FZF_INFO\"' "
$ FZF_DEFAULT_OPTS+="--bind 'ctrl-s:select-all,ctrl-d:deselect-all,ctrl-t:toggle-all' "
$ FZF_DEFAULT_OPTS+="--bind 'ctrl-y:execute-silent(/bin/echo -n {+} | ${COPY})' "
$ FZF_DEFAULT_OPTS+="--color=gutter:-1,bg+:-1,spinner:#e6db74,prompt:#404945,header:italic:#504945,info:#928374,pointer:#A66584,marker:#d79921,fg:#ebdbb2:dim,fg+:#A7A44E:regular,hl:#845069:italic,hl+:#A66584:bold:italic"
$
$ FZF_DEFAULT_COMMAND="fd --type f "
$ FZF_DEFAULT_COMMAND+="--strip-cwd-prefix "
$ FZF_DEFAULT_COMMAND+="--hidden "
$ FZF_DEFAULT_COMMAND+="--follow "
$ FZF_DEFAULT_COMMAND+="--exclude .git --exclude node_modules"
$ export FZF_DEFAULT_OPTS FZF_DEFAULT_COMMAND
pointer
▏
, ▕
, ┃
, ▎
, ▌
, ▊
, ▉
, ▒
, ⵗ
# -- or --
FZF_DEFAULT_OPTS+="--prompt=' ' --info='inline: ' "
# -- or --
FZF_DEFAULT_OPTS+="--prompt='ᑹ ∷ ' "
# or
FZF_DEFAULT_OPTS+="--prompt=' ' "
# -- or --
FZF_DEFAULT_OPTS+='--style full --layout reverse '
FZF_DEFAULT_OPTS+='--header-lines-border bottom --no-list-border '
# -- or --
FZF_DEFAULT_OPTS+="--no-bold "
# -- or --
FZF_DEFAULT_OPTS+="--color=fg+:#ebdbb2,pointer:#e6db74,hl+:#fb4934,prompt:#334D35"
$ FZF_DEFAULT_OPTS="--height 35%"
$ FZF_DEFAULT_OPTS+=" --layout=reverse"
$ FZF_DEFAULT_OPTS+=" --pointer='→' --marker='» ' --prompt='$ '"
$ FZF_DEFAULT_OPTS+=" --multi"
$ FZF_DEFAULT_OPTS+=" --inline-info"
$ FZF_DEFAULT_OPTS+=" --color=spinner:#e6db74,hl:#928374,fg:#ebdbb2,header:#928374,info:#504945,pointer:#98971a,marker:#d79921,fg+:#ebdbb2,prompt:#404945,hl+:#fb4934"
$ FZF_DEFAULT_COMMAND="fd --type f"
$ FZF_DEFAULT_COMMAND+=" --strip-cwd-prefix"
$ FZF_DEFAULT_COMMAND+=" --hidden"
$ FZF_DEFAULT_COMMAND+=" --follow"
$ FZF_DEFAULT_COMMAND+=" --exclude .git --exclude node_modules"
install from source code for wsl
[!NOTE|label:this solution for install latest fzf in wsl]
in wsl Ubuntu, the fzf version is
0.29
$ sudo apt search fzf Sorting... Done Full Text Search... Done fzf/jammy 0.29.0-1 amd64 general-purpose command-line fuzzy finder
$ git clone git@github.com:junegunn/fzf.git
$ bash -x install --all
$ sudo cp bin/fzf* /usr/local/bin/
offline install
[!NOTE]
curl: (60) SSL certificate problem: self-signed certificate in certificate chain
:$ curl -fL https://github.com/junegunn/fzf/releases/download/0.44.1/fzf-0.44.1-linux_amd64.tar.gz curl: (60) SSL certificate problem: self-signed certificate in certificate chain More details here: https://curl.se/docs/sslcerts.html curl failed to verify the legitimacy of the server and therefore could not establish a secure connection to it. To learn more about this situation and how to fix it, please visit the web page mentioned above.
~/.curlrc
$ echo '--insecure' >> ~/.curlrc
offline installation
################ for offline installation only ################
# check current version for offline installation
$ uname -sm
Linux x86_64
# download correct package according https://github.com/junegunn/fzf/blob/master/install#L170
# i.e.: Linux x86_64 -> fzf-$version-linux_amd64.tar.gz
$ cp fzf-0.42.0-linux_amd64.tar.gz /tmp/fzf.tar.gz
# modify install script `try_curl` function to not download but use local tar.gz directly
$ cat << 'EOF' | git apply --inaccurate-eof --ignore-whitespace
diff --git a/install b/install
index 5ac191b..342bc49 100755
--- a/install
+++ b/install
@@ -115,10 +115,8 @@ link_fzf_in_path() {
try_curl() {
command -v curl > /dev/null &&
if [[ $1 =~ tar.gz$ ]]; then
- curl -fL $1 | tar -xzf -
- else
- local temp=${TMPDIR:-/tmp}/fzf.zip
- curl -fLo "$temp" $1 && unzip -o "$temp" && rm -f "$temp"
+ local temp=${TMPDIR:-/tmp}/fzf.tar.gz
+ tar -xzf "$temp" && rm -rf "$temp"
fi
}
EOF
### or modify manually ###
# try_curl() {
# command -v curl > /dev/null &&
# if [[ $1 =~ tar.gz$ ]]; then
# local temp=${TMPDIR:-/tmp}/fzf.tar.gz
# tar -xzf "$temp" && rm -rf "$temp"
# fi
# }
################ for offline installation only ################
[!NOTE|label:references:]
enable via :
--multi
or-m
disable via :
--no-multi
or+m
CTRL-t
__fzf_select__
__fsel
FZF_CTRL_T_COMMAND
CTRL-r
__fzf_history__
fzf-history-widget
FZF_CTRL_R_OPTS
ALT-c
__fzf_cd__
fzf-cd-widget
FZF_ALT_C_COMMAND
⏎
ctrl + s
ctrl + d
ctrl + t
⇥
shift + ⇥
↑
↓
⇥
ctrl + k
ctrl + j
ctrl + p
ctrl + n
shift + ⇥
ctrl + k
ctrl + j
[!TIP]
customized shortcut key via:
export FZF_CTRL_T_OPTS="${FZF_CTRL_T_OPTS} --bind 'ctrl-p:preview-up,ctrl-n:preview-down'" export FZF_CTRL_T_OPTS="${FZF_CTRL_T_OPTS} --bind 'ctrl-/:change-preview-window(down|hidden|)'"
file list:
↑
↓
ctrl + /
ctrl + k
ctrl + j
ctrl + p
ctrl + n
preview content:
shift + ↑
shift + ↓
ctrl + ↑
ctrl + ↓
ctrl + p
ctrl + n
[!NOTE|label:references:]
[!TIP]
# magic vim - fzf list in recent modified order
# @author : marslo
# @source : https://github.com/marslo/mylinux/blob/master/confs/home/.marslo/bin/ffunc.sh
# @description :
# - if `nvim` installed using `nvim` instead of `vim`
# - using `-v` to force using `vim` instead of `nvim` even if nvim installed
# - if `vim` commands without paramters, then call fzf and using vim to open selected file
# - if `vim` commands with paramters
# - if single paramters and parameters is directlry, then call fzf in target directory and using vim to open selected file
# - otherwise call regular vim to open file(s)
# - to respect fzf options by: `type -t _fzf_opts_completion >/dev/null 2>&1 && complete -F _fzf_opts_completion -o bashdefault -o default vim`
# shellcheck disable=SC2155
function vim() { # magic vim - fzf list in most recent modified order
local voption
local target
local orgv # force using vim instead of nvim
local VIM="$(type -P vim)"
local foption='--multi --cycle '
local fdOpt="--type f --hidden --follow --unrestricted --ignore-file $HOME/.fdignore --exclude Music"
[[ "$(pwd)" = "$HOME" ]] && fdOpt+=' --max-depth 3'
if ! uname -r | grep -q "Microsoft"; then fdOpt+=' --exec-batch ls -t'; fi
while [[ $# -gt 0 ]]; do
case "$1" in
-v ) orgv=1 ; shift ;;
-h | --help ) voption+="$1 " ; shift ;;
--version ) voption+="$1 " ; shift ;;
-c ) voption+="$1 $2" ; shift ;;
--startuptime ) voption+="$1 $2 " ; shift 2 ;;
-Nu ) voption+="$1 $2 " ; shift 2 ;;
--cmd ) voption+="$1 $2 " ; shift 2 ;;
-* ) foption+="$1 $2 " ; shift 2 ;;
* ) break ;;
esac
done
[[ 1 -ne "${orgv}" ]] && command -v nvim >/dev/null && VIM="$(type -P nvim)"
if [[ 0 -eq $# ]] && [[ -z "${voption}" ]]; then
fd . ${fdOpt} | fzf ${foption} --bind="enter:become(${VIM} {+})"
elif [[ 1 -eq $# ]] && [[ -d $1 ]]; then
[[ '.' = "${1}" ]] && target="${1}" || target=". ${1}"
fd ${target} ${fdOpt} | fzf ${foption} --bind="enter:become(${VIM} {+})"
else
# shellcheck disable=SC2068
"${VIM}" ${voption} $@
fi
}
# v - open files in ~/.vim_mru_files # https://github.com/junegunn/fzf/wiki/Examples#v
# @author : marslo
# @source : https://github.com/marslo/mylinux/blob/master/confs/home/.marslo/bin/ffunc.sh
# @description : list 10 most recently used files via fzf, and open by regular vim
function v() { # v - open files in ~/.vim_mru_files
local files
files=$( grep --color=none -v '^#' ~/.vim_mru_files |
while read -r line; do [ -f "${line/\~/$HOME}" ] && echo "$line"; done |
fzf-tmux -d -m -q "$*" -1
) &&
vim ${files//\~/$HOME}
}
# vimr - open files by [vim] in whole [r]epository
# same series: [`cdr`](https://github.com/marslo/dotfiles/blob/main/.marslo/bin/ffunc.sh#L310-L318)
# similar with [`:Gfiles`](https://github.com/junegunn/fzf.vim?tab=readme-ov-file#commands)
# @author : marslo
# @source : https://github.com/marslo/mylinux/blob/master/confs/home/.marslo/bin/ffunc.sh
# @description :
# - if pwd inside the repo, then filter all files within current git repository via data modified and open by vim
# - if pwd not inside the repo, then call `vim`
function vimr() { # vimr - open file(s) via [vim] in whole [r]epository
local repodir
isrepo=$(git rev-parse --is-inside-work-tree >/dev/null 2>&1; echo $?)
if [[ 0 = "${isrepo}" ]]; then
repodir="$(git rev-parse --show-toplevel)"
# shellcheck disable=SC2164
files=$( fd . "${repodir}" --type f --hidden --ignore-file ~/.fdignore --exec-batch ls -t |
xargs -I{} bash -c "echo {} | sed \"s|${repodir}/||g\"" |
fzf --multi -0 |
xargs -I{} bash -c "echo ${repodir}/{}"
)
# shellcheck disable=SC2046
[[ -z "${files}" ]] || vim $(xargs <<< "${files}")
else
vim
fi
}
# vimrc - open rc files list from "${rcPaths}" to quick update/modify rc files
# @author : marslo
# @source : https://github.com/marslo/mylinux/blob/master/confs/home/.marslo/bin/ffunc.sh
# @description :
# - default rcPaths: ~/.marslo ~/.config/nvim ~/.*rc ~/.*profile ~/.*ignore
# - using nvim if `command -v nvim` is true
# - using `-v` force using `command vim` instead of `command nvim`
# shellcheck disable=SC2155
function vimrc() { # vimrc - fzf list all rc files in data modified order
local orgv # force using vim instead of nvim
local rcPaths="$HOME/.config/nvim $HOME/.marslo"
local VIM="$(type -P vim)"
local foption='--multi --cycle '
local fdOpt="--type f --hidden --follow --unrestricted --ignore-file $HOME/.fdignore"
if ! uname -r | grep -q "Microsoft"; then fdOpt+=' --exec-batch ls -t'; fi
while [[ $# -gt 0 ]]; do
case "$1" in
-v ) orgv=1 ; shift ;;
* ) break ;;
esac
done
[[ 1 -ne "${orgv}" ]] && command -v nvim >/dev/null && VIM="$(type -P nvim)"
fdInRC | sed -rn 's/^[^|]* \| (.+)$/\1/p' \
| fzf ${foption} --bind="enter:become(${VIM} {+})" \
--bind "ctrl-y:execute-silent(echo -n {+} | ${COPY})+abort" \
--header 'Press CTRL-Y to copy name into clipboard'
}
fdInRC
# shellcheck disable=SC2089,SC2090
function fdInRC() {
local rcPaths="$HOME/.config/nvim $HOME/.marslo $HOME/.idlerc $HOME/.ssh"
local fdOpt="--type f --hidden --follow --unrestricted --ignore-file $HOME/.fdignore"
fdOpt+=' --exec stat --printf="%y | %n\n"'
(
eval "fd --max-depth 1 --hidden '.*rc|.*profile|.*ignore' $HOME ${fdOpt}";
echo "${rcPaths}" | fmt -1 | xargs -I{} bash -c "fd . {} --exclude ss/ --exclude log/ --exclude .completion/ --exclude bin/bash-completion/ ${fdOpt}" ;
) | sort -r
}
function fzfInPath() { # return file name via fzf in particular folder
local fdOpt="--type f --hidden --follow --unrestricted --ignore-file $HOME/.fdignore"
if ! uname -r | grep -q 'Microsoft'; then fdOpt+=' --exec-batch ls -t'; fi
[[ '.' = "${1}" ]] && path="${1}" || path=". ${1}"
eval "fd ${path} ${fdOpt} | fzf --multi --cycle ${*:2} --header 'filter in ${1} :'"
}
# magic vimdiff - using fzf list in recent modified order
# @author : marslo
# @source : https://github.com/marslo/mylinux/blob/master/confs/home/.marslo/bin/ffunc.sh
# @description :
# - if any of paramters is directory, then get file path via fzf in target path first
# - if `vimdiff` commands without parameter , then compare files in `.` and `~/.marslo`
# - if `vimdiff` commands with 1 parameter , then compare files in current path and `$1`
# - if `vimdiff` commands with 2 parameters, then compare files in `$1` and `$2`
# - otherwise ( if more than 2 parameters ) , then compare files in `${*: -2:1}` and `${*: -1}` with paramters of `${*: 1:$#-2}`
# - to respect fzf options by: `type -t _fzf_opts_completion >/dev/null 2>&1 && complete -F _fzf_opts_completion -o bashdefault -o default vimdiff`
function vimdiff() { # smart vimdiff
local lFile
local rFile
local option
local var
while [[ $# -gt 0 ]]; do
case "$1" in
--help ) option+="$1 " ; shift ;;
-* ) option+="$1 $2 "; shift 2 ;;
* ) break ;;
esac
done
if [[ 0 -eq $# ]]; then
lFile=$(fzfInPath '.' "${option}")
# shellcheck disable=SC2154
rFile=$(fzfInPath "${iRCHOME}" "${option}")
elif [[ 1 -eq $# ]]; then
lFile=$(fzfInPath '.' "${option}")
[[ -d "$1" ]] && rFile=$(fzfInPath "$1" "${option}") || rFile="$1"
elif [[ 2 -eq $# ]]; then
[[ -d "$1" ]] && lFile=$(fzfInPath "$1" "${option}") || lFile="$1"
[[ -d "$2" ]] && rFile=$(fzfInPath "$2" "${option}") || rFile="$2"
else
var="${*: 1:$#-2}"
[[ -d "${*: -2:1}" ]] && lFile=$(fzfInPath "${*: -2:1}") || lFile="${*: -2:1}"
[[ -d "${*: -1}" ]] && rFile=$(fzfInPath "${*: -1}") || rFile="${*: -1}"
fi
[[ -f "${lFile}" ]] && [[ -f "${rFile}" ]] && $(type -P vim) -d ${var} "${lFile}" "${rFile}"
}
# vd - open vimdiff loaded files from ~/.vim_mru_files
# @author : marslo
# @source : https://github.com/marslo/mylinux/blob/master/confs/home/.marslo/bin/ffunc.sh
# @description : list 10 most recently used files via fzf, and open by vimdiff
# - if `vd` commands without parameter, list 10 most recently used files via fzf, and open selected files by vimdiff
# - if `vd` commands with `-q` ( [q]uiet ) parameter, list 10 most recently used files via fzf and automatic select top 2, and open selected files by vimdiff
function vd() { # vd - open vimdiff loaded files from ~/.vim_mru_files
[[ 1 -eq $# ]] && [[ '-q' = "$1" ]] && opt='--bind start:select+down+select+accept' || opt=''
# shellcheck disable=SC2046
files=$( grep --color=none -v '^#' ~/.vim_mru_files |
xargs -d'\n' -I_ bash -c "sed 's:\~:$HOME:' <<< _" |
fzf --multi 3 --sync --cycle --reverse ${opt}
) &&
vimdiff $(xargs <<< "${files}")
}
# smart cat - using bat by default for cat content, respect bat options
# @author : marslo
# @source : https://github.com/marslo/mylinux/blob/master/confs/home/.marslo/bin/ffunc.sh
# @description :
# - using `bat` by default if `command -v bat`
# - using `-c` ( `c`at ) as 1st parameter, to force using `type -P cat` instead of `type -P bat`
# - if `bat` without paramter, then search file via `fzf` and shows via `bat`
# - if `bat` with 1 paramter, and `$1` is directory, then search file via `fzf` from `$1` and shows via `bat`
# - otherwise respect `bat` options, and shows via `bat`
# shellcheck disable=SC2046,SC2155
function cat() { # smart cat
local fdOpt='--type f --hidden --follow --exclude .git --exclude node_modules'
local CAT="$(type -P cat)"
if ! uname -r | grep -q "Microsoft"; then fdOpt+=' --exec-batch ls -t'; fi
command -v nvim >/dev/null && CAT="$(type -P bat)"
if [[ 0 -eq $# ]]; then
"${CAT}" --theme='gruvbox-dark' $(fd . ${fdOpt} | fzf --multi --cycle --exit-1)
elif [[ '-c' = "$1" ]]; then
$(type -P cat) "${@:2}"
elif [[ 1 -eq $# ]] && [[ -d $1 ]]; then
local target=$1;
fd . "${target}" ${fdOpt} |
fzf --multi --cycle --exit-1 --bind="enter:become(${CAT} --theme='gruvbox-dark' {+})" ;
else
"${CAT}" --theme='gruvbox-dark' "${@:1:$#-1}" "${@: -1}"
fi
}
# smart copy - using `fzf` to list files and copy the selected file
# @author : marslo
# @source : https://github.com/marslo/mylinux/blob/master/confs/home/.marslo/bin/ffunc.sh
# @description :
# - if `copy` without parameter, then list file via `fzf` and copy the content
# - "${COPY}"
# - `pbcopy` in osx
# - `/mnt/c/Windows/System32/clip.exe` in wsl
# - otherwise copy the content of parameter `$1` via `pbcopy` or `clip.exe`
# shellcheck disable=SC2317
function copy() { # smart copy
local fdOpt='--type f --hidden --follow --exclude .git --exclude node_modules'
[[ -z "${COPY}" ]] && echo -e "$(c Rs)ERROR: 'copy' function NOT support :$(c) $(c Ri)$(uanme -v)$(c)$(c Rs). EXIT..$(c)" && return;
if [[ 0 -eq $# ]]; then
file=$(fzf --cycle --exit-0) &&
"${COPY}" < "${file}" &&
echo -e "$(c Wd)>>$(c) $(c Gis)${file}$(c) $(c Wdi)has been copied ..$(c)"
elif [[ 1 -eq $# ]] && [[ -d $1 ]]; then
local target=$1;
file=$( fd . "${target}" ${fdOpt} | fzf --cycle --exit-0 ) &&
"${COPY}" < "${file}" &&
echo -e "$(c Wd)>>$(c) $(c Gis)${file}$(c) $(c Wdi)has been copied ..$(c)"
else
"${COPY}" < "$1"
fi
}
image view
[!NOTE]
# imgview - fzf list and preview images
# @author : marslo
# @source : https://github.com/marslo/mylinux/blob/master/confs/home/.marslo/bin/ffunc.sh
# @description :
# - to respect fzf options by: `type -t _fzf_opts_completion >/dev/null 2>&1 && complete -F _fzf_opts_completion -o bashdefault -o default imgview`
# - disable `gif` due to imgcat performance issue
# shellcheck disable=SC2215
function imgview() { # view image via [imgcat](https://github.com/eddieantonio/imgcat)
fd --unrestricted --type f --exclude .git --exclude node_modules '^*\.(png|jpeg|jpg|xpm|bmp)$' |
fzf "$@" --height 100% \
--preview "imgcat -W \$FZF_PREVIEW_COLUMNS -H \$FZF_PREVIEW_LINES {}" \
--bind 'ctrl-y:execute-silent(echo -n {+} | pbcopy)+abort' \
--header 'Press CTRL-Y to copy name into clipboard' \
--preview-window 'down,80%,wrap' \
--exit-0 \
>/dev/null || true
}
fs
$ function fs() { fzf --multi --bind 'enter:become(vim {+})' }
fe
# fe [FUZZY PATTERN] - Open the selected file with the default editor
# - Bypass fuzzy finder if there's only one match (--select-1)
# - Exit if there's no match (--exit-0)
fe() {
IFS=$'\n' files=($(fzf-tmux --query="$1" --multi --select-1 --exit-0))
[[ -n "$files" ]] && ${EDITOR:-vim} "${files[@]}"
}
fo
# Modified version where you can press
# - CTRL-O to open with `open` command,
# - CTRL-E or Enter key to open with the $EDITOR
fo() {
IFS=$'\n' out=("$(fzf-tmux --query="$1" --exit-0 --expect=ctrl-o,ctrl-e)")
key=$(head -1 <<< "$out")
file=$(head -2 <<< "$out" | tail -1)
if [ -n "$file" ]; then
[ "$key" = ctrl-o ] && open "$file" || ${EDITOR:-vim} "$file"
fi
}
[!NOTE]
function fif() { # [f]ind-[i]n-[f]ile
if [ ! "$#" -gt 0 ]; then echo "Need a string to search for!"; return 1; fi
$(type -P rg) --files-with-matches --no-messages --hidden --follow --smart-case "$1" |
fzf --bind 'ctrl-p:preview-up,ctrl-n:preview-down' \
--bind "enter:become($(type -P vim) {+})" \
--header 'CTRL-N/CTRL-P or CTRL-↑/CTRL-↓ to view contents' \
--preview "bat --color=always --style=plain {} |
rg --no-line-number --colors 'match:bg:yellow' --ignore-case --pretty --context 10 \"$1\" ||
rg --no-line-number --ignore-case --pretty --context 10 \"$1\" {} \
"
}
# or highlight as preview tool
function fif() { # [f]ind-[i]n-[f]ile
if [ ! "$#" -gt 0 ]; then echo "Need a string to search for!"; return 1; fi
rg --color never --files-with-matches --no-messages "$1" |
fzf --bind 'ctrl-p:preview-up,ctrl-n:preview-down' \
--preview "highlight -O ansi {} 2> /dev/null |
rg --colors 'match:bg:yellow' --ignore-case --pretty --context 10 '$1' ||
rg --no-line-number --ignore-case --pretty --context 10 '$1' {} \
"
}
changing directory
[!NOTE|label:references:]
cdp
# shellcheck disable=SC2034,SC2316
function cdp() { # cdp - [c][d] to selected [p]arent directory
local declare dirs=()
get_parent_dirs() {
if [[ -d "${1}" ]]; then dirs+=("$1"); else return; fi
if [[ "${1}" == '/' ]]; then
for _dir in "${dirs[@]}"; do echo $_dir; done
else
# shellcheck disable=SC2046
get_parent_dirs $(dirname "$1")
fi
}
# shellcheck disable=SC2155,SC2046
local DIR=$(get_parent_dirs $(realpath "${1:-$PWD}") | fzf-tmux --tac)
cd "$DIR" || return
}
cdf
function cdf() { # [c][d] into the directory of the selected [f]ile
local file
local dir
# shellcheck disable=SC2164
file=$(fzf +m -q "$1") && dir=$(dirname "$file") && cd "$dir"
}
cdd
function cdd() { # cdd - [c][d] to selected sub [d]irectory
local dir
# shellcheck disable=SC2164
dir=$(fd --type d --hidden --ignore-file ~/.fdignore | fzf --no-multi -0) && cd "${dir}"
}
cdr
function cdr() { # cdd - [c][d] to selected [r]epo directory
local repodir
repodir="$(git rev-parse --show-toplevel)"
# shellcheck disable=SC2164
dir=$( ( echo './'; fd . "${repodir}" --type d --hidden --ignore-file ~/.fdignore |
xargs -I{} bash -c "echo {} | sed \"s|${repodir}/||g\""
) | fzf --no-multi -0
) && cd "${repodir}/${dir}"
}
function cd() {
if [[ "$#" != 0 ]]; then
# shellcheck disable=SC2164
builtin cd "$@";
return
fi
while true; do
# shellcheck disable=SC2155,SC2010
local lsd=$(echo ".." && ls -A --color=none -p | grep --color=none '/$' | sed 's;/$;;')
# shellcheck disable=SC2155,SC2016
local dir="$(printf '%s\n' "${lsd[@]}" |
fzf --reverse --preview '
__cd_nxt="$(echo {})";
__cd_path="$(echo $(pwd)/${__cd_nxt} | sed "s;//;/;")";
echo $__cd_path;
echo;
ls -p --color=always "${__cd_path}";
')"
[[ ${#dir} != 0 ]] || return 0
# shellcheck disable=SC2164
builtin cd "$dir" &> /dev/null
done
}
fd
[!DANGER]conflict with fd-find
# fd - cd to selected directory
fd() {
local dir
dir=$(find ${1:-.} -path '*/\.*' -prune \
-o -type d -print 2> /dev/null | fzf +m) &&
cd "$dir"
}
# Another fd - cd into the selected directory
# This one differs from the above, by only showing the sub directories and not
# showing the directories within those.
fd() {
DIR=$(find * -maxdepth 0 -type d -print 2> /dev/null | fzf-tmux) && cd "$DIR"
}
fda
# fda - including hidden directories
fda() {
local dir
dir=$(find ${1:-.} -type d 2> /dev/null | fzf +m) && cd "$dir"
}
# activate venv - using `fzf` to list and activate python venv
# @author : marslo
# @inspired : https://seb.jambor.dev/posts/improving-shell-workflows-with-fzf/#virtual-env
# @source : https://github.com/marslo/dotfiles/blob/main/.marslo/bin/ffunc.sh
function avenv() {
# shellcheck disable=SC2155
local _venv=$(command ls --color=never "$HOME/.venv" | fzf)
[[ -n "${_venv}" ]] &&
source "$HOME/.venv/${_venv}/bin/activate" &&
echo -e "$(c Wd)>>$(c) $(c Gis)${_venv}$(c) $(c Wdi)has been activated ..$(c)"
}
# https://github.com/junegunn/fzf/wiki/Examples#bookmarks
# shellcheck disable=SC2016
function b() { # chrome [b]ookmarks browser with jq
if [ "$(uname)" = "Darwin" ]; then
if [[ -e "$HOME/Library/Application Support/Google/Chrome Canary/Default/Bookmarks" ]]; then
bookmarks_path="$HOME/Library/Application Support/Google/Chrome Canary/Default/Bookmarks"
else
bookmarks_path="$HOME/Library/Application Support/Google/Chrome/Default/Bookmarks"
fi
open=open
else
bookmarks_path="$HOME/.config/google-chrome/Default/Bookmarks"
open=xdg-open
fi
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'
urls=$( jq -r "${jq_script}" < "${bookmarks_path}" \
| sed -E $'s/(.*)\t(.*)/\\1\t\x1b[36m\\2\x1b[m/g' \
| fzf --ansi \
| cut -d$'\t' -f2
)
# shellcheck disable=SC2046
[[ -z "${urls}" ]] || "${open}" $(echo "${urls}" | xargs)
}
[!NOTE]
# fman - fzf list and preview for manpage:
# @source : https://github.com/junegunn/fzf/wiki/examples#fzf-man-pages-widget-for-zsh
# @description :
# - CTRL-N/CTRL-P or SHIFT-↑/↓ for view preview content
# - ENTER/Q for toggle maximize/normal preview window
# - CTRL+O for toggle tldr in preview window
# - CTRL+I for toggle man in preview window
# - to respect fzf options by: `type -t _fzf_opts_completion >/dev/null 2>&1 && complete -F _fzf_opts_completion -o bashdefault -o default fman`
# shellcheck disable=SC2046
function fman() {
unset MANPATH
local option
local batman="man {1} | col -bx | bat --language=man --plain --color always --theme='gruvbox-dark'"
while [[ $# -gt 0 ]]; do
case "$1" in
-* ) option+="$1 $2 "; shift 2 ;;
* ) break ;;
esac
done
man -k . |
sort -u |
sed -r 's/(\(.+\))//g' |
grep -v -E '::' |
awk -v cyan=$(tput setaf 6) -v blue=$(tput setaf 4) -v res=$(tput sgr0) -v bld=$(tput bold) '{ $1=cyan bld $1; $2=res blue $2;} 1' |
fzf ${option:-} \
-d ' ' \
--nth 1 \
--height 100% \
--ansi \
--no-multi \
--tiebreak=begin \
--prompt='ᓆ > ' \
--color='prompt:#0099BD' \
--preview-window 'up,70%,wrap,rounded,<50(up,85%,border-bottom)' \
--preview "${batman}" \
--bind 'ctrl-p:preview-up,ctrl-n:preview-down' \
--bind "ctrl-o:+change-preview(tldr --color {1})+change-prompt(ﳁ tldr > )" \
--bind "ctrl-i:+change-preview(${batman})+change-prompt(ᓆ man > )" \
--bind "enter:execute(${batman})+change-preview(${batman})+change-prompt(ᓆ > )" \
--header 'CTRL-N/P or SHIFT-↑/↓ to view preview contents; ENTER/Q to maximize/normal preview window' \
--exit-0
}
simple version
$ apropos . |
fzf -d ') ' --nth 1 \
--height 100% \
--bind 'ctrl-p:preview-up,ctrl-n:preview-down' \
--header 'CTRL-N/CTRL-P or CTRL-↑/CTRL-↓ to view contents' \
--preview-window=up:88%:wrap \
--preview 'echo {} | sed -r "s/([^\(]+).*$/\1/" | xargs man' \
--exit-0 |
sed -r "s/([^\(]+).*$/\1/" |
xargs man
[!TIP]
[alias]
### checkout sorted [b]ranch
bb = "! bash -c 'branch=$(git for-each-ref refs/remotes refs/heads --sort=-committerdate --format=\"%(refname:short)\" | \n\
grep --color=never -v \"origin$\" | \n\
fzf +m --prompt=\"branch> \" | \n\
sed -rn \"s:\\s*(origin/)?(.*)$:\\2:p\") && \n\
[[ -n \"${branch}\" ]] && \n\
echo -e \"\\033[1;33m~~> ${branch}\\033[0m\" && \n\
git checkout \"${branch}\"; \n\
'"
### [b]ranch [copy]
bcopy = "! bash -c 'branch=$(git for-each-ref refs/remotes refs/heads --sort=-committerdate --format=\"%(refname:short)\" | \n\
grep --color=never -v \"origin$\" | \n\
fzf +m --prompt=\"branch> \" | \n\
sed -rn \"s:\\s*(origin/)?(.*)$:\\2:p\") && \n\
[[ -n \"${branch}\" ]] && \n\
echo -e \"\\033[0;33;1m~~> branch \\033[0m\\033[0;32;3m${branch}\\033[0m \\033[0;33;1mcopied\\033[0m\" && \n\
pbcopy <<< \"${branch}\" \n\
'"
export
# mkexp - compilation environment variable export, support multiple select
# @author : marslo
# @source : https://github.com/marslo/mylinux/blob/master/confs/home/.marslo/bin/ffunc.sh
# @description : list compilation environment variable via `fzf`, and export selected items
# - if paramter is [ -f | --full ], then load full tool paths
# shellcheck disable=SC1090
function mkexp() { # [m]a[k]e environment variable [e][x][p]ort
if [[ 1 -eq $# ]] && [[ '-f' = "$1" || '--full' = "$1" ]]; then
source ~/.marslo/.imac
fi
LDFLAGS="${LDFLAGS:-}"
test -d "${HOMEBREW_PREFIX}" && LDFLAGS+=" -L${HOMEBREW_PREFIX}/lib"
test -d '/usr/local/opt/readline' && LDFLAGS+=' -L/usr/local/opt/readline/lib'
test -d "${OPENLDAP_HOME}" && LDFLAGS+=" -L${OPENLDAP_HOME}/lib"
test -d "${CURL_OPENSSL_HOME}" && LDFLAGS+=" -L${CURL_OPENSSL_HOME}/lib"
test -d "${BINUTILS}" && LDFLAGS+=" -L${BINUTILS}/lib"
test -d "${PYTHON_HOME}" && LDFLAGS+=" -L${PYTHON_HOME}/lib"
test -d "${RUBY_HOME}" && LDFLAGS+=" -L${RUBY_HOME}/lib"
test -d "${TCLTK_HOME}" && LDFLAGS+=" -L${TCLTK_HOME}/lib"
test -d "${SQLITE_HOME}" && LDFLAGS+=" -L${SQLITE_HOME}/lib"
test -d "${OPENSSL_HOME}" && LDFLAGS+=" -L${OPENSSL_HOME}/lib"
test -d "${NODE_HOME}" && LDFLAGS+=" -L${NODE_HOME}/lib" # ${NODE_HOME}/libexec/lib for node@12
test -d "${LIBRESSL_HOME}" && LDFLAGS+=" -L${LIBRESSL_HOME}/lib"
test -d "${ICU4C_711}" && LDFLAGS+=" -L${ICU4C_711}/lib"
test -d "${EXPAT_HOME}" && LDFLAGS+=" -L${EXPAT_HOME}/lib"
test -d "${NCURSES_HOME}" && LDFLAGS+=" -L${NCURSES_HOME}/lib"
test -d "${LIBICONV_HOME}" && LDFLAGS+=" -L${LIBICONV_HOME}/lib"
test -d "${ZLIB_HOME}" && LDFLAGS+=" -L${ZLIB_HOME}/lib"
test -d "${LLVM_HOME}" && LDFLAGS+=" -L${LLVM_HOME}/lib"
test -d "${LLVM_HOME}" && LDFLAGS+=" -L${LLVM_HOME}/lib/c++ -Wl,-rpath,${LLVM_HOME}/lib/c++" # for c++
LDFLAGS=$( echo "$LDFLAGS" | tr ' ' '\n' | uniq | sed '/^$/d' | paste -s -d' ' )
CFLAGS="${CFLAGS:-}"
CFLAGS+=" -I/usr/local/include"
test -d "${TCLTK_HOME}" && CFLAGS+=" -I${TCLTK_HOME}/include"
CFLAGS=$( echo "$CFLAGS" | tr ' ' '\n' | uniq | sed '/^$/d' | paste -s -d' ' )
CPPFLAGS="${CPPFLAGS:-}"
test -d "${HOMEBREW_PREFIX}" && CPPFLAGS+=" -I${HOMEBREW_PREFIX}/include"
test -d "${JAVA_HOME}" && CPPFLAGS+=" -I${JAVA_HOME}/include"
test -d "${OPENLDAP_HOME}" && CPPFLAGS+=" -I${OPENLDAP_HOME}/include"
test -d "${CURL_OPENSSL_HOME}" && CPPFLAGS+=" -I${CURL_OPENSSL_HOME}/include"
test -d "${BINUTILS}" && CPPFLAGS+=" -I${BINUTILS}/include"
test -d "${SQLITE_HOME}" && CPPFLAGS+=" -I${SQLITE_HOME}/include"
test -d '/usr/local/opt/readline' && CPPFLAGS+=' -I/usr/local/opt/readline/include'
test -d "${OPENSSL_HOME}" && CPPFLAGS+=" -I${OPENSSL_HOME}/include"
test -d "${NODE_HOME}" && CPPFLAGS+=" -I${NODE_HOME}/include"
test -d "${LIBRESSL_HOME}" && CPPFLAGS+=" -I${LIBRESSL_HOME}/include"
test -d "${TCLTK_HOME}" && CPPFLAGS+=" -I${TCLTK_HOME}/include"
test -d "${RUBY_HOME}" && CPPFLAGS+=" -I${RUBY_HOME}/include"
test -d "${ICU4C_711}" && CPPFLAGS+=" -I${ICU4C_711}/include"
test -d "${LLVM_HOME}" && CPPFLAGS+=" -I${LLVM_HOME}/include"
test -d "${LIBICONV_HOME}" && CPPFLAGS+=" -I${LIBICONV_HOME}/include"
test -d "${EXPAT_HOME}" && CPPFLAGS+=" -I${EXPAT_HOME}/include"
test -d "${NCURSES_HOME}" && CPPFLAGS+=" -I${NCURSES_HOME}/include"
test -d "${ZLIB_HOME}" && CPPFLAGS+=" -I${ZLIB_HOME}/include"
CPPFLAGS=$( echo "$CPPFLAGS" | tr ' ' '\n' | uniq | sed '/^$/d' | paste -s -d' ' )
PKG_CONFIG_PATH=${PKG_CONFIG_PATH:-}
PKG_CONFIG_PATH+=":${HOMEBREW_PREFIX}/lib/pkgconfig"
test -d "${CURL_OPENSSL_HOME}" && PKG_CONFIG_PATH+=":${CURL_OPENSSL_HOME}/lib/pkgconfig"
test -d "${TCLTK_HOME}" && PKG_CONFIG_PATH+=":${TCLTK_HOME}/lib/pkgconfig"
command -v brew >/dev/null 2>&1 && PKG_CONFIG_PATH+=':/usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig/14'
test -d "${SQLITE_HOME}" && PKG_CONFIG_PATH+=":${SQLITE_HOME}/lib/pkgconfig"
test -d "${OPENSSL_HOME}" && PKG_CONFIG_PATH+=":${OPENSSL_HOME}/lib/pkgconfig"
test -d "${PYTHON_HOME}" && PKG_CONFIG_PATH+=":${PYTHON_HOME}/lib/pkgconfig"
test -d "${RUBY_HOME}" && PKG_CONFIG_PATH+=":${RUBY_HOME}/lib/pkgconfig"
test -d "${LIBRESSL_HOME}" && PKG_CONFIG_PATH+=":${LIBRESSL_HOME}/lib/pkgconfig"
test -d "${ICU4C_711}" && PKG_CONFIG_PATH+=":${ICU4C_711}/lib/pkgconfig"
test -d "${EXPAT_HOME}" && PKG_CONFIG_PATH+=":${EXPAT_HOME}/lib/pkgconfig"
test -d "${NCURSES_HOME}" && PKG_CONFIG_PATH+=":${NCURSES_HOME}/lib/pkgconfig"
test -d "${ZLIB_HOME}" && PKG_CONFIG_PATH+=":${ZLIB_HOME}/lib/pkgconfig"
PKG_CONFIG_PATH=$( echo "$PKG_CONFIG_PATH" | tr ':' '\n' | uniq | sed '/^$/d' | paste -s -d: )
LIBRARY_PATH="${HOMEBREW_PREFIX}/lib"
test -d "${LIBICONV_HOME}" && LIBRARY_PATH+=":${LIBICONV_HOME}/lib"
LIBRARY_PATH=$( echo "$LIBRARY_PATH" | tr ':' '\n' | uniq | sed '/^$/d' | paste -s -d: )
LD_LIBRARY_PATH=/usr/local/lib
LD_LIBRARY_PATH=$( echo "$LD_LIBRARY_PATH" | tr ':' '\n' | uniq | sed '/^$/d' | paste -s -d: )
while read -r _env; do
export "${_env?}"
echo -e "$(c Ys)>> ${_env}$(c)\n$(c Wi).. $(eval echo \$${_env})$(c)"
done < <( echo 'LDFLAGS CFLAGS CPPFLAGS PKG_CONFIG_PATH LIBRARY_PATH LD_LIBRARY_PATH' |
fmt -1 |
fzf -1 --exit-0 \
--no-sort \
--multi \
--cycle \
--prompt 'env> ' \
--header 'TAB/SHIFT-TAB to select multiple items, CTRL-D to deselect-all, CTRL-S to select-all'
)
}
unset
alternative:
$ unset ,,<TAB> # by deafult $ unset **<TAB>
# eclr - environment variable clear, support multiple select
# @author : marslo
# @source : https://github.com/marslo/mylinux/blob/master/confs/home/.marslo/bin/ffunc.sh
# @description : list all environment varialbe via `fzf`, and unset for selected items
function eclr() { # [e]nvironment variable [c][l]ea[r]
while read -r _env; do
echo -e "$(c Ys)>> unset ${_env}$(c)\n$(c Wdi).. $(eval echo \$${_env})$(c)"
unset "${_env}"
done < <( env |
sed -rn 's/^([a-zA-Z0-9]+)=.*$/\1/p' |
fzf -1 --exit-0 --no-sort --multi --prompt='env> ' --header 'TAB to select multiple items'
)
}
or unset limited to environment list
# mkclr - compilation environment variable clear, support multiple select
# @author : marslo
# @source : https://github.com/marslo/mylinux/blob/master/confs/home/.marslo/bin/ffunc.sh
# @description : list compilation environment variable via `fzf`, and unset for selected items
function mkclr() { # [m]a[k]e environment variable [c][l]ea[r]
while read -r _env; do
echo -e "$(c Ys)>> unset ${_env}$(c)\n$(c Wdi).. $(eval echo \$${_env})$(c)"
unset "${_env}"
done < <( echo 'LDFLAGS CFLAGS CPPFLAGS PKG_CONFIG_PATH LIBRARY_PATH LD_LIBRARY_PATH' |
fmt -1 |
fzf -1 --exit-0 \
--no-sort \
--multi \
--cycle \
--prompt 'env> ' \
--header 'TAB/SHIFT-TAB to select multiple items, CTRL-D to deselect-all, CTRL-S to select-all'
)
# echo -e "\n$(c Wdi)[TIP]>> to list all env via $(c)$(c Wdiu)\$ env | sed -rn 's/^([a-zA-Z0-9]+)=.*$/\1/p'$(c)"
}
print and copy
[!NOTE|label:references:]
environ – user environment
: (man environ
)
# penv - print environment variable, support multiple select
# @author : marslo
# @source : https://github.com/marslo/mylinux/blob/master/confs/home/.marslo/bin/ffunc.sh
# @description : list all environment variable via `fzf`, and print values for selected items
# - to copy via `-c`
# - "${COPY}"
# - `pbcopy` in osx
# - `/mnt/c/Windows/System32/clip.exe` in wsl
# - to respect fzf options via `type -t _fzf_opts_completion >/dev/null 2>&1 && complete -F _fzf_opts_completion -o bashdefault -o default penv`
# - more options: https://github.com/junegunn/fzf/issues/3599#issuecomment-1907233847
# shellcheck disable=SC2215,SC2016
function penv() { # [p]rint [env]ironment variable
local option
local -a array
while [[ $# -gt 0 ]]; do
case "$1" in
-c ) option+="$1 " ; shift ;;
-* ) option+="$1 $2 "; shift 2 ;;
* ) break ;;
esac
done
option+='-1 --exit-0 --sort --multi --cycle'
_echo_values() { echo -e "$(c Ys)>> $1$(c)\n$(c Wi).. $(eval echo \$$1)$(c)"; }
while read -r _env; do
_echo_values $_env
array+=( "${_env}=$(eval echo \$${_env})" )
done < <( env |
sed -r 's/^([a-zA-Z0-9_-]+)=.*$/\1/' |
fzf ${option//-c\ /} \
--prompt 'env> ' \
--height '50%' \
--preview-window 'top,30%,wrap,rounded' \
--preview='source ~/.marslo/bin/bash-color.sh; _env={}; echo -e "$(c Gs)${_env}=${!_env}$(c)"' \
--header 'TAB/SHIFT-TAB to select multiple items, CTRL-D to deselect-all, CTRL-S to select-all'
)
[[ "${option}" == *-c\ * ]] && [[ -n "${COPY}" ]] && "${COPY}" < <( printf '%s\n' "${array[@]}" | head -c-1 )
}
[!NOTE]
$ (date; ps -ef) |
fzf --bind='ctrl-r:reload(date; ps -ef)' \
--header=$'Press CTRL-R to reload\n\n' --header-lines=2 \
--preview='echo {}' --preview-window=down,3,wrap \
--layout=reverse --height=80% |
awk '{print $2}'
# or kill
$ (date; ps -ef) |
fzf --bind='ctrl-r:reload(date; ps -ef)' \
--header=$'Press CTRL-R to reload\n\n' --header-lines=2 \
--preview='echo {}' --preview-window=down,3,wrap \
--layout=reverse --height=80% |
awk '{print $2}' |
xargs kill -9
functions
function lsps() { # [l]i[s]t [p]roces[s]
(date; ps -ef) |
fzf --bind='ctrl-r:reload(date; ps -ef)' \
--header=$'Press CTRL-R to reload\n\n' --header-lines=2 \
--preview='echo {}' --preview-window=down,3,wrap \
--layout=reverse --height=80% |
awk '{print $2}'
}
function killps() { # [kill] [p]roces[s]
(date; ps -ef) |
fzf --bind='ctrl-r:reload(date; ps -ef)' \
--header=$'Press CTRL-R to reload\n\n' --header-lines=2 \
--preview='echo {}' --preview-window=down,3,wrap \
--layout=reverse --height=80% |
awk '{print $2}' |
xargs kill -9
}
kns
# kns - kubectl set default namesapce
# @author : marslo
# @source : https://github.com/marslo/mylinux/blob/master/confs/home/.marslo/bin/ffunc.sh
# @description : using `fzf` to list all available namespaces and use the selected namespace as default
# [k]ubectl [n]ame[s]pace
function kns() { # [k]ubectl [n]ame[s]pace
local krn=$(kubecolor config get-contexts --no-headers $(kubectl config current-context) | awk "{print \$5}" | sed "s/^$/default/")
kubectl get -o name namespace |
sed "s|^.*/| |;\|^ $(krn)$|s/ /*/" |
fzf -e |
sed "s/^..//" |
xargs -i bash -c "echo -e \"\033[1;33m~~> {}\\033[0m\";
kubecolor config set-context --current --namespace {};
kubecolor config get-contexts;
"
}
# or limited with `kubectl get namespace`
function kns() {
echo 'namepsace-1 namespace-2 namespace-3 ...' |
fmt -1 |
fzf -1 -0 --no-sort +m --prompt='namespace> ' |
xargs -i bash -c "echo -e \"\033[1;33m~~> {}\\033[0m\";
kubectl config set-context --current --namespace {};
kubecolor config get-contexts;
"
}
kcani
# kcani - kubectl check permission (auth can-i)
# @author : marslo
# @source : https://github.com/marslo/mylinux/blob/master/confs/home/.marslo/bin/ffunc.sh
# @description : check whether an action is allowed in given namespaces. support multiple selection
# [k]ubectl [can]-[i]
function kcani() { # [k]ubectl [can]-[i]
local namespaces=''
local actions='list get watch create update delete'
local components='sts deploy secrets configmap ingressroute ingressroutetcp'
namespaces=$( echo 'namepsace-1 namespace-2 namespace-3 ...' |
fmt -1 |
fzf -1 -0 --no-sort --prompt='namespace> ' \
--bind 'ctrl-y:execute-silent(echo -n {+} | pbcopy)+abort' \
--header 'Press CTRL-Y to copy name into clipboard'
)
[[ -z "${namespaces}" ]] && echo "$(c Rs)ERROR: select at least one namespace !$(c)" && return
while read -r namespace; do
echo -e "\n>> $(c Ys)${namespace}$(c)"
k-p-cani ${namespace} # for pods component
for _c in ${components}; do
local res=''
echo -e ".. $(c Ms)${_c}$(c) :"
for _a in ${actions}; do
r=$(_can_i -n "${namespace}" "${_a}" "${_c}")
res+="${r} ";
done; # in actions
echo -e "${actions}\n${res}" | "${COLUMN}" -t | sed 's/^/\t/g'
done; # in components
done< <(echo "${namespaces}" | fmt -1)
}
# _can_i - kubectl check permission (auth can-i) for pods component
# @author : marslo
# @source : https://github.com/marslo/mylinux/blob/master/confs/home/.marslo/bin/ifunc.sh
# @description : check whether given action is allowed in given namespaces; if namespace not provide, using default namespace
function _can_i() {
local namespace
namespace=$(command kubectl config view --minify -o jsonpath='{..namespace}')
while [[ $# -gt 0 ]]; do
case "$1" in
-n | --namespace ) namespace="$2" ; shift 2 ;;
* ) break ;;
esac
done
[[ 0 = "$#" ]] && echo -e "$(c Rs)>> ERROR: must provide action to check with$(c)\n\nUSAGE$(c Gis)\n\t\$ $0 list pod\n\t\$ $0 -n <namespace> create deploy$(c)" && return
checker=$*
r="$(kubectl auth can-i ${checker} -n ${namespace})";
[[ 'yes' = "${r}" ]] && r="$(c Gs)${r}$(c)" || r="$(c Rs)${r}$(c)";
echo -e "${r}";
}
# k-p-cani - kubectl check permission (auth can-i) for pods component
# @author : marslo
# @source : https://github.com/marslo/mylinux/blob/master/confs/home/.marslo/bin/ifunc.sh
# @description : check whether certain action is allowed in given namespaces
# [k]ubectl [can]-[i]
function k-p-cani() {
local components='pods'
declare -A pactions
pactions=(
['0_get']="get ${components}"
['1_get/exec']="get ${components}/exec"
['2_get/sub/exec']="get ${components} --subresource=exec"
['2_get/sub/log']="get ${components} --subresource=log"
['3_list']="list ${components}"
['4_create']="create ${components}"
['5_create/exec']="create ${components}/exec"
['6_get/sub/exec']="get ${components} --subresource=exec"
)
while read -r pnamespace; do
local headers=''
local pres=''
while read -r _a; do
headers+="$(sed -rn 's/^[0-9]+_(.+)$/\1/p' <<< ${_a}) "
r=$(_can_i -n "${pnamespace}" "${pactions[${_a}]}")
pres+="${r} "
done < <( for _act in "${!pactions[@]}"; do echo "${_act}"; done | sort -h )
echo -e ".. $(c Ms)pods$(c) :"
echo -e "${headers}\n${pres}" | "${COLUMN}" -t | sed 's/^/\t/g'
done< <(echo "$*" | fmt -1)
}
pods() {
: | command='kubectl get pods --all-namespaces' fzf \
--info=inline --layout=reverse --header-lines=1 \
--prompt "$(kubectl config current-context | sed 's/-context$//')> " \
--header $'╱ Enter (kubectl exec) ╱ CTRL-O (open log in editor) ╱ CTRL-R (reload) ╱\n\n' \
--bind 'start:reload:$command' \
--bind 'ctrl-r:reload:$command' \
--bind 'ctrl-/:change-preview-window(80%,border-bottom|hidden|)' \
--bind 'enter:execute:kubectl exec -it --namespace {1} {2} -- bash > /dev/tty' \
--bind 'ctrl-o:execute:${EDITOR:-vim} <(kubectl logs --all-containers --namespace {1} {2}) > /dev/tty' \
--preview-window up:follow \
--preview 'kubectl logs --follow --all-containers --tail=10000 --namespace {1} {2}' "$@"
}
bip
# Install (one or multiple) selected application(s)
# using "brew search" as source input
# mnemonic [B]rew [I]nstall [P]ackage
bip() {
local inst=$(brew search "$@" | fzf -m)
if [[ $inst ]]; then
for prog in $(echo $inst);
do; brew install $prog; done;
fi
}
bup
# Update (one or multiple) selected application(s)
# mnemonic [B]rew [U]pdate [P]ackage
bup() {
local upd=$(brew leaves | fzf -m)
if [[ $upd ]]; then
for prog in $(echo $upd);
do; brew upgrade $prog; done;
fi
}
FZF_CTRL_R_OPTS="--preview 'echo {}'"
FZF_CTRL_R_OPTS+=" --preview-window up:3:hidden:wrap"
FZF_CTRL_R_OPTS+=" --bind 'ctrl-/:toggle-preview'"
FZF_CTRL_R_OPTS+=" --bind 'ctrl-y:execute-silent(echo -n {2..} | pbcopy)+abort'"
FZF_CTRL_R_OPTS+=" --color header:italic"
FZF_CTRL_R_OPTS+=" --header 'Press CTRL-Y to copy command into clipboard'"
export FZF_CTRL_R_OPTS
# or
export FZF_CTRL_R_OPTS="
--preview 'echo {}' --preview-window up:3:hidden:wrap
--bind 'ctrl-/:toggle-preview'
--bind 'ctrl-y:execute-silent(echo -n {2..} | pbcopy)+abort'
--color header:italic
--header 'Press CTRL-Y to copy command into clipboard'"
__fzf_history__
$ type __fzf_history__
__fzf_history__ is a function
__fzf_history__ ()
{
local output opts script;
opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore ${FZF_DEFAULT_OPTS-} -n2..,.. --scheme=history --bind=ctrl-r:toggle-sort ${FZF_CTRL_R_OPTS-} +m --read0";
script='BEGIN { getc; $/ = "\n\t"; $HISTCOUNT = $ENV{last_hist} + 1 } s/^[ *]//; print $HISTCOUNT - $. . "\t$_" if !$seen{$_}++';
output=$(set +o pipefail
builtin fc -lnr -2147483648 | last_hist=$(HISTTIMEFORMAT='' builtin history 1) command perl -n -l0 -e "$script" | FZF_DEFAULT_OPTS="$opts" $(__fzfcmd) --query "$READLINE_LINE") || return;
READLINE_LINE=${output#*' '};
if [[ -z "$READLINE_POINT" ]]; then
echo "$READLINE_LINE";
else
READLINE_POINT=0x7fffffff;
fi
}
$ fcf __fzf_history__
/usr/local/Cellar/fzf/0.42.0/shell/key-bindings.bash
[!NOTE|label:references:]
to disable/reset osx default ⌃+↑ and ⌃+↓
# preview file content using bat (https://github.com/sharkdp/bat)
FZF_CTRL_T_OPTS="--preview 'bat -n --color=always {}'"
FZF_CTRL_T_OPTS+=" --bind 'ctrl-/:change-preview-window(down|hidden|)'"
FZF_CTRL_T_OPTS+=" --bind 'ctrl-p:preview-up,ctrl-n:preview-down'"
FZF_CTRL_T_OPTS+=" --header 'CTRL-N/CTRL-P or CTRL-↑/CTRL-↓ to view contents'"
export FZF_CTRL_T_OPTS
# or
export FZF_CTRL_T_OPTS="
--preview 'bat -n --color=always {}'
--bind 'ctrl-p:preview-up,ctrl-n:preview-down'
--bind 'ctrl-/:change-preview-window(down|hidden|)'"
__fzf_select__
$ type __fzf_select__
__fzf_select__ is a function
__fzf_select__ ()
{
local cmd opts;
cmd="${FZF_CTRL_T_COMMAND:-"command find -L . -mindepth 1 \\( -path '*/.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \\) -prune -o -type f -print -o -type d -print -o -type l -print 2> /dev/null | command cut -b3-"}";
opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore --reverse --scheme=path ${FZF_DEFAULT_OPTS-} ${FZF_CTRL_T_OPTS-} -m";
eval "$cmd" | FZF_DEFAULT_OPTS="$opts" $(__fzfcmd) "$@" | while read -r item; do
printf '%q ' "$item";
done
}
$ fcf __fzf_select__
__fzf_select__ 19 /Users/marslo/.marslo/utils/fzf/shell/key-bindings.bas
$ mdfind key-bindings.bas
/Users/marslo/iMarslo/tools/git/marslo/mbook/docs/devops/adminTools.md
/usr/local/Cellar/fzf/0.42.0/shell/key-bindings.bash
# another ctrl-t script to select a directory and paste it into line
__fzf_select_dir () {
builtin typeset READLINE_LINE_NEW="$(
command find -L . \( -path '*/\.*' -o -fstype dev -o -fstype proc \) \
-prune \
-o -type f -print \
-o -type d -print \
-o -type l -print 2>/dev/null \
| command sed 1d \
| command cut -b3- \
| env fzf -m
)"
if [[ -n $READLINE_LINE_NEW ]]; then
builtin bind '"\er": redraw-current-line'
builtin bind '"\e^": magic-space'
READLINE_LINE=${READLINE_LINE:+${READLINE_LINE:0:READLINE_POINT}}${READLINE_LINE_NEW}${READLINE_LINE:+${READLINE_LINE:READLINE_POINT}}
READLINE_POINT=$(( READLINE_POINT + ${#READLINE_LINE_NEW} ))
else
builtin bind '"\er":'
builtin bind '"\e^":'
fi
}
builtin bind -x '"\C-x1": __fzf_select_dir'
builtin bind '"\C-t": "\C-x1\e^\er"'
# junegunn/seoul256.vim (dark)
export FZF_DEFAULT_OPTS='--color=bg+:#3F3F3F,bg:#4B4B4B,border:#6B6B6B,spinner:#98BC99,hl:#719872,fg:#D9D9D9,header:#719872,info:#BDBB72,pointer:#E12672,marker:#E17899,fg+:#D9D9D9,preview-bg:#3F3F3F,prompt:#98BEDE,hl+:#98BC99'
# junegunn/seoul256.vim (light)
export FZF_DEFAULT_OPTS='--color=bg+:#D9D9D9,bg:#E1E1E1,border:#C8C8C8,spinner:#719899,hl:#719872,fg:#616161,header:#719872,info:#727100,pointer:#E12672,marker:#E17899,fg+:#616161,preview-bg:#D9D9D9,prompt:#0099BD,hl+:#719899'
# morhetz/gruvbox
export FZF_DEFAULT_OPTS='--color=bg+:#3c3836,bg:#32302f,spinner:#fb4934,hl:#928374,fg:#ebdbb2,header:#928374,info:#8ec07c,pointer:#fb4934,marker:#fb4934,fg+:#ebdbb2,prompt:#fb4934,hl+:#fb4934'
# arcticicestudio/nord-vim
export FZF_DEFAULT_OPTS='--color=bg+:#3B4252,bg:#2E3440,spinner:#81A1C1,hl:#616E88,fg:#D8DEE9,header:#616E88,info:#81A1C1,pointer:#81A1C1,marker:#81A1C1,fg+:#D8DEE9,prompt:#81A1C1,hl+:#81A1C1'
# tomasr/molokai
export FZF_DEFAULT_OPTS='--color=bg+:#293739,bg:#1B1D1E,border:#808080,spinner:#E6DB74,hl:#7E8E91,fg:#F8F8F2,header:#7E8E91,info:#A6E22E,pointer:#A6E22E,marker:#F92672,fg+:#F8F8F2,prompt:#F92672,hl+:#F92672'
let g:fzf_colors =
\ { 'fg': ['fg', 'Normal'],
\ 'bg': ['bg', 'Normal'],
\ 'preview-bg': ['bg', 'NormalFloat'],
\ 'hl': ['fg', 'Comment'],
\ 'fg+': ['fg', 'CursorLine', 'CursorColumn', 'Normal'],
\ 'bg+': ['bg', 'CursorLine', 'CursorColumn'],
\ 'hl+': ['fg', 'Statement'],
\ 'info': ['fg', 'PreProc'],
\ 'border': ['fg', 'Ignore'],
\ 'prompt': ['fg', 'Conditional'],
\ 'pointer': ['fg', 'Exception'],
\ 'marker': ['fg', 'Keyword'],
\ 'spinner': ['fg', 'Label'],
\ 'header': ['fg', 'Comment'] }
:echo fzf#wrap()
:call append('$', printf('export FZF_DEFAULT_OPTS="%s"', matchstr(fzf#wrap().options, "--color[^']*")))
move cursor to position
[!TIP]
$ seq 100 | fzf --sync --bind 'start:pos(N)'
select by column
[!NOTE]
$ seq 20 | pr -ts' ' --column 4
1 6 11 16
2 7 12 17
3 8 13 18
4 9 14 19
5 10 15 20
$ seq 20 | pr -ts' ' --column 4 | fzf --sync --bind 'start:select-all+become:cat {+f2}'
6
7
8
9
10
$ seq 20 | pr -ts' ' --column 4 | fzf --sync --bind 'start:select-all+become:echo {+2}'
6 7 8 9 10
--with-nth
[!NOTE]
$ echo {a..z} | fzf --with-nth='1..3'
# https://github.com/junegunn/fzf/issues/1323#issuecomment-499615418
# for git comment show
$ git log --pretty=oneline |
fzf --ansi --delimiter=' ' --no-multi --preview='git show --color=always {1}' --with-nth=2.. |
cut --delimiter=' ' --field=1
$ echo -e 'first line\tfirst preview\nsecond line\tsecond preview' |
fzf --delimiter='\t' --with-nth=1 --preview='echo {2}'
--track
$ git log --oneline --graph --color=always |
nl |
fzf --ansi --track --no-sort --layout=reverse-list
select-all
$ seq 3 | fzf --multi --sync --bind start:last+select-all
select-n
[!TIP]
# select top 2 and move down
$ seq 10 | fzf --multi --sync --reverse --bind start:select+down+select+down
# select top 2
$ seq 10 | fzf --multi --sync --reverse --bind start:select+down+select
for git
[!NOTE]
# cannot be used to grab a sha as an argument.
fshow() {
git log --color=always \
--format="%C(auto)%h%d %s %C(black)%C(bold)%cr" "$@" |
fzf --ansi --no-sort --reverse --tiebreak=index --bind=ctrl-s:toggle-sort \
--bind "ctrl-o:execute(git show --color=always {1})"
}
$ git log --pretty=oneline \
| fzf --ansi --delimiter=' ' --no-multi --preview='git show --color=always {1}' --with-nth=2.. \
| cut --delimiter=' ' --field=1
# or
$ git log --pretty=oneline --all \
| fzf --ansi --no-multi --preview='git show --color=always {1}' --with-nth=2.. \
| awk '{print $1}'
[!NOTE]
function pr-checkout() {
local jq_template pr_number
jq_template='"'\
'#\(.number) - \(.title)'\
'\t'\
'Author: \(.user.login)\n'\
'Created: \(.created_at)\n'\
'Updated: \(.updated_at)\n\n'\
'\(.body)'\
'"'
pr_number=$(
gh api 'repos/:owner/:repo/pulls' |
jq ".[] | $jq_template" |
sed -e 's/"\(.*\)"/\1/' -e 's/\\t/\t/' |
fzf \
--with-nth=1 \
--delimiter='\t' \
--preview='echo -e {2}' \
--preview-window=top:wrap |
sed 's/^#\([0-9]\+\).*/\1/'
)
if [ -n "$pr_number" ]; then
gh pr checkout "$pr_number"
fi
}
function create-branch() {
# The function expectes that username and password are stored using secret-tool.
# To store these, use
# secret-tool store --label="JIRA username" jira username
# secret-tool store --label="JIRA password" jira password
local jq_template query username password branch_name
jq_template='"'\
'\(.key). \(.fields.summary)'\
'\t'\
'Reporter: \(.fields.reporter.displayName)\n'\
'Created: \(.fields.created)\n'\
'Updated: \(.fields.updated)\n\n'\
'\(.fields.description)'\
'"'
query='project=BLOG AND status="In Progress" AND assignee=currentUser()'
username=$(secret-tool lookup jira username)
password=$(secret-tool lookup jira password)
branch_name=$(
curl \
--data-urlencode "jql=$query" \
--get \
--user "$username:$password" \
--silent \
--compressed \
'https://jira.example.com/rest/api/2/search' |
jq ".issues[] | $jq_template" |
sed -e 's/"\(.*\)"/\1/' -e 's/\\t/\t/' |
fzf \
--with-nth=1 \
--delimiter='\t' \
--preview='echo -e {2}' \
--preview-window=top:wrap |
cut -f1 |
sed -e 's/\. /\t/' -e 's/[^a-zA-Z0-9\t]/-/g' |
awk '{printf "%s/%s", $1, tolower($2)}'
)
if [ -n "$branch_name" ]; then
git checkout -b "$branch_name"
fi
}
$ fzf --listen --sync --bind 'focus:transform-header:curl -s localhost:$FZF_PORT?limit=0 | jq .' --height 100%
[--style
]
[!NOTE|label:references:]
[!NOTE|label:references:]
[!NOTE|label:references:]
install
# osx
$ brew install fd
$ ln -sf $(brew --prefix fd)/share/bash-completion/completions/fd $(brew --prefix)/etc/bash_completion.d/fd
# or
$ fd --gen-completions bash | sudo tee $(brew --prefix)/etc/bash_completion.d/fd
# or - v9.0.0
$ ln -sf $(brew --prefix fd)/share/bash-completion/completions/fd /usr/local/etc/bash_completion.d/fd
# debine
$ sudo apt install fd-find # ubuntu 22.04 : fd 8.3.1
$ curl -fsSL -O http://ftp.osuosl.org/pub/ubuntu/pool/universe/r/rust-fd-find/fd-find_9.0.0-1_amd64.deb
$ sudo dpkg -i fd-find_9.0.0-1_amd64.deb # ubuntu any: fd 9.0.0
$ ln -s $(which fdfind) ~/.local/bin/fd
$ export PATH=~/.local:$PATH
# centos
$ sudo dnf install fd-find
from source
[!NOTE]
install rust via
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh $ source "$HOME/.cargo/env" $ cargo --version cargo 1.74.1 (ecb9851af 2023-10-18)
bash
fd --gen-completions bash
fish
fd --gen-completions fish
zsh
fd --gen-completions zsh
elvsih
fd --gen-completions elvish
powershell
fd --gen-completions powershell
$ git clone https://github.com/sharkdp/fd && cd fd
# osx
$ brew install rust
$ cargo install amethyst_tools
# wsl/ubuntu
$ sudo apt install cargo
$ cargo build # build
$ cargo test # run unit tests and integration tests
$ cargo install --debug --path . # install in osx
$ cargo install --path . # install in ubuntu/wsl
$ ln -sf /home/marslo/.cargo/bin/fd /home/marslo/.local/bin/fd
# completion ( >= 9.0.0 )
# wsl/ubuntu/centos
$ fd --gen-completions bash | sudo tee /usr/share/bash-completion/completions/fd
# or centos
$ fd --gen-completions bash | sudo tee /etc/bash_completion.d/fd
# osx
$ fd --gen-completions bash | sudo tee $(brew --prefix)/etc/bash_completion.d/fd
verify
$ fd --version
fd 9.0.0
usage
$ fd --hidden ^.env$
.env
$ fd --type f --strip-cwd-prefix --hidden --follow --exclude .git --exclude node_modules ifunc
bin/ifunc.sh
crontab for delete '.DS_'
/usr/local/bin/fd -IH --glob '*\.DS_*' $HOME | xargs -r -i rm '{}'
# or
/usr/local/bin/fd -Iu --glob '*\.DS_*' $HOME | xargs -r -i rm '{}'
# or
/usr/local/bin/fd --type f --hidden --follow --unrestricted --color=never --exclude .Trash --glob '*\.DS_*' $HOME | xargs -r -i rm '{}'
ffs
# [f]ind [f]ile and [s]ort
function ffs() {
local opt=''
while [[ $# -gt 0 ]]; do
case "$1" in
-g ) opt+="$1 " ; shift ;;
-fg ) opt+="$1 " ; shift ;;
-f ) opt+="$1 " ; shift ;;
--* ) opt+="$1 $2 "; shift 2 ;;
-* ) opt+="$1 " ; shift ;;
* ) break ;;
esac
done
local path=${1:-~/.marslo}
local num=${2:-10}
num=${num//-/}
local depth=${3:-}
depth=${depth//-/}
local option='--type f'
if [[ "${opt}" =~ '-g ' ]]; then
# git show --name-only --pretty="format:" -"${num}" | awk 'NF' | sort -u
# references: https://stackoverflow.com/a/54677384/2940319
git log --date=iso-local --first-parent --pretty=%cd --name-status --relative |
awk 'NF==1{date=$1}NF>1 && !seen[$2]++{print date,$0}' FS=$'\t' |
head -"${num}"
elif [[ "${opt}" =~ '-fg ' ]]; then
# references: https://stackoverflow.com/a/63864280/2940319
git ls-tree -r --name-only HEAD -z |
TZ=PDT xargs -0 -I_ git --no-pager log -1 --date=iso-local --format="%ad | _" -- _ |
sort -r |
head -"${num}"
elif [[ "${opt}" =~ '-f ' ]]; then
option=${option: 1}
[[ -n "${depth}" ]] && option="-maxdepth ${depth} ${option}"
# shellcheck disable=SC2086
find "${path}" ${option} \
-not -path '*/\.git/*' \
-not -path '*/node_modules/*' \
-not -path '*/go/pkg/*' \
-not -path '*/git/git*/*' \
-not -path '*/.marslo/utils/*' \
-not -path '*/.marslo/.completion/*' \
-printf "%10T+ | %p\n" |
sort -r |
head -"${num}"
else
if [[ "${opt}}" =~ .*-t.* ]] || [[ "${opt}" =~ .*--type.* ]]; then
option="${option//--type\ f/}"
fi
option="${opt} ${option} --hidden --follow --unrestricted --ignore-file ~/.fdignore"
[[ -n "${depth}" ]] && option="--max-depth ${depth} ${option}"
[[ '.' != "${path}" ]] && option="${path} ${option}"
# shellcheck disable=SC2086,SC2027
eval """ fd . "${option}" --exec stat --printf='%y | %n\n' | sort -r | head -"${num}" """
fi
}
search for multiple pattern
[!NOTE]
$ fd --unrestricted '^*\.(png|gif|jpg)$'
$ fd --unrestricted --extension png --extension jpg --extension gif
[!NOTE]
install
# with cargo
$ cargo install ripgrep
# osx
$ brew install ripgrep
# rhel/centos
$ sudo yum install -y yum-utils
$ sudo yum-config-manager --add-repo=https://copr.fedorainfracloud.org/coprs/carlwgeorge/ripgrep/repo/epel-7/carlwgeorge-ripgrep-epel-7.repo
$ sudo yum install ripgrep
# or via epel: https://marslo.github.io/ibook/linux/basic.html#tools-installation
$ sudo yum install -y yum-utils epel-release
$ sudo yum install ripgrep
# ubuntu
$ curl -LO https://github.com/BurntSushi/ripgrep/releases/download/14.0.3/ripgrep_14.0.3-1_amd64.deb
$ sudo dpkg -i ripgrep_14.0.3-1_amd64.deb
# or
$ sudo apt install -y ripgrep
# from source
$ git clone https://github.com/BurntSushi/ripgrep && cd ripgrep
$ cargo build --release
$ ./target/release/rg --version
0.1.3
# completion
# wsl/ubuntu/centos
$ rg --generate complete-bash | sudo tee /usr/share/bash-completion/completions/rg
# or centos
$ rg --generate complete-bash | sudo tee /etc/bash_completion.d/rg
# osx
$ rg --generate complete-bash | sudo tee /usr/local/etc/bash_completion.d/rg
crontab for delete '.DS_'
/usr/local/bin/rg --hidden --smart-case --files "$HOME" -g '*\.DS_*' | xargs -r -i rm '{}'
[!NOTE|label:references:]
$ rg --hidden 'alias cat'
# or https://github.com/BurntSushi/ripgrep/issues/623#issuecomment-659909044
alias rg="rg --hidden --glob '!.git'"
# or `.ignore` or `.rgignore`
$ cat ~/.rgignore
.git/
.tox/
.github/
info
$ tree -a .
.
├── .no-hidden
└── no-hidden
1 directory, 2 files
$ rg --files --debug
DEBUG|globset|crates/globset/src/lib.rs:416: glob converted to regex: Glob { glob: "**/.DS_Store?", re: "(?-u)^(?:/?|.*/)\\.DS_Store[^/]$", opts: GlobOptions { case_insensitive: false, literal_separator: true, backslash_escape: true }, tokens: Tokens([RecursivePrefix, Literal('.'), Literal('D'), Literal('S'), Literal('_'), Literal('S'), Literal('t'), Literal('o'), Literal('r'), Literal('e'), Any]) }
DEBUG|globset|crates/globset/src/lib.rs:416: glob converted to regex: Glob { glob: "**/._*", re: "(?-u)^(?:/?|.*/)\\._[^/]*$", opts: GlobOptions { case_insensitive: false, literal_separator: true, backslash_escape: true }, tokens: Tokens([RecursivePrefix, Literal('.'), Literal('_'), ZeroOrMore]) }
DEBUG|globset|crates/globset/src/lib.rs:421: built glob set; 0 literals, 7 basenames, 0 extensions, 0 prefixes, 0 suffixes, 0 required extensions, 2 regexes
DEBUG|ignore::walk|crates/ignore/src/walk.rs:1741: ignoring ./.no-hidden: Ignore(IgnoreMatch(Hidden))
no-hidden
$ rg --files --debug --hidden
DEBUG|globset|crates/globset/src/lib.rs:416: glob converted to regex: Glob { glob: "**/.DS_Store?", re: "(?-u)^(?:/?|.*/)\\.DS_Store[^/]$", opts: GlobOptions { case_insensitive: false, literal_separator: true, backslash_escape: true }, tokens: Tokens([RecursivePrefix, Literal('.'), Literal('D'), Literal('S'), Literal('_'), Literal('S'), Literal('t'), Literal('o'), Literal('r'), Literal('e'), Any]) }
DEBUG|globset|crates/globset/src/lib.rs:416: glob converted to regex: Glob { glob: "**/._*", re: "(?-u)^(?:/?|.*/)\\._[^/]*$", opts: GlobOptions { case_insensitive: false, literal_separator: true, backslash_escape: true }, tokens: Tokens([RecursivePrefix, Literal('.'), Literal('_'), ZeroOrMore]) }
DEBUG|globset|crates/globset/src/lib.rs:421: built glob set; 0 literals, 7 basenames, 0 extensions, 0 prefixes, 0 suffixes, 0 required extensions, 2 regexes
no-hidden
.no-hidden
show file name only
$ rg --hidden 'alias ping' --no-heading --files-with-matches
alias.d/utils
in vimgrep format
$ rg --hidden 'alias ping' --no-heading
alias.d/utils:13: alias ping='/sbin/ping --apple-time -v'
# or
$ rg 'alias ping' --no-heading --line-number --with-filename
alias.d/utils:13: alias ping='/sbin/ping --apple-time -v'
$ rg --hidden 'alias ping' --vimgrep
alias.d/utils:13:3: alias ping='/sbin/ping --apple-time -v'
[!NOTE|label:references:]
if executable("rg")
set grepprg=rg\ --vimgrep\ --smart-case\ --hidden
set grepformat=%f:%l:%c:%m
endif
" -- more --
" handling search and replace boilerplate using ripgrep
if executable('rg') | set grepformat+=%f:%l:%c:%m grepprg=rg\ --vimgrep\ --no-heading\ --smart-case | endif
" use feedkeys because we don't want to press enter at the end of this command
command! -nargs=1 FindReplaceAll :silent grep <args> | copen | call feedkeys(":cdo %s/" . <q-args> . "/") | redraw!
" use feedkeys because otherwise the screen isn't redrawn
nnoremap <silent> <C-r> :call feedkeys(':FindReplaceAll ')<CR>
install
# osx
$ brew install the_silver_searcher
# ubuntu >= 13.10
$ apt-get install silversearcher-ag
install
# osx
$ brew install fzy
# debine
$ sudo apt install fzy
# source code
$ git clone git@github.com:jhawthorn/fzy.git && cd fzy
$ make
$ sudo make install
verify
$ fzy --version
fzy 1.0 © 2014-2018 John Hawthorn
[!NOTE|label:references:]
unset PAGER
install
# osx
$ brew install bat
## extra
$ brew install bat-extras
# ubuntu
$ sudo apt intall bat -y
$ ln -s /usr/bin/batcat ~/.marslo/bin/bat
# centos
$ dnf install bat
## extra
$ sudo dnf install dnf-plugins-core
$ sudo dnf copr enable awood/bat-extras
$ sudo dnf install bat-extras
# ubuntu latest version
$ sudo apt instal -y https://github.com/sharkdp/bat/releases/download/v0.23.0/bat-musl_0.23.0_amd64.deb
$ ln -s /usr/bin/batcat ~/.marslo/bin/bat
# from release package
$ curl -fsSL https://github.com/sharkdp/bat/releases/download/v0.23.0/bat-v0.23.0-x86_64-unknown-linux-musl.tar.gz |
tar xzf - -C ${iRCHOME}/utils/bat-v0.23.0
$ ln -sf ${iRCHOME}/utils/bat-v0.23.0/bat ${iRCHOME}/bin/bat
# or
$ V=$(curl --silent "https://api.github.com/repos/sharkdp/bat/releases/latest" | grep -Eo '"tag_name": "v(.*)"' | sed -E 's/.*"([^"]+)".*/\1/') &&
curl -sOL "https://github.com/sharkdp/bat/releases/download/$V/bat-$V-x86_64-unknown-linux-musl.tar.gz" &&
tar xzvf "bat-$V-x86_64-unknown-linux-musl.tar.gz" -C . &&
sudo sh -c "cp ./bat-$V-x86_64-unknown-linux-musl/bat /usr/local/bin/bat" &&
rm bat-$V-x86_64-unknown-linux-musl.tar.gz &&
unset V
# from source
$ git clone git@github.com:sharkdp/bat.git && cd bat
$ git submodule update -f --init --recursive
# or
$ git clone --recurse-submodules git@github.com:sharkdp/bat.git && cd bat
$ cargo install --locked bat
# build a bat binary with modified syntaxes and themes
$ bash assets/create.sh
$ cargo install --path . --locked --force
completion
$ sed 's/{{PROJECT_EXECUTABLE}}/bat/' "${iRCHOME}/utils/bat/assets/completions/bat.bash.in" | sudo tee /etc/bash_completion.d/bat
# or
$ sed 's/{{PROJECT_EXECUTABLE}}/-o nosort -o bashdefault -o default bat/' "${iRCHOME}/utils/bat/assets/completions/bat.bash.in" | sudo tee /etc/bash_completion.d/bat
# or
$ sed 's/{{PROJECT_EXECUTABLE}}/bat/' -i "${iRCHOME}/utils/bat/assets/completions/bat.bash.in"
$ sed 's/{{PROJECT_EXECUTABLE}}/-o nosort -o bashdefault -o default bat/' -i "${iRCHOME}/utils/bat/assets/completions/bat.bash.in"
$ sudo ln -sf "${iRCHOME}/utils/bat/assets/completions/bat.bash.in" /usr/share/bash-completion/completions/bat
# or without modify `bat.bash.in` and add complete into bashrc
$ sudo ln -sf "${iRCHOME}/utils/bat/assets/completions/bat.bash.in" /usr/share/bash-completion/completions/bat
$ echo 'type -t _bat >/dev/null 2>&1 && complete -F _bat -o nosort -o bashdefault -o default bat' >> ~/.bashrc
verify
$ bat --version
bat 0.24.0 (28990bc-modified)
help()
# in your .bashrc/.zshrc/*rc
alias bathelp='bat --plain --language=help'
help() { "$@" --help 2>&1 | bathelp }
# calling in bash:
# $ help bat
for zsh
$ alias -g -- -h='-h 2>&1 | bat --language=help --style=plain'
$ alias -g -- --help='--help 2>&1 | bat --language=help --style=plain'
bat() {
local index
local args=("$@")
for index in $(seq 0 ${#args[@]}) ; do
case "${args[index]}" in
-* ) continue;;
* ) [ -e "${args[index]}" ] && args[index]="$(cygpath --windows "${args[index]}") ";;
esac
done
command bat "${args[@]}"
}
manpages themes
$ bat --list-themes |
fzf --preview="man git-checkout | sed -r 's/\x1B\[(([0-9]+)(;[0-9]+)*)?[mGKHfJ]//g' | bat --theme={} --color=always --plain --language=help" \
--height 100% \
--preview-window=up,85%,nofollow \
--preview-label-pos='bottom'
script themes
$ bat --list-themes |
fzf --preview="bat --theme={} --color=always /path/to/script" \
--height 100% \
--preview-window=up,85%,nofollow \
--preview-label-pos='bottom'
$ bat --config-file
/Users/marslo/.config/bat/config
# if need modify
$ export BAT_CONFIG_PATH="$(bat --config-file)"
# generate standard config-file
$ bat --generate-config-file
Success! Config file written to /Users/marslo/.config/bat/config
sample content
$ bat $(bat --config-file) | sed -r '/^(#.*)$/d;/^\s*$/d' | bat --language ini
STDIN
1 --theme="gruvbox-dark"
2 --style="numbers,changes,header"
3 --italic-text=always
4 --pager="less --RAW-CONTROL-CHARS --quit-if-one-screen --mouse"
5 --map-syntax "*.ino:C++"
6 --map-syntax ".ignore:Git Ignore"
7 --map-syntax='*.conf:INI'
8 --map-syntax='/etc/apache2/**/*.conf:Apache Conf'
# list themes
$ bat --list-themes
# modify them
$ export BAT_THEME='gruvbox-dark'
# or
$ echo '--theme="gruvbox-dark"' >> $(bat --config-file)
$ mkdir -p "$(bat --config-dir)/themes"
$ cd "$(bat --config-dir)/themes"
# download a theme in '.tmtheme' format, for example:
$ git clone https://github.com/greggb/sublime-snazzy
# Update the binary cache
$ bat cache --build
tldr
[!NOTE|label:references:]
# node version
$ npm install -g tldr
# -- usage --
$ $(npm config get prefix)/bin/tldr --theme ocean <cmd>
# rust version
$ brew install --HEAD tlrc
# c version
$ brew install --HEAD tldr
# python version
$ python3 -m pip intall tldr
rust version
[!TIP|label:references:]
config file :
linux and bsd:
$XDG_CONFIG_HOME/tlrc/config.toml
or~/.config/tlrc/config.toml
if$XDG_CONFIG_HOME
is unsetmacos:
~/Library/Application Support/tlrc/config.toml
windows:
%ROAMINGAPPDATA%\tlrc\config.toml
# rust version
# -- default configure --
$ tldr --gen-config > $(tldr --config-path)
# -- user defined configure --
$ export TLRC_CONFIG="$HOME/.marslo/.tlrc.toml"
# or
$ tldr --config "$HOME/.marslo/.tlrc.toml" <cmd>
python version
# tldr-pypi : https://pypi.org/project/tldr/
export TLDR_COLOR_NAME='cyan'
export TLDR_COLOR_DESCRIPTION='white'
export TLDR_COLOR_EXAMPLE='green'
export TLDR_COLOR_COMMAND='red'
export TLDR_COLOR_PARAMETER='white'
export TLDR_LANGUAGE='en'
export TLDR_CACHE_ENABLED=1
export TLDR_CACHE_MAX_AGE=720
export TLDR_PAGES_SOURCE_LOCATION='https://raw.githubusercontent.com/tldr-pages/tldr/main/pages'
export TLDR_DOWNLOAD_CACHE_LOCATION='https://tldr-pages.github.io/assets/tldr.zip'
cht.sh
[!NOTE]
# install
$ curl -fsSL https://cht.sh/:cht.sh --create-dirs -o ~/.local/bin/cht.sh
$ chmod +x ~/.local/bin/cht.sh
# completion
$ curl -fsSL https://cheat.sh/:bash_completion --create-dirs -o ~/.marslo/.completion/cht.sh
$ source ~/.marslo/.completion/cht.sh
# added in .bashrc
$ [[ -f "${iRCHOME}"/.completion/cht.sh ]] && source "${iRCHOME}"/.completion/cht.sh
:list
:learn
[!NOTE|label:references:]
path:
~/.cht.sh/
file :
~/.cht.sh/cht.sh.conf
CHTSH_HOME
~/.cht.sh/
CHTSH_CONF
$CHTSH_HOME/cht.sh.conf
CHTSH_URL
https://cht.sh
CHTSH_MODE
$(cat "$CHTSH_HOME/mode 2>/dev/null")
CHTSH_CURL_OPTIONS
-
CHEATSH_INSTALLATION
$(cat "$CHTSH_HOME/standalone" 2>/dev/null)
CHEATSH_TEST_STANDALONE
YES/NO
CHEATSH_TEST_SKIP_ONLINE
YES/NO
CHEATSH_TEST_SHOW_DETAILS
YES/NO
list themes
$ cht.sh :styles
# or
$ curl cht.sh/:styles
show themes
$ cht.sh :styles-demo
# or
$ cht.sh :styles |
while read -r _s; do
echo -e "\n---";
echo -e "${_s}";
echo -e "---";
curl "cheat.sh/bash/advanced?style=${_s}";
done
configure theme
$ cat ~/.cht.sh/cht.sh.conf
CHTSH_QUERY_OPTIONS="style=arduino"
themes
algol_nu
arduino
native
solarized-dark
stata-dark
[!NOTE|label:references:]
path :
~/.cht.sh/mode
$ cht.sh --mode lite # use https://cheat.sh/ only
$ cht.sh --mode auto # use local installation
--shell
[!NOTE|label:references:]
$ brew install --HEAD rlwrap
$ cht.sh --shell python
cheat
[!NOTE|label:references:]
$ brew install cheat
$ mkdir -p ~/.config/cheat && cheat --init > ~/.config/cheat/conf.yml
# -- config path --
$ cheat --conf
reset cheatsheets repo
$ cd ~/.config/cheat/cheatsheets
$ rm -rf community
$ git clone https://github.com/cheat/cheatsheets.git community
arduino
github-dark
gruvbox
native
onedark
optional
doom-one
evergarden
lovelace
nord
solarized-dark256
vulcan
[!TIP]
# deps install
$ sudo snap install zig --class --beta
$ sudo apt install libncurses-dev
$ make
$ sudo make install PREFIX=/usr/local
# verify
$ ncdu --version
ncdu 2.3
[!NOTE|label:Alternatives:]
CLI
TUI:
[!TIP]
flags
┌───────┬────────────────┬─────────────────┐ ┌───────┬─────────────────┬───────┐ │ Fg/Bg │ Color │ Octal │ │ Code │ Style │ Octal │ ├───────┼────────────────┼─────────────────┤ ├───────┼─────────────────┼───────┤ │ K/k │ Black │ \e[ + 3/4 + 0m │ │ s/S │ Bold (strong) │ \e[1m │ │ R/r │ Red │ \e[ + 3/4 + 1m │ │ d/D │ Dim │ \e[2m │ │ G/g │ Green │ \e[ + 3/4 + 2m │ │ i/I │ Italic │ \e[3m │ │ Y/y │ Yellow │ \e[ + 3/4 + 3m │ │ u/U │ Underline │ \e[4m │ │ B/b │ Blue │ \e[ + 3/4 + 4m │ │ f/F │ Blink (flash) │ \e[5m │ │ M/m │ Magenta │ \e[ + 3/4 + 5m │ │ n/N │ Negative │ \e[7m │ │ C/c │ Cyan │ \e[ + 3/4 + 6m │ │ h/H │ Hidden │ \e[8m │ │ W/w │ White │ \e[ + 3/4 + 7m │ │ t/T │ Strikethrough │ \e[9m │ ├───────┴────────────────┴─────────────────┤ ├───────┼─────────────────┼───────┤ │ High intensity │ \e[ + 9/10 + *m │ │ 0 │ Reset │ \e[0m │ └────────────────────────┴─────────────────┘ └───────┴─────────────────┴───────┘ Uppercase = Reset a style: \e[2*m
[!NOTE|label:references:]
install
$ curl -sL git.io/ansi -o "${iRCHOME}"/utils/ansi && chmod +x $_
$ ln -sf $(realpath "${iRCHOME}"/utils/ansi) $(realpath "${iRCHOME}"/bin)/ansi
[!NOTE|label:references:]
# ubuntu
$ sudo add-apt-repository ppa:aos1/diff-so-fancy
$ sudo apt update
$ sudo apt install diff-so-fancy
# verify
$ diff-so-fancy --version
Diff-so-fancy: https://github.com/so-fancy/diff-so-fancy
Version : 1.4.2
elinks
[!NOTE|label:references:]
MacOS:
$ brew install felinks $ which -a elinks /usr/local/bin/elinks
$ elinks https://google.com
configure
[!NOTE|label:references:]
$ cat ~/.elinks/elinks.conf
set connection.ssl.cert_verify = 0
[!NOTE|label:references:]
" original autocmd BufWritePre * :retab! " automatic retab " for ltsv if has( "autocmd" ) autocmd BufRead,BufNewFile *.ltsv set filetype=ltsv syntax=groovy noexpandtab autocmd BufWritePre *\(.ltsv\|.diffs\)\@<! :retab! " automatic retab endif
install
$ git clone https://github.com/babarot/enhancd && source enhancd/init.sh
# or
$ curl -L git.io/enhancd | sh
re-mapping cmd
diff --git a/init.sh b/init.sh
index 55a9c95..bc3ae89 100644
--- a/init.sh
+++ b/init.sh
@@ -52,8 +52,8 @@ if [[ ! -f ${ENHANCD_DIR}/enhancd.log ]]; then
touch "${ENHANCD_DIR}/enhancd.log"
fi
-# alias to cd
-eval "alias ${ENHANCD_COMMAND:=cd}=__enhancd::cd"
+# alias to ce
+eval "alias ${ENHANCD_COMMAND:=ce}=__enhancd::cd"
# Set the filter if empty
if [[ -z ${ENHANCD_FILTER} ]]; then
usage
$ brew install fzy
# debine
$ sudo apt install fzy
$ export ENHANCD_FILTER="fzf --height 35%:fzy"
$ source /path/to/enhancd/init.sh
$ ce .
|
|
|
|
fuzzy-cd : |
to delete both local and remote branches automatically
System Settings ⇢ Keyboard ⇢ Keyboard Shutcuts... ⇢ Mission Control
System Settings ⇢ Desktop & Dock ⇢ Shortcuts...
)
| |
export TLRC_CONFIG="$HOME/.marslo/.tlrc.toml"
| | -
i.e.:
i.e.:
configuration is stored in ~/.cht.sh/
(can be overridden with CHTSH
env var.)
|