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
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}"
|
|
|