-
Notifications
You must be signed in to change notification settings - Fork 31
/
fzrepl
executable file
·107 lines (88 loc) · 2.06 KB
/
fzrepl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#!/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% \
--disabled \
--print-query \
--query="$default_query" \
${FZREPL_FILE:+--history=$FZREPL_FILE} \
--preview="$cmd < '$tmpfile'"
)
q="${REPLY[0]}"
q=${q@Q}
echo "${cmd//'{q}'/$q}"