@kecan0406/ttheme 1.2.1 → 1.2.3

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.1",
2
+ "version": "1.2.3",
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.1",
3
+ "version": "1.2.3",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "ttheme": "bin/ttheme.js"
@@ -37,6 +37,7 @@
37
37
  "@material/material-color-utilities": "^0.4.0",
38
38
  "@types/bun": "^1.3.0",
39
39
  "@types/pngjs": "6.0.5",
40
+ "@xterm/headless": "6.0.0",
40
41
  "fast-string-width": "^3.0.2",
41
42
  "jpeg-js": "^0.4.4",
42
43
  "pngjs": "7.0.0",
@@ -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() {
@@ -220,7 +222,7 @@ __tt_bg_write() {
220
222
  rm -f -- $dir/${bgtunef[$1]}
221
223
  else
222
224
  shape=$size
223
- [[ $size == <20-100> && $pos != center ]] && ! __tt_bg_aligns && shape=window
225
+ [[ $size == <20-100> ]] && { [[ $pos != center ]] || __tt_bg_covers } && ! __tt_bg_aligns && shape=window
224
226
  case $shape in
225
227
  fill) img=${bgfill[$1]} fit=cover ;;
226
228
  100) img=$src ;;
@@ -320,6 +322,12 @@ __tt_pv_bg_show() {
320
322
  __tt_bg_at $id -1073741826 $(( at[1] - 1 )) $(( at[2] - 1 )) $at[3] $at[4] $at[5] $at[6] $at[7] $at[8]
321
323
  }
322
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
+
323
331
  __tt_bg_send() {
324
332
  local -i cost=0
325
333
  if [[ -n ${bgsent[$1]} ]]; then
@@ -329,8 +337,7 @@ __tt_bg_send() {
329
337
  bgsent[$1]=$(( ++bgnext + 2 )) bgcost[$1]=$cost
330
338
  (( bgbytes += cost ))
331
339
  bgorder+=("$1")
332
- __tt_b64s "$1"
333
- printf '\e_Ga=t,t=f,f=100,i=%d,q=2;%s\e\\' ${bgsent[$1]} "$REPLY"
340
+ __tt_bg_transmit ${bgsent[$1]} "$1"
334
341
  while (( ${#bgorder} > 1 && bgbytes > 134217728 )); do
335
342
  printf '\e_Ga=d,d=I,i=%d,q=2\e\\' ${bgsent[$bgorder[1]]}
336
343
  (( bgbytes -= bgcost[$bgorder[1]] ))
@@ -449,6 +456,7 @@ __tt_pv_bg_find() {
449
456
  [[ $applied == "$painted" ]] || { __tt_apply "$applied" && painted=$applied }
450
457
  __tt_pv_bg_commit $name
451
458
  __tt_pv_bg_close
459
+ __tt_bg_hide $name
452
460
  err=$(__tt_cli find $name 2>&1 >/dev/tty)
453
461
  rc=$?
454
462
  for var in ${(k)parameters[(I)TTHEME_FIND_*]}; do
@@ -63,6 +63,12 @@ __tt_unpainted() { : }
63
63
 
64
64
  __tt_follows_focus() { return 1 }
65
65
 
66
+ __tt_takes_default() { return 0 }
67
+
68
+ __tt_follows_prompt() { return 1 }
69
+
70
+ __tt_prompted() { : }
71
+
66
72
  __tt_pv_bg_open() { : }
67
73
 
68
74
  __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 +1,3 @@
1
1
  __tt_keepable() { (( ${TTHEME_TERMINALS[(Ie)alacritty]} )) }
2
+
3
+ __tt_follows_focus() { return 0 }
@@ -1,17 +1,35 @@
1
1
  source $TTHEME_HOME/adapters/_bg.zsh
2
2
 
3
3
  if (( ! ${+TTHEME_ITERM_SHOWN} )); then
4
- typeset -gx TTHEME_ITERM_SHOWN=""
4
+ typeset -gx TTHEME_ITERM_SHOWN="" TTHEME_ITERM_DYED=0
5
5
  [[ $ITERM_PROFILE == 'ttheme · '* ]] && TTHEME_ITERM_SHOWN=${ITERM_PROFILE#ttheme · }
6
6
  fi
7
7
 
8
8
  __tt_keepable() { return 0 }
9
9
 
10
+ __tt_follows_focus() { return 0 }
11
+
12
+ __tt_takes_default() {
13
+ local REPLY was=$TTHEME_ITERM_SHOWN
14
+ (( ! TTHEME_ITERM_DYED )) || return 1
15
+ (( TTHEME_TMUX )) && was=$(tmux show -qv @ttheme_shown 2>/dev/null)
16
+ [[ $was == default ]] && return 0
17
+ [[ -z $was ]] && __tt_hear && [[ $REPLY == ${TTHEME_PALETTE[$TTHEME_STARTUP]%% *} ]] || return 1
18
+ TTHEME_ITERM_SHOWN=default
19
+ (( TTHEME_TMUX )) && tmux set -q @ttheme_shown default 2>/dev/null
20
+ return 0
21
+ }
22
+
23
+ __tt_worn() { [[ -z $1 ]] || TTHEME_ITERM_DYED=1 }
24
+
10
25
  __tt_pv_paint() {
11
26
  local -a p=(${=1})
12
27
  if (( ${#p} < 20 )); then
13
28
  __tt_out $'\e]110\e\\\e]111\e\\'
14
- elif [[ $p[1] == - ]]; then
29
+ return 0
30
+ fi
31
+ TTHEME_ITERM_DYED=1
32
+ if [[ $p[1] == - ]]; then
15
33
  __tt_out $'\e]111\e\\\e]10;'$p[2]$'\e\\'
16
34
  else
17
35
  __tt_out $'\e]11;'$p[1]$'\e\\\e]10;'$p[2]$'\e\\'
@@ -34,7 +52,7 @@ __tt_shown() {
34
52
  [[ -r $dir/${${1/@/--}/\//--}.conf || ( -n $was && -r $dir/${${was/@/--}/\//--}.conf ) ]] || (( TTHEME_MUXED )) || return 1
35
53
  (( ${TTHEME_ORDER[(Ie)$1]} )) || return 1
36
54
  __tt_out $'\e]1337;SetProfile=ttheme · '$1$'\a'
37
- TTHEME_ITERM_SHOWN=$1
55
+ TTHEME_ITERM_SHOWN=$1 TTHEME_ITERM_DYED=0
38
56
  (( TTHEME_TMUX )) && tmux set -q @ttheme_shown $1 2>/dev/null
39
57
  return 1
40
58
  }
@@ -44,7 +62,7 @@ __tt_unshown() {
44
62
  (( TTHEME_TMUX )) && was=$(tmux show -qv @ttheme_shown 2>/dev/null)
45
63
  [[ $1 != force && $was == "$want" ]] && return 0
46
64
  __tt_out $'\e]1337;SetProfile=\a'
47
- TTHEME_ITERM_SHOWN=$want
65
+ TTHEME_ITERM_SHOWN=$want TTHEME_ITERM_DYED=0
48
66
  (( TTHEME_TMUX )) && tmux set -q @ttheme_shown "$want" 2>/dev/null
49
67
  return 0
50
68
  }
@@ -6,6 +6,10 @@ __tt_unpainted() {
6
6
 
7
7
  __tt_keepable() { __tt_paints }
8
8
 
9
+ __tt_takes_default() { __tt_osc_reset }
10
+
11
+ __tt_follows_focus() { return 0 }
12
+
9
13
  __tt_scheme() {
10
14
  local -a p=(${=TTHEME_PALETTE[$1]})
11
15
  REPLY="ColorScheme=ttheme-${${1/@/--}/\//--};UseCustomCursorColor=true;customCursorColor=$p[3]"
@@ -21,6 +21,8 @@ __tt_hear() {
21
21
 
22
22
  __tt_heard() { TTHEME_TERMINAL_BASE=$1 }
23
23
 
24
+ __tt_takes_default() { return 1 }
25
+
24
26
  __tt_osc_reset() {
25
27
  [[ -n $TTHEME_TERMINAL_BASE ]] && __tt_osc_apply "$TTHEME_TERMINAL_BASE"
26
28
  unset TTHEME_PAINTED
@@ -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
  }
@@ -4,6 +4,8 @@ typeset -g TTHEME_WEZTERM_SHOWN="" TTHEME_WEZTERM_VIEW=""
4
4
 
5
5
  __tt_keepable() { (( ${TTHEME_TERMINALS[(Ie)wezterm]} )) }
6
6
 
7
+ __tt_follows_focus() { return 0 }
8
+
7
9
  __tt_wezterm_var() {
8
10
  local REPLY
9
11
  __tt_b64s "$2"