@kecan0406/ttheme 1.2.8 → 1.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1949 @@
1
+ __tt_pv_norm() { REPLY=${(L)1//[^[:alnum:]]/} }
2
+
3
+ __tt_pv_seek() {
4
+ local t part key REPLY
5
+ for t in ${(k)TTHEME_PALETTE}; do
6
+ key=""
7
+ for part in "$t" "${TTHEME_GROUP[$t]:-Other}" "${TTHEME_NATIVE[$t]}" "${TTHEME_CATALOG[$t]}" "${(@s:|:)TTHEME_NATIVE_NAMES[$t]}" "${TTHEME_CHARACTER[$t]}"; do
8
+ [[ -n $part ]] || continue
9
+ __tt_pv_norm "$part"
10
+ key+="|$REPLY"
11
+ done
12
+ pvseek[$t]=$key
13
+ done
14
+ }
15
+
16
+ __tt_pv_alias() {
17
+ REPLY=""
18
+ [[ -n $nflt && -n $2 ]] || return 0
19
+ local main
20
+ __tt_pv_norm "$1"
21
+ main=$REPLY
22
+ __tt_pv_norm "$2"
23
+ [[ $main != *$nflt* && $REPLY == *$nflt* ]] && REPLY=$2 || REPLY=""
24
+ return 0
25
+ }
26
+
27
+ __tt_pv_rows() {
28
+ rtype=() rval=() rcnt=()
29
+ local g t c ruled="" nflt="" REPLY
30
+ local -a ts cs loose inside
31
+ if [[ -n $flt ]]; then
32
+ (( ${#pvseek} )) || __tt_pv_seek
33
+ __tt_pv_norm "$flt"
34
+ nflt=$REPLY
35
+ fi
36
+ for g in $groups; do
37
+ ts=()
38
+ for t in ${=gthemes[$g]}; do
39
+ [[ -z $flt || ${pvseek[$t]} == *$nflt* ]] && ts+=($t)
40
+ done
41
+ [[ -n $flt ]] && (( ! ${#ts} )) && continue
42
+ if [[ $g == *@* && -z $ruled ]]; then
43
+ ruled=1
44
+ (( ${#rtype} )) && { rtype+=(rule); rval+=(''); rcnt+=(0) }
45
+ fi
46
+ rtype+=(hdr); rval+=($g); rcnt+=(${#ts})
47
+ [[ -n $flt || -n ${exp[$g]} ]] || continue
48
+ cs=() loose=()
49
+ for t in $ts; do
50
+ c=${TTHEME_CATALOG[$t]}
51
+ if [[ -n $c && $g == *@* ]]; then
52
+ (( ${cs[(Ie)$c]} )) || cs+=($c)
53
+ else
54
+ loose+=($t)
55
+ fi
56
+ done
57
+ for c in $cs; do
58
+ inside=()
59
+ for t in $ts; do
60
+ [[ ${TTHEME_CATALOG[$t]} == "$c" ]] && inside+=($t)
61
+ done
62
+ rtype+=(cat); rval+=("$g/$c"); rcnt+=(${#inside})
63
+ if [[ -n $flt || -n ${exp[$g/$c]} ]]; then
64
+ for t in $inside; do rtype+=(thm); rval+=($t); rcnt+=(0); done
65
+ fi
66
+ done
67
+ for t in $loose; do rtype+=(thm); rval+=($t); rcnt+=(0); done
68
+ done
69
+ }
70
+
71
+ __tt_pv_at() {
72
+ local i
73
+ for (( i = 1; i <= ${#rval}; i++ )); do
74
+ [[ ${rtype[i]} == (hdr|cat) && ${rval[i]} == "$1" ]] && { cur=$i; return 0 }
75
+ done
76
+ return 0
77
+ }
78
+
79
+ __tt_pv_first() {
80
+ local name=$1 i
81
+ cur=1 top=1
82
+ if [[ -n $name ]]; then
83
+ for (( i = 1; i <= ${#rval}; i++ )); do
84
+ [[ ${rtype[i]} == thm && ${rval[i]} == $name ]] && { cur=$i; return 0 }
85
+ done
86
+ fi
87
+ for (( i = 1; i <= ${#rtype}; i++ )); do
88
+ [[ ${rtype[i]} == thm ]] && { cur=$i; return 0 }
89
+ done
90
+ return 0
91
+ }
92
+
93
+ __tt_pv_goto() {
94
+ local name=$1 i g=${TTHEME_GROUP[$1]:-Other} c=${TTHEME_CATALOG[$1]}
95
+ exp[$g]=1
96
+ [[ -n $c && $g == *@* ]] && exp[$g/$c]=1
97
+ __tt_pv_rows
98
+ for (( i = 1; i <= ${#rval}; i++ )); do
99
+ [[ ${rtype[i]} == thm && ${rval[i]} == $name ]] && { cur=$i; return 0 }
100
+ done
101
+ cur=1
102
+ }
103
+
104
+ __tt_pv_shows() {
105
+ REPLY=${bgview[$1]:-$1}
106
+ [[ -n $tune && $1 == "$tune" ]] && REPLY=$tpick
107
+ return 0
108
+ }
109
+
110
+ __tt_pv_focus() {
111
+ if (( te )); then
112
+ __tt_pv_shows $tename
113
+ (( resized )) || [[ $REPLY == "$bgname" ]] || __tt_pv_bg_show "$REPLY"
114
+ return 0
115
+ fi
116
+ [[ ${rtype[cur]} == thm ]] || return 0
117
+ __tt_pv_shows ${rval[cur]}
118
+ (( resized )) || [[ $REPLY == "$bgname" ]] || __tt_pv_bg_show "$REPLY"
119
+ local spec=${TTHEME_PALETTE[${rval[cur]}]}
120
+ [[ $spec == "$applied" ]] && return 0
121
+ __tt_pv_paint "$spec"
122
+ applied=$spec
123
+ }
124
+
125
+ __tt_pv_toggle() {
126
+ [[ -n $flt ]] && return 0
127
+ local g=${rval[cur]}
128
+ if [[ -n ${exp[$g]} ]]; then
129
+ exp[$g]=""
130
+ else
131
+ exp[$g]=1
132
+ fi
133
+ __tt_pv_rows
134
+ }
135
+
136
+ __tt_pv_left() {
137
+ [[ -n $flt ]] && return 0
138
+ if [[ ${rtype[cur]} == (hdr|cat) ]]; then
139
+ if [[ -n ${exp[${rval[cur]}]} ]]; then
140
+ __tt_pv_toggle
141
+ elif [[ ${rtype[cur]} == cat ]]; then
142
+ __tt_pv_at ${rval[cur]%%/*}
143
+ fi
144
+ return 0
145
+ fi
146
+ local g=${TTHEME_GROUP[${rval[cur]}]:-Other} c=${TTHEME_CATALOG[${rval[cur]}]}
147
+ [[ -n $c && $g == *@* ]] && g=$g/$c
148
+ exp[$g]=""
149
+ __tt_pv_rows
150
+ __tt_pv_at $g
151
+ }
152
+
153
+ typeset -gA TTHEME_GLYPHS=(
154
+ 0 111101101101111 1 010110010010111 2 111001111100111 3 111001111001111 4 101101111001001
155
+ 5 111100111001111 6 111100111101111 7 111001001001001 8 111101111101111 9 111101111001111
156
+ '%' 101001010100101 F 111100110100100 I 111010010010111 L 100100100100111
157
+ )
158
+
159
+ __tt_pv_osd() {
160
+ local text=${(U)osd} bits line oc=$'\e[1m' blank
161
+ local -i s=2 n=${#text} w r c k i top left
162
+ (( n * 16 + 4 <= pw && ph >= 14 )) || s=1
163
+ w=$(( n * 8 * s - 2 * s + 4 ))
164
+ top=$(( (ph - 5 * s) / 2 )) left=$(( (pw - w) / 2 + 1 ))
165
+ (( top < 2 )) && top=2
166
+ (( left < 1 )) && left=1
167
+ if (( color )) && [[ ${rtype[cur]} == thm ]]; then
168
+ local -a fp=(${=TTHEME_PALETTE[${rval[cur]}]})
169
+ local fc=${fp[3]#\#}
170
+ printf -v oc '\e[1;38;2;%d;%d;%dm' $((16#${fc:0:2})) $((16#${fc:2:2})) $((16#${fc:4:2}))
171
+ fi
172
+ blank=${(l:w:: :)}
173
+ out+=$'\e['$(( top - 1 ))';'${left}H$blank
174
+ for (( r = 0; r < 5; r++ )); do
175
+ line=" "
176
+ for (( k = 1; k <= n; k++ )); do
177
+ bits=${TTHEME_GLYPHS[${text[k]}]}
178
+ for (( c = 1; c <= 3; c++ )); do
179
+ if [[ ${bits[r * 3 + c]} == 1 ]]; then
180
+ line+=${(l:2*s::█:)}
181
+ else
182
+ line+=${(l:2*s:: :)}
183
+ fi
184
+ done
185
+ (( k < n )) && line+=${(l:2*s:: :)}
186
+ done
187
+ line+=" "
188
+ for (( i = 0; i < s; i++ )); do
189
+ out+=$'\e['$(( top + r * s + i ))';'${left}H$oc$line$'\e[0m'
190
+ done
191
+ done
192
+ out+=$'\e['$(( top + 5 * s ))';'${left}H$blank
193
+ }
194
+
195
+ __tt_pv_lw() {
196
+ local -i lw=$(( pw - 2 < 48 ? pw - 2 : 48 )) l=$(( pw * 3 / 10 )) sw=$(( pw * 45 / 100 ))
197
+ (( l < 38 )) && l=38
198
+ (( l > 56 )) && l=56
199
+ (( sw > 64 )) && sw=64
200
+ if (( te && sw < 50 )); then
201
+ sw=50
202
+ (( pw - l - 6 < sw )) && l=$(( pw - sw - 6 ))
203
+ (( l < 30 )) && l=30
204
+ fi
205
+ (( sw > pw - l - 6 )) && sw=$(( pw - l - 6 ))
206
+ if (( color && sw >= 32 )); then
207
+ lw=$l
208
+ else
209
+ sw=0
210
+ fi
211
+ reply=($lw $sw)
212
+ }
213
+
214
+ __tt_pv_hl() {
215
+ local t=$1 lt=${(L)1} pre
216
+ REPLY=$t
217
+ (( color )) && [[ -n $flt && $lt == *$flt* ]] || return 0
218
+ pre=${lt%%$flt*}
219
+ REPLY=${t[1,${#pre}]}$'\e[1;4m'$ac${t[${#pre}+1,${#pre}+${#flt}]}$'\e[22;24;39m'$2${t[${#pre}+${#flt}+1,-1]}
220
+ }
221
+
222
+ __tt_pv_fit() {
223
+ local extra=$1
224
+ REPLY=""
225
+ [[ -n $extra ]] || return 0
226
+ while [[ -n $extra ]] && (( ${(m)#extra} + 3 > w )); do
227
+ extra=${extra[1,-2]}
228
+ done
229
+ [[ -n $extra ]] || return 0
230
+ (( w -= ${(m)#extra} + 2 ))
231
+ REPLY=" "$d$extra$r
232
+ }
233
+
234
+ __tt_pv_row() {
235
+ local t=${rval[$1]} b=$'\e[1m' d=$'\e[2m' r=$'\e[22;24;39m' z=$'\e[0m' on="" gut=" " base="" lead=$'\e[2m' mark=" " name arrow=▸ ind=" " hl extra part
236
+ local -i w
237
+ (( color )) || b= d= r= z= lead=
238
+ if (( $1 == cur )); then
239
+ gut=$ac"▌"$r" "
240
+ (( color )) && on=$sb
241
+ fi
242
+ if [[ ${rtype[$1]} == rule ]]; then
243
+ name='── Markets '
244
+ REPLY=" "$d$name${(l:lw - 4 - ${#name}::─:)}$z
245
+ return 0
246
+ fi
247
+ if [[ ${rtype[$1]} == hdr ]]; then
248
+ [[ -n $flt || -n ${exp[$t]} ]] && arrow=▾
249
+ name=$t
250
+ (( ${(m)#name} > lw - 10 )) && name="${name[1,lw-11]}…"
251
+ base=$b
252
+ if (( color )) && [[ $t == "$ag" ]]; then
253
+ base+=$ac lead=$ac
254
+ elif (( $1 == cur )); then
255
+ lead=""
256
+ fi
257
+ __tt_pv_hl "$name" "$base"
258
+ hl=$REPLY
259
+ w=$(( lw - 6 - ${(m)#name} - ${#rcnt[$1]} ))
260
+ __tt_pv_alias "$t" "${TTHEME_NATIVE[${${=gthemes[$t]}[1]}]}"
261
+ __tt_pv_fit "$REPLY"
262
+ extra=$REPLY
263
+ (( w < 1 )) && w=1
264
+ REPLY=$gut$on" "$lead$arrow$r" "$base$hl$r$extra${(l:w:: :)}$d${rcnt[$1]}$r" "$z
265
+ return 0
266
+ fi
267
+ if [[ ${rtype[$1]} == cat ]]; then
268
+ [[ -n $flt || -n ${exp[$t]} ]] && arrow=▾
269
+ name=${t#*/}
270
+ (( ${(m)#name} > lw - 12 )) && name="${name[1,lw-13]}…"
271
+ base=$b
272
+ if (( color )) && [[ $t == "$acat" ]]; then
273
+ base+=$ac lead=$ac
274
+ elif (( $1 == cur )); then
275
+ lead=""
276
+ fi
277
+ __tt_pv_hl "$name" "$base"
278
+ w=$(( lw - 8 - ${(m)#name} - ${#rcnt[$1]} ))
279
+ (( w < 1 )) && w=1
280
+ REPLY=$gut$on" "$lead$arrow$r" "$base$REPLY$r${(l:w:: :)}$d${rcnt[$1]}$r" "$z
281
+ return 0
282
+ fi
283
+ if (( $1 == cur )); then
284
+ mark=$ac"■"$r base=$b
285
+ elif [[ -n $cdot && $t == "$cn" ]]; then
286
+ mark=$cdot
287
+ fi
288
+ name=${t##*/}
289
+ [[ -n ${TTHEME_CATALOG[$t]} && ${TTHEME_GROUP[$t]} == *@* ]] && ind=" "
290
+ __tt_pv_hl "$name" "$base"
291
+ hl=$REPLY
292
+ extra=""
293
+ for part in "${(@s:|:)TTHEME_NATIVE_NAMES[$t]}" "${TTHEME_CHARACTER[$t]}"; do
294
+ __tt_pv_alias "$name" "$part"
295
+ [[ -n $REPLY ]] && { extra=$REPLY; break }
296
+ done
297
+ if (( color )); then
298
+ [[ -n ${tstrip[$t]} ]] || __tt_pv_strip $t
299
+ w=$(( lw - 16 - ${#ind} - ${#name} ))
300
+ __tt_pv_fit "$extra"
301
+ (( w < 1 )) && w=1
302
+ REPLY=$gut$on"$ind$mark $base$hl$r$REPLY${(l:w:: :)}${tstrip[$t]} "$z
303
+ else
304
+ REPLY="$gut$ind$mark $hl${extra:+ $extra}"
305
+ fi
306
+ }
307
+
308
+ __tt_pv_bg_title() {
309
+ local by=${bgby[$tpick]} ref=${bgfrom[$tpick]} url=${bgurl[$tpick]} mark="" sgr=""
310
+ local -i room=$1
311
+ [[ -n $ref && $url == http(s|)://* ]] && (( ${TTHEME_LINKS[(Ie)$TTHEME_ADAPTER]} )) && mark="⧉ "
312
+ REPLY=Background${by:+ · $by}${ref:+ · $mark$ref}$2
313
+ (( ${#REPLY} > room )) && REPLY=Background${by:+ · $by}
314
+ (( ${#REPLY} > room )) && REPLY=Background
315
+ [[ -n $mark && $REPLY == *"$mark$ref"* ]] || return 0
316
+ (( color )) && [[ -n ${TTHEME_SITE_ANSI[${ref%% *}]} ]] && sgr=$'\e[3'${TTHEME_SITE_ANSI[${ref%% *}]}m
317
+ REPLY=${REPLY/"$mark$ref"/$sgr⧉${sgr:+$'\e[39m'} $'\e]8;;'$url$'\e\\'$ref$'\e]8;;\e\\'}
318
+ return 0
319
+ }
320
+
321
+ __tt_pv_bar() {
322
+ local z=$'\e[0m' d=$'\e[2m' on=$'\e[7;1m'$ac line=" " title hint="tab next"
323
+ local -i i at=${TTHEME_HUB_TABS[(Ie)preview]} len=${#TTHEME_HUB_TITLES}
324
+ (( color )) || z= d= on=
325
+ [[ ${rtype[cur]} == thm ]] && hint="⇧tab switch"
326
+ for title in $TTHEME_HUB_TITLES; do
327
+ (( len += ${#title} + 2 ))
328
+ done
329
+ for (( i = 1; i <= ${#TTHEME_HUB_TITLES}; i++ )); do
330
+ title=${TTHEME_HUB_TITLES[i]}
331
+ (( i > 1 )) && line+=" "
332
+ if (( i != at )); then
333
+ line+=$d" $title "$z
334
+ elif (( color )); then
335
+ line+=$on" $title "$z
336
+ else
337
+ line+="[$title]"
338
+ fi
339
+ done
340
+ (( len + ${#hint} + 2 <= $1 )) && line+=" "$d$hint$z
341
+ REPLY=$line
342
+ }
343
+
344
+ __tt_pv_head() {
345
+ local b=$'\e[1m' d=$'\e[2m' z=$'\e[0m' right=$6
346
+ (( color )) || b= d= z=
347
+ out+=$'\e['$1';'$2'H'$b$ac$4$z
348
+ [[ -n $5 ]] && out+=" "$d$5$z
349
+ [[ -n $right ]] && out+=$'\e['$(( $3 - ${(m)#right} + 1 ))'G'$d$right$z
350
+ return 0
351
+ }
352
+
353
+ __tt_pv_foot() {
354
+ setopt localoptions extendedglob
355
+ local b=$'\e[1m' d=$'\e[2m' z=$'\e[0m' y=$'\e[33m' on=$'\e[7;1m'$ac badge="" lead="" note="" right="" text line plain hex tb=EDIT
356
+ local -a kk=() kl=() seg=()
357
+ local -i end=$1 i lwid rwid room
358
+ (( color )) || b= d= z= y= on=
359
+ if (( color )) && [[ -n $applied && $applied != "$painted" ]]; then
360
+ hex=${${=applied}[8]#\#}
361
+ printf -v y '\e[38;2;%d;%d;%dm' $((16#${hex:0:2})) $((16#${hex:2:2})) $((16#${hex:4:2}))
362
+ fi
363
+ if (( help )); then
364
+ badge=HELP right=$b"? esc"$z$d" close"$z
365
+ elif [[ -n $pick ]]; then
366
+ badge='PREVIEW (APPLY)' lead="$pick →"
367
+ (( te )) && badge="$tb (APPLY)"
368
+ for (( i = 1; i <= ${#plabel}; i++ )); do
369
+ if (( i != pk )); then
370
+ lead+=" "$d${plabel[i]}$z
371
+ elif (( color )); then
372
+ lead+=" "$on${plabel[i]}$z
373
+ else
374
+ lead+=" [${${plabel[i]# }% }]"
375
+ fi
376
+ done
377
+ if [[ $mode == pin ]]; then
378
+ badge='PREVIEW (PIN)'
379
+ (( te )) && badge="$tb (PIN)"
380
+ __tt_pin_where "${pkeys[pk]}"
381
+ note=$REPLY
382
+ elif (( pk == 2 )); then
383
+ note="Until this tab closes"
384
+ else
385
+ note="New tabs · the default palette"
386
+ fi
387
+ kk=(enter) kl=(confirm)
388
+ right=$b"esc"$z$d" back"$z
389
+ elif (( te && tfocus == 0 )); then
390
+ badge=$tb
391
+ kk=("${(@ps:\x1e:)teframe[6]}") kl=("${(@ps:\x1e:)teframe[7]}")
392
+ i=${kk[(Ie)esc]}
393
+ (( i )) && kk[i]=() kl[i]=()
394
+ right=$b"esc"$z$d" cancel"$z
395
+ if [[ $temode == list ]]; then
396
+ kk=("${kk[1]}" s "${(@)kk[2,-1]}" ⇧enter) kl=("${kl[1]}" save "${(@)kl[2,-1]}" apply)
397
+ elif [[ $temode == tune ]]; then
398
+ right=$b"esc"$z$d" undo"$z
399
+ elif [[ $temode == (type|compare) ]]; then
400
+ right=$b"esc"$z$d" back"$z
401
+ fi
402
+ elif (( te && tfocus == 2 )); then
403
+ badge=$tb kk=(enter ↑↓ s) kl=(apply move save)
404
+ right=$b"esc"$z$d" cancel"$z
405
+ elif (( te )); then
406
+ badge=$tb
407
+ kk=(↑↓ ←→ s) kl=(field step save)
408
+ if [[ -n $tune ]] && (( tf == 5 )); then
409
+ __tt_pv_bg_images $tune
410
+ kl[2]="image ×$REPLY"
411
+ (( REPLY > 1 )) || { kk[2]=() kl[2]=() }
412
+ __tt_pv_bg_findable $tune && { kk+=(f); kl+=(find) }
413
+ kk+=(D) kl+=(remove)
414
+ elif [[ -n $tune ]]; then
415
+ __tt_pv_bg_findable $tune && { kk+=(f); kl+=(find) }
416
+ if (( tf == 2 )); then
417
+ kl[2]=move kk+=(1-9 '=' +) kl+=(place reset "reset all")
418
+ elif (( tf == 4 )); then
419
+ kl[2]=switch kk+=(+) kl+=("reset all")
420
+ else
421
+ kk+=('=' + ⇧←→) kl+=(reset "reset all" ×10)
422
+ fi
423
+ (( bgoff[$tpick] )) && { kk+=(space); kl+=(show) } || { kk+=(c space); kl+=(colors hide) }
424
+ __tt_pv_bg_images $tune
425
+ (( REPLY > 1 )) && { kk+=(', .' D); kl+=("image ×$REPLY" remove) }
426
+ else
427
+ kk=(enter ↑↓ s) kl=(find move save)
428
+ fi
429
+ kk+=(⇧enter) kl+=(apply)
430
+ right=$b"esc"$z$d" cancel"$z
431
+ elif (( conf )); then
432
+ badge=CONFIG kk=(↑↓ ←→ enter) kl=(setting value save)
433
+ right=$b"esc"$z$d" undo"$z
434
+ else
435
+ badge=PREVIEW
436
+ [[ -n $flt ]] && badge='PREVIEW (FILTER)'
437
+ if (( ! ${#rval} )); then
438
+ kk=(bksp) kl=(edit)
439
+ elif [[ ${rtype[cur]} == (hdr|cat) ]]; then
440
+ if [[ -z $flt && -n ${exp[${rval[cur]}]} ]]; then
441
+ kk=(←) kl=(close)
442
+ elif [[ -z $flt ]]; then
443
+ kk=(→) kl=(open)
444
+ fi
445
+ else
446
+ kk=(enter tab) kl=(apply edit)
447
+ (( split )) && { kk+=(⇧←→); kl+=(example) }
448
+ [[ -n $flt ]] && { kk+=(bksp); kl+=(edit) }
449
+ fi
450
+ kk+=('?') kl+=(keys)
451
+ if [[ -n $flt ]]; then
452
+ right=$b"esc"$z$d" clear filter"$z
453
+ else
454
+ right=$b"esc"$z$d" restore"$z
455
+ [[ -n $cdot ]] && right+=" $cdot$z $cn"
456
+ fi
457
+ fi
458
+ if (( msgt > 0 )) && [[ -z $pick ]]; then
459
+ text=$msg
460
+ room=$(( end - (${#badge} ? ${#badge} + 4 : 0) ))
461
+ if (( ${(m)#text} > room )); then
462
+ while [[ -n $text ]] && (( ${(m)#text} > room - 1 )); do text=${text[1,-2]}; done
463
+ text+=…
464
+ fi
465
+ lead=$y$text$z note="" kk=() kl=()
466
+ fi
467
+ while :; do
468
+ seg=()
469
+ [[ -n $lead ]] && seg+=("$lead")
470
+ [[ -n $note ]] && seg+=("$d$note$z")
471
+ for (( i = 1; i <= ${#kk}; i++ )); do
472
+ seg+=("$b${kk[i]}$z$d ${kl[i]}$z")
473
+ done
474
+ line=${(j: :)seg}
475
+ if [[ -n $badge ]]; then
476
+ if (( color )); then
477
+ line=$'\e[7;1m'$ac" $badge "$z" "$line
478
+ else
479
+ line="[$badge] $line"
480
+ fi
481
+ fi
482
+ plain=${line//$'\e'\[[0-9;]##m/}
483
+ lwid=${(m)#plain}
484
+ plain=${right//$'\e'\[[0-9;]##m/}
485
+ rwid=${(m)#plain}
486
+ (( lwid <= end && (! rwid || lwid + 3 + rwid <= end) )) && break
487
+ if [[ -n $note ]]; then
488
+ note=""
489
+ elif (( ${#kk} > 2 )); then
490
+ kk[-2]=() kl[-2]=()
491
+ elif [[ -n $right ]]; then
492
+ right=""
493
+ elif (( ${#kk} > 1 )); then
494
+ kk[-2]=() kl[-2]=()
495
+ else
496
+ break
497
+ fi
498
+ done
499
+ out+=$line$'\e[K'
500
+ [[ -n $right ]] && out+=$'\e['$(( end - rwid + 1 ))'G'$right
501
+ return 0
502
+ }
503
+
504
+ __tt_pv_help() {
505
+ local back="the tab" z=$'\e[0m' b=$'\e[1m' blank
506
+ [[ -n ${TTHEME_PALETTE[$cn]} ]] && back=$cn
507
+ local -a hk=() hv=()
508
+ if (( te )); then
509
+ hk=(Move Image "" "" "" Palette "" "" "" Apply Save Cancel)
510
+ hv=(
511
+ "↑↓ j k the image, the palette, then Apply · home end"
512
+ "Images ←→ , . pick one · D removes it · f finds one"
513
+ "enter on the empty frame · finds the first one"
514
+ "←→ step ⇧←→ ×10 1-9 place · = resets · + all"
515
+ "space hides · c colors"
516
+ "←→ normal or bright · enter tab tune it · # a color"
517
+ "r resets a slot · R all · space the colors before"
518
+ "c copies · v pastes · = bright follows normal"
519
+ "f moves the colors the gate misses · u undo"
520
+ "enter on Apply, or ⇧enter anywhere · saves, asks where"
521
+ "s · keeps the picture and the palette"
522
+ "esc · back to the list, dropping what changed since s"
523
+ )
524
+ else
525
+ hk=(Move Series Filter "" Example Apply Edit)
526
+ hv=(
527
+ "↑↓ home end pgup pgdn"
528
+ "←→ · enter or space on a series"
529
+ "Any text · bksp · ctrl-u clears"
530
+ "Names and titles, in Japanese too"
531
+ "⇧←→ ${(Lj:, :)TTHEME_SCENES}"
532
+ "enter applies · esc restores $back"
533
+ "tab → ctrl+e · its colors and picture"
534
+ )
535
+ hk+=(Config "")
536
+ hv+=("alt-c · ↑↓ setting ←→ value" "enter saves · esc undoes")
537
+ (( hub )) && { hk+=(Screens); hv+=("shift+tab · tab on a series") }
538
+ fi
539
+ hk+=(Close)
540
+ hv+=("? esc")
541
+ (( color )) || z= b=
542
+ local -i i r x y w hh
543
+ if (( split && sw >= 48 )); then
544
+ for (( i = 1; i <= ${#hk}; i++ )); do
545
+ r=$(( i + 3 ))
546
+ (( r < ph )) || break
547
+ out+=$'\e['$r';'$sc'H'$b${hk[i]}$z$'\e['$r';'$(( sc + 10 ))'H'${hv[i][1,se-sc-9]}
548
+ done
549
+ return 0
550
+ fi
551
+ w=$(( pw - 2 < 58 ? pw - 2 : 58 )) hh=$(( ${#hk} + 4 ))
552
+ (( te )) && w=$(( pw - 2 < 76 ? pw - 2 : 76 ))
553
+ x=$(( (pw - w) / 2 + 1 )) y=$(( (ph - hh) / 2 ))
554
+ (( y < 4 )) && y=4
555
+ blank=${(l:w:: :)}
556
+ out+=$'\e['$y';'$x'H'"╭─ Help ${(l:$(( w - 9 ))::─:)}╮"
557
+ for (( r = y + 1; r < y + hh - 1; r++ )); do
558
+ out+=$'\e['$r';'$x'H'$blank$'\e['$r';'$x'H│'$'\e['$r';'$(( x + w - 1 ))'H│'
559
+ done
560
+ for (( i = 1; i <= ${#hk}; i++ )); do
561
+ r=$(( y + 1 + i ))
562
+ out+=$'\e['$r';'$(( x + 3 ))'H'$b${hk[i]}$z$'\e['$r';'$(( x + 13 ))'H'${hv[i][1,w-16]}
563
+ done
564
+ out+=$'\e['$(( y + hh - 1 ))';'$x'H'"╰${(l:$(( w - 2 ))::─:)}╯"
565
+ }
566
+
567
+ __tt_pv_specimen() {
568
+ local -a sp=(${=applied}) lines parts
569
+ (( ${#sp} >= 20 )) || return 0
570
+ local z=$'\e[0m' d=$'\e[2m' cell hex fore line text piece role tabs="" built="" key="$applied|$painted|$scene|$sw|$sc|$ph"
571
+ local -A rs=(p "" d $'\e[2m' b $'\e[1m')
572
+ local -i i r=6 cw=4 k n=${#TTHEME_SCENES} at
573
+ (( n )) || return 0
574
+ if [[ $key == "$pvscene" ]]; then
575
+ out+=$pvscenes
576
+ return 0
577
+ fi
578
+ at=$(( (scene % n + n) % n + 1 ))
579
+ if [[ $applied == "$painted" ]]; then
580
+ for (( i = 0; i < 16; i++ )); do
581
+ k=$(( i < 8 ? 30 + i : 82 + i ))
582
+ rs[$i]=$'\e['$k'm' rs[B$i]=$'\e[1;'$k'm' rs[K$i]=$'\e[30;'$(( k + 10 ))'m'
583
+ done
584
+ else
585
+ fore=${sp[5]#\#}
586
+ for (( i = 0; i < 16; i++ )); do
587
+ hex=${sp[i+5]#\#}
588
+ printf -v cell '\e[38;2;%d;%d;%dm' $((16#${hex:0:2})) $((16#${hex:2:2})) $((16#${hex:4:2}))
589
+ rs[$i]=$cell
590
+ printf -v cell '\e[38;2;%d;%d;%d;48;2;%d;%d;%dm' $((16#${fore:0:2})) $((16#${fore:2:2})) $((16#${fore:4:2})) \
591
+ $((16#${hex:0:2})) $((16#${hex:2:2})) $((16#${hex:4:2}))
592
+ rs[K$i]=$cell
593
+ hex=${sp[(i < 8 ? i + 13 : i + 5)]#\#}
594
+ printf -v cell '\e[1;38;2;%d;%d;%dm' $((16#${hex:0:2})) $((16#${hex:2:2})) $((16#${hex:4:2}))
595
+ rs[B$i]=$cell
596
+ done
597
+ fi
598
+ printf -v cell '\e[48;2;%d;%d;%dm' $((16#${sp[4]:1:2})) $((16#${sp[4]:3:2})) $((16#${sp[4]:5:2}))
599
+ rs[s]=$cell
600
+ printf -v cell '\e[48;2;%d;%d;%dm' $((16#${sp[3]:1:2})) $((16#${sp[3]:3:2})) $((16#${sp[3]:5:2}))
601
+ rs[c]=$cell
602
+ if (( ${#${(j: :)TTHEME_SCENES}} <= sw )); then
603
+ for (( k = 1; k <= n; k++ )); do
604
+ (( k > 1 )) && tabs+=" "
605
+ if (( k == at )); then
606
+ tabs+=$'\e[1m'$ac$TTHEME_SCENES[k]$z
607
+ else
608
+ tabs+=$d$TTHEME_SCENES[k]$z
609
+ fi
610
+ done
611
+ else
612
+ tabs=$'\e[1m'$ac$TTHEME_SCENES[at]$z" "$d"$at/$n"$z
613
+ fi
614
+ built+=$'\e[2;'$sc'H'$tabs
615
+ (( sw < 44 )) && cw=3
616
+ (( sw >= 56 )) && cw=$(( (sw + 1) / 8 - 1 ))
617
+ (( cw > 7 )) && cw=7
618
+ line=""
619
+ for (( i = 0; i < 8; i++ )); do
620
+ fore=${sp[i+5]#\#} hex=${sp[i+13]#\#}
621
+ printf -v cell '\e[38;2;%d;%d;%d;48;2;%d;%d;%dm%s\e[0m ' \
622
+ $((16#${fore:0:2})) $((16#${fore:2:2})) $((16#${fore:4:2})) \
623
+ $((16#${hex:0:2})) $((16#${hex:2:2})) $((16#${hex:4:2})) "${(l:cw::▀:)}"
624
+ line+=$cell
625
+ done
626
+ built+=$'\e[4;'$sc'H'$line
627
+ lines=("${(@P)${:-TTHEME_SCENE_$at}}")
628
+ for line in "${lines[@]}"; do
629
+ [[ $line == «w»* ]] && (( sw < 44 )) && continue
630
+ [[ $line == «n»* ]] && (( sw >= 44 )) && continue
631
+ (( r < ph )) || break
632
+ parts=("${(@s:«:)line}")
633
+ text=$parts[1]
634
+ for piece in "${(@)parts[2,-1]}"; do
635
+ role=${piece%%»*}
636
+ [[ $role == [wn] ]] && role=p
637
+ text+=$z${rs[${role:-p}]}${piece#*»}
638
+ done
639
+ built+=$'\e['$r';'$sc'H'$text$z
640
+ (( ++r ))
641
+ done
642
+ pvscene=$key pvscenes=$built
643
+ out+=$built
644
+ }
645
+
646
+ __tt_pv_tune() {
647
+ local -a fields=(size pos op)
648
+ local -i n=1
649
+ local name
650
+ case $key in
651
+ $'\x03') return 1 ;;
652
+ up) tf=$(( tf > 1 ? tf - 1 : 4 )) ;;
653
+ down) tf=$(( tf < 4 ? tf + 1 : 1 )) ;;
654
+ c) (( bgoff[$tpick] )) || __tt_pv_bg_recolor ;;
655
+ left|right|sleft|sright)
656
+ if (( tf == 4 )); then
657
+ (( bgoff[$tpick] )) || __tt_pv_bg_recolor
658
+ return 0
659
+ fi
660
+ [[ $key == *left ]] && n=-1
661
+ [[ $key == s* ]] && (( tf != 2 )) && n=$(( n * 10 ))
662
+ __tt_pv_bg_adjust ${fields[tf]} $n
663
+ ;;
664
+ [1-9])
665
+ tf=2
666
+ __tt_pv_bg_adjust at $key
667
+ ;;
668
+ ' ') __tt_pv_bg_adjust on ;;
669
+ '=') (( tf == 4 )) || __tt_pv_bg_adjust def $tf ;;
670
+ '+') __tt_pv_bg_adjust def ;;
671
+ ',') __tt_pv_bg_pick -1 ;;
672
+ '.') __tt_pv_bg_pick 1 ;;
673
+ D) __tt_pv_bg_drop ;;
674
+ esac
675
+ return 0
676
+ }
677
+
678
+ __tt_pv_tune_stage() {
679
+ local img was=${bgview[$tune]:-$tune}
680
+ local -i changed=0
681
+ for img in ${(k)tsnaps}; do
682
+ [[ "${bgsize[$img]} ${bgpos[$img]} ${bgop[$img]} ${bgoff[$img]}" == "${tsnaps[$img]}" ]] && continue
683
+ bgedit[$img]=1 changed=1
684
+ done
685
+ if [[ $tpick != "$was" ]]; then
686
+ changed=1
687
+ if [[ $tpick == "$tune" ]]; then
688
+ unset "bgview[$tune]" "bgswap[$tune]"
689
+ else
690
+ bgview[$tune]=$tpick bgswap[$tune]=${tpick##*:}
691
+ fi
692
+ fi
693
+ (( changed )) && msg="Kept · saved when preview closes" msgt=200
694
+ tune="" tpick="" tsnaps=() bgname=""
695
+ }
696
+
697
+ __tt_pv_tune_keep() {
698
+ __tt_pv_bg_strip_off
699
+ __tt_pv_tune_stage
700
+ }
701
+
702
+ __tt_pv_untune() {
703
+ local img
704
+ local -a s
705
+ for img in ${(k)tsnaps}; do
706
+ s=(${=tsnaps[$img]})
707
+ bgsize[$img]=$s[1] bgpos[$img]=$s[2] bgop[$img]=$s[3] bgoff[$img]=$s[4]
708
+ done
709
+ __tt_pv_bg_strip_off
710
+ tune="" tpick="" tsnaps=() bgname=""
711
+ }
712
+
713
+ __tt_pv_regroup() {
714
+ local ty=${rtype[cur]} v=${rval[cur]} i
715
+ __tt_pv_group
716
+ __tt_pv_rows
717
+ for (( i = 1; i <= ${#rval}; i++ )); do
718
+ [[ ${rtype[i]} == "$ty" && ${rval[i]} == "$v" ]] && { cur=$i; return 0 }
719
+ done
720
+ cur=1
721
+ }
722
+
723
+ __tt_pv_conf() {
724
+ case $key in
725
+ $'\x03') return 1 ;;
726
+ up|k) cf=$(( cf > 1 ? cf - 1 : ${#cvars} )) ;;
727
+ down|j) cf=$(( cf < ${#cvars} ? cf + 1 : 1 )) ;;
728
+ left|sleft) __tt_pv_conf_step -1 ;;
729
+ right|sright) __tt_pv_conf_step 1 ;;
730
+ $'\r'|$'\n') __tt_pv_conf_save ;;
731
+ esc) __tt_pv_unconf ;;
732
+ '?') help=1 ;;
733
+ esac
734
+ return 0
735
+ }
736
+
737
+ __tt_pv_conf_step() {
738
+ local var=${cvars[cf]}
739
+ local -a ch=(${=cchoice[cf]})
740
+ local -i i=${ch[(Ie)${(P)var}]}
741
+ (( i += $1 ))
742
+ (( i >= 1 && i <= ${#ch} )) || return 0
743
+ __tt_pv_conf_put $var ${ch[i]}
744
+ }
745
+
746
+ __tt_pv_conf_put() {
747
+ [[ ${(P)1} == "$2" ]] && return 0
748
+ typeset -g "$1=$2"
749
+ case $1 in
750
+ TTHEME_SORT) __tt_pv_regroup ;;
751
+ TTHEME_FX) [[ -n $flt ]] || { __tt_pv_roll; gstep=8 } ;;
752
+ TTHEME_TAB_PALETTE) __tt_pv_canpick ;;
753
+ esac
754
+ }
755
+
756
+ __tt_pv_unconf() {
757
+ local -i i
758
+ for (( i = 1; i <= ${#cvars}; i++ )); do
759
+ __tt_pv_conf_put ${cvars[i]} "${csnap[i]}"
760
+ done
761
+ conf=0
762
+ }
763
+
764
+ __tt_pv_conf_save() {
765
+ local var REPLY
766
+ local -a pairs=()
767
+ local -i i
768
+ for (( i = 1; i <= ${#cvars}; i++ )); do
769
+ var=${cvars[i]}
770
+ [[ ${(P)var} == "${csnap[i]}" ]] || pairs+=($var "${(P)var}")
771
+ done
772
+ if (( ! ${#pairs} )); then
773
+ conf=0
774
+ return 0
775
+ fi
776
+ __tt_tilde "$TTHEME_CONFIG"
777
+ if __tt_config_write "${pairs[@]}"; then
778
+ conf=0 msg="Saved · $REPLY" msgt=200
779
+ (( ${pairs[(Ie)TTHEME_BG_BLUR]} )) && __tt_pv_redraw
780
+ else
781
+ __tt_pv_unconf
782
+ msg="Could not write $REPLY" msgt=200
783
+ fi
784
+ }
785
+
786
+ __tt_pv_redraw() {
787
+ local name out
788
+ if (( $+functions[__tt_bg_write] )); then
789
+ for name in ${(k)bgedit}; do
790
+ __tt_bg_write $name
791
+ done
792
+ fi
793
+ bgedit=()
794
+ msg="Drawing the background pictures again" msgt=300
795
+ printf '\e[?2026h'
796
+ __tt_pv_draw
797
+ out=$(__tt_cli redraw 2>&1)
798
+ bgsrc=() resized=1 bgname="" bgshown="" bgdim=()
799
+ __tt_reload
800
+ (( $+functions[__tt_bg_refresh] )) && __tt_bg_refresh $TTHEME_ORDER
801
+ msg=${${out//$'\n'/ }:-"Saved · no background pictures to draw"} msgt=300
802
+ }
803
+
804
+ __tt_pv_conf_panel() {
805
+ local z=$'\e[0m' b=$'\e[1m' d=$'\e[2m' c=$ac on=$'\e[7;1m'$ac var v note
806
+ local -a ch sh
807
+ local -i r0=$1 col=$2 end=$3 k i j fit=1
808
+ (( color )) || z= b= d= c= on=
809
+ for (( k = 1; k <= ${#cvars}; k++ )); do
810
+ sh=(${=cshow[k]})
811
+ (( 13 + ${#${(j: :)sh}} + 2 * ${#sh} > end - col + 1 )) && fit=0
812
+ done
813
+ for (( k = 1; k <= ${#cvars}; k++ )); do
814
+ var=${cvars[k]} ch=(${=cchoice[k]}) sh=(${=cshow[k]})
815
+ i=${ch[(Ie)${(P)var}]}
816
+ out+=$'\e['$(( r0 + k - 1 ))';'$col'H'
817
+ if (( k == cf )); then
818
+ out+=$c"▶"$z" "$b
819
+ else
820
+ out+=" "$d
821
+ fi
822
+ out+=${(r:11:)clabel[k]}$z
823
+ if (( ! fit )); then
824
+ v=${(P)var}
825
+ (( i )) && v=${sh[i]}
826
+ if (( k == cf )); then
827
+ out+=$c"‹ "$z$b$v$z$c" ›"$z
828
+ else
829
+ out+=" "$v
830
+ fi
831
+ continue
832
+ fi
833
+ for (( j = 1; j <= ${#sh}; j++ )); do
834
+ (( j > 1 )) && out+=" "
835
+ if (( j != i )); then
836
+ out+=$d" ${sh[j]} "$z
837
+ elif (( ! color )); then
838
+ out+="[${sh[j]}]"
839
+ elif (( k == cf )); then
840
+ out+=$on" ${sh[j]} "$z
841
+ else
842
+ out+=" ${sh[j]} "
843
+ fi
844
+ done
845
+ done
846
+ var=${cvars[cf]}
847
+ note=${cnote[$var:${(P)var}]}
848
+ [[ -n $note ]] && out+=$'\e['$(( r0 + ${#cvars} + 1 ))';'$col'H'$d${note[1,end-col+1]}$z
849
+ return 0
850
+ }
851
+
852
+ __tt_pv_flush() {
853
+ local REPLY
854
+ print -rn -- "$out"
855
+ if (( wiped )); then
856
+ local bn=$bgname
857
+ if [[ ${rtype[cur]} == thm ]]; then
858
+ __tt_pv_shows ${rval[cur]}
859
+ bn=$REPLY
860
+ fi
861
+ [[ -n $bn ]] && __tt_pv_bg_show "$bn" 1
862
+ fi
863
+ if [[ -n $bgstrip ]]; then
864
+ __tt_pv_bg_strip ${=bgstrip}
865
+ elif (( ${#bgthumb} )); then
866
+ __tt_pv_bg_strip_off
867
+ fi
868
+ printf '\e[1;%dH\e[?2026l' $(( 4 + ${(m)#flt} ))
869
+ }
870
+
871
+ __tt_pv_reach() {
872
+ local key=${pkeys[pk]} base top k home=${HOME:a} here=${PWD:a} htip="" d=$'\e[2m' z=$'\e[0m' REPLY
873
+ local -A own=() below=() parent=() mark=() tstrip=()
874
+ local -a roots=() lp=() lpw=() ll=() lat=() lpal=() lnote=() lflag=() reply was=()
875
+ local -A TTHEME_PINS=("${(@kv)TTHEME_PINS}")
876
+ local -i room=$2
877
+ (( color )) || d= z=
878
+ (( room < 2 )) && room=2
879
+ if [[ $key == ssh:* ]]; then
880
+ __tt_pin_scope "$key"
881
+ [[ -n ${TTHEME_PINS[$key]} && $TTHEME_PINS[$key] != "$pick" ]] && was+=("${TTHEME_PINS[$key]} · $REPLY")
882
+ TTHEME_PINS[$key]=$pick
883
+ mark[$key]=new
884
+ __tt_map_ssh
885
+ else
886
+ __tt_pin_base "$key"
887
+ base=$REPLY
888
+ for k in ${(k)TTHEME_PINS}; do
889
+ [[ $k == /* ]] || continue
890
+ __tt_pin_base "$k"
891
+ [[ $REPLY == "$base" ]] || continue
892
+ if [[ $k != "$key" || $TTHEME_PINS[$k] != "$pick" ]]; then
893
+ __tt_pin_scope "$k"
894
+ was+=("${TTHEME_PINS[$k]} · $REPLY")
895
+ fi
896
+ unset "TTHEME_PINS[$k]"
897
+ done
898
+ TTHEME_PINS[$key]=$pick
899
+ top=$base
900
+ [[ $base != / ]] && __tt_pin_cover "${base:h}" && __tt_pin_base "$REPLY" && top=$REPLY
901
+ mark[$base]=new
902
+ __tt_map_build "$top"
903
+ fi
904
+ __tt_map_fit $1
905
+ (( ${#reply} > room )) && reply=("${(@)reply[1,room-1]}" " …")
906
+ reach=("${reply[@]}")
907
+ [[ $key == /* || ${#was} -gt 0 ]] && reach+=("")
908
+ __tt_pin_where "$key"
909
+ base=$REPLY
910
+ for k in $was; do
911
+ __tt_clip "${d}Replaces ${k% · *} on $base · ${k##* · }$z" $1
912
+ reach+=("$REPLY")
913
+ done
914
+ __tt_pin_scope "$key"
915
+ __tt_clip "→ $base · $REPLY" $(( $1 - ${(m)#pick} - 2 ))
916
+ rsub=$REPLY
917
+ [[ $key == /* ]] || return 0
918
+ __tt_here_fit "Then here" $1
919
+ reach+=("${reply[@]}")
920
+ }
921
+
922
+ __tt_pv_draw() {
923
+ local out line cnt ex ag="" acat="" ac="" sb="" dd="" zz="" state=on src="" nflt="" rsub="" REPLY
924
+ local -i lw sw split sc se=$(( pw - 2 )) h k i N=${#rval} mt=${#TTHEME_ORDER} wiped=0
925
+ local -a held
926
+ bgstrip=""
927
+ if [[ -n $flt ]]; then
928
+ __tt_pv_norm "$flt"
929
+ nflt=$REPLY
930
+ fi
931
+ if (( te )) && [[ -n $tespec && $tespec != "$applied" ]]; then
932
+ __tt_pv_paint "$tespec"
933
+ applied=$tespec
934
+ fi
935
+ __tt_pv_lw
936
+ lw=$reply[1] sw=$reply[2]
937
+ split=$(( sw > 0 )) sc=$(( pw - 1 - sw ))
938
+ h=$(( ph - 5 ))
939
+ (( conf && ! split )) && h=$(( ph - 6 - ${#cvars} ))
940
+ reach=()
941
+ if [[ -n $pick && $mode == pin ]]; then
942
+ if (( split )); then
943
+ __tt_pv_reach $sw $(( ph - 6 ))
944
+ else
945
+ __tt_pv_reach $se $(( ph - 13 ))
946
+ h=$(( ph - 6 - ${#reach} ))
947
+ fi
948
+ fi
949
+ (( h < 1 )) && h=1
950
+ (( cur < top )) && top=$cur
951
+ (( cur >= top + h )) && top=$(( cur - h + 1 ))
952
+ (( top < 1 )) && top=1
953
+ (( N > h && top > N - h + 1 )) && top=$(( N - h + 1 ))
954
+ if (( color )); then
955
+ dd=$'\e[2m' zz=$'\e[0m'
956
+ if [[ -n $applied ]]; then
957
+ local -a ap=(${=applied})
958
+ local acx=${ap[3]#\#} sbx=${ap[4]#\#}
959
+ printf -v ac '\e[38;2;%d;%d;%dm' $((16#${acx:0:2})) $((16#${acx:2:2})) $((16#${acx:4:2}))
960
+ printf -v sb '\e[48;2;%d;%d;%dm' $((16#${sbx:0:2})) $((16#${sbx:2:2})) $((16#${sbx:4:2}))
961
+ fi
962
+ if [[ ${rtype[cur]} == thm ]]; then
963
+ ag=${TTHEME_GROUP[${rval[cur]}]:-Other}
964
+ [[ -n ${TTHEME_CATALOG[${rval[cur]}]} ]] && acat=$ag/${TTHEME_CATALOG[${rval[cur]}]}
965
+ fi
966
+ fi
967
+ if [[ -n $flt ]]; then
968
+ local -a mm=(${(M)rtype:#thm})
969
+ mt=${#mm}
970
+ fi
971
+ cnt="$mt/${#TTHEME_ORDER}"
972
+ out=$'\e[H'
973
+ if (( resized )); then
974
+ out+=$'\e[K\e[2H\e[J\e[H'
975
+ (( bgcw )) && out+=$'\e_Ga=d,d=A,q=2\e\\'
976
+ resized=0 wiped=1
977
+ fi
978
+ if (( pw < 40 || ph < 12 )); then
979
+ line="ttheme preview"
980
+ (( color )) && line=$'\e[1m'$ac$line$'\e[0m'
981
+ out+=$line$'\e[K\n'"Needs 40×12 — now ${pw}×${ph}"$'\e[K\n'
982
+ line="esc quits"
983
+ (( color )) && line=$'\e[2m'$line$'\e[0m'
984
+ out+=$line$'\e[K\e[J'
985
+ __tt_pv_flush
986
+ return 0
987
+ fi
988
+ if (( te && ! split )); then
989
+ __tt_pv_te_draw
990
+ return 0
991
+ fi
992
+ if [[ -n $flt ]]; then
993
+ if (( color )); then
994
+ line=" "$'\e[1m'$flt$zz$ac$'\e[7m \e[0m'
995
+ else
996
+ line=" ${flt}_"
997
+ fi
998
+ else
999
+ ex="$expal | $exgrp"
1000
+ (( ${#ex} > lw - 19 - ${#cnt} )) && ex="${ex[1,lw-20-${#cnt}]}…"
1001
+ if (( gstep > 0 )); then
1002
+ local gkeep=$(( ${#ex} * (8 - gstep) / 8 ))
1003
+ if [[ $TTHEME_FX == (decode|glitch) ]]; then
1004
+ local gpool='▓▒░#*+=<>?/-_' gstill=' ' gout="" gi
1005
+ [[ $TTHEME_FX == decode ]] && gpool='abcdefghijklmnopqrstuvwxyz' gstill='[^[:alnum:]]'
1006
+ for (( gi = 1; gi <= ${#ex}; gi++ )); do
1007
+ if (( gi + (gi * 7 + gseed) % 3 <= gkeep )) || [[ ${ex[gi]} == $~gstill ]]; then
1008
+ gout+=${ex[gi]}
1009
+ else
1010
+ gout+=${gpool[RANDOM % ${#gpool} + 1]}
1011
+ fi
1012
+ done
1013
+ ex=$gout
1014
+ else
1015
+ ex="${ex[1,gkeep]}▏"
1016
+ fi
1017
+ fi
1018
+ line=" "$dd"Search… e.g. $ex"$zz
1019
+ fi
1020
+ local tail=$'\e['$(( lw - ${#cnt} ))'G'$dd$cnt$zz
1021
+ [[ -n $flt ]] && tail=$'\e['$(( lw - ${#cnt} ))'G'$cnt
1022
+ if [[ $1 == hint ]] && (( ! wiped )); then
1023
+ print -rn -- $'\e['$(( 1 + hub ))$'H\e[0m\e['$lw'X'$line$tail
1024
+ printf '\e[%d;%dH\e[?2026l' $(( 1 + hub )) $(( 4 + ${(m)#flt} ))
1025
+ return 0
1026
+ fi
1027
+ if (( hub )); then
1028
+ __tt_pv_bar $(( split ? sc - 2 : pw - 1 ))
1029
+ out+=$REPLY$'\e[K\n'$line$'\e[K'$tail$'\n'
1030
+ else
1031
+ out+=$line$'\e[K'$tail$'\n\e[K\n'
1032
+ fi
1033
+ (( N > h && top > 1 )) && out+=" "$dd"…"$zz
1034
+ out+=$'\e[K\n'
1035
+ for (( k = 0; k < ph - 4; k++ )); do
1036
+ i=$(( top + k ))
1037
+ line=""
1038
+ if (( k < h )); then
1039
+ if (( ! N )); then
1040
+ (( k == 0 )) && line=" ${dd}No palettes match '$flt'$zz"
1041
+ elif (( i <= N )); then
1042
+ __tt_pv_row $i
1043
+ line=$REPLY
1044
+ fi
1045
+ elif (( k == h && N > h && top + h <= N )); then
1046
+ line=" "$dd"…"$zz
1047
+ fi
1048
+ out+=$line$'\e[K\n'
1049
+ done
1050
+ __tt_pv_foot $(( split ? se : pw ))
1051
+ if (( split )); then
1052
+ if (( help && sw >= 48 )); then
1053
+ __tt_pv_head 1 $sc $se Help
1054
+ __tt_pv_help
1055
+ elif (( ${#reach} )); then
1056
+ __tt_pv_head 1 $sc $se "$pick" "$rsub"
1057
+ for (( k = 1; k <= ${#reach} && k + 2 < ph; k++ )); do
1058
+ out+=$'\e['$(( k + 2 ))';'$sc'H'${reach[k]}
1059
+ done
1060
+ elif (( conf )); then
1061
+ __tt_tilde "$TTHEME_CONFIG"
1062
+ src=$REPLY
1063
+ (( 8 + ${#src} > sw )) && src=""
1064
+ __tt_pv_head 1 $sc $se Config "" "$src"
1065
+ __tt_pv_conf_panel 4 $sc $se
1066
+ elif (( te )); then
1067
+ __tt_pv_te_head $sc $se
1068
+ __tt_pv_te_panel $sc $se 3 $(( ph - 1 ))
1069
+ else
1070
+ [[ -n $an ]] && src=${TTHEME_SRC[$an]}
1071
+ (( ${#an} + 2 + ${#src} > sw )) && src=""
1072
+ __tt_pv_head 1 $sc $se ${an:-custom} "" "$src"
1073
+ __tt_pv_specimen
1074
+ fi
1075
+ (( help && sw < 48 )) && __tt_pv_help
1076
+ else
1077
+ if (( ${#reach} )); then
1078
+ __tt_pv_head $(( ph - 1 - ${#reach} )) 1 $se "$pick" "$rsub"
1079
+ for (( k = 1; k <= ${#reach}; k++ )); do
1080
+ out+=$'\e['$(( ph - 1 - ${#reach} + k ))';1H'${reach[k]}
1081
+ done
1082
+ elif (( conf )); then
1083
+ __tt_pv_head $(( ph - 2 - ${#cvars} )) 1 $lw Config
1084
+ __tt_pv_conf_panel $(( ph - 1 - ${#cvars} )) 1 $lw
1085
+ fi
1086
+ (( help )) && __tt_pv_help
1087
+ fi
1088
+ (( osdt > 0 )) && __tt_pv_osd
1089
+ __tt_pv_flush
1090
+ }
1091
+
1092
+ __tt_pv_group() {
1093
+ local k g
1094
+ groups=() gthemes=()
1095
+ __tt_order
1096
+ for k in $reply; do
1097
+ g=${TTHEME_GROUP[$k]:-Other}
1098
+ [[ -n ${gthemes[$g]} ]] || groups+=($g)
1099
+ gthemes[$g]+=" $k"
1100
+ done
1101
+ }
1102
+
1103
+ __tt_pv_canpick() {
1104
+ canpick=0
1105
+ if [[ $mode == pin ]]; then
1106
+ canpick=1
1107
+ elif __tt_keepable && [[ $TTHEME_TAB_PALETTE == off ]]; then
1108
+ canpick=1
1109
+ fi
1110
+ }
1111
+
1112
+ __tt_pv_strip() {
1113
+ local hex cell=""
1114
+ local -a sw=(${=TTHEME_SWATCH[$1]})
1115
+ local -i j
1116
+ for (( j = 1; j <= 6; j++ )); do
1117
+ hex=${sw[j]#\#}
1118
+ (( j > 1 )) && cell+=" "
1119
+ if [[ -n $hex ]]; then
1120
+ cell+=$'\e[38;2;'$((16#${hex:0:2}))';'$((16#${hex:2:2}))';'$((16#${hex:4:2}))'m■'
1121
+ else
1122
+ cell+=" "
1123
+ fi
1124
+ done
1125
+ tstrip[$1]=$cell$'\e[39m'
1126
+ }
1127
+
1128
+ __tt_pv_init() {
1129
+ local lo
1130
+ local -a tp
1131
+ __tt_pv_group
1132
+ [[ -n $orig ]] && __tt_name_of "$orig" && cn=$REPLY
1133
+ [[ -n ${TTHEME_PALETTE[$cn]} ]] || return 0
1134
+ cdot="◆"
1135
+ (( color )) || return 0
1136
+ tp=(${=TTHEME_PALETTE[$cn]})
1137
+ lo=${tp[3]#\#}
1138
+ printf -v cdot '\e[38;2;%d;%d;%dm◆\e[39m' $((16#${lo:0:2})) $((16#${lo:2:2})) $((16#${lo:4:2}))
1139
+ }
1140
+
1141
+ __tt_pv_roll() {
1142
+ expal=${TTHEME_ORDER[RANDOM % ${#TTHEME_ORDER} + 1]}
1143
+ exgrp=${groups[RANDOM % ${#groups} + 1]}
1144
+ gseed=$RANDOM
1145
+ exnext=$(( SECONDS + 3 ))
1146
+ }
1147
+
1148
+ __tt_pv_size() {
1149
+ local sz=$(stty size 2>/dev/null)
1150
+ [[ $sz == <1->" "<1-> ]] || return 1
1151
+ [[ $sz == "$ph $pw" ]] && return 1
1152
+ ph=${sz%% *} pw=${sz##* } resized=1
1153
+ return 0
1154
+ }
1155
+
1156
+ __tt_pv_getch() {
1157
+ if (( $# )); then
1158
+ read -sk 1 -t $1 2>/dev/null
1159
+ return
1160
+ fi
1161
+ local -F t=0.2 at
1162
+ local -i quick=0
1163
+ (( gstep )) && t=0.06
1164
+ while :; do
1165
+ at=$EPOCHREALTIME
1166
+ read -sk 1 -t $t 2>/dev/null && return 0
1167
+ if (( EPOCHREALTIME - at < t / 4 )); then
1168
+ (( ++quick >= 5 )) && { pvgone=1; return 1 }
1169
+ else
1170
+ quick=0
1171
+ fi
1172
+ [[ -t 0 ]] || return 1
1173
+ __tt_pv_size && return 1
1174
+ if (( osdt > 0 )); then
1175
+ (( osdt -= gstep ? 6 : 20 ))
1176
+ (( osdt > 0 )) || return 1
1177
+ fi
1178
+ if (( msgt > 0 )); then
1179
+ (( msgt -= gstep ? 6 : 20 ))
1180
+ (( msgt > 0 )) || return 1
1181
+ fi
1182
+ (( gstep )) && { gstep=$(( gstep - 1 )); tick=1; return 1 }
1183
+ (( ! te && SECONDS >= exnext )) && { __tt_pv_roll; gstep=8; tick=1; return 1 }
1184
+ done
1185
+ }
1186
+
1187
+ __tt_pv_read() {
1188
+ key=""
1189
+ if (( $# )); then
1190
+ __tt_pv_getch 0 || return 1
1191
+ else
1192
+ __tt_pv_getch || return 1
1193
+ fi
1194
+ key=$REPLY
1195
+ [[ $key == ç ]] && key=altc
1196
+ [[ $key == $'\e' ]] || return 0
1197
+ local seq=""
1198
+ if ! __tt_pv_getch 0.05; then
1199
+ key=esc
1200
+ return 0
1201
+ fi
1202
+ if [[ $REPLY != '[' && $REPLY != O ]]; then
1203
+ key=nop
1204
+ [[ $REPLY == c ]] && key=altc
1205
+ return 0
1206
+ fi
1207
+ while __tt_pv_getch 0.05; do
1208
+ seq+=$REPLY
1209
+ [[ $REPLY == [A-Za-z~] ]] && break
1210
+ done
1211
+ case $seq in
1212
+ A) key=up ;;
1213
+ B) key=down ;;
1214
+ C) key=right ;;
1215
+ D) key=left ;;
1216
+ H|"1~"|"7~") key=home ;;
1217
+ F|"4~"|"8~") key=end ;;
1218
+ "5~") key=pgup ;;
1219
+ "6~") key=pgdn ;;
1220
+ "1;2C") key=sright ;;
1221
+ "1;2D") key=sleft ;;
1222
+ "27;2;13~"|"13;2u") key=senter ;;
1223
+ Z) key=stab ;;
1224
+ *) key=nop ;;
1225
+ esac
1226
+ }
1227
+
1228
+ __tt_pv_pick() {
1229
+ case $key in
1230
+ $'\x03') return 1 ;;
1231
+ esc) pick="" ;;
1232
+ left|stab) pk=$(( (pk + ${#plabel} - 2) % ${#plabel} + 1 )) ;;
1233
+ right|$'\t') pk=$(( pk % ${#plabel} + 1 )) ;;
1234
+ $'\r'|$'\n'|senter)
1235
+ sel=$pick picked=$pk
1236
+ return 1
1237
+ ;;
1238
+ esac
1239
+ return 0
1240
+ }
1241
+
1242
+ __tt_pv_screen() {
1243
+ local err
1244
+ local -i at=${TTHEME_HUB_TABS[(Ie)preview]} n=${#TTHEME_HUB_TABS} rc
1245
+ local -i to=$(( (at - 1 + $1 + n) % n + 1 ))
1246
+ __tt_pv_bg_close
1247
+ while (( to != at )); do
1248
+ hubwas="$TTHEME_STARTUP ${TTHEME_PALETTE[$TTHEME_STARTUP]}"
1249
+ err=$(TTHEME_HUB=${TTHEME_HUB_TABS[to]} __tt_cli ${TTHEME_HUB_TABS[to]} 2>&1 >/dev/tty)
1250
+ rc=$?
1251
+ if (( rc == TTHEME_HUB_CLOSED )); then
1252
+ hubleft=1
1253
+ return 1
1254
+ elif (( rc > TTHEME_HUB_SWITCH && rc <= TTHEME_HUB_SWITCH + n )); then
1255
+ to=$(( rc - TTHEME_HUB_SWITCH ))
1256
+ else
1257
+ err=${${err//$'\n'/ }## #}
1258
+ msg=${err:-"${TTHEME_HUB_TITLES[to]} failed"} msgt=300
1259
+ to=$at
1260
+ fi
1261
+ done
1262
+ printf '\e[?2026h\e[?25l'
1263
+ if [[ -n $applied ]]; then
1264
+ __tt_pv_paint "$applied"
1265
+ else
1266
+ __tt_osc_reset
1267
+ painted=""
1268
+ fi
1269
+ resized=1 bgname="" bgshown="" bgdim=()
1270
+ return 0
1271
+ }
1272
+
1273
+ __tt_te_stop() {
1274
+ setopt localoptions nomonitor nonotify
1275
+ (( TE_IN )) && { print -r -u $TE_IN -- quit 2>/dev/null; exec {TE_IN}>&- }
1276
+ (( TE_OUT )) && exec {TE_OUT}<&-
1277
+ TE_IN=0 TE_OUT=0
1278
+ (( TE_PID )) && { kill $TE_PID 2>/dev/null; wait $TE_PID 2>/dev/null }
1279
+ TE_PID=0
1280
+ return 0
1281
+ }
1282
+
1283
+ __tt_te_ask() {
1284
+ local line
1285
+ (( TE_IN && TE_OUT )) || return 1
1286
+ print -r -u $TE_IN -- "$1" 2>/dev/null || { __tt_te_stop; return 1 }
1287
+ if ! IFS= read -r -u $TE_OUT -t 5 line 2>/dev/null; then
1288
+ __tt_te_stop
1289
+ msg="The palette panel stopped" msgt=300
1290
+ return 1
1291
+ fi
1292
+ teframe=("${(@ps:\x1f:)line}")
1293
+ temode=${teframe[3]:-list}
1294
+ tedirty=${teframe[4]:-0}
1295
+ [[ ${teframe[1]} == error ]] && { msg=${teframe[8]:-"Could not save the tone"} msgt=300 }
1296
+ [[ -n ${teframe[5]} ]] && tespec=${teframe[5]}
1297
+ return 0
1298
+ }
1299
+
1300
+ __tt_te_unsaved_image() {
1301
+ local img
1302
+ for img in ${(k)tsnaps}; do
1303
+ [[ "${bgsize[$img]} ${bgpos[$img]} ${bgop[$img]} ${bgoff[$img]}" == "${tsnaps[$img]}" ]] || return 0
1304
+ done
1305
+ [[ -n $tune && $tpick != "${bgview[$tune]:-$tune}" ]] && return 0
1306
+ return 1
1307
+ }
1308
+
1309
+ __tt_te_unsaved() {
1310
+ (( tedirty )) && return 0
1311
+ __tt_te_unsaved_image
1312
+ }
1313
+
1314
+ __tt_te_save_image() {
1315
+ __tt_te_unsaved_image || return 0
1316
+ __tt_pv_tune_keep
1317
+ __tt_pv_bg_save > /dev/null 2>&1
1318
+ bgedit=() bgswap=() bgview=()
1319
+ __tt_pv_bg_reset $tename
1320
+ bgload[$tename]=""
1321
+ __tt_pv_tune_open $tename
1322
+ }
1323
+
1324
+ __tt_te_open() {
1325
+ local name=$1
1326
+ local -i rfd wfd
1327
+ setopt localoptions nomonitor nonotify
1328
+ coproc __tt_cli tone $name 2>/dev/null
1329
+ exec {rfd}<&p {wfd}>&p
1330
+ TE_OUT=$rfd TE_IN=$wfd TE_PID=$!
1331
+ tename=$name tfocus=0 tespec="" tesz="" teframe=() tedirty=0 temode=list tetop=0 msgt=0
1332
+ if ! __tt_te_ask "focus 1"; then
1333
+ msg="Could not start the palette panel for $name" msgt=300
1334
+ __tt_te_stop
1335
+ return 0
1336
+ fi
1337
+ te=1
1338
+ (( bgcw )) && __tt_pv_bg_state $name && __tt_pv_tune_open $name
1339
+ __tt_te_image && __tt_te_to_image 1
1340
+ resized=1
1341
+ return 0
1342
+ }
1343
+
1344
+ __tt_te_close() {
1345
+ [[ -n $tune ]] && __tt_pv_untune
1346
+ __tt_te_stop
1347
+ te=0 tfocus=0 tename="" tespec="" tesz="" teframe=() tetop=0 help=0 pick=""
1348
+ resized=1 bgname=""
1349
+ return 0
1350
+ }
1351
+
1352
+ __tt_te_save() {
1353
+ __tt_te_save_image
1354
+ if (( tedirty )); then
1355
+ __tt_te_ask save || return 1
1356
+ if [[ ${teframe[1]} == saved ]]; then
1357
+ __tt_palettes_load && __tt_reloaded
1358
+ __tt_reload
1359
+ applied=${TTHEME_PALETTE[$tename]:-$applied}
1360
+ tespec=$applied
1361
+ else
1362
+ return 1
1363
+ fi
1364
+ fi
1365
+ msg="Saved" msgt=200
1366
+ return 0
1367
+ }
1368
+
1369
+ __tt_te_apply() {
1370
+ if __tt_te_unsaved; then
1371
+ __tt_te_save || return 0
1372
+ fi
1373
+ if (( canpick )); then
1374
+ pick=$tename pk=$pkdef
1375
+ return 0
1376
+ fi
1377
+ sel=$tename
1378
+ return 1
1379
+ }
1380
+
1381
+ __tt_te_image() {
1382
+ [[ -n $tune ]] || __tt_pv_bg_findable $tename
1383
+ }
1384
+
1385
+ __tt_te_to_image() {
1386
+ tfocus=1 tf=5
1387
+ [[ $1 == last && -n $tune ]] && tf=3
1388
+ __tt_te_ask "focus 0"
1389
+ }
1390
+
1391
+ __tt_te_to_palette() {
1392
+ tfocus=0
1393
+ __tt_te_ask "focus 1" && __tt_te_ask "key $1"
1394
+ }
1395
+
1396
+ __tt_te_to_apply() {
1397
+ tfocus=2
1398
+ __tt_te_ask "focus 0"
1399
+ }
1400
+
1401
+ __tt_te_to_top() {
1402
+ if __tt_te_image; then
1403
+ __tt_te_to_image first
1404
+ else
1405
+ __tt_te_to_palette home
1406
+ fi
1407
+ }
1408
+
1409
+ __tt_te_find() {
1410
+ local name=$tename
1411
+ __tt_pv_bg_findable $name || return 0
1412
+ __tt_te_save_image
1413
+ __tt_pv_untune
1414
+ __tt_pv_bg_find $name
1415
+ __tt_pv_bg_state $name && __tt_pv_tune_open $name
1416
+ tf=5
1417
+ return 0
1418
+ }
1419
+
1420
+ __tt_te_key() {
1421
+ local m
1422
+ if [[ $temode == list ]]; then
1423
+ case $key in
1424
+ home) __tt_te_to_top; return 0 ;;
1425
+ end) __tt_te_to_apply; return 0 ;;
1426
+ esac
1427
+ fi
1428
+ case $key in
1429
+ up|down|left|right|home|end|pgup|pgdn|esc) m="key $key" ;;
1430
+ sleft) m="key shift-left" ;;
1431
+ sright) m="key shift-right" ;;
1432
+ stab) m="key shift-tab" ;;
1433
+ $'\t') m="key tab" ;;
1434
+ $'\r'|$'\n') m="key enter" ;;
1435
+ $'\x7f'|$'\x08') m="key backspace" ;;
1436
+ $'\x03') m="key ctrl-c" ;;
1437
+ nop|altc) return 0 ;;
1438
+ *)
1439
+ (( ${#key} == 1 )) || return 0
1440
+ m="ch $(( #key ))"
1441
+ ;;
1442
+ esac
1443
+ __tt_te_ask "$m" || { __tt_te_close; return 0 }
1444
+ case ${teframe[2]} in
1445
+ save) __tt_te_save ;;
1446
+ cancel) __tt_te_close ;;
1447
+ below) __tt_te_to_apply ;;
1448
+ above)
1449
+ if __tt_te_image; then
1450
+ __tt_te_to_image last
1451
+ else
1452
+ __tt_te_to_apply
1453
+ fi
1454
+ ;;
1455
+ esac
1456
+ return 0
1457
+ }
1458
+
1459
+ __tt_pv_te_image() {
1460
+ local -a order=(5)
1461
+ local -i i
1462
+ [[ -n $tune ]] && order=(5 4 1 2 3)
1463
+ i=${order[(Ie)$tf]}
1464
+ (( i )) || { tf=5; i=1 }
1465
+ case $key in
1466
+ s) __tt_te_save ;;
1467
+ esc) __tt_te_close ;;
1468
+ up|k)
1469
+ if (( i > 1 )); then
1470
+ tf=${order[i-1]}
1471
+ else
1472
+ __tt_te_to_apply
1473
+ fi
1474
+ ;;
1475
+ down|j)
1476
+ if (( i < ${#order} )); then
1477
+ tf=${order[i+1]}
1478
+ else
1479
+ __tt_te_to_palette home
1480
+ fi
1481
+ ;;
1482
+ home) tf=5 ;;
1483
+ end) __tt_te_to_apply ;;
1484
+ $'\r'|$'\n') [[ -n $tune ]] || __tt_te_find ;;
1485
+ f) __tt_te_find ;;
1486
+ left|right|sleft|sright)
1487
+ if (( tf == 5 )); then
1488
+ if [[ -z $tune ]]; then
1489
+ :
1490
+ elif [[ $key == *left ]]; then
1491
+ __tt_pv_bg_pick -1
1492
+ else
1493
+ __tt_pv_bg_pick 1
1494
+ fi
1495
+ elif [[ -n $tune ]]; then
1496
+ __tt_pv_tune
1497
+ fi
1498
+ ;;
1499
+ '=') [[ -n $tune ]] && (( tf != 5 )) && __tt_pv_tune ;;
1500
+ *) [[ -n $tune ]] && __tt_pv_tune ;;
1501
+ esac
1502
+ [[ -n $tune ]] || tf=5
1503
+ return 0
1504
+ }
1505
+
1506
+ __tt_te_button() {
1507
+ case $key in
1508
+ $'\r'|$'\n') __tt_te_apply; return $? ;;
1509
+ s) __tt_te_save ;;
1510
+ esc) __tt_te_close ;;
1511
+ up|k) __tt_te_to_palette end ;;
1512
+ down|j|home) __tt_te_to_top ;;
1513
+ esac
1514
+ return 0
1515
+ }
1516
+
1517
+ __tt_pv_te() {
1518
+ case $key in
1519
+ $'\x03') return 1 ;;
1520
+ $'\x05') return 0 ;;
1521
+ senter) __tt_te_apply; return $? ;;
1522
+ '?') help=1; return 0 ;;
1523
+ esac
1524
+ case $tfocus in
1525
+ 0) __tt_te_key ;;
1526
+ 1) __tt_pv_te_image ;;
1527
+ *) __tt_te_button ;;
1528
+ esac
1529
+ return $?
1530
+ }
1531
+
1532
+ __tt_pv_te_head() {
1533
+ local z=$'\e[0m' d=$'\e[2m' b=$'\e[1m' y=$'\e[33m' line REPLY
1534
+ local -i col=$1 end=$2 room=$(( $2 - $1 + 1 ))
1535
+ (( color )) || z= d= b= y=
1536
+ __tt_te_unsaved && (( room -= 11 ))
1537
+ line=$b$ac"◆"$z" "$b$tename$z
1538
+ [[ -n ${TTHEME_GROUP[$tename]} ]] && line+=" "$d"· ${TTHEME_GROUP[$tename]}"$z
1539
+ __tt_clip "$line" $room
1540
+ out+=$'\e[1;'$col'H'$REPLY$z
1541
+ __tt_te_unsaved && out+=$'\e[1;'$(( end - 8 ))'H'$y"●"$z" "$d"unsaved"$z
1542
+ return 0
1543
+ }
1544
+
1545
+ __tt_pv_te_tile() {
1546
+ local z=$'\e[0m' d=$'\e[2m' b=$'\e[1m' sty top side bot
1547
+ local -i y=$1 col=$2 r tc=10
1548
+ (( color )) || z= d= b=
1549
+ if (( tfocus == 1 && tf == 5 )); then
1550
+ sty=$b$ac top="┏${(l:tc::━:)}┓" side="┃" bot="┗${(l:tc::━:)}┛"
1551
+ else
1552
+ sty=$d top="╭${(l:tc::─:)}╮" side="│" bot="╰${(l:tc::─:)}╯"
1553
+ fi
1554
+ out+=$'\e['$y';'$col'H'$sty$top$z
1555
+ for (( r = 1; r <= 3; r++ )); do
1556
+ out+=$'\e['$(( y + r ))';'$col'H'$sty$side${(l:tc::░:)}$side$z
1557
+ done
1558
+ out+=$'\e['$(( y + 4 ))';'$col'H'$sty$bot$z$'\e['$(( y + 2 ))';'$(( col + tc + 4 ))'H'
1559
+ if (( tfocus == 1 && tf == 5 )); then
1560
+ out+=$b"enter"$z$d" finds one"$z
1561
+ else
1562
+ out+=$d"enter finds one"$z
1563
+ fi
1564
+ return 0
1565
+ }
1566
+
1567
+ __tt_pv_te_ghost() {
1568
+ local z=$'\e[0m' d=$'\e[2m'
1569
+ local -i r0=$1 col=$2 T=$(( $3 - $2 - 21 )) i
1570
+ (( color )) || z= d=
1571
+ (( T < 8 )) && T=8
1572
+ out+=$'\e['$r0';'$col'H '$d"Colors"$'\e['$r0';'$(( col + 12 ))'H'" tone original "$z
1573
+ out+=$'\e['$(( r0 + 1 ))';'$col'H '$d"Size"$'\e['$(( r0 + 1 ))';'$(( col + 12 ))'H'${(l:T::─:)}$z
1574
+ for (( i = 1; i <= 9; i++ )); do
1575
+ out+=$'\e['$(( r0 + 3 + (i - 1) / 3 ))';'$(( col + 12 + (i - 1) % 3 * 3 ))'H'$d"·"$z
1576
+ done
1577
+ out+=$'\e['$(( r0 + 4 ))';'$col'H '$d"Position"$z
1578
+ out+=$'\e['$(( r0 + 7 ))';'$col'H '$d"Opacity"$'\e['$(( r0 + 7 ))';'$(( col + 12 ))'H'${(l:T::─:)}$z
1579
+ return 0
1580
+ }
1581
+
1582
+ __tt_pv_te_panel() {
1583
+ local z=$'\e[0m' d=$'\e[2m' b=$'\e[1m' tt st note REPLY
1584
+ local -a held
1585
+ local -i col=$1 end=$2 r0=$3 r1=$4 R W T I=3 V at i n y tfs=$tf lo=15
1586
+ (( color )) || z= d= b=
1587
+ R=$(( r1 - r0 + 1 )) W=$(( end - col + 1 ))
1588
+ [[ $temode == list ]] || lo=21
1589
+ [[ -n $tune ]] || __tt_pv_bg_findable $tename && I=17
1590
+ T=$(( R - I - 3 ))
1591
+ (( T > 26 )) && T=26
1592
+ (( T < 21 )) && T=$lo
1593
+ if [[ "$W $T" != "$tesz" ]]; then
1594
+ tesz="$W $T"
1595
+ __tt_te_ask "size $W $T"
1596
+ fi
1597
+ V=$(( I + T + 3 ))
1598
+ if (( V <= R || tfocus == 1 )); then
1599
+ tetop=0
1600
+ elif (( tfocus == 2 )); then
1601
+ tetop=$(( V - R ))
1602
+ else
1603
+ at=$(( I + 1 + ${teframe[9]:-2} ))
1604
+ (( at - 2 < tetop )) && tetop=$(( at > 2 ? at - 2 : 0 ))
1605
+ (( at > tetop + R )) && tetop=$(( at - R ))
1606
+ (( tetop > V - R )) && tetop=$(( V - R ))
1607
+ fi
1608
+ if (( tetop == 0 && I <= R )); then
1609
+ y=$r0
1610
+ tt=$d
1611
+ (( tfocus == 1 )) && tt=$b$ac
1612
+ out+=$'\e['$y';'$(( col + 2 ))'H'$tt"Image"$z
1613
+ if [[ -n $tune ]]; then
1614
+ (( bgoff[$tpick] )) && st=off || st=on
1615
+ __tt_pv_bg_title $(( W - 14 ))
1616
+ out+=" "$d$REPLY$z$'\e['$y';'$(( end - ${#st} + 1 ))'H'$d$st$z
1617
+ fi
1618
+ if (( I == 17 )); then
1619
+ held=() n=0 note="0/0"
1620
+ if [[ -n $tune ]]; then
1621
+ held=(${=bgpics[$tune]})
1622
+ n=${held[(Ie)${${tpick#$tune}#:}]}
1623
+ (( n )) || n=${held[(Ie)${bgact[$tune]}]}
1624
+ (( n )) || n=1
1625
+ note="$n/$(( ${#held} ? ${#held} : 1 ))"
1626
+ fi
1627
+ st=" " tt=$d
1628
+ (( tfocus == 1 && tf == 5 )) && st=$ac"▶"$z" " tt=$b
1629
+ out+=$'\e['$(( y + 2 ))';'$col'H'$st$tt"Images"$z$'\e['$(( y + 2 ))';'$(( end - ${#note} + 1 ))'H'$d$note$z
1630
+ if [[ -n $tune ]]; then
1631
+ bgstrip="$(( y + 2 )) $col $end"
1632
+ (( tfocus == 1 )) || tf=0
1633
+ __tt_pv_bg_panel $tpick $(( y + 9 )) $col $end
1634
+ tf=$tfs
1635
+ else
1636
+ __tt_pv_te_tile $(( y + 3 )) $col
1637
+ __tt_pv_te_ghost $(( y + 9 )) $col $end
1638
+ fi
1639
+ elif (( bgcw )); then
1640
+ out+=$'\e['$(( y + 2 ))';'$(( col + 2 ))'H'$d"No picture yet"$z
1641
+ else
1642
+ out+=$'\e['$(( y + 2 ))';'$(( col + 2 ))'H'$d"This terminal shows no pictures"$z
1643
+ fi
1644
+ fi
1645
+ for (( i = 1; i <= T; i++ )); do
1646
+ y=$(( r0 + I + i - tetop ))
1647
+ (( y >= r0 && y <= r1 )) || continue
1648
+ out+=$'\e['$y';'$col'H'${teframe[9 + i]}$z
1649
+ done
1650
+ y=$(( r0 + V - 1 - tetop ))
1651
+ (( y >= r0 && y <= r1 )) || return 0
1652
+ if [[ $mode == pin ]]; then
1653
+ note="saves, then asks how far it reaches"
1654
+ elif (( canpick )); then
1655
+ note="saves, then asks where"
1656
+ else
1657
+ note="saves and wears it in this tab"
1658
+ fi
1659
+ out+=$'\e['$y';'$col'H'
1660
+ if (( tfocus == 2 )); then
1661
+ (( color )) && out+=$ac"▶"$z" "$'\e[7;1m'$ac" Apply "$z || out+="▶ [Apply]"
1662
+ else
1663
+ (( color )) && out+=" "$b" Apply "$z || out+=" Apply "
1664
+ fi
1665
+ out+=" "$d$note$z
1666
+ return 0
1667
+ }
1668
+
1669
+ __tt_pv_te_draw() {
1670
+ local -i i end=$(( pw - 2 < 66 ? pw - 2 : 66 ))
1671
+ for (( i = 1; i < ph; i++ )); do
1672
+ out+=$'\e['$i$';1H\e[K'
1673
+ done
1674
+ __tt_pv_te_head 2 $end
1675
+ __tt_pv_te_panel 2 $end 3 $(( ph - 1 ))
1676
+ reach=()
1677
+ if [[ -n $pick && $mode == pin ]]; then
1678
+ __tt_pv_reach $se $(( ph - 13 ))
1679
+ if (( ${#reach} )); then
1680
+ __tt_pv_head $(( ph - 1 - ${#reach} )) 1 $se "$pick" "$rsub"
1681
+ for (( i = 1; i <= ${#reach}; i++ )); do
1682
+ out+=$'\e['$(( ph - 1 - ${#reach} + i ))$';1H\e[K'${reach[i]}
1683
+ done
1684
+ fi
1685
+ fi
1686
+ (( help )) && __tt_pv_help
1687
+ out+=$'\e['$ph';1H'
1688
+ __tt_pv_foot $pw
1689
+ (( osdt > 0 )) && __tt_pv_osd
1690
+ __tt_pv_flush
1691
+ }
1692
+
1693
+ __tt_pv_handle() {
1694
+ local name
1695
+ if (( help )); then
1696
+ case $key in
1697
+ $'\x03') return 1 ;;
1698
+ '?'|esc) help=0 ;;
1699
+ esac
1700
+ return 0
1701
+ fi
1702
+ if [[ -n $pick ]]; then
1703
+ __tt_pv_pick
1704
+ return
1705
+ fi
1706
+ if (( te )); then
1707
+ __tt_pv_te
1708
+ return
1709
+ fi
1710
+ if [[ -n $tune ]]; then
1711
+ __tt_pv_tune
1712
+ return
1713
+ fi
1714
+ if (( conf )); then
1715
+ __tt_pv_conf
1716
+ return
1717
+ fi
1718
+ case $key in
1719
+ $'\x03') return 1 ;;
1720
+ esc|$'\x15')
1721
+ if [[ -z $flt ]]; then
1722
+ [[ $key == esc ]] && return 1
1723
+ else
1724
+ name=""
1725
+ [[ ${rtype[cur]} == thm ]] && name=${rval[cur]}
1726
+ flt=""
1727
+ if [[ -n $name ]]; then
1728
+ __tt_pv_goto "$name"
1729
+ else
1730
+ __tt_pv_rows
1731
+ (( cur > ${#rval} )) && cur=${#rval}
1732
+ (( cur < 1 )) && cur=1
1733
+ fi
1734
+ fi
1735
+ ;;
1736
+ $'\r'|$'\n'|senter)
1737
+ if [[ ${rtype[cur]} == thm ]]; then
1738
+ if (( canpick )); then
1739
+ pick=${rval[cur]} pk=$pkdef
1740
+ else
1741
+ sel=${rval[cur]}
1742
+ return 1
1743
+ fi
1744
+ elif [[ ${rtype[cur]} == (hdr|cat) ]]; then
1745
+ __tt_pv_toggle
1746
+ fi
1747
+ ;;
1748
+ up)
1749
+ if (( cur > 1 )); then
1750
+ cur=$(( cur - 1 ))
1751
+ [[ ${rtype[cur]} == rule ]] && cur=$(( cur - 1 ))
1752
+ elif (( ${#rval} )); then
1753
+ cur=${#rval}
1754
+ fi
1755
+ ;;
1756
+ down)
1757
+ if (( cur < ${#rval} )); then
1758
+ cur=$(( cur + 1 ))
1759
+ [[ ${rtype[cur]} == rule ]] && cur=$(( cur + 1 ))
1760
+ elif (( ${#rval} )); then
1761
+ cur=1
1762
+ fi
1763
+ ;;
1764
+ right)
1765
+ if [[ ${rtype[cur]} == thm ]]; then
1766
+ __tt_te_open ${rval[cur]}
1767
+ elif [[ ${rtype[cur]} == (hdr|cat) && -z ${exp[${rval[cur]}]} ]]; then
1768
+ __tt_pv_toggle
1769
+ fi
1770
+ ;;
1771
+ $'\x05') [[ ${rtype[cur]} == thm ]] && __tt_te_open ${rval[cur]} ;;
1772
+ left) __tt_pv_left ;;
1773
+ home) cur=1 ;;
1774
+ end) (( ${#rval} )) && cur=${#rval} ;;
1775
+ pgup)
1776
+ if (( cur <= 1 )); then
1777
+ (( ${#rval} )) && cur=${#rval}
1778
+ else
1779
+ cur=$(( cur - ph + 5 ))
1780
+ (( cur < 1 )) && cur=1
1781
+ [[ ${rtype[cur]} == rule ]] && cur=$(( cur - 1 ))
1782
+ fi
1783
+ ;;
1784
+ pgdn)
1785
+ if (( cur >= ${#rval} )); then
1786
+ cur=1
1787
+ else
1788
+ cur=$(( cur + ph - 5 ))
1789
+ (( cur > ${#rval} )) && cur=${#rval}
1790
+ [[ ${rtype[cur]} == rule ]] && cur=$(( cur + 1 ))
1791
+ fi
1792
+ ;;
1793
+ ' ') [[ ${rtype[cur]} == (hdr|cat) ]] && __tt_pv_toggle ;;
1794
+ $'\t')
1795
+ if [[ ${rtype[cur]} == thm ]]; then
1796
+ __tt_te_open ${rval[cur]}
1797
+ elif (( hub )); then
1798
+ __tt_pv_screen 1 || return 1
1799
+ fi
1800
+ ;;
1801
+ stab) (( hub )) && { __tt_pv_screen -1 || return 1 } ;;
1802
+ altc)
1803
+ conf=1 cf=1 csnap=()
1804
+ for name in $cvars; do
1805
+ csnap+=("${(P)name}")
1806
+ done
1807
+ ;;
1808
+ '?') help=1 ;;
1809
+ sleft) (( --scene )) ;;
1810
+ sright) (( ++scene )) ;;
1811
+ $'\x7f'|$'\x08')
1812
+ if [[ -n $flt ]]; then
1813
+ name=""
1814
+ [[ ${rtype[cur]} == thm ]] && name=${rval[cur]}
1815
+ flt=${flt%?}
1816
+ __tt_pv_rows
1817
+ __tt_pv_first "$name"
1818
+ fi
1819
+ ;;
1820
+ [[:print:]])
1821
+ __tt_pv_lw
1822
+ (( ${(m)#flt} + ${(m)#key} > reply[1] - 12 )) && return 0
1823
+ name=""
1824
+ [[ ${rtype[cur]} == thm ]] && name=${rval[cur]}
1825
+ flt+=${(L)key}
1826
+ __tt_pv_rows
1827
+ __tt_pv_first "$name"
1828
+ ;;
1829
+ esac
1830
+ return 0
1831
+ }
1832
+
1833
+ __tt_preview() {
1834
+ emulate -L zsh ${=${options[xtrace]:#off}:+-o xtrace}
1835
+ zmodload -F zsh/datetime p:EPOCHREALTIME 2>/dev/null
1836
+ local mode=$1 pdir=${2:-$PWD} hubwas=""
1837
+ local -i hub=0 hubleft=0
1838
+ [[ $mode == hub ]] && hub=1
1839
+ if [[ ! -t 0 || ! -t 1 ]]; then
1840
+ print -u2 "ttheme ${mode:-preview}: needs a terminal"
1841
+ return 1
1842
+ fi
1843
+ local orig=$TTHEME_SPEC applied=$TTHEME_SPEC painted=$TTHEME_SPEC flt="" sel="" cn="" cdot="" key="" REPLY="" cur=1 top=1 color=0 pw=80 ph=24 resized=1 expal="" exgrp="" exnext=0 gstep=0 gseed=0 tick=0
1844
+ local pick="" pk=1 pkdef=1 picked=0 canpick=0 bgcw=0 bgch=0 bgname="" bgshown="" bginc="" osd="" osdt=0
1845
+ local tune="" tpick="" tf=1 help=0 msg="" msgt=0 an="" bgrel=0 bgmx=0 bgmy=0 bganchor=0 bgcut="" bgnext=0 bgbytes=0 bgstrip="" pvscene="" pvscenes=""
1846
+ local -i scene=0
1847
+ local -a bgorder=()
1848
+ local -A bgfrom=() bgurl=() bgby=() bgsent=() bgcost=() bgdim=() bgsrc=() bgfill=() bgfocus=() bgsize=() bgpos=() bgop=() bgdef=() bgoff=() bgbase=() bgload=() bgshot=() bgshotkey=() bgedit=() bgtunef=() bgofff=() bgimages=()
1849
+ local -A bgpic=() bgpics=() bgact=() bgview=() bgswap=() bgthumb=() tsnaps=() pvseek=() bgcolors=() bgprep=()
1850
+ local conf=0 cf=1
1851
+ local -a plabel=(" Default " " This tab ") pkeys=() reach=() csnap=() teframe=()
1852
+ local te=0 tfocus=0 tetop=0 tename="" tedirty=0 temode=list tespec="" tesz=""
1853
+ local -i TE_IN=0 TE_OUT=0 TE_PID=0 pvgone=0 bgprepid=0
1854
+ local -a cvars=(TTHEME_TAB_PALETTE TTHEME_ANNOUNCE TTHEME_FX TTHEME_SORT TTHEME_BG_BLUR TTHEME_BG_COLORS) clabel=("New tabs" Announce "Search fx" Sort Blur Colors)
1855
+ local -a cchoice=("off seq" "1 0" "typewriter decode glitch" "abc series" "0 1 2 3 4" "tone original") cshow=("off seq" "on off" "typewriter decode glitch" "abc series" "off 1px 2px 3px 4px" "tone original")
1856
+ local -A cnote=(
1857
+ TTHEME_TAB_PALETTE:seq "New tabs rotate through palettes" TTHEME_TAB_PALETTE:off "New tabs keep the terminal theme"
1858
+ TTHEME_ANNOUNCE:1 "Shows the palette notice" TTHEME_ANNOUNCE:0 "Silences the palette notice"
1859
+ TTHEME_FX:typewriter "The search hint types itself" TTHEME_FX:decode "The search hint decodes" TTHEME_FX:glitch "The search hint glitches in"
1860
+ TTHEME_SORT:abc "Series and palettes by name" TTHEME_SORT:series "Series in the order added"
1861
+ TTHEME_BG_BLUR:0 "Pictures stay sharp" TTHEME_BG_BLUR:1 "Pictures soften a little behind the text"
1862
+ TTHEME_BG_BLUR:2 "Pictures soften behind the text" TTHEME_BG_BLUR:3 "Pictures blur behind the text"
1863
+ TTHEME_BG_BLUR:4 "Pictures blur well behind the text"
1864
+ TTHEME_BG_COLORS:tone "New pictures are tinted in one color of the palette"
1865
+ TTHEME_BG_COLORS:original "New pictures keep their own colors"
1866
+ )
1867
+ __tt_pv_conf_rows
1868
+ [[ $mode == pin ]] && __tt_pin_scopes "$pdir"
1869
+ __tt_pv_canpick
1870
+ __tt_pv_size
1871
+ local -a groups=() rtype=() rval=() rcnt=() reply=()
1872
+ local -A gthemes=() exp=() tstrip=()
1873
+ __tt_color && color=1
1874
+ __tt_pv_init
1875
+ __tt_pv_roll
1876
+ __tt_pv_rows
1877
+ [[ -n ${TTHEME_PALETTE[$cn]} ]] && __tt_pv_goto "$cn"
1878
+ local tty=""
1879
+ local -i TTHEME_RAW=0
1880
+ {
1881
+ tty=$(stty -g 2>/dev/null) && stty -echo -icanon min 1 time 0 2>/dev/null || tty=""
1882
+ TTHEME_RAW=$(( ${#tty} > 0 ))
1883
+ __tt_pv_bg_open
1884
+ printf '\e[?2026h\e[?1049h\e[?7l\e[?25l'
1885
+ while :; do
1886
+ printf '\e[?2026h'
1887
+ if (( tick && ! te )); then
1888
+ __tt_pv_draw hint
1889
+ else
1890
+ __tt_pv_focus
1891
+ [[ ${rtype[cur]} == thm ]] && an=${rval[cur]}
1892
+ __tt_pv_draw
1893
+ fi
1894
+ tick=0
1895
+ if ! __tt_pv_read; then
1896
+ (( pvgone )) && break
1897
+ [[ -t 0 ]] && continue
1898
+ break
1899
+ fi
1900
+ while :; do
1901
+ __tt_pv_handle || break 2
1902
+ __tt_pv_read drain || break
1903
+ done
1904
+ done
1905
+ } always {
1906
+ local spec=${sel:+${TTHEME_PALETTE[$sel]}}
1907
+ [[ -n $spec && $mode != pin ]] && (( ! ${#bgedit} && ! ${#bgswap} )) && __tt_pv_claim "$sel"
1908
+ printf '\e[?2026h'
1909
+ __tt_pv_bg_close
1910
+ if [[ -n $spec ]]; then
1911
+ [[ $spec == "$painted" ]] || __tt_apply "$spec"
1912
+ elif [[ $painted != "$orig" ]]; then
1913
+ if [[ -z $orig ]]; then
1914
+ __tt_osc_reset
1915
+ else
1916
+ __tt_apply "$orig"
1917
+ fi
1918
+ elif [[ $applied != "$orig" ]]; then
1919
+ __tt_pv_paint "${TTHEME_PAINTED:+$orig}"
1920
+ fi
1921
+ printf '\e[?7h'
1922
+ (( hubleft )) || printf '\e[?1049l'
1923
+ printf '\e[?25h\e[?2026l'
1924
+ [[ -n $tty ]] && stty "$tty" 2>/dev/null
1925
+ TTHEME_RAW=0
1926
+ [[ -n $tune ]] && __tt_pv_untune
1927
+ (( TE_IN )) && __tt_te_stop
1928
+ (( conf )) && __tt_pv_unconf
1929
+ __tt_pv_bg_save
1930
+ if [[ -n $spec ]]; then
1931
+ TTHEME_SPEC=$spec
1932
+ if [[ $mode == pin ]]; then
1933
+ __tt_pin_save "$sel" "${pkeys[picked]}" "$orig"
1934
+ [[ $TTHEME_SPEC == "$orig" ]] || __tt_announce
1935
+ __tt_sync
1936
+ elif (( picked == 1 )); then
1937
+ __tt_announce
1938
+ __tt_keep "$sel" force
1939
+ else
1940
+ __tt_announce
1941
+ __tt_shown "$sel" force && __tt_reload
1942
+ fi
1943
+ else
1944
+ (( ${#bgedit} + ${#bgswap} )) && [[ -n ${TTHEME_PALETTE[$cn]} ]] && { __tt_shown "$cn" && __tt_reload }
1945
+ fi
1946
+ (( hubleft )) && __tt_catalog_done "$hubwas"
1947
+ }
1948
+ return 0
1949
+ }