-
Notifications
You must be signed in to change notification settings - Fork 6
/
fzfimg.sh
executable file
·146 lines (121 loc) · 4.29 KB
/
fzfimg.sh
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/usr/bin/env bash
# This is just an example how ueberzug can be used with fzf.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
readonly BASH_BINARY="$(which bash)"
readonly REDRAW_COMMAND="toggle-preview+toggle-preview"
readonly REDRAW_KEY="µ"
declare -r -x DEFAULT_PREVIEW_POSITION="right"
declare -r -x UEBERZUG_FIFO="$(mktemp --dry-run --suffix "fzf-$$-ueberzug")"
declare -r -x PREVIEW_ID="preview"
function is_option_key [[ "${@}" =~ ^(\-.*|\+.*) ]]
function is_key_value [[ "${@}" == *=* ]]
function map_options {
local -n options="${1}"
local -n options_map="${2}"
for ((i=0; i < ${#options[@]}; i++)); do
local key="${options[$i]}" next_key="${options[$((i + 1))]:---}"
local value=true
is_option_key "${key}" || \
continue
if is_key_value "${key}"; then
<<<"${key}" \
IFS='=' read key value
elif ! is_option_key "${next_key}"; then
value="${next_key}"
fi
options_map["${key}"]="${value}"
done
}
function parse_options {
declare -g -a script_options=("${@}")
declare -g -A mapped_options
map_options script_options mapped_options
declare -g -r -x PREVIEW_POSITION="${mapped_options[--preview-window]%%:[^:]*}"
}
function start_ueberzug {
mkfifo "${UEBERZUG_FIFO}"
<"${UEBERZUG_FIFO}" \
ueberzug layer --parser bash --silent &
# prevent EOF
3>"${UEBERZUG_FIFO}" \
exec
}
function finalise {
3>&- \
exec
&>/dev/null \
rm "${UEBERZUG_FIFO}"
&>/dev/null \
kill $(jobs -p)
}
function calculate_position {
# TODO costs: creating processes > reading files
# so.. maybe we should store the terminal size in a temporary file
# on receiving SIGWINCH
# (in this case we will also need to use perl or something else
# as bash won't execute traps if a command is running)
< <(</dev/tty stty size) \
read TERMINAL_LINES TERMINAL_COLUMNS
case "${PREVIEW_POSITION:-${DEFAULT_PREVIEW_POSITION}}" in
left|up|top)
X=1
Y=1
;;
right)
X=$((TERMINAL_COLUMNS - COLUMNS - 2))
Y=1
;;
down|bottom)
X=1
Y=$((TERMINAL_LINES - LINES - 1))
;;
esac
}
function draw_preview {
calculate_position
>"${UEBERZUG_FIFO}" declare -A -p cmd=( \
[action]=add [identifier]="${PREVIEW_ID}" \
[x]="${X}" [y]="${Y}" \
[width]="${COLUMNS}" [height]="${LINES}" \
[scaler]=forced_cover [scaling_position_x]=0.5 [scaling_position_y]=0.5 \
[path]="${@}")
# add [synchronously_draw]=True if you want to see each change
}
function print_on_winch {
# print "$@" to stdin on receiving SIGWINCH
# use exec as we will only kill direct childs on exiting,
# also the additional bash process isn't needed
</dev/tty \
exec perl -e '
require "sys/ioctl.ph";
while (1) {
local $SIG{WINCH} = sub {
ioctl(STDIN, &TIOCSTI, $_) for split "", join " ", @ARGV;
};
sleep;
}' \
"${@}" &
}
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
trap finalise EXIT
parse_options "${@}"
# print the redraw key twice as there's a run condition we can't circumvent
# (we can't know the time fzf finished redrawing it's layout)
print_on_winch "${REDRAW_KEY}${REDRAW_KEY}"
start_ueberzug
export -f draw_preview calculate_position
SHELL="${BASH_BINARY}" \
fzf --preview "draw_preview {}" \
--preview-window "${DEFAULT_PREVIEW_POSITION}" \
--bind "${REDRAW_KEY}:${REDRAW_COMMAND}" \
"${@}"
fi