-
Notifications
You must be signed in to change notification settings - Fork 0
/
diffsed
executable file
·77 lines (66 loc) · 1.5 KB
/
diffsed
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
#!/usr/bin/env bash
declare sexpr
declare file
declare sedopts=()
declare diffprg='diff'
declare interactive
usage() {
LESS=-FEXR less <<'HELP'
Usage: diffsed [OPTION]... <EXPR> <FILE>
show a diff before a file transformed with sed
OPTIONS:
-i prompt to save changes
-r use extended regex with sed
-h, --help show this help
HELP
}
select_from() {
local o c cmd OPTARG OPTIND
cmd='command -v'
while getopts 'c:' o; do
case "$o" in
c) cmd="$OPTARG" ;;
esac
done
shift "$((OPTIND-1))"
for c; do
if $cmd "${c%% *}" &> /dev/null; then
echo "$c"
return 0
fi
done
return 1
}
ask() {
read -r -N1 -p "$* " ans
printf '\n'
[[ ${ans^} == Y* ]]
}
while true; do
case "$1" in
-i) interactive=true; shift ;;
-r) sedopts+=( -r ); shift ;;
-h|--help) usage; exit ;;
*) break
esac
done
sexpr="$1"
shift
file=( "$@" )
diffprg=$(select_from "delta -w $COLUMNS" diff-so-fancy diff-highlight colordiff 'diff -u' )
patch=''
for f in "${file[@]}"; do
patch+=$($diffprg "$f" <(sed "${sedopts[@]}" "$sexpr" "$f"))
done
if [[ ! -t 1 || ! -p /dev/stdout ]]; then
if [[ "$diffprg" == 'diff -u' ]]; then
# TODO: use ${parameter/pattern/string} + cached `tput` instead of sed
patch=$(sed 's/^-/\x1b[31m-/; s/^+/\x1b[32m+/; s/^@/\x1b[34m@/; s/$/\x1b[0m/' <<< "$patch")
fi
less -FEXR <<< "$patch"
if [[ -n "$interactive" ]]; then
ask 'save changes?' && sed "${sedopts[@]}" -i "$sexpr" "${file[@]}"
fi
else
echo "$patch"
fi