dotwryn/zsh/rc.d/80.frog.zsh

155 lines
3.2 KiB
Bash
Raw Normal View History

command -v \
echo.error \
echo.status \
echo.success \
echo.success.color \
rg \
sed \
utils.check-errors \
utils.colors.green \
utils.yN \
&>/dev/null || return 0
frog() {
eval "$(usage.reset)"
local USAGE__description='
find-and-replace for all files in the current directory
frog = [F]ix [R]ip[G]rep ... and "o" because 🐸
'
local USAGE__options='
-s, --search <sed regex> the regex to search for
-r, --replace <string> replacement value
-d, --delete delete instead having a replacement value
--trim trim trailing spaces from all files in the work-tree
-h, --help print this message
'
local USAGE__args='
\$1 search regex
\$2 replacement value
'
local SEARCH_REGEX REPLACE_VALUE DELETE=false TRIM=false
local _S ERRORS=0 POSITIONAL_ARGUMENT_COUNT=0
while [[ $# -gt 0 ]]
do
_S=1
case $1 in
( -s | --search )
_S=2
SEARCH_REGEX="$2"
;;
( -r | --replace )
_S=2
REPLACE_VALUE="$2"
;;
( -d | --delete )
_S=1
DELETE=true
;;
( --trim )
_S=1
TRIM=true
DELETE=true
SEARCH_REGEX='\s+$'
;;
( -h | --help )
utils.io.usage
return 0
;;
( * )
((POSITIONAL_ARGUMENT_COUNT+=1))
case ${POSITIONAL_ARGUMENT_COUNT} in
( 1 )
case "${SEARCH_REGEX}" in
( '' )
SEARCH_REGEX="$1"
;;
( * )
[ ! "${REPLACE_VALUE}" ] \
&& REPLACE_VALUE="$1" \
|| echo.error "too many arguments" \
;
;;
esac
;;
( 2 )
[ ! "${REPLACE_VALUE}" ] \
&& REPLACE_VALUE="$1" \
|| echo.error "too many arguments" \
;
;;
( * )
echo.error "unknown argument '$1'"
;;
esac
;;
esac
[[ ${_S} -le $# ]] \
&& shift ${_S} \
|| echo.error "argument error for '$1'" \
|| shift $#
done
[ ! "${SEARCH_REGEX}" ] && [ ! "${REPLACE_VALUE}" ] && [[ ${DELETE} =~ false ]] && [[ ${POSITIONAL_ARGUMENT_COUNT} -eq 0 ]] \
&& utils.io.usage \
&& return 0 \
;
[ "${SEARCH_REGEX}" ] \
|| echo.error "missing search regex"
[ ! "${REPLACE_VALUE}" ] && [[ ${DELETE} =~ false ]] \
&& echo.error "missing replacement value"
[ "${REPLACE_VALUE}" ] && [[ ${DELETE} =~ true ]] \
&& echo.error "cannot use '--delete' with a replacement value"
utils.check-errors || return $?
##########################################
local FILES_MATCHED=($(rg -l -- "${SEARCH_REGEX}"))
[[ ${#FILES_MATCHED[@]} -gt 0 ]] || {
echo.status "no files contain '${SEARCH_REGEX}' in the current tree; nothing to do"
return 0
}
clear
rg -- "${SEARCH_REGEX}" ${FILES_MATCHED[@]}
echo.status "showing matches from $(utils.colors.green)${#FILES_MATCHED[@]} file(s)$(echo.status.color) in the current directory"
utils.yN "replace all matches with '${REPLACE_VALUE}'?" || return 1
[[ ${TRIM} =~ true ]] && SEARCH_REGEX='\s\+$'
local FILENAME
for FILENAME in ${FILES_MATCHED[@]}
do
sed -i "s${SEARCH_REGEX}${REPLACE_VALUE}g" "${FILENAME}" \
|| echo.error "failed to update '${FILENAME}'"
done
[[ ${ERRORS} -eq 0 ]] \
&& echo.success "successfully replaced '${SEARCH_REGEX}' with '${REPLACE_VALUE}'" \
|| echo.error "something went wrong (see above)" \
;
}