Last active
February 14, 2021 04:33
-
-
Save b0o/6523f0b0c335a1c9898988b6ab5f55a7 to your computer and use it in GitHub Desktop.
some fun zsh zle widgets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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