my xfce4 dotfiles
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

213 lines
6.7 KiB

3 years ago
  1. # invoked in worker: _p9k_worker_main <pgid>
  2. function _p9k_worker_main() {
  3. mkfifo -- $_p9k__worker_file_prefix.fifo || return
  4. echo -nE - s$_p9k_worker_pgid$'\x1e' || return
  5. exec <$_p9k__worker_file_prefix.fifo || return
  6. zf_rm -- $_p9k__worker_file_prefix.fifo || return
  7. local -i reset
  8. local req fd
  9. local -a ready
  10. local _p9k_worker_request_id
  11. local -A _p9k_worker_fds # fd => id$'\x1f'callback
  12. local -A _p9k_worker_inflight # id => inflight count
  13. function _p9k_worker_reply() {
  14. print -nr -- e${(pj:\n:)@}$'\x1e' || kill -- -$_p9k_worker_pgid
  15. }
  16. # usage: _p9k_worker_async <work> <callback>
  17. function _p9k_worker_async() {
  18. local fd async=$1
  19. sysopen -r -o cloexec -u fd <(() { eval $async; } && print -n '\x1e') || return
  20. (( ++_p9k_worker_inflight[$_p9k_worker_request_id] ))
  21. _p9k_worker_fds[$fd]=$_p9k_worker_request_id$'\x1f'$2
  22. }
  23. trap '' PIPE
  24. {
  25. while zselect -a ready 0 ${(k)_p9k_worker_fds}; do
  26. [[ $ready[1] == -r ]] || return
  27. for fd in ${ready:1}; do
  28. if [[ $fd == 0 ]]; then
  29. local buf=
  30. [[ -t 0 ]] # https://www.zsh.org/mla/workers/2020/msg00207.html
  31. if sysread -t 0 'buf[$#buf+1]'; then
  32. while [[ $buf != *$'\x1e' ]]; do
  33. sysread 'buf[$#buf+1]' || return
  34. done
  35. else
  36. (( $? == 4 )) || return
  37. fi
  38. for req in ${(ps:\x1e:)buf}; do
  39. _p9k_worker_request_id=${req%%$'\x1f'*}
  40. () { eval $req[$#_p9k_worker_request_id+2,-1] }
  41. (( $+_p9k_worker_inflight[$_p9k_worker_request_id] )) && continue
  42. print -rn -- d$_p9k_worker_request_id$'\x1e' || return
  43. done
  44. else
  45. local REPLY=
  46. while true; do
  47. if sysread -i $fd 'REPLY[$#REPLY+1]'; then
  48. [[ $REPLY == *$'\x1e' ]] || continue
  49. else
  50. (( $? == 5 )) || return
  51. break
  52. fi
  53. done
  54. local cb=$_p9k_worker_fds[$fd]
  55. _p9k_worker_request_id=${cb%%$'\x1f'*}
  56. unset "_p9k_worker_fds[$fd]"
  57. exec {fd}>&-
  58. if [[ $REPLY == *$'\x1e' ]]; then
  59. REPLY[-1]=""
  60. () { eval $cb[$#_p9k_worker_request_id+2,-1] }
  61. fi
  62. if (( --_p9k_worker_inflight[$_p9k_worker_request_id] == 0 )); then
  63. unset "_p9k_worker_inflight[$_p9k_worker_request_id]"
  64. print -rn -- d$_p9k_worker_request_id$'\x1e' || return
  65. fi
  66. fi
  67. done
  68. done
  69. } always {
  70. kill -- -$_p9k_worker_pgid
  71. }
  72. }
  73. # invoked in master: _p9k_worker_invoke <request-id> <list>
  74. function _p9k_worker_invoke() {
  75. [[ -n $_p9k__worker_resp_fd ]] || return
  76. local req=$1$'\x1f'$2$'\x1e'
  77. if [[ -n $_p9k__worker_req_fd && $+_p9k__worker_request_map[$1] == 0 ]]; then
  78. _p9k__worker_request_map[$1]=
  79. print -rnu $_p9k__worker_req_fd -- $req
  80. else
  81. _p9k__worker_request_map[$1]=$req
  82. fi
  83. }
  84. function _p9k_worker_cleanup() {
  85. # __p9k_intro bugs out here in some cases for some reason.
  86. emulate -L zsh
  87. [[ $_p9k__worker_shell_pid == $sysparams[pid] ]] && _p9k_worker_stop
  88. return 0
  89. }
  90. function _p9k_worker_stop() {
  91. # See comments in _p9k_worker_cleanup.
  92. emulate -L zsh
  93. add-zsh-hook -D zshexit _p9k_worker_cleanup
  94. [[ -n $_p9k__worker_resp_fd ]] && zle -F $_p9k__worker_resp_fd
  95. [[ -n $_p9k__worker_resp_fd ]] && exec {_p9k__worker_resp_fd}>&-
  96. [[ -n $_p9k__worker_req_fd ]] && exec {_p9k__worker_req_fd}>&-
  97. [[ -n $_p9k__worker_pid ]] && kill -- -$_p9k__worker_pid 2>/dev/null
  98. [[ -n $_p9k__worker_file_prefix ]] && zf_rm -f -- $_p9k__worker_file_prefix.fifo
  99. _p9k__worker_pid=
  100. _p9k__worker_req_fd=
  101. _p9k__worker_resp_fd=
  102. _p9k__worker_shell_pid=
  103. _p9k__worker_request_map=()
  104. return 0
  105. }
  106. function _p9k_worker_receive() {
  107. eval "$__p9k_intro"
  108. [[ -z $_p9k__worker_resp_fd ]] && return
  109. {
  110. (( $# <= 1 )) || return
  111. local buf resp
  112. [[ -t $_p9k__worker_resp_fd ]] # https://www.zsh.org/mla/workers/2020/msg00207.html
  113. if sysread -i $_p9k__worker_resp_fd -t 0 'buf[$#buf+1]'; then
  114. while [[ $buf == *[^$'\x05\x1e']$'\x05'# ]]; do
  115. sysread -i $_p9k__worker_resp_fd 'buf[$#buf+1]' || return
  116. done
  117. else
  118. (( $? == 4 )) || return
  119. fi
  120. local -i reset max_reset
  121. for resp in ${(ps:\x1e:)${buf//$'\x05'}}; do
  122. local arg=$resp[2,-1]
  123. case $resp[1] in
  124. d)
  125. local req=$_p9k__worker_request_map[$arg]
  126. if [[ -n $req ]]; then
  127. _p9k__worker_request_map[$arg]=
  128. print -rnu $_p9k__worker_req_fd -- $req || return
  129. else
  130. unset "_p9k__worker_request_map[$arg]"
  131. fi
  132. ;;
  133. e)
  134. () { eval $arg }
  135. (( reset > max_reset )) && max_reset=reset
  136. ;;
  137. s)
  138. [[ -z $_p9k__worker_req_fd ]] || return
  139. [[ $arg == <1-> ]] || return
  140. _p9k__worker_pid=$arg
  141. sysopen -w -o cloexec -u _p9k__worker_req_fd $_p9k__worker_file_prefix.fifo || return
  142. local req=
  143. for req in $_p9k__worker_request_map; do
  144. print -rnu $_p9k__worker_req_fd -- $req || return
  145. done
  146. _p9k__worker_request_map=({${(k)^_p9k__worker_request_map},''})
  147. ;;
  148. *)
  149. return 1
  150. ;;
  151. esac
  152. done
  153. if (( max_reset == 2 )); then
  154. _p9k__refresh_reason=worker
  155. _p9k_set_prompt
  156. _p9k__refresh_reason=''
  157. fi
  158. (( max_reset )) && _p9k_reset_prompt
  159. return 0
  160. } always {
  161. (( $? )) && _p9k_worker_stop
  162. }
  163. }
  164. function _p9k_worker_start() {
  165. setopt monitor || return
  166. {
  167. [[ -n $_p9k__worker_resp_fd ]] && return
  168. _p9k__worker_file_prefix=${TMPDIR:-/tmp}/p10k.worker.$EUID.$sysparams[pid].$EPOCHSECONDS
  169. sysopen -r -o cloexec -u _p9k__worker_resp_fd <(
  170. exec 0</dev/null
  171. if [[ -n $_POWERLEVEL9K_WORKER_LOG_LEVEL ]]; then
  172. exec 2>$_p9k__worker_file_prefix.log
  173. setopt xtrace
  174. else
  175. exec 2>/dev/null
  176. fi
  177. builtin cd -q / || return
  178. zmodload zsh/zselect || return
  179. ! { zselect -t0 || (( $? != 1 )) } || return
  180. local _p9k_worker_pgid=$sysparams[pid]
  181. _p9k_worker_main &
  182. {
  183. trap '' PIPE
  184. while syswrite $'\x05'; do zselect -t 1000; done
  185. zf_rm -f $_p9k__worker_file_prefix.fifo
  186. kill -- -$_p9k_worker_pgid
  187. } &
  188. exec =true) || return
  189. _p9k__worker_pid=$sysparams[procsubstpid]
  190. zle -F $_p9k__worker_resp_fd _p9k_worker_receive
  191. _p9k__worker_shell_pid=$sysparams[pid]
  192. add-zsh-hook zshexit _p9k_worker_cleanup
  193. } always {
  194. (( $? )) && _p9k_worker_stop
  195. }
  196. }