You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
2.1 KiB

#!/usr/bin/env bash
usage() {
less -FEXR <<'HELP'
fzrepl
interactively edit stdin using stream filters like awk, sed, jq
-c, --cmd command used to filter input
-q, --query default command string to use
command history can be saved to a file by setting the environment variable
FZREPL_FILE
examples:
echo 'foo bar' | fzrepl -c 'awk {q}' -q '{print}'
echo 'hello world' | fzrepl -q p 'sed -n {q}'
FZREPL_FILE=jqhistory fzrepl jq package.json
HELP
}
# TODO: better "wrapping", this is painful:
# fzrepl 'node -e {q}' -q "done = data => data;\nlet A='';process.stdin.on('data',x=>A=A.concat(x.toString())).on('end',()=>{let d = done(A);process.stdout.write(`${String.prototype.trim.call(typeof d==='string'?d:JSON.stringify(d,null,2))}\n`)})"
declare tmpfile=/tmp/fzreplinput
declare cmd
declare default_query
declare output
declare -A colors
colors[red]=$(tput setaf 1)
colors[green]=$(tput setaf 2)
colors[reset]=$(tput sgr0)
cleanup() {
[[ -e "$tmpfile" ]] && rm "$tmpfile"
}
trap cleanup SIGHUP SIGINT SIGTERM
color() {
local color
color="$1"; shift
printf '%s' "${colors[$color]}" "$*" "${colors[reset]}"
}
err() {
color red "$@" >&2
return 1
}
die() {
(( $# > 0 )) && err "$@"
exit 1
}
for arg; do
case $arg in
-q|--query)
[[ -z $2 || $2 = -* ]] && die "missing argument to $1"
default_query="$2"
shift 2 ;;
-c|--cmd)
[[ -z $2 || $2 = -* ]] && die "missing argument to $1"
cmd="$2"
shift 2 ;;
-h|--help) usage; exit ;;
*) break 2;
esac
done
if [[ -z $cmd && -n $1 && ! -f $1 ]]; then
cmd="$1"
shift
fi
if [[ -z $cmd ]]; then
usage
exit 1
fi
if [[ $cmd != *'{q}'* ]]; then
cmd+=' {q}'
fi
if [[ -n $1 && -f $1 ]]; then
file=$1
shift
fi
if [[ -z $file ]]; then
file=/dev/stdin
fi
mapfile -t REPLY < <(
tee "$tmpfile" < "$file" | fzf \
--sync \
--ansi \
--height=100% \
--phony \
--print-query \
--query="$default_query" \
${FZREPL_FILE:+--history=$FZREPL_FILE} \
--preview="$cmd < '$tmpfile'"
)
q="${REPLY[0]}"
q=${q@Q}
echo "${cmd//'{q}'/$q}"