Skip to content

Instantly share code, notes, and snippets.

@b0o
Last active February 14, 2021 04:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save b0o/6523f0b0c335a1c9898988b6ab5f55a7 to your computer and use it in GitHub Desktop.
Save b0o/6523f0b0c335a1c9898988b6ab5f55a7 to your computer and use it in GitHub Desktop.
some fun zsh zle widgets
# Assorted zsh zle widgets that I've made over the years
# (c) 2017-2021 Maddison Hellstrom (github.com/b0o)
# License: GPL v3.0 or later
## smartie-hands
function _smart_l() {
local cmd="${1:-l}"
local p=""
if [[ -n "$BUFFER" ]]; then
zmodload -e zsh/pcre || zmodload zsh/pcre
pcre_compile -- '^(?U)((.*\s+)*)((\S|\\\s)+)$'
if [[ -n "$LBUFFER" ]] && pcre_match -a mat -- "$LBUFFER"; then
# Cursor is right-adjacent to some text
p="${mat[3]//(#m)\\/}"
fi
pcre_compile -- '^((\\\s|\S)+)((\s+.*)*)$'
if [[ -n "$RBUFFER" ]] && pcre_match -a mat -- "$RBUFFER"; then
# Cursor is left-adjacent to some text
p="${p}${mat[1]//(#m)\\/}"
fi
fi
printf '\n'
p=${p:-$PWD}
if [[ -e "$p" ]]; then
$cmd "$p"
else
zle menu-complete
fi
zle reset-prompt
}
zle -N smart-l _smart_l
bindkey "^[l" smart-l
# fzf path finding filesystem navigation thing by maddy (github.com/b0o)
#
# key bindings:
# - return: accept final
# - alt-return: accept final (absolute)
# - esc: escape
# - ctrl-g: escape (absolute)
# - alt-o: accept query
# - alt-P append query
# - ctrl-o: replace query
# - alt-i: descend into directory or accept file
# - alt-u: ascend into parent directory
# - alt-U ascend to next existing ancestor
# - ctrl-n: next
# - alt-n: next
# - tab: next
# - down: next
# - ctrl-p: prev
# - alt-p: prev
# - shift-tab: prev
# - up: prev
function _smart_fzf () {
local left="$LBUFFER"
local right="$RBUFFER"
local path_orig="$*"
if [[ -z "$path_orig" && -n "$BUFFER" ]]; then
zmodload -e zsh/pcre || zmodload zsh/pcre
# Split before word adjacent to the left of the cursor
pcre_compile -- '^(?U)((.*\s+)*)((\S|\\\s)+)$'
if [[ -n "$LBUFFER" ]] && pcre_match -a mat -- "$LBUFFER"; then
path_orig="${mat[3]//(#m)\\/}"
left="${LBUFFER:0:$((${#LBUFFER} - ${#path_orig}))}"
fi
# Split after word adjacent to the right of the cursor
pcre_compile -- '^((\\\s|\S)+)((\s+.*)*)$'
if [[ -n "$RBUFFER" ]] && pcre_match -a mat -- "$RBUFFER"; then
right="${mat[3]}"
path_orig="${path_orig}${mat[1]//(#m)\\/}"
fi
fi
path_orig="${path_orig:-.}"
path_orig=${~path_orig} # expand tilde
path_orig="${(e)path_orig}" # expand variables
local path_orig_absolute
local relative="$PWD"
if [[ "$path_orig" =~ ^/ ]]; then
path_orig_absolute="$path_orig"
relative="/"
else
path_orig_absolute="$(realpath -m "$path_orig")"
fi
local fzf_preview=(
'f="$(realpath -m "'"$path_orig_absolute"'/{}")";'
'bat --color always "$f" 2>/dev/null || exa --tree --level=1 --color=always "$f" 2>/dev/null || stat "$f" 2>/dev/null'
)
local res
res="$(
{
{
find "$path_orig_absolute" -mindepth 1 -maxdepth 1 -type b -or -type c -printf "${fg_bold[yellow]}%f${reset_color}\\n";
find "$path_orig_absolute" -mindepth 1 -maxdepth 1 -type f -not -executable -printf "${fg_no_bold[default]}%f${reset_color}\\n";
find "$path_orig_absolute" -mindepth 1 -maxdepth 1 -type f -executable -printf "${fg_no_bold[green]}%f${reset_color}\\n";
find "$path_orig_absolute" -mindepth 1 -maxdepth 1 -type l -printf "${fg_no_bold[cyan]}%f${reset_color}\\n";
find "$path_orig_absolute" -mindepth 1 -maxdepth 1 -type p -printf "${fg_no_bold[yellow]}%f${reset_color}\\n";
find "$path_orig_absolute" -mindepth 1 -maxdepth 1 -type s -printf "${fg_bold[magenta]}%f${reset_color}\\n";
find "$path_orig_absolute" -mindepth 1 -maxdepth 1 -not '(' -type b -or -type c -or -type f -or -type l -or -type p -or -type s -or -type d ')' -printf "${fg_no_bold[red]}%f${reset_color}\\n";
} | sort -k 1.8 # The '-k 1.8' argument tells sort to skip the first 8 characters of each line, which happens to be the length of the ANSI color code escape sequences
find "$path_orig_absolute" -mindepth 1 -maxdepth 1 -type d -printf "${fg_bold[blue]}%f${reset_color}\\n";
printf "${fg_bold[white]}%s${reset_color}\n" "." ".."
} 2>/dev/null \
| fzf \
--reverse --no-sort --ansi --height='50%' --header="$path_orig_absolute" \
--print-query --cycle \
--expect='alt-return,ctrl-g,alt-P,alt-o,alt-i,alt-u,alt-U' \
--bind='ctrl-o:replace-query,tab:down,btab:up,alt-n:down,alt-p:up' \
--preview="bash -c '${fzf_preview[*]}'")"
local -i code=$?
local path_new
local query key match
case $code in
0|1|130)
query="$(head -1 <<<"$res")"
;|
0|1)
key="$(head -2 <<<"$res" | tail -1)"
case "${key:-}" in
"alt-u")
path_new=".."
;;
"alt-o"|"alt-P")
path_new="${query:-}"
;;
"alt-U"|"ctrl-g")
path_new="."
;;
esac
;|
# Match
0)
path_new="${path_new:-$(tail -1 <<<"$res")}"
;;
# No match
1)
;;
# Interrupted with CTRL-C or ESC
130)
path_new=""
;;
# Error
2|*)
return 1
;;
esac
if [[ "$key" != "alt-o" ]]; then
path_new="$(realpath -m --relative-to="$relative" "${path_orig:+$path_orig/}${path_new}")"
if [[ "$key" == "alt-U" ]]; then
local -i c_u_once=0
while [[ $c_u_once -eq 0 || ! -e "$path_new" ]]; do
c_u_once=1
path_new="$(realpath -m --relative-to="$relative" "${path_new}/..")"
done
fi
if [[ "$relative" == "/" ]]; then
path_new="/${path_new}"
fi
fi
if [[ "$key" == "alt-return" || "$key" == "ctrl-g" ]]; then
path_new="$(realpath -m "$path_new")"
fi
LBUFFER="${left}${path_new}"
RBUFFER="$right"
zle reset-prompt
if [[ "$key" =~ ^alt-[uUoP]$ || ( "$key" == "alt-i" && ( ! -e "$path_new" || -d "$path_new" ) ) ]]; then
_smart_fzf
fi
}
zle -N smart-fzf _smart_fzf
bindkey "^[." smart-fzf
# smart wrap
function _smart_wrap() {
zmodload zsh/pcre
pcre_compile -- '^((.*\s+)*)(\S+)$'
if [[ -n "$LBUFFER" ]] && pcre_match -a mat -- "$LBUFFER"; then
LBUFFER="${mat[1]}${1}${mat[3]}"
else
LBUFFER="${LBUFFER}${1}"
fi
pcre_compile -- '^(\S+)((\s+.*)*)$'
if [[ -n "$RBUFFER" ]] && pcre_match -a mat -- "$RBUFFER"; then
RBUFFER="${mat[1]}${2}${mat[2]}"
else
RBUFFER="${2}${RBUFFER}"
fi
}
function _smart_wrap_parens() { _smart_wrap '(' ')' }
function _smart_wrap_brackets() { _smart_wrap '[' ']' }
function _smart_wrap_cbrackets() { _smart_wrap '{' '}' }
function _smart_wrap_squotes() { _smart_wrap "'" "'" }
function _smart_wrap_dquotes() { _smart_wrap '"' '"' }
function _smart_wrap_backticks() { _smart_wrap '`' '`' }
function _smart_wrap_cmd_subst() { _smart_wrap '$(' ')' }
function _smart_wrap_param_subst() { _smart_wrap '${' '}' }
function _smart_wrap_arith_subst() { _smart_wrap '$((' '))' }
zle -N smart-wrap-parens _smart_wrap_parens
zle -N smart-wrap-brackets _smart_wrap_brackets
zle -N smart-wrap-cbrackets _smart_wrap_cbrackets
zle -N smart-wrap-squotes _smart_wrap_squotes
zle -N smart-wrap-dquotes _smart_wrap_dquotes
zle -N smart-wrap-backticks _smart_wrap_backticks
zle -N smart-wrap-cmd-subst _smart_wrap_cmd_subst
zle -N smart-wrap-param-subst _smart_wrap_param_subst
zle -N smart-wrap-arith-subst _smart_wrap_arith_subst
bindkey '^[(' smart-wrap-parens
bindkey '^[[' smart-wrap-brackets
bindkey '^[{' smart-wrap-cbrackets
bindkey "^['" smart-wrap-squotes
bindkey '^["' smart-wrap-dquotes
bindkey '^[`' smart-wrap-backticks
bindkey '^[$' smart-wrap-cmd-subst
bindkey '^[)' smart-wrap-cmd-subst
bindkey '^[}' smart-wrap-param-subst
bindkey '^[=' smart-wrap-arith-subst
bindkey '^[+' smart-wrap-arith-subst
# fancy-ctrl-z
# inspired by fancy-ctrl-z from oh-my-zsh
function fancy-c-z () {
if [[ $#BUFFER -eq 0 ]]; then
if [[ $1 == "-b" ]]; then
BUFFER=" bg"
else
BUFFER=" fg"
fi
zle accept-line
else
zle push-input
zle clear-screen
fi
}
function fancy-c-z_b () { fancy-c-z -b }
zle -N fancy-c-z
zle -N fancy-c-z_b
bindkey '^z' fancy-c-z
bindkey '^[z' fancy-c-z_b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment