@kecan0406/ttheme 1.2.0 → 1.2.2

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.2.0",
2
+ "version": "1.2.2",
3
3
  "gate": [
4
4
  {
5
5
  "rule": "foreground",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kecan0406/ttheme",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "ttheme": "bin/ttheme.js"
@@ -8,6 +8,8 @@ __tt_bg_saved() {
8
8
 
9
9
  __tt_bg_refresh() { : }
10
10
 
11
+ __tt_bg_hide() { : }
12
+
11
13
  __tt_bg_lasting() { : }
12
14
 
13
15
  __tt_bg_frame() {
@@ -75,12 +77,16 @@ __tt_bg_load() {
75
77
  bgimages[$name]=${bgimages[$pal]:-1}
76
78
  elif [[ -r $dir/$file.conf ]]; then
77
79
  lines=("${(@f)$(<$dir/$file.conf)}")
80
+ for line in ${(k)bgcolors[(I)${(b)pal}:*]}; do
81
+ unset "bgcolors[$line]"
82
+ done
78
83
  fi
79
84
  for line in $lines; do
80
85
  case $line in
81
86
  'config-file = ?'*.tune.conf) bgtunef[$name]=${line#config-file = \?} ;;
82
87
  'config-file = ?'*.off.conf) bgofff[$name]=${line#config-file = \?} ;;
83
88
  '# image '*/<->) bgimages[$name]=${line##*/} bgact[$pal]=${${line#\# image }%% *} ;;
89
+ '# colors '*) pd=(${=line#\# colors }); [[ -n $key ]] || bgcolors[$pal:$pd[1]]=$pd[2] ;;
84
90
  '# picture '*)
85
91
  pd=(${=line#\# picture })
86
92
  bgpic[$pal:$pd[1]]=${(j: :)pd[2,-1]}
@@ -131,6 +137,12 @@ __tt_bg_load() {
131
137
  fi
132
138
  }
133
139
 
140
+ __tt_bg_coloring() {
141
+ local key=${1##*:}
142
+ [[ $1 == *:* ]] || key=${bgact[$1]}
143
+ REPLY=${bgcolors[${1%:*}:$key]:-tone}
144
+ }
145
+
134
146
  __tt_bg_image() {
135
147
  REPLY=${bgsrc[$1]}
136
148
  [[ ${bgsize[$1]} == fill ]] && REPLY=${bgfill[$1]}
@@ -210,7 +222,7 @@ __tt_bg_write() {
210
222
  rm -f -- $dir/${bgtunef[$1]}
211
223
  else
212
224
  shape=$size
213
- [[ $size == <20-100> && $pos != center ]] && ! __tt_bg_aligns && shape=window
225
+ [[ $size == <20-100> ]] && { [[ $pos != center ]] || __tt_bg_covers } && ! __tt_bg_aligns && shape=window
214
226
  case $shape in
215
227
  fill) img=${bgfill[$1]} fit=cover ;;
216
228
  100) img=$src ;;
@@ -310,6 +322,12 @@ __tt_pv_bg_show() {
310
322
  __tt_bg_at $id -1073741826 $(( at[1] - 1 )) $(( at[2] - 1 )) $at[3] $at[4] $at[5] $at[6] $at[7] $at[8]
311
323
  }
312
324
 
325
+ __tt_bg_transmit() {
326
+ local REPLY
327
+ __tt_b64s "$2"
328
+ printf '\e_Ga=t,t=f,f=100,i=%d,q=2;%s\e\\' $1 "$REPLY"
329
+ }
330
+
313
331
  __tt_bg_send() {
314
332
  local -i cost=0
315
333
  if [[ -n ${bgsent[$1]} ]]; then
@@ -319,8 +337,7 @@ __tt_bg_send() {
319
337
  bgsent[$1]=$(( ++bgnext + 2 )) bgcost[$1]=$cost
320
338
  (( bgbytes += cost ))
321
339
  bgorder+=("$1")
322
- __tt_b64s "$1"
323
- printf '\e_Ga=t,t=f,f=100,i=%d,q=2;%s\e\\' ${bgsent[$1]} "$REPLY"
340
+ __tt_bg_transmit ${bgsent[$1]} "$1"
324
341
  while (( ${#bgorder} > 1 && bgbytes > 134217728 )); do
325
342
  printf '\e_Ga=d,d=I,i=%d,q=2\e\\' ${bgsent[$bgorder[1]]}
326
343
  (( bgbytes -= bgcost[$bgorder[1]] ))
@@ -439,6 +456,7 @@ __tt_pv_bg_find() {
439
456
  [[ $applied == "$painted" ]] || { __tt_apply "$applied" && painted=$applied }
440
457
  __tt_pv_bg_commit $name
441
458
  __tt_pv_bg_close
459
+ __tt_bg_hide $name
442
460
  err=$(__tt_cli find $name 2>&1 >/dev/tty)
443
461
  rc=$?
444
462
  for var in ${(k)parameters[(I)TTHEME_FIND_*]}; do
@@ -472,6 +490,9 @@ __tt_pv_bg_reset() {
472
490
  for img in ${(k)bgsrc[(I)${(b)1}(|:*)]}; do
473
491
  unset "bgsrc[$img]"
474
492
  done
493
+ for img in ${(k)bgcolors[(I)${(b)1}:*]}; do
494
+ unset "bgcolors[$img]"
495
+ done
475
496
  unset "bgview[$1]" "bgswap[$1]"
476
497
  }
477
498
 
@@ -532,15 +553,48 @@ __tt_pv_bg_drop() {
532
553
  __tt_pv_tune_open $name
533
554
  }
534
555
 
556
+ __tt_pv_bg_recolor() {
557
+ local name=$tune was=$tpick key=${tpick##*:} want err REPLY
558
+ local -i rc row=$tf
559
+ [[ $tpick == *:* ]] || key=${bgact[$name]}
560
+ __tt_bg_coloring $tpick
561
+ want=original
562
+ [[ $REPLY == original ]] && want=tone
563
+ __tt_pv_tune_keep
564
+ __tt_pv_bg_commit $name
565
+ msg="Drawing in its own colors"
566
+ [[ $want == tone ]] && msg="Drawing in the palette's tone"
567
+ msgt=300
568
+ printf '\e[?2026h'
569
+ __tt_pv_draw
570
+ __tt_pv_bg_close
571
+ err=$(__tt_cli image $name $want $key 2>&1)
572
+ rc=$?
573
+ err=${${err//$'\n'/ }## #}
574
+ resized=1 bgname="" bgshown="" bgdim=()
575
+ __tt_pv_bg_reset $name
576
+ __tt_bg_load $name
577
+ bgload[$name]="" bgedit[$name]=1
578
+ msg=${err:-"Background · $name"} msgt=$(( rc ? 300 : 200 ))
579
+ [[ -r ${TTHEME_CONFIG:h}/backgrounds/${${name/@/--}/\//--}.conf ]] || return 0
580
+ __tt_pv_tune_open $name
581
+ if [[ $was != "$tpick" ]]; then
582
+ tpick=$was
583
+ __tt_bg_load $tpick
584
+ tsnaps[$tpick]="${bgsize[$tpick]} ${bgpos[$tpick]} ${bgop[$tpick]} ${bgoff[$tpick]}"
585
+ fi
586
+ tf=$row
587
+ }
588
+
535
589
  __tt_pv_bg_panel() {
536
- local name=$1 z=$'\e[0m' b=$'\e[1m' d=$'\e[2m' c=$ac val sty mark REPLY
537
- local -a labs=(Size Position Opacity) at=(0 3 6) def=(${=bgdef[$1]})
590
+ local name=$1 z=$'\e[0m' b=$'\e[1m' d=$'\e[2m' c=$ac val sty mark choice REPLY
591
+ local -a labs=(Size Position Opacity Colors) at=(0 3 6 7) def=(${=bgdef[$1]})
538
592
  local -i r0=$2 col=$3 end=$4 off=${bgoff[$1]} T=$(( $4 - $3 - 21 )) lo=100 hi=100 k i r knob pos=${bgpos[$1]} o tuned
539
593
  (( color )) || z= b= d= c=
540
594
  (( T < 8 )) && T=8
541
595
  (( $+commands[sips] )) && lo=20
542
596
  __tt_pv_bg_fs $name && (( REPLY > hi )) && hi=$REPLY
543
- for k in 1 2 3; do
597
+ for k in 1 2 3 4; do
544
598
  r=$(( r0 + at[k] ))
545
599
  sty=$d
546
600
  (( tf == k && ! off )) && sty=$b
@@ -551,6 +605,23 @@ __tt_pv_bg_panel() {
551
605
  out+=" "
552
606
  fi
553
607
  out+=$sty$labs[k]$z
608
+ if (( k == 4 )); then
609
+ __tt_bg_coloring $name
610
+ val=$REPLY
611
+ out+=$'\e['$r';'$(( col + 12 ))'H'
612
+ for choice in tone original; do
613
+ if (( ! color )); then
614
+ if [[ $choice == $val ]]; then out+="[$choice] "; else out+=" $choice "; fi
615
+ elif [[ $choice != $val ]]; then
616
+ out+=$d" $choice "$z" "
617
+ elif (( tf == k && ! off )); then
618
+ out+=$'\e[7;1m'$c" $choice "$z" "
619
+ else
620
+ out+=$sty" $choice "$z" "
621
+ fi
622
+ done
623
+ continue
624
+ fi
554
625
  if (( k == 2 )); then
555
626
  for (( i = 1; i <= 9; i++ )); do
556
627
  out+=$'\e['$(( r0 + 2 + (i - 1) / 3 ))';'$(( col + 12 + (i - 1) % 3 * 3 ))'H'
@@ -598,7 +669,7 @@ __tt_pv_bg_panel() {
598
669
  out+=$'\e['$r';'$end'H'$mark"↺"$z
599
670
  fi
600
671
  done
601
- (( split )) && bgstrip="$(( r0 + 8 )) $col $end"
672
+ (( split )) && bgstrip="$(( r0 + 9 )) $col $end"
602
673
  }
603
674
 
604
675
  __tt_pv_bg_strip() {
@@ -63,6 +63,10 @@ __tt_unpainted() { : }
63
63
 
64
64
  __tt_follows_focus() { return 1 }
65
65
 
66
+ __tt_follows_prompt() { return 1 }
67
+
68
+ __tt_prompted() { : }
69
+
66
70
  __tt_pv_bg_open() { : }
67
71
 
68
72
  __tt_pv_bg_show() { : }
@@ -52,4 +52,8 @@ __tt_pictured_ghostty() {
52
52
 
53
53
  __tt_pictured_iterm2() { __tt_cli image $1 tuned }
54
54
 
55
- __tt_bg_aligns() { (( ! ${TTHEME_TERMINALS[(Ie)iterm2]} )) }
55
+ __tt_pictured_warp() { (( ${TTHEME_TERMINALS[(Ie)iterm2]} )) || __tt_cli image $1 tuned }
56
+
57
+ __tt_bg_aligns() { (( ! ${TTHEME_TERMINALS[(Ie)iterm2]} && ! ${TTHEME_TERMINALS[(Ie)warp]} )) }
58
+
59
+ __tt_bg_covers() { (( ${TTHEME_TERMINALS[(Ie)warp]} )) }
@@ -1,5 +1,491 @@
1
- __tt_paints() { return 1 }
1
+ source $TTHEME_HOME/adapters/_bg.zsh
2
+
3
+ typeset -g TTHEME_WARP_SETTINGS=$HOME/.warp/settings.toml TTHEME_WARP_THEMES=$HOME/.warp/themes TTHEME_WARP_WORN=""
4
+ typeset -g TTHEME_WARP_TABS=$TTHEME_STATE_DIR/warp TTHEME_WARP_DB="" TTHEME_WARP_ID="" TTHEME_WARP_LAST="" TTHEME_WARP_SEEN=""
5
+ typeset -g TTHEME_WARP_SHOWING="" TTHEME_WARP_VIEW=""
6
+ typeset -gi TTHEME_WARP_VIEWS=0 TTHEME_WARP_BUSY=0 TTHEME_WARP_FOLLOWS=-1 TTHEME_WARP_TICK=0
7
+ typeset -ga TTHEME_WARP_LAID=()
8
+ typeset -g TTHEME_WARP_SQL='with t as (select id, window_id, row_number() over (partition by window_id order by id) - 1 as ix from tabs) select lower(hex(p.uuid)) from app a join windows w on w.id = a.active_window_id join t on t.window_id = w.id and t.ix = w.active_tab_index join pane_nodes n on n.tab_id = t.id and n.is_leaf join pane_leaves l on l.pane_node_id = n.id and l.is_focused join terminal_panes p on p.id = n.id'
9
+ if [[ $OSTYPE != darwin* ]]; then
10
+ TTHEME_WARP_SETTINGS=${XDG_CONFIG_HOME:-$HOME/.config}/warp-terminal/settings.toml
11
+ TTHEME_WARP_THEMES=${XDG_DATA_HOME:-$HOME/.local/share}/warp-terminal/themes
12
+ fi
13
+
14
+ zmodload -F zsh/files b:zf_rm b:zf_mkdir 2>/dev/null
15
+ zmodload -F zsh/zselect b:zselect 2>/dev/null
16
+ zmodload -F zsh/datetime p:EPOCHREALTIME 2>/dev/null
17
+
18
+ __tt_paints() { __tt_warp_wired }
19
+
20
+ __tt_warp_wired() { (( ${TTHEME_TERMINALS[(Ie)warp]} )) && [[ -r $TTHEME_WARP_SETTINGS ]] }
2
21
 
3
22
  __tt_unpainted() {
4
- print -u2 "ttheme: Warp wears one theme app-wide and paints no tab background of its own — \`ttheme default <palette>\` puts one on every Warp window"
23
+ print -u2 "ttheme: Warp takes a palette only through the settings.toml init wires — wire it with \`npx @kecan0406/ttheme@latest init\`"
24
+ }
25
+
26
+ __tt_keepable() { return 0 }
27
+
28
+ __tt_follows_prompt() { return 0 }
29
+
30
+ __tt_prompted() {
31
+ emulate -L zsh ${=${options[xtrace]:#off}:+-o xtrace}
32
+ __tt_warp_publish
33
+ __tt_warp_follow
34
+ __tt_warp_follows || __tt_sync
35
+ }
36
+
37
+ __tt_hear() {
38
+ if [[ -n $TTHEME_PAINTED ]] && __tt_warp_wearing && [[ -n ${TTHEME_PALETTE[$REPLY]} ]]; then
39
+ REPLY=${TTHEME_PALETTE[$REPLY]%% *}
40
+ elif [[ -n $TTHEME_STARTUP && -n ${TTHEME_PALETTE[$TTHEME_STARTUP]} ]]; then
41
+ REPLY=${TTHEME_PALETTE[$TTHEME_STARTUP]%% *}
42
+ else
43
+ REPLY=""
44
+ return 1
45
+ fi
46
+ }
47
+
48
+ __tt_warp_value() {
49
+ setopt localoptions extendedglob
50
+ local file=ttheme-${${1/@/--}/\//--}
51
+ local -a pics=($TTHEME_WARP_THEMES/$file.[0-9a-f](#c8).yaml(Nom))
52
+ (( ${#pics} )) && file=${pics[1]:t:r}
53
+ REPLY="{ custom = { name = \"$1\", path = \"$file.yaml\" } }"
54
+ }
55
+
56
+ __tt_warp_read() {
57
+ setopt localoptions extendedglob
58
+ local f=$TTHEME_WARP_SETTINGS line
59
+ local -a at=(0 0)
60
+ integer i s=0
61
+ reply=() REPLY="" TTHEME_WARP_WORN=""
62
+ [[ -r $f ]] || return 1
63
+ reply=("${(@f)$(<$f)}")
64
+ for (( i = 1; i <= $#reply; i++ )); do
65
+ line=${reply[i]}
66
+ if (( s )); then
67
+ [[ $line == [[:space:]]#\[* ]] && break
68
+ [[ $line == theme[[:space:]]#=* ]] && { at=($s $i); break }
69
+ elif [[ $line == [[:space:]]#'[appearance.themes]'[[:space:]]# ]]; then
70
+ s=$i at=($s 0)
71
+ fi
72
+ done
73
+ TTHEME_WARP_LINES=($at)
74
+ (( at[2] )) && REPLY=${${reply[at[2]]#theme}##[[:space:]]#=[[:space:]]#}
75
+ [[ $REPLY == '{ custom = { name = "'*'", path = "ttheme-'* ]] && TTHEME_WARP_WORN=${${REPLY#*name = \"}%%\"*}
76
+ return 0
77
+ }
78
+
79
+ __tt_warp_set() {
80
+ local REPLY
81
+ local -a at reply TTHEME_WARP_LINES
82
+ __tt_warp_read || return 1
83
+ [[ $REPLY == "$1" ]] && return 0
84
+ if [[ $1 == *'path = "ttheme-'* && -z $TTHEME_WARP_WORN && ! -e $TTHEME_HOME/warp.base ]]; then
85
+ __tt_put $TTHEME_HOME/warp.base "$REPLY" || return 1
86
+ fi
87
+ [[ -e $TTHEME_WARP_SETTINGS.ttheme.bak ]] || __tt_put $TTHEME_WARP_SETTINGS.ttheme.bak "${reply[@]}"
88
+ at=($TTHEME_WARP_LINES)
89
+ if (( at[2] )); then
90
+ reply[at[2]]="theme = $1"
91
+ elif (( at[1] )); then
92
+ reply[at[1]]=("${reply[at[1]]}" "theme = $1")
93
+ else
94
+ reply+=("" "[appearance.themes]" "theme = $1")
95
+ fi
96
+ __tt_put $TTHEME_WARP_SETTINGS "${reply[@]}"
97
+ }
98
+
99
+ __tt_warp_wearing() {
100
+ local -a reply TTHEME_WARP_LINES
101
+ __tt_warp_read || return 1
102
+ REPLY=$TTHEME_WARP_WORN
103
+ [[ -n $REPLY ]]
104
+ }
105
+
106
+ __tt_warp_want() {
107
+ local pal=$1 view=$2 base=$TTHEME_HOME/warp.base
108
+ if [[ -n $pal && -n ${TTHEME_PALETTE[$pal]} ]]; then
109
+ if [[ -n $view && -r $TTHEME_WARP_THEMES/$view ]]; then
110
+ REPLY="{ custom = { name = \"$pal\", path = \"$view\" } }"
111
+ else
112
+ __tt_warp_value $pal
113
+ fi
114
+ elif [[ -n $TTHEME_STARTUP && -n ${TTHEME_PALETTE[$TTHEME_STARTUP]} ]]; then
115
+ __tt_warp_value $TTHEME_STARTUP
116
+ elif [[ -e $base ]]; then
117
+ REPLY=$(<$base)
118
+ [[ -n $REPLY ]] || REPLY='"dark"'
119
+ else
120
+ __tt_warp_wearing || return 1
121
+ REPLY='"dark"'
122
+ fi
123
+ return 0
124
+ }
125
+
126
+ __tt_warp_wear() {
127
+ local value=$1
128
+ local -a at
129
+ integer wait
130
+ if [[ $value == *'path = "ttheme-'* ]]; then
131
+ zstat -F %s.%N -A at +mtime -- $TTHEME_WARP_THEMES/${${value#*path = \"}%%\"*} 2>/dev/null || return 1
132
+ wait=$(( (0.26 - (EPOCHREALTIME - at[1])) * 100 ))
133
+ (( wait > 0 )) && zselect -t $wait
134
+ fi
135
+ __tt_warp_set "$value" || return 1
136
+ [[ $value == *'path = "ttheme-'* ]] || zf_rm -f -- $TTHEME_HOME/warp.base 2>/dev/null
137
+ return 0
138
+ }
139
+
140
+ __tt_warp_here() {
141
+ local fd f=$TTHEME_WARP_TABS/.active
142
+ [[ -r $f && -e $TTHEME_WARP_TABS/.follow && -n $WARP_TERMINAL_SESSION_UUID ]] || return 0
143
+ [[ "$(<$f)" == "$WARP_TERMINAL_SESSION_UUID" ]] && return 0
144
+ zsystem flock -t 0 -f fd $TTHEME_WARP_TABS/.follow 2>/dev/null || return 1
145
+ zsystem flock -u $fd
146
+ return 0
147
+ }
148
+
149
+ __tt_warp_publish() {
150
+ local id=$WARP_TERMINAL_SESSION_UUID f pal=$1 line REPLY
151
+ [[ ${#id} == 32 && -e $TTHEME_HOME ]] || return 0
152
+ if (( ! $# )); then
153
+ __tt_warp_tab
154
+ pal=$REPLY
155
+ fi
156
+ f=$TTHEME_WARP_TABS/$id line="$$ ${TTHEME_STARTUP:--} ${pal:--} ${2:--}"
157
+ [[ -r $f && "$(<$f)" == "$line" ]] && return 0
158
+ [[ -d $TTHEME_WARP_TABS ]] || zf_mkdir -p $TTHEME_WARP_TABS 2>/dev/null || return 0
159
+ __tt_put $f "$line" 2>/dev/null
160
+ }
161
+
162
+ __tt_warp_db() {
163
+ setopt localoptions extendedglob
164
+ local -a db
165
+ [[ -n $TTHEME_WARP_DB ]] && return 0
166
+ if [[ $OSTYPE == darwin* ]]; then
167
+ db=($HOME/Library/Group\ Containers/*.dev.warp/Library/Application\ Support/dev.warp.Warp-Stable/warp.sqlite(N) $HOME/Library/Application\ Support/dev.warp.Warp-Stable/warp.sqlite(N))
168
+ else
169
+ db=(${XDG_STATE_HOME:-$HOME/.local/state}/warp-terminal/warp.sqlite(N))
170
+ fi
171
+ TTHEME_WARP_DB=${db[1]}
172
+ [[ -n $TTHEME_WARP_DB ]]
173
+ }
174
+
175
+ __tt_warp_follows() {
176
+ setopt localoptions extendedglob
177
+ (( TTHEME_WARP_FOLLOWS < 0 )) || return $(( ! TTHEME_WARP_FOLLOWS ))
178
+ TTHEME_WARP_FOLLOWS=0
179
+ [[ -o interactive && $WARP_TERMINAL_SESSION_UUID == [0-9a-f](#c32) ]] && (( $+commands[sqlite3] )) && __tt_warp_db || return 1
180
+ TTHEME_WARP_FOLLOWS=1
181
+ }
182
+
183
+ __tt_warp_follow() {
184
+ local fd lock=$TTHEME_WARP_TABS/.follow
185
+ __tt_warp_follows || return 0
186
+ if [[ ! -e $lock ]]; then
187
+ [[ -d $TTHEME_WARP_TABS ]] || zf_mkdir -p $TTHEME_WARP_TABS 2>/dev/null || return 0
188
+ : >>| $lock 2>/dev/null || return 0
189
+ fi
190
+ zsystem flock -t 0 -f fd $lock 2>/dev/null || return 0
191
+ zsystem flock -u $fd
192
+ zsh -fc 'source $1; __tt_warp_follower' zsh $TTHEME_HOME/ttheme.zsh </dev/null >/dev/null 2>&1 &!
193
+ }
194
+
195
+ __tt_warp_active() {
196
+ setopt localoptions extendedglob
197
+ REPLY=$(sqlite3 -readonly -cmd '.timeout 300' $TTHEME_WARP_DB $TTHEME_WARP_SQL 2>/dev/null)
198
+ [[ $REPLY == [0-9a-f](#c32) ]]
199
+ }
200
+
201
+ __tt_warp_line() {
202
+ local pal=${3#-} view=${4#-}
203
+ [[ $2 != - && -z $TTHEME_STARTUP ]] && pal="" view=""
204
+ __tt_warp_want "$pal" "$view"
205
+ }
206
+
207
+ __tt_warp_tick() {
208
+ local line="" REPLY
209
+ local -a at
210
+ if zstat -F %s.%N -A at +mtime -- $TTHEME_WARP_DB-wal 2>/dev/null || zstat -F %s.%N -A at +mtime -- $TTHEME_WARP_DB 2>/dev/null; then
211
+ if [[ $at[1] != "$TTHEME_WARP_SEEN" ]]; then
212
+ TTHEME_WARP_SEEN=$at[1]
213
+ if __tt_warp_active && [[ $REPLY != "$TTHEME_WARP_ID" ]]; then
214
+ TTHEME_WARP_ID=$REPLY
215
+ __tt_put $TTHEME_WARP_TABS/.active $REPLY 2>/dev/null
216
+ fi
217
+ fi
218
+ fi
219
+ zstat -F %s.%N -A at +mtime -- $TTHEME_HOME/palettes.zsh 2>/dev/null && [[ $at[1] != "$TTHEME_PALETTES_AT" ]] && __tt_palettes_load
220
+ [[ -n $TTHEME_WARP_ID && -r $TTHEME_WARP_TABS/$TTHEME_WARP_ID ]] && line=$(<$TTHEME_WARP_TABS/$TTHEME_WARP_ID)
221
+ [[ "$TTHEME_WARP_ID $line $TTHEME_PALETTES_AT" == "$TTHEME_WARP_LAST" ]] && return 0
222
+ TTHEME_WARP_LAST="$TTHEME_WARP_ID $line $TTHEME_PALETTES_AT"
223
+ [[ -n $line ]] && __tt_warp_line ${=line} && __tt_warp_wear "$REPLY"
224
+ return 0
225
+ }
226
+
227
+ __tt_warp_live() {
228
+ setopt localoptions extendedglob
229
+ local f pid
230
+ integer live=0
231
+ for f in $TTHEME_WARP_TABS/[0-9a-f](#c32)(N); do
232
+ pid=${"$(<$f)"%% *}
233
+ if [[ $pid == <-> ]] && kill -0 $pid 2>/dev/null; then
234
+ live=1
235
+ else
236
+ zf_rm -f -- $f 2>/dev/null
237
+ fi
238
+ done
239
+ (( live ))
240
+ }
241
+
242
+ __tt_warp_follower() {
243
+ emulate -L zsh
244
+ local fd
245
+ __tt_warp_db && zsystem flock -t 0 -f fd $TTHEME_WARP_TABS/.follow 2>/dev/null || return 0
246
+ trap '' HUP
247
+ while [[ -e $TTHEME_HOME/palettes.zsh && -e $TTHEME_WARP_DB ]]; do
248
+ __tt_warp_tick
249
+ (( ++TTHEME_WARP_TICK % 50 )) || __tt_warp_live || break
250
+ zselect -t 10
251
+ done
252
+ zf_rm -f -- $TTHEME_WARP_TABS/.active 2>/dev/null
253
+ }
254
+
255
+ __tt_apply() {
256
+ local REPLY pal
257
+ __tt_name_of "$1"
258
+ pal=$REPLY
259
+ [[ -n ${TTHEME_PALETTE[$pal]} ]] || return 1
260
+ TTHEME_WARP_VIEW=""
261
+ __tt_warp_publish $pal
262
+ __tt_warp_here && __tt_warp_want $pal && __tt_warp_wear "$REPLY"
263
+ export TTHEME_PAINTED=1
264
+ return 0
265
+ }
266
+
267
+ __tt_osc_reset() {
268
+ local REPLY
269
+ TTHEME_WARP_VIEW=""
270
+ __tt_warp_publish ""
271
+ __tt_warp_here && __tt_warp_want "" && __tt_warp_wear "$REPLY"
272
+ unset TTHEME_PAINTED
273
+ return 0
274
+ }
275
+
276
+ __tt_warp_tab() {
277
+ REPLY=""
278
+ [[ -n $TTHEME_PAINTED && -n $TTHEME_SPEC ]] || return 0
279
+ __tt_name_of "$TTHEME_SPEC"
280
+ [[ -n ${TTHEME_PALETTE[$REPLY]} ]] || REPLY=""
281
+ }
282
+
283
+ __tt_shown() {
284
+ local REPLY pal
285
+ __tt_warp_tab
286
+ pal=$REPLY
287
+ __tt_warp_publish "$pal"
288
+ if [[ $2 == force ]] || ! __tt_warp_follows; then
289
+ __tt_warp_here && __tt_warp_want "$pal" && __tt_warp_wear "$REPLY"
290
+ fi
291
+ return 1
292
+ }
293
+
294
+ __tt_reloaded() {
295
+ __tt_paints && __tt_shown "" force
296
+ return 0
297
+ }
298
+
299
+ __tt_bg_shown() { __tt_warp_wearing }
300
+
301
+ __tt_bg_refresh() { __tt_warp_unview }
302
+
303
+ __tt_bg_bake() {
304
+ local place
305
+ printf -v place '%dx%d%+d%+d' $5 $6 $7 $8
306
+ __tt_cli bake "$1" "$2" "${3}x$4" "$place" >/dev/null 2>&1
307
+ }
308
+
309
+ __tt_bg_hide() {
310
+ __tt_warp_set "{ custom = { name = \"$1\", path = \"ttheme-${${1/@/--}/\//--}.yaml\" } }"
311
+ TTHEME_WARP_VIEW=""
312
+ }
313
+
314
+ __tt_bg_cells() {
315
+ local REPLY resp
316
+ local -a px cells
317
+ __tt_ask $'\e[14t\e[18t' || return 0
318
+ resp=$REPLY
319
+ [[ $resp == *'[4;'<1->';'<1->t* && $resp == *'[8;'<1->';'<1->t* ]] || return 0
320
+ px=(${(s:;:)${${resp##*\[4;}%%t*}}) cells=(${(s:;:)${${resp##*\[8;}%%t*}})
321
+ bgch=$(( 2 * px[1] / cells[1] )) bgcw=$(( 2 * px[2] / cells[2] ))
322
+ }
323
+
324
+ __tt_bg_transmit() {
325
+ local data
326
+ integer at=1 n
327
+ data=${"$(base64 < $2 2>/dev/null)"//$'\n'/}
328
+ n=${#data}
329
+ (( n )) || return 0
330
+ printf '\e_Ga=t,f=100,i=%d,m=%d,q=2;%s\e\\' $1 $(( n > 4096 )) "${data[1,4096]}"
331
+ for (( at = 4097; at <= n; at += 4096 )); do
332
+ printf '\e_Gm=%d,q=2;%s\e\\' $(( at + 4096 <= n )) "${data[at,at+4095]}"
333
+ done
334
+ }
335
+
336
+ __tt_bg_crop() {
337
+ __tt_bg_send $1
338
+ REPLY="$REPLY $4"
339
+ }
340
+
341
+ __tt_warp_tuned() {
342
+ [[ $1 == *:* ]] && return 0
343
+ __tt_bg_load $1
344
+ [[ "${bgsize[$1]} ${bgpos[$1]} ${bgop[$1]} ${bgoff[$1]}" != "${bgload[$1]}" ]]
345
+ }
346
+
347
+ __tt_warp_loading() {
348
+ msg="Loading the background" msgt=100
349
+ printf '\e[?2026h'
350
+ __tt_pv_draw
351
+ }
352
+
353
+ __tt_warp_saved() {
354
+ local name=$1
355
+ if [[ "${bgsize[$name]} ${bgpos[$name]} ${bgop[$name]}" == "${bgdef[$name]}" ]]; then
356
+ REPLY=${bgbase[$name]}
357
+ elif [[ ${bgsize[$name]} == fill ]]; then
358
+ REPLY=${bgfill[$name]}
359
+ elif [[ "${bgsize[$name]} ${bgpos[$name]}" == "${bgshotkey[$name]}" && -r ${bgshot[$name]} ]]; then
360
+ REPLY=${bgshot[$name]}
361
+ else
362
+ REPLY=${bgsrc[$name]%.png}@${bgsize[$name]}-${TTHEME_BG_POSITIONS[${bgpos[$name]}]}-${2}x$3.png
363
+ fi
364
+ }
365
+
366
+ __tt_warp_laid() {
367
+ setopt localoptions nomultibyte
368
+ local s=$2$'\n'${(L)${TTHEME_PALETTE[$1]}%% *} c
369
+ local -i h=16#811c9dc5 i n
370
+ for (( i = 1; i <= $#s; i++ )); do
371
+ c=${s[i]}
372
+ n=$(( #c ))
373
+ (( n < 0 )) && (( n += 256 ))
374
+ (( h = ((h ^ n) * 16777619) & 16#ffffffff ))
375
+ done
376
+ printf -v REPLY '%s/ttheme-%s.%08x.png' $TTHEME_WARP_THEMES ${${1/@/--}/\//--} $h
377
+ }
378
+
379
+ __tt_warp_view() {
380
+ local name=$1 pal=${1%:*} img="" out="" canvas="" place="" base theme line at REPLY
381
+ local -a wh fr lines
382
+ local -i W=$(( pw * bgcw )) H=$(( ph * bgch )) op wait
383
+ __tt_bg_load $name
384
+ op=$(( ${bgop[$name]} * 100 + 0.5 ))
385
+ base=$TTHEME_WARP_THEMES/ttheme-${${pal/@/--}/\//--}.yaml
386
+ [[ -r $base ]] || return 1
387
+ if (( ! bgoff[$name] )); then
388
+ __tt_warp_saved $name $W $H
389
+ img=$REPLY
390
+ __tt_warp_laid $pal $img
391
+ out=$REPLY
392
+ if [[ ! -r $img ]]; then
393
+ img=${bgsrc[$name]}
394
+ __tt_bg_dim "$img" && (( W && H )) || return 1
395
+ wh=(${=bgdim[$img]})
396
+ __tt_bg_frame $wh[1] $wh[2] $W $H ${bgsize[$name]} ${bgpos[$name]} contain ${bgfocus[$name]}
397
+ fr=(${=REPLY})
398
+ canvas=${W}x$H
399
+ printf -v place '%dx%d%+d%+d' $fr
400
+ fi
401
+ fi
402
+ [[ "$pal $out $op" == "$TTHEME_WARP_VIEW" ]] && return 0
403
+ __tt_warp_loading
404
+ for line in "${(@f)$(<$base)}"; do
405
+ lines+=("$line")
406
+ [[ -n $out && $line == details:* ]] && lines+=("background_image:" " path: \"$out\"" " opacity: $op")
407
+ done
408
+ theme=ttheme-${${pal/@/--}/\//--}.view-$(( ++TTHEME_WARP_VIEWS )).yaml
409
+ __tt_put $TTHEME_WARP_THEMES/$theme "${lines[@]}" || return 1
410
+ at=$EPOCHREALTIME
411
+ if [[ -n $out && ! -r $out ]]; then
412
+ if ! __tt_cli flatten "$img" "$out" "${${TTHEME_PALETTE[$pal]}%% *}" 1 $canvas $place >/dev/null 2>&1; then
413
+ zf_rm -f -- $TTHEME_WARP_THEMES/$theme 2>/dev/null
414
+ return 1
415
+ fi
416
+ TTHEME_WARP_LAID+=($out)
417
+ fi
418
+ wait=$(( 25 - (EPOCHREALTIME - at) * 100 ))
419
+ (( wait > 0 )) && zselect -t $wait
420
+ __tt_warp_set "{ custom = { name = \"$pal\", path = \"$theme\" } }" || return 1
421
+ [[ -z $TTHEME_WARP_SHOWING ]] || zf_rm -f -- $TTHEME_WARP_THEMES/$TTHEME_WARP_SHOWING 2>/dev/null
422
+ TTHEME_WARP_SHOWING=$theme TTHEME_WARP_VIEW="$pal $out $op"
423
+ __tt_warp_publish $pal $theme
424
+ }
425
+
426
+ __tt_warp_unview() {
427
+ [[ -n $TTHEME_WARP_SHOWING ]] || return 0
428
+ local spec=$1
429
+ [[ -n $spec ]] && __tt_apply "$spec"
430
+ zf_rm -f -- $TTHEME_WARP_THEMES/$TTHEME_WARP_SHOWING 2>/dev/null
431
+ TTHEME_WARP_SHOWING="" TTHEME_WARP_VIEW=""
432
+ }
433
+
434
+ __tt_pv_bg_show() {
435
+ (( bgcw && ! TTHEME_WARP_BUSY )) || return 0
436
+ local spec=${TTHEME_PALETTE[${1%:*}]} REPLY
437
+ local -i tuned=0
438
+ __tt_warp_tuned $1 && tuned=1
439
+ if (( tuned )) || [[ $spec == "$applied" && -n $TTHEME_WARP_SHOWING ]]; then
440
+ if zselect -t 15 -r 0 2>/dev/null; then
441
+ bgname=""
442
+ return 0
443
+ fi
444
+ fi
445
+ bgname=$1
446
+ TTHEME_WARP_BUSY=1
447
+ if (( tuned )); then
448
+ __tt_warp_view $1 && applied=$spec painted=$spec
449
+ elif [[ $spec == "$applied" ]]; then
450
+ if [[ -n $TTHEME_WARP_SHOWING ]]; then
451
+ __tt_warp_loading
452
+ __tt_warp_unview "$applied"
453
+ elif __tt_warp_wearing && [[ $REPLY == "${1%:*}" ]]; then
454
+ local want
455
+ local -a reply TTHEME_WARP_LINES
456
+ __tt_warp_value ${1%:*}
457
+ want=$REPLY
458
+ __tt_warp_read
459
+ if [[ $REPLY != "$want" ]]; then
460
+ __tt_warp_loading
461
+ zselect -t 25
462
+ __tt_warp_set "$want"
463
+ fi
464
+ fi
465
+ fi
466
+ [[ $msg == "Loading the background" ]] && msg="" msgt=0
467
+ TTHEME_WARP_BUSY=0
468
+ return 0
469
+ }
470
+
471
+ __tt_pv_bg_close() {
472
+ (( bgcw )) && { printf '\e_Ga=d,d=A,q=2\e\\'; __tt_bg_forget }
473
+ (( ${+bgedit[$bgname]} )) || [[ -n $bgname && ${bgview[${bgname%:*}]} == "$bgname" ]] || __tt_warp_unview "$applied"
474
+ [[ -z $bgcut ]] || { ( zselect -t 1000; rm -rf -- $bgcut ) &!; bgcut="" }
475
+ (( ${#TTHEME_WARP_LAID} )) || return 0
476
+ local -a laid=($TTHEME_WARP_LAID)
477
+ TTHEME_WARP_LAID=()
478
+ ( zselect -t 1000; __tt_warp_sweep $laid ) &!
479
+ }
480
+
481
+ __tt_warp_sweep() {
482
+ setopt localoptions extendedglob
483
+ local f
484
+ local -A used
485
+ for f in $TTHEME_WARP_THEMES/ttheme-*.yaml(N); do
486
+ [[ "$(<$f)" == (#b)*$'\n path: "'([^\"]##)'"'* ]] && used[$match[1]]=1
487
+ done
488
+ for f; do
489
+ (( ${+used[$f]} )) || zf_rm -f -- $f 2>/dev/null
490
+ done
5
491
  }