=== modified file 'bin/powerbox-menu-list' --- old/bin/powerbox-menu-list 2024-08-03 22:38:44 +0000 +++ new/bin/powerbox-menu-list 2024-07-31 22:48:55 +0000 @@ -59,7 +59,7 @@ if [[ -f $cntdir/data/fstab ]] && read imgdir ignored <$cntdir/data/fstab; then if img_has_bins $imgdir zsh; then img_has_bins $imgdir tmux && \ - printf "!c.tmux %s\n" ${${cntdir:t}#container.} + printf "!c.tmux %s -A\n" ${${cntdir:t}#container.} #img_has_bins $imgdir tmux && \ # printf "container-urxvt/%s/tmux -2u new-session -s %s -A\n" \ # ${${cntdir:t}#container.} ${(qqq)${${cntdir:t}#container.}%.*} === modified file 'bin/xsession-cmd' --- old/bin/xsession-cmd 2024-08-03 22:38:44 +0000 +++ new/bin/xsession-cmd 2024-05-07 20:36:32 +0000 @@ -1,5 +1,6 @@ #!/bin/zsh setopt no_unset extended_glob warn_create_global +set -x # helpers die() { @@ -18,7 +19,6 @@ ensure-container-started $name done } -typeset -f -t cmd_up cmd_down() { local name @@ -28,7 +28,6 @@ s6-svc -wd -T 1000 -dk /run/service/container.$name done } -typeset -f -t cmd_down cmd_link() { local old new relpath @@ -48,42 +47,16 @@ ensure-container-started $new link-to-container-inbox $old $new "$@" || exit $? } -typeset -f -t cmd_link -cmd_services() { - local -a args - local c s - while (($#)); do - case $1 in - (-o) - args+=( $1 $2 ) - shift 2 || exit $? - ;; - (-*) - args+=( $1 ) - shift || exit $? - ;; - (*) - die "non_whitelisted argument: ${(qqq)1}" - ;; - esac - done - for c in /run{,/user/$UID}/service/*/supervise/control(pN); do - s=${c:h:h} - printf '%s\t' $s - s6-svstat "$args[@]" $s - done -} main() { [[ $# -gt 0 ]] || die "xsession-cmd: argument required" local cmd=$1 shift - if (($+functions[cmd_$cmd])); then - cmd_$cmd "$@" || die "command failed: ${(qqq)cmd}" - else - die "unknown command: ${(qqq)cmd}" - fi + case $cmd in + (up|down|link) cmd_$cmd "$@" || die "command failed: ${(qqq)cmd}";; + (*) die "unknown command: ${(qqq)cmd}" + esac } main "$@" === removed file 'xpra-skel/homedir/bin/fakeplumb' --- old/xpra-skel/homedir/bin/fakeplumb 2024-08-03 22:38:44 +0000 +++ new/xpra-skel/homedir/bin/fakeplumb 1970-01-01 00:00:00 +0000 @@ -1,9 +0,0 @@ -#!/bin/zsh -setopt no_unset warn_create_global no_multibyte # count bytes in argv[1] -zmodload zsh/zutil - -typeset -ga plumb_src plumb_dst plumb_wdir plumb_type plumb_attr - -zparseopts -D -E s:=plumb_src d:=plumb_dst w:=plumb_wdir t:=plumb_type a:=plumb_attr || exit $? - -printf "%s\n%s\n%s\n%s\n%s\n%d\n%s" "${plumb_src:-fakeplumb}" "$plumb_dst" "$plumb_wdir" "${plumb_type:-text}" "${plumb_attr}" "$#1" "$1" === modified file 'xpra-skel/homedir/bin/start-xpra-for-container' --- old/xpra-skel/homedir/bin/start-xpra-for-container 2024-08-03 22:38:44 +0000 +++ new/xpra-skel/homedir/bin/start-xpra-for-container 2024-07-31 15:04:42 +0000 @@ -1,7 +1,7 @@ #!/bin/zsh # vim: sts=2 sw=2 et setopt no_unset warn_create_global -zmodload zsh/system || exit $? +zmodload zsh/system typeset -g map=/run/display-container-map typeset -g scandir=/run/service === removed file 'xpra-skel/homedir/bin/wmctrl-all' --- old/xpra-skel/homedir/bin/wmctrl-all 2024-08-03 22:38:44 +0000 +++ new/xpra-skel/homedir/bin/wmctrl-all 1970-01-01 00:00:00 +0000 @@ -1,37 +0,0 @@ -#!/bin/zsh -# vim: sts=2 sw=2 et -setopt no_unset warn_create_global - -typeset -gA display_to_container - -read_map() { - local record container display - for record in /run/display-container-map/*=*(N); do - record=${record:t} - display=${record%%=*} - container=${record#*=} - display_to_container[$display]=$container - done -} - -process_server() { - local disp=$1 wid w_desktop w_pid w_host w_title - (( $+display_to_container[$disp] )) || return - local -a l cmd=( env DISPLAY=:$disp ) - [[ -e /run/Xauthority.$disp ]] && cmd+=( XAUTHORITY=/run/Xauthority.$disp ) - $cmd wmctrl -lp | while IFS=' ' read -r wid w_desktop w_pid w_host w_title; do - l=( $disp $display_to_container[$disp] $((wid)) $w_desktop $w_pid $w_host $w_title ) - printf '%s\n' "${(@pj:\t:)l}" - done -} - -main() { - read_map - local sock - for sock in /tmp/.X11-unix/X*; do - process_server ${sock##*/X} - done -} -#typeset -f -t main - -main "$@" === modified file 'xsession-skel/homedir/.config/i3/config' --- old/xsession-skel/homedir/.config/i3/config 2024-08-03 22:38:44 +0000 +++ new/xsession-skel/homedir/.config/i3/config 2024-07-27 01:48:41 +0000 @@ -13,8 +13,8 @@ # font for window titles. ISO 10646 = Unicode #font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 -font -misc-fixed-*-*-semicondensed-*-13-*-*-*-*-*-*-* -#font pango:Misc Fixed:style=SemiCondensed:pixelsize=13 +#font pango:Fixed SemiCondensed 12px +font "Misc Fixed SemiCondensed 12px" # Use Mouse+$mod to drag floating windows to their wanted position floating_modifier $mod @@ -26,7 +26,7 @@ workspace_auto_back_and_forth yes show_marks yes -for_window [all] title_format "%title - «%instance»" +for_window [all] title_format "%instance» %title" for_window [all] title_window_icon padding 3 for_window [title="Media viewer" class="TelegramDesktop"] floating enable, fullscreen enable @@ -54,7 +54,7 @@ #bindsym $mod+Shift+O exec xscreensaver-command -lock bindsym $mod+Shift+O exec powerbox-plumb lock bindsym $mod+grave exec powerbox-menu -#bindsym $mod+Shift+G exec wswitch +bindsym $mod+Shift+G exec wswitch bindsym $mod+Control+t exec c.exec.user mpd mpc toggle bindsym $mod+Control+Up exec c.exec.user sndiod master-set "2dB+" bindsym $mod+Control+Down exec c.exec.user sndiod master-set "2dB-" @@ -145,7 +145,7 @@ #bindsym $mod+z layout default # zenv unnecessary here, remove after I fix dmenu font in env -bindsym $mod+g exec goa +bindsym $mod+g exec zenv goa # toggle tiling / floating bindsym $mod+Shift+space floating toggle === removed file 'xsession-skel/homedir/.urxvt-perl/52-osc' --- old/xsession-skel/homedir/.urxvt-perl/52-osc 2024-08-03 22:38:44 +0000 +++ new/xsession-skel/homedir/.urxvt-perl/52-osc 1970-01-01 00:00:00 +0000 @@ -1,41 +0,0 @@ -#! perl - -=head1 NAME - -52-osc - Implement OSC 52 ; Interact with X11 clipboard - -=head1 SYNOPSIS - - urxvt -pe 52-osc - -=head1 DESCRIPTION - -This extension implements OSC 52 for interacting with system clipboard - -Most code stolen from: -http://ailin.tucana.uberspace.de/static/nei/*/Code/urxvt/ - -=cut - -use MIME::Base64; -use Encode; - -sub on_osc_seq { - my ($term, $op, $args) = @_; - return () unless $op eq 52; - - my ($clip, $data) = split ';', $args, 2; - if ($data eq '?') { - my $data_free = $term->selection(); - Encode::_utf8_off($data_free); # XXX - $term->tt_write("\e]52;$clip;".encode_base64($data_free, '')."\a"); - } - else { - my $data_decoded = decode_base64($data); - Encode::_utf8_on($data_decoded); # XXX - $term->selection($data_decoded, $clip =~ /c/); - $term->selection_grab(urxvt::CurrentTime, $clip =~ /c/); - } - - () -} \ No newline at end of file === modified file 'xsession-skel/homedir/.urxvt-perl/ccx-osc-52' --- old/xsession-skel/homedir/.urxvt-perl/ccx-osc-52 2024-08-03 22:38:44 +0000 +++ new/xsession-skel/homedir/.urxvt-perl/ccx-osc-52 2024-08-03 21:17:58 +0000 @@ -123,6 +123,21 @@ sub key_press { my ($self, $event, $keysym, $string) = @_; + #my $paste = delete $self->{paste}; + + #if ($keysym == 121) { # y + # dbg("y"); + # #my $paste = $$paste; + # #$paste =~ s/[\x00-\x1f]+/ /g; + # #$self->tt_paste ($paste); + # $self->leave; + #} elsif ($keysym == 112) { # p + # dbg("p"); + # #$self->tt_paste ($$paste); + # $self->leave; + #} elsif ($keysym == 110) { # n + # dbg("n"); + # $self->leave; if ($keysym == 0x6b or $keysym == 0xff52) { # k or Up clip_cursor_up($self); } elsif ($keysym == 0x6a or $keysym == 0xff54) { # j or Down @@ -136,6 +151,8 @@ $self->leave; } + #$self->{paste} = $paste; + 1 } @@ -150,6 +167,10 @@ if ($data eq '?') { print STDERR "\n= 3 =\n"; + #open(my $fh, "-|", "clip"); + #read($fh, my $data_free, 8096); + #close($fh); + open(my $fh, "-|", "s6-sudo /run/inbox/xpra.ccx/run/exec/exec clip -0"); read($fh, my $clip_data, 8096); close($fh); @@ -176,6 +197,12 @@ $self->{clip_label} = \@clip_label; $self->{clip_content} = \@clip_content; clip_menu($self); + + #my $data_free = sprintf('GetSelection(%s)', qquote($clip)); + + ## my $data_free = $self->selection(); + #Encode::_utf8_off($data_free); # XXX + #$self->tt_write("\e]52;$clip;".encode_base64($data_free, '')."\a"); } else { print STDERR "\n= 4 =\n"; === removed file 'xsession-skel/homedir/.zshenv' --- old/xsession-skel/homedir/.zshenv 2024-08-03 22:38:44 +0000 +++ new/xsession-skel/homedir/.zshenv 1970-01-01 00:00:00 +0000 @@ -1,15 +0,0 @@ -# nice PS4 with elapsed seconds (to two decimal places) and subshell indication -if zmodload zsh/system; then # to get actual pid - setopt PROMPT_SUBST - if (( ${terminfo[colors]:-0} >= 8 )); then - # first color is for main shell process, second is subshell - PS4_PID_COLORS=(cyan magenta) - PS4='+%B${SECONDS} %F{${PS4_PID_COLORS[1+($$ != ${sysparams[pid]})]}}%N%f:%F{yellow}%i%f>%b ' - else - PS4='+%B${SECONDS} ${sysparams[pid]} %N:%i>%b ' - fi - - # two digits after the decimal point - typeset -g -F 2 SECONDS - # typeset -F 2 SECONDS # do it twice, some bug I don't understand -fi === modified file 'xsession-skel/homedir/.zshrc' --- old/xsession-skel/homedir/.zshrc 2024-08-03 22:38:44 +0000 +++ new/xsession-skel/homedir/.zshrc 2023-01-10 19:16:35 +0000 @@ -13,12 +13,3 @@ promptinit prompt suse setopt extended_history inc_append_history hist_find_no_dups hist_expire_dups_first - -REPORTTIME=5 -TIMEFMT="$( print -P %f%B )time:$( print -P %b%F{cyan} ) %*E total %U user %S system %P cpu $( print -P %f%B )mem:$( print -P %b%F{green} ) %MM max %Xk txt %Dk res $( print -P %f%B )io:$( print -P %b%F{yellow} ) %Ii %Oo %Fpf $( print -P %b%f )%J" - -bindkey -e - -alias ll='ls -lh --full-time' -alias ns='netstat -ltup' - === removed file 'xsession-skel/homedir/JSON_callbacks.awk' --- old/xsession-skel/homedir/JSON_callbacks.awk 2024-08-03 22:38:44 +0000 +++ new/xsession-skel/homedir/JSON_callbacks.awk 1970-01-01 00:00:00 +0000 @@ -1,127 +0,0 @@ -# Default callbacks. -# Mawk must always define all callbacks. -# Gawk and busybox awk must define callbacks when STREAM=1 only. -# More info in FAQ.md#5. - -# cb_parse_array_empty - parse an empty JSON array. -# Called in JSON.awk's main loop when STREAM=0 only. -# This example returns the standard representation of an empty array. -function cb_parse_array_empty(jpath) { - -# print "parse_array_empty("jpath")" >"/dev/stderr" - return "[]" -} - -# cb_parse_object_empty - parse an empty JSON object. -# Called in JSON.awk's main loop when STREAM=0 only. -# This example returns the standard representation of an empty object. -function cb_parse_object_empty(jpath) { - -# print "parse_object_empty("jpath")" >"/dev/stderr" - return "{}" -} - -# cb_parse_array_enter - begin parsing an array. -# Called in JSON.awk's main loop when STREAM=0 only. -# Use this function to initialize or output other values involved in -# processing each new JSON array. -function cb_parse_array_enter(jpath) { - -# print "cb_parse_array_enter("jpath") token("TOKEN")" >"/dev/stderr" - if ("" != jpath) - ; -} - -# cb_parse_array_exit - end parsing an array. -# Called in JSON.awk's main loop when STREAM=0 only. -# If status == 0 then global CB_VALUE holds the JSON text of the parsed array. -function cb_parse_array_exit(jpath, status) { - -# print "cb_parse_array_exit("jpath") status("status") token("TOKEN") value("CB_VALUE")" >"/dev/stderr" -} - -# cb_parse_object_enter - begin parsing an object. -# Called in JSON.awk's main loop when STREAM=0 only. -# Use this function to initialize or output other values involved in -# processing each new JSON object. -function cb_parse_object_enter(jpath) { - -# print "cb_parse_object_enter("jpath") token("TOKEN")" >"/dev/stderr" - if ("" != jpath) - ; -} - -# cb_parse_object_exit - end parsing an object. -# Called in JSON.awk's main loop when STREAM=0 only. -# If status == 0 then global CB_VALUE holds the JSON text of the parsed object. -function cb_parse_object_exit(jpath, status) { - -# print "cb_parse_object_exit("jpath") status("status") token("TOKEN") value("CB_VALUE")" >"/dev/stderr" -} - -# cb_append_jpath_component - format jpath components -# Called in JSON.awk's main loop when STREAM=0 only. -# This example formats jpaths exactly as JSON.awk does when STREAM=1. -function cb_append_jpath_component (jpath, component) { - -# print "cb_append_jpath_component("jpath") ("jpath") component("component")" >"/dev/stderr" - return (jpath != "" ? jpath "," : "") component -} - -# cb_append_jpath_value - format a jpath / value pair -# Called in JSON.awk's main loop when STREAM=0 only. -# This example formats the jpath / value pair exactly as JSON.awk does when -# STREAM=1. -function cb_append_jpath_value (jpath, value) { - -# print "cb_append_jpath_value("jpath") ("jpath") value("value")" >"/dev/stderr" - return sprintf("[%s]\t%s", jpath, value) -} - -# cb_jpaths - process cb_append_jpath_value outputs -# Called in JSON.awk's main loop when STREAM=0 only. -# This example illustrates printing jpaths to stdout as JSON.awk does when STREAM=1. -# See also cb_parse_array_enter and cb_parse_object_enter. -function cb_jpaths (ary, size, i) { - - # When BRIEF mode is off by default JSON.awk prints the whole input JSON - # text as the last output line. This code block shows how to avoid that. - if (0 == BRIEF) { - # Don't print the last line, which contains the whole input, - # unless it's a simple value or an empty array/object. - if (match(ary[size], /\t[[{][[:space:]]*[^]}]/)) { - if (index(ary[size], "\t") == RSTART) { - size -= 1 - } - } - } - - # Print ary - array of size jpaths and their values. - for(i=1; i <= size; i++) { - print ary[i] - } -} - -# cb_fails - process all error messages at once after parsing -# has completed. Called in JSON.awk's END action when STREAM=0 only. -# This example illustrates printing parsing errors to stdout, -function cb_fails (ary, size, k) { - - # Print ary - associative array of parsing failures. - # ary's keys are the size input file names that JSON.awk read. - for(k in ary) { - print "cb_fails: invalid input file:", k - print FAILS[k] - } -} - -# cb_fail1 - process a single parse error as soon as it is -# encountered. Called in JSON.awk's main loop when STREAM=0 only. -# Return non-zero to let JSON.awk also print the message to stderr. -# This example illustrates printing the error message to stdout only. -function cb_fail1 (message) { - - print "cb_fail1: invalid input file:", FILENAME - print message -} - === removed file 'xsession-skel/homedir/bin/JSON.awk' --- old/xsession-skel/homedir/bin/JSON.awk 2024-08-03 22:38:44 +0000 +++ new/xsession-skel/homedir/bin/JSON.awk 1970-01-01 00:00:00 +0000 @@ -1,407 +0,0 @@ -#!/usr/bin/awk -f -# -# Software: JSON.awk - a practical JSON parser written in awk -# Version: 1.4.2 -# Copyright (c) 2013-2020, step -# License: MIT or Apache 2 -# Project home: https://github.com/step-/JSON.awk -# Credits: https://github.com/step-/JSON.awk#credits - -# See README.md for full usage instructions. -# Usage: -# awk [-v Option="value"...] -f JSON.awk "-" -or- Filepath [Filepath...] -# printf "%s\n" Filepath [Filepath...] | awk [-v Option="value"...] -f JSON.awk -# Options: (default value in braces) -# BRIEF=: 0 or M {1}: -# non-zero excludes non-leaf nodes (array and object) from stdout; bit -# mask M selects which to include of ""(1), "[]"(2) and "{}"(4), or -# excludes ""(8) and wins over bit 1. BRIEF=0 includeѕ all. -# STREAM=: 0 or 1 {1}: -# zero hooks callbacks into parser and stdout printing. -# STRICT=: 0,1,2 {0}: -# 1 enforce RFC8259#7 character escapes except for solidus '/' -# 2 enforce solidus escape too (for JSON embedded in HTML/XML) - -BEGIN { #{{{1 - if (BRIEF == "") BRIEF=1 # when 1 parse() omits non-leaf nodes from stdout - if (STREAM == "") STREAM=1 # when 0 parse() stores JPATHS[] for callback cb_jpaths - if (STRICT == "") STRICT=1 # when 1 parse() enforces valid character escapes (RFC8259 7) - - # Set if empty string/array/object go to stdout and cb_jpaths when BRIEF>0 - # defaults compatible with version up to 1.2 - NO_EMPTY_STR = 0; NO_EMPTY_ARY = NO_EMPTY_OBJ = 1 - # leaf non-leaf non-leaf - - if (BRIEF > 0) { # parse() will look at NO_EMPTY_* - NO_EMPTY_STR = !(x=bit_on(BRIEF, 0)) - NO_EMPTY_ARY = !(x=bit_on(BRIEF, 1)) - NO_EMPTY_OBJ = !(x=bit_on(BRIEF, 2)) - if (x=bit_on(BRIEF, 3)) NO_EMPTY_STR = 1 # wins over bit 0 - } - - # for each input file: - # TOKENS[], NTOKENS, ITOKENS - tokens after tokenize() - # JPATHS[], NJPATHS - parsed data (when STREAM=0) - # at script exit: - # FAILS[] - maps names of invalid files to logged error lines - delete FAILS - reset() - - if (1 == ARGC) { - # file pathnames from stdin - # usage: echo -e "file1\nfile2\n" | awk -f JSON.awk - # usage: { echo; cat file1; } | awk -f JSON.awk - while (getline ARGV[++ARGC] < "/dev/stdin") { - if (ARGV[ARGC] == "") - break - } - } # else usage: awk -f JSON.awk file1 [file2...] - - # set file slurping mode - srand(); RS="\1n/o/m/a/t/c/h" rand() -} - -{ # main loop: process each file in turn {{{1 - reset() # See important application note in reset() - - ++FILEINDEX # 1-based - tokenize($0) # while(get_token()) {print TOKEN} - if (0 == parse() && 0 == STREAM) { - # Pass the callback an array of jpaths. - cb_jpaths(JPATHS, NJPATHS) - } -} - -END { # process invalid files {{{1 - if (0 == STREAM) { - # Pass the callback an associative array of failed objects. - cb_fails(FAILS, NFAILS) - } - exit(NFAILS > 0) -} - -function bit_on(n, b) { #{{{1 -# Return n & (1 << b) for b>0 n>=0 - for awk portability - if (b == 0) return n % 2 - return int(n / 2^b) % 2 -} - -function append_jpath_component(jpath, component) { #{{{1 - if (0 == STREAM) { - return cb_append_jpath_component(jpath, component) - } else { - return (jpath != "" ? jpath "," : "") component - } -} - -function append_jpath_value(jpath, value) { #{{{1 - if (0 == STREAM) { - return cb_append_jpath_value(jpath, value) - } else { - return sprintf("[%s]\t%s", jpath, value) - } -} - -function get_token() { #{{{1 -# usage: {tokenize($0); while(get_token()) {print TOKEN}} - - # return getline TOKEN # for external tokenizer - - TOKEN = TOKENS[++ITOKENS] # for internal tokenize() - return ITOKENS < NTOKENS # 1 if more tokens to come -} - -function parse_array_empty(jpath) { #{{{1 - if (0 == STREAM) { - return cb_parse_array_empty(jpath) - } - return "[]" -} - -function parse_array_enter(jpath) { #{{{1 - if (0 == STREAM) { - cb_parse_array_enter(jpath) - } -} - -function parse_array_exit(jpath, status) { #{{{1 - if (0 == STREAM) { - cb_parse_array_exit(jpath, status) - } -} - -function parse_array(a1, idx,ary,ret) { #{{{1 - idx=0 - ary="" - get_token() -# print "parse_array(" a1 ") TOKEN=" TOKEN >"/dev/stderr" - if (TOKEN != "]") { - while (1) { - if (ret = parse_value(a1, idx)) { - return ret - } - idx=idx+1 - ary=ary VALUE - get_token() - if (TOKEN == "]") { - break - } else if (TOKEN == ",") { - ary = ary "," - } else { - report(", or ]", TOKEN ? TOKEN : "EOF") - return 2 - } - get_token() - } - CB_VALUE = sprintf("[%s]", ary) - # VALUE="" marks non-leaf jpath - VALUE = 0 == BRIEF ? CB_VALUE : "" - } else { - VALUE = CB_VALUE = parse_array_empty(a1) - } - return 0 -} - -function parse_object_empty(jpath) { #{{{1 - if (0 == STREAM) { - return cb_parse_object_empty(jpath) - } - return "{}" -} - -function parse_object_enter(jpath) { #{{{1 - if (0 == STREAM) { - cb_parse_object_enter(jpath) - } -} - -function parse_object_exit(jpath, status) { #{{{1 - if (0 == STREAM) { - cb_parse_object_exit(jpath, status) - } -} - -function parse_object(a1, key,obj) { #{{{1 - obj="" - get_token() -# print "parse_object(" a1 ") TOKEN=" TOKEN >"/dev/stderr" - if (TOKEN != "}") { - while (1) { - if (TOKEN ~ /^".*"$/) { - key=TOKEN - } else { - report("string", TOKEN ? TOKEN : "EOF") - return 3 - } - get_token() - if (TOKEN != ":") { - report(":", TOKEN ? TOKEN : "EOF") - return 4 - } - get_token() - if (parse_value(a1, key)) { - return 5 - } - obj=obj key ":" VALUE - get_token() - if (TOKEN == "}") { - break - } else if (TOKEN == ",") { - obj=obj "," - } else { - report(", or }", TOKEN ? TOKEN : "EOF") - return 6 - } - get_token() - } - CB_VALUE = sprintf("{%s}", obj) - # VALUE="" marks non-leaf jpath - VALUE = 0 == BRIEF ? CB_VALUE : "" - } else { - VALUE = CB_VALUE = parse_object_empty(a1) - } - return 0 -} - -function parse_value(a1, a2, jpath,ret,x,reason) { #{{{1 - jpath = append_jpath_component(a1, a2) -# print "parse_value(" a1 "," a2 ") TOKEN=" TOKEN " jpath=" jpath >"/dev/stderr" - - if (TOKEN == "{") { - parse_object_enter(jpath) - if (parse_object(jpath)) { - parse_object_exit(jpath, 7) - return 7 - } - parse_object_exit(jpath, 0) - } else if (TOKEN == "[") { - parse_array_enter(jpath) - if (ret = parse_array(jpath)) { - parse_array_exit(jpath, ret) - return ret - } - parse_array_exit(jpath, 0) - } else if (TOKEN == "") { #test case 20150410 #4 - report("value", "EOF") - return 8 - } else if ((x = is_value(TOKEN)) >0) { - CB_VALUE = VALUE = TOKEN - } else { - if (-1 == x || -2 == x) { - reason = "missing or invalid character escape" - } - report("value", TOKEN, reason) - return 9 - } - - # jpath=="" occurs on starting and ending the parsing session. - # VALUE=="" is set on parsing a non-empty array or a non-empty object. - # Either condition is a reason to discard the parsed jpath if BRIEF>0. - if (0 < BRIEF && ("" == jpath || "" == VALUE)) { - return 0 - } - - # BRIEF>1 is a bit mask that selects if an empty string/array/object is passed on - if (0 < BRIEF && (NO_EMPTY_STR && VALUE=="\"\"" || NO_EMPTY_ARY && VALUE=="[]" || NO_EMPTY_OBJ && VALUE=="{}")) { - return 0 - } - - x = append_jpath_value(jpath, VALUE) - if(0 == STREAM) { - # save jpath+value for cb_jpaths - JPATHS[++NJPATHS] = x - } else { - # consume jpath+value directly - print x - } - return 0 -} - -function parse( ret) { #{{{1 - get_token() - if (ret = parse_value()) { - return ret - } - if (get_token() || "" != TOKEN) { - report("EOF", TOKEN) - return 10 - # TODO the next JSON text starts here. - } - return 0 -} - -function report(expected, got, extra, i,from,to,context) { #{{{1 - from = ITOKENS - 10; if (from < 1) from = 1 - to = ITOKENS + 10; if (to > NTOKENS) to = NTOKENS - for (i = from; i < ITOKENS; i++) - context = context sprintf("%s ", TOKENS[i]) - context = context "<<" got ">> " - for (i = ITOKENS + 1; i <= to; i++) - context = context sprintf("%s ", TOKENS[i]) - scream("expected <" expected "> but got <" got "> (length " length(got) (extra ? ", "extra :"") ") at input token " ITOKENS "\n" context) -} - -function reset() { #{{{1 -# Application Note: -# If you need to build JPATHS[] incrementally from multiple input files: -# 1) Comment out below: delete JPATHS; NJPATHS=0 -# otherwise each new input file would reset JPATHS[]. -# 2) Move the call to apply() from the main loop to the END statement. -# 3) In the main loop consider adding code that deletes partial JPATHS[] -# elements that would result from parsing invalid JSON files. -# Compatibility Note: -# 1) Very old gawk versions: replace 'delete JPATHS' with 'split("", JPATHS)'. - - TOKEN=""; delete TOKENS; NTOKENS=ITOKENS=0 - delete JPATHS; NJPATHS=0 - CB_VALUE = VALUE = "" -} - -function scream(msg) { #{{{1 - NFAILS += (FILENAME in FAILS ? 0 : 1) - FAILS[FILENAME] = FAILS[FILENAME] (FAILS[FILENAME]!="" ? "\n" : "") msg - if(0 == STREAM) { - if(cb_fail1(msg)) { - print FILENAME ": " msg >"/dev/stderr" - } - } else { - print FILENAME ": " msg >"/dev/stderr" - } -} - -function tokenize(a1) { #{{{1 -# usage A: {for(i=1; i<=tokenize($0); i++) print TOKENS[i]} -# see also get_token() - -# Pattern string summary with adjustments: -# - replace strings with regex constant; https://github.com/step-/JSON.awk/issues/1 -# - reduce [:cntrl:] to [\000-\037]; https://github.com/step-/JSON.awk/issues/5 -# - reduce [:space:] to [ \t\n\r]; https://tools.ietf.org/html/rfc8259#page-5 ws -# - replace {4} quantifier with three [0-9a-fA-F] for mawk; https://unix.stackexchange.com/a/506125 -# - UTF-8 BOM signature; https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding -# ---------- -# TOKENS = BOM "|" STRING "|" NUMBER "|" KEYWORD "|" SPACE "|." -# BOM = "^\357\273\277" # cf. issue #17 -# STRING = "\"" CHAR "*(" ESCAPE CHAR "*)*\"" -# ESCAPE = "(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})" -# CHAR = "[^[:cntrl:]\\\"]" -# NUMBER = "-?(0|[1-9][0-9]*)([.][0-9]+)?([eE][+-]?[0-9]+)?" -# KEYWORD = "null|false|true" -# SPACE = "[[:space:]]+" - - gsub(/^\357\273\277|"[^"\\\000-\037]*((\\[^u\000-\037]|\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])[^"\\\000-\037]*)*"|-?(0|[1-9][0-9]*)([.][0-9]+)?([eE][+-]?[0-9]+)?|null|false|true|[ \t\n\r]+|./, "\n&", a1) - gsub("\n" "[ \t\n\r]+", "\n", a1) - # ^\n BOM or \n$? - gsub(/^\n(\357\273\277\n)?|\n$/, "", a1) - ITOKENS=0 # get_token() helper - return NTOKENS = split(a1, TOKENS, /\n/) -} - -function is_value(a1) { #{{{1 - # Return 0(malformed ) <0( but !strict content) >0(pass) - - # STRING | NUMBER | KEYWORD - if(!STRICT) - return a1 ~ /^("[^"\\\000-\037]*((\\[^u\000-\037]|\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])[^"\\\000-\037]*)*"|-?(0|[1-9][0-9]*)([.][0-9]+)?([eE][+-]?[0-9]+)?|null|false|true)$/ - - # STRICT is on - # unescaped = %x20-21 / %x23-5B / %x5D-10FFFF - # Characters in a STRING are restricted as follows (RFC8259): - # All Unicode characters may be placed within the quotation marks, except for the characters that MUST be escaped: - # quotation mark, reverse solidus, and the control characters (U+0000 through U+001F). - # Any character may be escaped with \uXXXX, alternatively, with the following two-character escapes: - # %x75 4HEXDIG ; uXXXX U+XXXX - # %x22 / ; " quotation mark U+0022 - # %x5C / ; \ reverse solidus U+005C - # %x62 / ; b backspace U+0008 - # %x66 / ; f form feed U+000C - # %x6E / ; n line feed U+000A removed by tokenizer - # %x72 / ; r carriage return U+000D removed by tokenizer - # %x2F / ; / solidus U+002F enforced only when STRICT >1 - # %x74 / ; t tab U+0009 removed by tokenizer - - # NUMBER | KEYWORD - if (1 != index(a1, "\"")) { - return a1 ~ /^(-?(0|[1-9][0-9]*)([.][0-9]+)?([eE][+-]?[0-9]+)?|null|false|true)$/ - } - # invalid STRING - if (a1 !~ /^("[^"\\\000-\037]*((\\[^u\000-\037]|\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])[^"\\\000-\037]*)*")$/) { - return 0 - } - a1 = substr(a1, 2, length(a1) -2) - - # STRICT 1: allowed character escapes - gsub(/\\["\\\/bfnrt]|\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]/, "", a1) - # STRICT 1: unescaped quotation-mark, reverse solidus and control characters - if (a1 ~ /["\\\000-\037]/) { - return -1 - } - # STRICT 2: unescaped solidus - if (STRICT > 1 && index(a1, "/")) { - return -2 - } - # PASS STRICT STRING - return 1 -} - -# vim:fdm=marker: === removed file 'xsession-skel/homedir/bin/JSON.bbawk' --- old/xsession-skel/homedir/bin/JSON.bbawk 2024-08-03 22:38:44 +0000 +++ new/xsession-skel/homedir/bin/JSON.bbawk 1970-01-01 00:00:00 +0000 @@ -1,407 +0,0 @@ -#!/usr/bin/awk -f -# -# Software: JSON.awk - a practical JSON parser written in awk -# Version: 1.4.2 -# Copyright (c) 2013-2020, step -# License: MIT or Apache 2 -# Project home: https://github.com/step-/JSON.awk -# Credits: https://github.com/step-/JSON.awk#credits - -# See README.md for full usage instructions. -# Usage: -# awk [-v Option="value"...] -f JSON.awk "-" -or- Filepath [Filepath...] -# printf "%s\n" Filepath [Filepath...] | awk [-v Option="value"...] -f JSON.awk -# Options: (default value in braces) -# BRIEF=: 0 or M {1}: -# non-zero excludes non-leaf nodes (array and object) from stdout; bit -# mask M selects which to include of ""(1), "[]"(2) and "{}"(4), or -# excludes ""(8) and wins over bit 1. BRIEF=0 includeѕ all. -# STREAM=: 0 or 1 {1}: -# zero hooks callbacks into parser and stdout printing. -# STRICT=: 0,1,2 {0}: -# 1 enforce RFC8259#7 character escapes except for solidus '/' -# 2 enforce solidus escape too (for JSON embedded in HTML/XML) - -BEGIN { #{{{1 - if (BRIEF == "") BRIEF=1 # when 1 parse() omits non-leaf nodes from stdout - if (STREAM == "") STREAM=1 # when 0 parse() stores JPATHS[] for callback cb_jpaths - if (STRICT == "") STRICT=1 # when 1 parse() enforces valid character escapes (RFC8259 7) - - # Set if empty string/array/object go to stdout and cb_jpaths when BRIEF>0 - # defaults compatible with version up to 1.2 - NO_EMPTY_STR = 0; NO_EMPTY_ARY = NO_EMPTY_OBJ = 1 - # leaf non-leaf non-leaf - - if (BRIEF > 0) { # parse() will look at NO_EMPTY_* - NO_EMPTY_STR = !(x=bit_on(BRIEF, 0)) - NO_EMPTY_ARY = !(x=bit_on(BRIEF, 1)) - NO_EMPTY_OBJ = !(x=bit_on(BRIEF, 2)) - if (x=bit_on(BRIEF, 3)) NO_EMPTY_STR = 1 # wins over bit 0 - } - - # for each input file: - # TOKENS[], NTOKENS, ITOKENS - tokens after tokenize() - # JPATHS[], NJPATHS - parsed data (when STREAM=0) - # at script exit: - # FAILS[] - maps names of invalid files to logged error lines - delete FAILS - reset() - - if (1 == ARGC) { - # file pathnames from stdin - # usage: echo -e "file1\nfile2\n" | awk -f JSON.awk - # usage: { echo; cat file1; } | awk -f JSON.awk - while (getline ARGV[++ARGC] < "/dev/stdin") { - if (ARGV[ARGC] == "") - break - } - } # else usage: awk -f JSON.awk file1 [file2...] - - # set file slurping mode - srand(); RS="\1n/o/m/a/t/c/h" rand() -} - -{ # main loop: process each file in turn {{{1 - reset() # See important application note in reset() - - ++FILEINDEX # 1-based - tokenize($0) # while(get_token()) {print TOKEN} - if (0 == parse() && 0 == STREAM) { - # Pass the callback an array of jpaths. - cb_jpaths(JPATHS, NJPATHS) - } -} - -END { # process invalid files {{{1 - if (0 == STREAM) { - # Pass the callback an associative array of failed objects. - cb_fails(FAILS, NFAILS) - } - exit(NFAILS > 0) -} - -function bit_on(n, b) { #{{{1 -# Return n & (1 << b) for b>0 n>=0 - for awk portability - if (b == 0) return n % 2 - return int(n / 2^b) % 2 -} - -function append_jpath_component(jpath, component) { #{{{1 - if (0 == STREAM) { - return cb_append_jpath_component(jpath, component) - } else { - return (jpath != "" ? jpath "," : "") component - } -} - -function append_jpath_value(jpath, value) { #{{{1 - if (0 == STREAM) { - return cb_append_jpath_value(jpath, value) - } else { - return sprintf("[%s]\t%s", jpath, value) - } -} - -function get_token() { #{{{1 -# usage: {tokenize($0); while(get_token()) {print TOKEN}} - - # return getline TOKEN # for external tokenizer - - TOKEN = TOKENS[++ITOKENS] # for internal tokenize() - return ITOKENS < NTOKENS # 1 if more tokens to come -} - -function parse_array_empty(jpath) { #{{{1 - if (0 == STREAM) { - return cb_parse_array_empty(jpath) - } - return "[]" -} - -function parse_array_enter(jpath) { #{{{1 - if (0 == STREAM) { - cb_parse_array_enter(jpath) - } -} - -function parse_array_exit(jpath, status) { #{{{1 - if (0 == STREAM) { - cb_parse_array_exit(jpath, status) - } -} - -function parse_array(a1, idx,ary,ret) { #{{{1 - idx=0 - ary="" - get_token() -# print "parse_array(" a1 ") TOKEN=" TOKEN >"/dev/stderr" - if (TOKEN != "]") { - while (1) { - if (ret = parse_value(a1, idx)) { - return ret - } - idx=idx+1 - ary=ary VALUE - get_token() - if (TOKEN == "]") { - break - } else if (TOKEN == ",") { - ary = ary "," - } else { - report(", or ]", TOKEN ? TOKEN : "EOF") - return 2 - } - get_token() - } - CB_VALUE = sprintf("[%s]", ary) - # VALUE="" marks non-leaf jpath - VALUE = 0 == BRIEF ? CB_VALUE : "" - } else { - VALUE = CB_VALUE = parse_array_empty(a1) - } - return 0 -} - -function parse_object_empty(jpath) { #{{{1 - if (0 == STREAM) { - return cb_parse_object_empty(jpath) - } - return "{}" -} - -function parse_object_enter(jpath) { #{{{1 - if (0 == STREAM) { - cb_parse_object_enter(jpath) - } -} - -function parse_object_exit(jpath, status) { #{{{1 - if (0 == STREAM) { - cb_parse_object_exit(jpath, status) - } -} - -function parse_object(a1, key,obj) { #{{{1 - obj="" - get_token() -# print "parse_object(" a1 ") TOKEN=" TOKEN >"/dev/stderr" - if (TOKEN != "}") { - while (1) { - if (TOKEN ~ /^".*"$/) { - key=TOKEN - } else { - report("string", TOKEN ? TOKEN : "EOF") - return 3 - } - get_token() - if (TOKEN != ":") { - report(":", TOKEN ? TOKEN : "EOF") - return 4 - } - get_token() - if (parse_value(a1, key)) { - return 5 - } - obj=obj key ":" VALUE - get_token() - if (TOKEN == "}") { - break - } else if (TOKEN == ",") { - obj=obj "," - } else { - report(", or }", TOKEN ? TOKEN : "EOF") - return 6 - } - get_token() - } - CB_VALUE = sprintf("{%s}", obj) - # VALUE="" marks non-leaf jpath - VALUE = 0 == BRIEF ? CB_VALUE : "" - } else { - VALUE = CB_VALUE = parse_object_empty(a1) - } - return 0 -} - -function parse_value(a1, a2, jpath,ret,x,reason) { #{{{1 - jpath = append_jpath_component(a1, a2) -# print "parse_value(" a1 "," a2 ") TOKEN=" TOKEN " jpath=" jpath >"/dev/stderr" - - if (TOKEN == "{") { - parse_object_enter(jpath) - if (parse_object(jpath)) { - parse_object_exit(jpath, 7) - return 7 - } - parse_object_exit(jpath, 0) - } else if (TOKEN == "[") { - parse_array_enter(jpath) - if (ret = parse_array(jpath)) { - parse_array_exit(jpath, ret) - return ret - } - parse_array_exit(jpath, 0) - } else if (TOKEN == "") { #test case 20150410 #4 - report("value", "EOF") - return 8 - } else if ((x = is_value(TOKEN)) >0) { - CB_VALUE = VALUE = TOKEN - } else { - if (-1 == x || -2 == x) { - reason = "missing or invalid character escape" - } - report("value", TOKEN, reason) - return 9 - } - - # jpath=="" occurs on starting and ending the parsing session. - # VALUE=="" is set on parsing a non-empty array or a non-empty object. - # Either condition is a reason to discard the parsed jpath if BRIEF>0. - if (0 < BRIEF && ("" == jpath || "" == VALUE)) { - return 0 - } - - # BRIEF>1 is a bit mask that selects if an empty string/array/object is passed on - if (0 < BRIEF && (NO_EMPTY_STR && VALUE=="\"\"" || NO_EMPTY_ARY && VALUE=="[]" || NO_EMPTY_OBJ && VALUE=="{}")) { - return 0 - } - - x = append_jpath_value(jpath, VALUE) - if(0 == STREAM) { - # save jpath+value for cb_jpaths - JPATHS[++NJPATHS] = x - } else { - # consume jpath+value directly - print x - } - return 0 -} - -function parse( ret) { #{{{1 - get_token() - if (ret = parse_value()) { - return ret - } - if (get_token() || "" != TOKEN) { - report("EOF", TOKEN) - return 10 - # TODO the next JSON text starts here. - } - return 0 -} - -function report(expected, got, extra, i,from,to,context) { #{{{1 - from = ITOKENS - 10; if (from < 1) from = 1 - to = ITOKENS + 10; if (to > NTOKENS) to = NTOKENS - for (i = from; i < ITOKENS; i++) - context = context sprintf("%s ", TOKENS[i]) - context = context "<<" got ">> " - for (i = ITOKENS + 1; i <= to; i++) - context = context sprintf("%s ", TOKENS[i]) - scream("expected <" expected "> but got <" got "> (length " length(got) (extra ? ", "extra :"") ") at input token " ITOKENS "\n" context) -} - -function reset() { #{{{1 -# Application Note: -# If you need to build JPATHS[] incrementally from multiple input files: -# 1) Comment out below: delete JPATHS; NJPATHS=0 -# otherwise each new input file would reset JPATHS[]. -# 2) Move the call to apply() from the main loop to the END statement. -# 3) In the main loop consider adding code that deletes partial JPATHS[] -# elements that would result from parsing invalid JSON files. -# Compatibility Note: -# 1) Very old gawk versions: replace 'delete JPATHS' with 'split("", JPATHS)'. - - TOKEN=""; delete TOKENS; NTOKENS=ITOKENS=0 - delete JPATHS; NJPATHS=0 - CB_VALUE = VALUE = "" -} - -function scream(msg) { #{{{1 - NFAILS += (FILENAME in FAILS ? 0 : 1) - FAILS[FILENAME] = FAILS[FILENAME] (FAILS[FILENAME]!="" ? "\n" : "") msg - if(0 == STREAM) { - if(cb_fail1(msg)) { - print FILENAME ": " msg >"/dev/stderr" - } - } else { - print FILENAME ": " msg >"/dev/stderr" - } -} - -function tokenize(a1) { #{{{1 -# usage A: {for(i=1; i<=tokenize($0); i++) print TOKENS[i]} -# see also get_token() - -# Pattern string summary with adjustments: -# - replace strings with regex constant; https://github.com/step-/JSON.awk/issues/1 -# - reduce [:cntrl:] to [\001-\037]; https://github.com/step-/JSON.awk/issues/5 -# - reduce [:space:] to [ \t\n\r]; https://tools.ietf.org/html/rfc8259#page-5 ws -# - replace {4} quantifier with three [0-9a-fA-F] for mawk; https://unix.stackexchange.com/a/506125 -# - UTF-8 BOM signature; https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding -# ---------- -# TOKENS = BOM "|" STRING "|" NUMBER "|" KEYWORD "|" SPACE "|." -# BOM = "^\357\273\277" # cf. issue #17 -# STRING = "\"" CHAR "*(" ESCAPE CHAR "*)*\"" -# ESCAPE = "(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})" -# CHAR = "[^[:cntrl:]\\\"]" -# NUMBER = "-?(0|[1-9][0-9]*)([.][0-9]+)?([eE][+-]?[0-9]+)?" -# KEYWORD = "null|false|true" -# SPACE = "[[:space:]]+" - - gsub(/^\357\273\277|"[^"\\\001-\037]*((\\[^u\001-\037]|\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])[^"\\\001-\037]*)*"|-?(0|[1-9][0-9]*)([.][0-9]+)?([eE][+-]?[0-9]+)?|null|false|true|[ \t\n\r]+|./, "\n&", a1) - gsub("\n" "[ \t\n\r]+", "\n", a1) - # ^\n BOM or \n$? - gsub(/^\n(\357\273\277\n)?|\n$/, "", a1) - ITOKENS=0 # get_token() helper - return NTOKENS = split(a1, TOKENS, /\n/) -} - -function is_value(a1) { #{{{1 - # Return 0(malformed ) <0( but !strict content) >0(pass) - - # STRING | NUMBER | KEYWORD - if(!STRICT) - return a1 ~ /^("[^"\\\001-\037]*((\\[^u\001-\037]|\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])[^"\\\001-\037]*)*"|-?(0|[1-9][0-9]*)([.][0-9]+)?([eE][+-]?[0-9]+)?|null|false|true)$/ - - # STRICT is on - # unescaped = %x20-21 / %x23-5B / %x5D-10FFFF - # Characters in a STRING are restricted as follows (RFC8259): - # All Unicode characters may be placed within the quotation marks, except for the characters that MUST be escaped: - # quotation mark, reverse solidus, and the control characters (U+0000 through U+001F). - # Any character may be escaped with \uXXXX, alternatively, with the following two-character escapes: - # %x75 4HEXDIG ; uXXXX U+XXXX - # %x22 / ; " quotation mark U+0022 - # %x5C / ; \ reverse solidus U+005C - # %x62 / ; b backspace U+0008 - # %x66 / ; f form feed U+000C - # %x6E / ; n line feed U+000A removed by tokenizer - # %x72 / ; r carriage return U+000D removed by tokenizer - # %x2F / ; / solidus U+002F enforced only when STRICT >1 - # %x74 / ; t tab U+0009 removed by tokenizer - - # NUMBER | KEYWORD - if (1 != index(a1, "\"")) { - return a1 ~ /^(-?(0|[1-9][0-9]*)([.][0-9]+)?([eE][+-]?[0-9]+)?|null|false|true)$/ - } - # invalid STRING - if (a1 !~ /^("[^"\\\001-\037]*((\\[^u\001-\037]|\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])[^"\\\001-\037]*)*")$/) { - return 0 - } - a1 = substr(a1, 2, length(a1) -2) - - # STRICT 1: allowed character escapes - gsub(/\\["\\\/bfnrt]|\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]/, "", a1) - # STRICT 1: unescaped quotation-mark, reverse solidus and control characters - if (a1 ~ /["\\\001-\037]/) { - return -1 - } - # STRICT 2: unescaped solidus - if (STRICT > 1 && index(a1, "/")) { - return -2 - } - # PASS STRICT STRING - return 1 -} - -# vim:fdm=marker: === modified file 'xsession-skel/homedir/bin/c.tmux' --- old/xsession-skel/homedir/bin/c.tmux 2024-08-03 22:38:44 +0000 +++ new/xsession-skel/homedir/bin/c.tmux 2024-07-31 22:48:55 +0000 @@ -11,11 +11,11 @@ [[ $1 == */* ]] && die "Invalid container name: ${(qqq)1}" container=$1 shift 1 || exit $? - if (($#)) && [[ $1 == -s ]]; then + if [[ $1 == -s ]]; then session=$2 shift 2 || exit $? fi - c.urxvt.named $container tmux-session-$session tmux -2u new-session -s $session -A "$@" + c.urxvt2 $container tmux -2u new-session -s $session -A "$@" } typeset -f -t main === modified file 'xsession-skel/homedir/bin/c.urxvt' --- old/xsession-skel/homedir/bin/c.urxvt 2024-08-03 22:38:44 +0000 +++ new/xsession-skel/homedir/bin/c.urxvt 2024-07-31 22:50:19 +0000 @@ -7,7 +7,7 @@ } direct-urxvt() { - local container cmd sock display + local container cmd sockd display container=$1 cmd=$2 sock=/run/inbox/$container/run/exec/exec @@ -29,7 +29,7 @@ ' importas -i -u TERM_NAME TERM_NAME' '}' '/mnt/ns/bin/socketpair 3 1' - 'background -d {' + 'background {' ' fdclose 3' ' s6-sudo $EXEC_PATH' ' /mnt/ns/bin/spawn-pty rxvt-unicode-256color {' === removed file 'xsession-skel/homedir/bin/c.urxvt.named' --- old/xsession-skel/homedir/bin/c.urxvt.named 2024-08-03 22:38:44 +0000 +++ new/xsession-skel/homedir/bin/c.urxvt.named 1970-01-01 00:00:00 +0000 @@ -1,206 +0,0 @@ -#!/bin/zsh -# vim: sts=2 sw=2 et -setopt no_unset warn_create_global -zmodload zsh/system || exit $? - -typeset -g scandir=/run/service -typeset -g build=/run/urxvt.named.service - -main() { - local container name arg cmd sock s - local -a quoted - container=$1 - [[ $container == */* ]] && exit 100 - name=$2 - [[ $name == */* ]] && exit 100 - shift 2 || exit 100 - sock=/run/inbox/$container/run/exec/exec - s=urxvt.for-$container.named-$name - - - sv_start $s - - sv_env EXEC_PATH $sock - - sv_env TERM_NAME ${container//./:} - - for arg in "$@"; do - quoted+=( "$(s6-quote -- "$arg")" ) - done - local -a el_cmd=( - 's6-envdir env' - 'multisubstitute {' - ' importas -i -u EXEC_PATH EXEC_PATH' - ' importas -i -u TERM_NAME TERM_NAME' - '}' - '/mnt/ns/bin/socketpair 3 1' - 'background -d {' - ' fdclose 9' - ' fdclose 3' - ' s6-sudo $EXEC_PATH' - ' /mnt/ns/bin/spawn-pty rxvt-unicode-256color {' - " ${(j: :)quoted}" - ' } /mnt/ns/bin/fdsend 1 0 true' - '}' - 'fdmove -c 1 2' - '/mnt/ns/bin/fdrecvto 3 4' - 'fdclose 3' - 'backtick -E PTS_NAME { /mnt/ns/bin/ptsname 4 }' - 'if { fdmove 1 9 printf %s\n ${TERM_NAME}:${PTS_NAME} }' - 'fdclose 9' - 'urxvt -name ${TERM_NAME}:${PTS_NAME} -pty-fd 4' - ) - - sv_el_script run $el_cmd - - sv_notification_fd 9 - - sv_end - - s6-sudo /run/cmd.s link $container xsession.${DISPLAY#:}.$USER run/exec/exec || - die "Failed to link ${(qqq)container} exec socket." - - - s6-svc -wU -T 5000 -o $scandir/$s -} - -typeset -f -t main - -### Color and text definition {{{1 - -typeset -g hl_fatal hl_reset - -# die messages -if (( $terminfo[colors] >= 8 )); then - hl_fatal='%F{red}%B'; hl_fatal=${(%)hl_fatal} - hl_warn='%F{yellow}%B'; hl_warn=${(%)hl_warn} - hl_reset='%b%f'; hl_reset=${(%)hl_reset} -fi - -### Utility functions {{{1 -err_msg() { - local first=$1 - shift - printf >&2 '%s%s%s%s\n' "$hl_fatal" "$first" "$hl_reset" "$*" -} - -warn_msg() { - local first=$1 - shift - printf >&2 '%s%s%s%s\n' "$hl_warn" "$first" "$hl_reset" "$*" -} - -# helper that prints out stack, error message and exits -die_ret() { - set +x - local ret n - ret=$1 - shift - print -r - >&2 "${hl_fatal}Fatal$hl_reset error occurend in:" - for n in {${#funcfiletrace}..1}; do - printf >&2 '%d> %s (%s)\n' $n "$funcfiletrace[$n]" "$functrace[$n]" - done - printf >&2 '%s\n' "${hl_fatal}*$hl_reset $^@" - exit $ret -} - -die() { - set +x - die_ret 1 "$@" -} -die100() { # 100: wrong usage - set +x - die_ret 100 "$@" -} -die111() { # 111: system call failed - set +x - die_ret 111 "$@" -} - --() { # Run command and die on nonzero exitcode - "$@" || die_ret $? "command failed with exitcode $?: ${(j: :)${(q)@}}" -} - -# service builder - -sv_start() { - (($+sv_name)) && \ - die100 "sv_start: previous service definition ${(qqq)sv_name} wasn't ended properly" - (( $# != 1 )) && die100 "sv_start: incorrect arguments" - [[ $1 == */* ]] && die100 "sv_start: incorrect argument" - - typeset -g sv_name=$1 - typeset -g sv_dir=$build/$1 - - mkdir -p $sv_dir - - touch $sv_dir/down -} - -sv_end() { - (($+sv_name)) || die100 "$0: no service definition started" - (($+sv_dir)) || die100 "$0: inconsistent state for service ${(qqq)sv_name}" - (( $# != 0 )) && die100 "$0: incorrect arguments" - - if ! [[ -L $scandir/$sv_name ]]; then - - s6-svlink -t 3000 $scandir $sv_dir - # - s6-mkfifodir $sv_dir/event - # - ln -s -T $sv_dir $scandir/$sv_name - # new_services+=( $scandir/$sv_name ) - fi - unset sv_name sv_dir -} - -sv_link_command() { - (($+sv_name)) || die100 "$0: no service definition started" - (($+sv_dir)) || die100 "$0: inconsistent state for service ${(qqq)sv_name}" - (( $# != 2 )) && die100 "$0: incorrect arguments" - - local script_path=$sv_dir/$1 - - ln -s -f -T ${commands[$2]} $script_path -} - -sv_write_lines() { - (($+sv_name)) || die100 "$0: no service definition started" - (($+sv_dir)) || die100 "$0: inconsistent state for service ${(qqq)sv_name}" - (( $# < 2 )) && die100 "$0: incorrect arguments" - - local file_path=$sv_dir/$1 - shift - printf '%s\n' >$file_path "$@" || \ - die111 "Error writing to ${(qqq)file_path}" -} - -sv_el_script() { - (($+sv_name)) || die100 "$0: no service definition started" - (($+sv_dir)) || die100 "$0: inconsistent state for service ${(qqq)sv_name}" - - - sv_write_lines $1 '#!/bin/execlineb -P' "$@[2,-1]" - - chmod +x $sv_dir/$1 -} - -sv_notification_fd() { - (($+sv_name)) || die100 "$0: no service definition started" - (($+sv_dir)) || die100 "$0: inconsistent state for service ${(qqq)sv_name}" - (( $# != 1 )) && die100 "$0: incorrect arguments" - - - sv_write_lines notification-fd $1 -} - -sv_env() { - (($+sv_name)) || die100 "$0: no service definition started" - (($+sv_dir)) || die100 "$0: inconsistent state for service ${(qqq)sv_name}" - (( $# < 2 )) && die100 "$0: incorrect arguments" - - - mkdir -p $sv_dir/env - local k v - for k v in "$@"; do - [[ $k == */* ]] && die100 "$0: invalid env variable ${(qqq)k}" - - sv_write_lines env/$k $v - done -} - -sv_mkdir() { - (($+sv_name)) || die100 "$0: no service definition started" - (($+sv_dir)) || die100 "$0: inconsistent state for service ${(qqq)sv_name}" - (( $# < 1 )) && die100 "$0: incorrect arguments" - - - mkdir -p $sv_dir/${^@} -} - -# end service builder - - - -main "$@" === modified file 'xsession-skel/homedir/bin/clip' --- old/xsession-skel/homedir/bin/clip 2024-08-03 22:38:44 +0000 +++ new/xsession-skel/homedir/bin/clip 2024-07-27 01:48:41 +0000 @@ -7,4 +7,4 @@ #clipboards=( ${(0)"$(c.exec xpra.$USER clip -0)"} ) choice=$(printf '%s » %s\n' ${(kv)clipboards//$'\n'/»} | dmenu -l 8 -fn Terminus) choice=${choice%% » *} -printf "%s" $clipboards[$choice] +printf "%s\n" $clipboards[$choice] === removed file 'xsession-skel/homedir/bin/dmenu-custom' --- old/xsession-skel/homedir/bin/dmenu-custom 2024-08-03 22:38:44 +0000 +++ new/xsession-skel/homedir/bin/dmenu-custom 1970-01-01 00:00:00 +0000 @@ -1,2 +0,0 @@ -#!/bin/execlineb -S0 -dmenu -fn "Misc Fixed:semicondensed:pixelsize=13:lang=cs" $@ === removed file 'xsession-skel/homedir/bin/goa' --- old/xsession-skel/homedir/bin/goa 2024-08-03 22:38:44 +0000 +++ new/xsession-skel/homedir/bin/goa 1970-01-01 00:00:00 +0000 @@ -1,629 +0,0 @@ -#!/bin/zsh -setopt no_unset extended_glob warn_create_global - -typeset -g -A item_title item_to_id id_to_item container_exec_linked -typeset -g -a items dmenu_cmd links item_props -typeset -g delim _0 RS current_item next_item_id - -delim=' » ' -_0=$'\0' -RS=$'\036' -next_item_id=1 - -if (($+commands[dmenu-custom])); then - dmenu_cmd=( dmenu-custom ) -else - dmenu_cmd=( dmenu ) -fi -dmenu_cmd+=( -i -l 30 ) - -### Utility functions {{{1 -typeset -g hl_fatal hl_reset - -# die messages -if (( $terminfo[colors] >= 8 )); then - hl_success='%F{green}%B'; hl_success=${(%)hl_success} - hl_fatal='%F{red}%B'; hl_fatal=${(%)hl_fatal} - hl_warn='%F{yellow}%B'; hl_warn=${(%)hl_warn} - hl_reset='%b%f'; hl_reset=${(%)hl_reset} -fi - -err_msg() { - local first=$1 - shift - printf >&2 '%s%s%s%s\n' "$hl_fatal" "$first" "$hl_reset" "$*" -} - -warn_msg() { - local first=$1 - shift - printf >&2 '%s%s%s%s\n' "$hl_warn" "$first" "$hl_reset" "$*" -} - -# helper that prints out stack, error message and exits -die_ret() { - set +x - local ret n - ret=$1 - shift - print -r - >&2 "${hl_fatal}Fatal$hl_reset error occurend in:" - for n in {${#funcfiletrace}..1}; do - printf >&2 '%d> %s (%s)\n' $n "$funcfiletrace[$n]" "$functrace[$n]" - done - printf >&2 '%s\n' "${hl_fatal}*$hl_reset $^@" - exit $ret -} - -die() { - set +x - die_ret 1 "$@" -} -die100() { # 100: wrong usage - set +x - die_ret 100 "$@" -} -die111() { # 111: system call failed - set +x - die_ret 111 "$@" -} - --() { # Run command and die on nonzero exitcode - "$@" || die_ret $? "command failed with exitcode $?: ${(j: :)${(q)@}}" -} - -::() { - : "$@" -} -typeset -f -t :: - -### main code { - -item_make_id() { - (($# == 1)) || die "Must specify packed item name" - (($+item_to_id[$1])) && return - item_to_id[$1]=$next_item_id - id_to_item[$next_item_id]=$1 - : $(( next_item_id++ )) -} -item_start() { - (($#)) || die "Must specify item name" - if [[ -n $current_item ]]; then - die "Previous item not closed: ${(qqq)current_item}" - fi - current_item=${(pj:\0:)*} - local x - for x in "$@"; do - [[ $x == ?*=?* ]] || - die "Malformed item name ${(j: :)${(qqq)*}}" - done - (($+item_to_id[$current_item])) && die "Duplicate item: ${(qqq)current_item}" - item_make_id $current_item -} -#typeset -f -t item_start - -item_end() { - [[ -z $current_item ]] && die "No opened item" - (($#)) && item_title "$@" - items+=( $current_item ) - current_item= -} - -item_title() { - [[ -z $current_item ]] && die "No opened item" - item_title[$current_item]=$* -} - -item_prop() { - [[ -z $current_item ]] && die "No opened item" - (($# == 2)) || die "Must specify prop key and value" - item_props+=( $current_item $1 $2 ) -} - -item_link() { - [[ -z $current_item ]] && die "No opened item" - (($#)) || die "Must specify item name" - links+=( $current_item ${(pj:\0:)*} ) -} - -item_backlink() { - [[ -z $current_item ]] && die "No opened item" - (($#)) || die "Must specify item name" - links+=( ${(pj:\0:)*} $current_item ) -} - -load() { - # load_vim - load_x - load_xpra - load_tmux - process_items -} - -#typeset -f -t load -c_exec() { - local container=$1 display=${DISPLAY#:} - shift - if ! (( $+container_exec_linked[$container] )); then - - s6-sudo /run/cmd.s link $container xsession.$display.$USER run/exec/exec 2>/dev/null - # die_ret $? "Failed to link run/exec/exec from ${(qqq)container}" - container_exec_linked[$container]=1 - fi - s6-sudo /run/inbox/$container/run/exec/exec "$@" -} - -#load_vim() { -# local s b f -# vim --serverlist | while read s; do -# vim --servername $s --remote-expr "ccx#PrintBuffers()" | \ -# while read b f; do -# items+=($s $b $f) -# done -# done -#} - -load_x() { - local line wid w_host w_class w_instance w_title term_container term_pts - local -a l - #local MATCH MBEGIN MEND # used by =~ - i3-msg -t get_tree | awk -f $HOME/i3_list_windows.awk -f $HOME/bin/JSON.bbawk -v STREAM=0 - | while IFS= read -r line; do - l=( "${(@ps:\t:)line}" ) - wid=$l[1] - w_host=${(Q)l[2]} - w_class=${(Q)l[3]} - w_instance=${(Q)l[4]} - w_title=${(Q)l[5]} - item_start X=$wid - item_title $w_title - if [[ $w_host == $HOST && $w_class == URxvt ]]; then - # local urxvt - if [[ $w_instance == *:/dev/pts/* ]]; then - term_container=${${w_instance%%:/dev/pts/*}//:/.} - term_pts=${w_instance#*:/dev/pts/} - item_link C=$term_container PTS=$term_pts - - else - term_container= - term_pts= - fi -# if [[ -n $term_container && $w_title == *tmux::*:$USER@${term_container%%.*} ]]; then -# links[X$_0$wid]=C/$term_container/TMUX/${${w_title##*tmux::}%%:*} -# elif [[ $w_title =~ 'VIM/[0-9]+$' ]]; then -# links[X$_0$wid]=$MATCH -# fi - elif [[ $w_host == xpra && $w_title == *'«s=xpra c'* ]]; then - local x= - local -A xpra_info=( ) - for x in "${(@s: :)${w_title##*«s=xpra }}"; do - [[ $x == ?=* ]] || die "Malformed xpra info: ${(qqq)x}" - xpra_info[${x%%=*}]=${x#?=} - done - item_link XPRA=${xpra_info[d]} C=${xpra_info[c]}.$USER X=${xpra_info[w]} - fi - item_end - done -} -#typeset -f -t load_x - -load_xpra() { - local disp container wid w_desktop w_pid w_host w_title - c_exec xpra.$USER wmctrl-all | while IFS=$'\t' read -r disp container wid w_desktop w_pid w_host w_title; do - item_start XPRA=$disp C=$container X=$wid - item_title $w_title - item_prop pid $w_pid - item_prop desktop $w_desktop - item_prop host $w_host - item_end - - done -} -#typeset -f -t load_xpra - -load_container_tmux() { - local container line has_tmux=0 n - local -a tmux_vars tmux_fmt l - local -A info - #local MATCH MBEGIN MEND # used by =~ - container=$1 - - tmux_vars=( - session_name - session_id - window_index - window_active - pane_id - pane_active - pane_title - pane_current_command - ) - tmux_fmt=( "#{"$^tmux_vars"}" ) - c_exec 2>/dev/null $container tmux list-panes -a -F ${(pj:\t:)tmux_fmt} | \ - while IFS= read line; do - l=( "${(@ps:\t:)line}" ) - info=( ) - for n in {1..$#tmux_vars}; do - info[$tmux_vars[$n]]=${l[$n]} - done - item_start C=$container TMUX=$info[session_name] PANE=$info[pane_id] - item_title "$info[pane_title] [$info[pane_current_command]]" - item_prop pane_window $info[window_index] - item_backlink C=$container TMUX=$info[session_name] - if [[ $info[window_active] == 1 ]]; then - item_props+=( C=$container${_0}TMUX=$info[session_name] active_window $info[window_index] ) - if [[ $info[pane_active] == 1 ]]; then - item_props+=( C=$container${_0}TMUX=$info[session_name] active_pane $info[pane_id] ) - item_props+=( C=$container${_0}TMUX=$info[session_name] session_id $info[session_id] ) - item_title "*$info[pane_title] [$info[pane_current_command]]" - fi - fi - -# if [[ $pane_title =~ 'VIM/[0-9]+$' ]]; then -# links[C/$container/TMUX/$session_name$_0$window_index/$pane_id]=$MATCH -# fi - item_end - has_tmux=1 - done - ((has_tmux)) || return - tmux_vars=( - client_tty - session_name - window_index - pane_id - #client_flags - #client_termfeatures - #client_activity - #client_created - #client_readonly - ) - tmux_fmt=( "#{"$^tmux_vars"}" ) - c_exec $container tmux list-clients -F ${(pj:\t:)tmux_fmt} | \ - while IFS= read line; do - l=( "${(@ps:\t:)line}" ) - info=( ) - for n in {1..$#tmux_vars}; do - info[$tmux_vars[$n]]=$l[$n] - done - [[ $info[client_tty] == /dev/pts/* ]] || continue - item_start C=$container PTS=${info[client_tty]:t} - item_link C=$container TMUX=$info[session_name] - item_prop tmux_window_index $info[window_index] - item_prop tmux_pane_id $info[pane_id] - item_end - done -} -#typeset -f -t load_container_tmux - -load_tmux() { - local -A service_up - local sv container - service_up=( $(s6-sudo /run/cmd.s services -u) ) - for sv in ${(k)service_up[(R)true]}; do - [[ $sv == /run/service/container.*.$USER ]] || continue - container=${sv##*/container.} - load_container_tmux $container - done - return - local session_name window_index pane_id pane_title - #local MATCH MBEGIN MEND # used by =~ - tmux list-panes -a -F '#{session_name}|#{window_index}|#{pane_id}|#{pane_title} | #{pane_current_command}' | \ - while IFS='|' read session_name window_index pane_id pane_title; do - item_start TMUX=$session_name PANE=$pane_id - item_title $pane_title - item_prop pane_window $window_index - item_backlink TMUX=$session_name -# if [[ $pane_title =~ 'VIM/[0-9]+$' ]]; then -# links[C/$container/TMUX/$session_name$_0$window_index/$pane_id]=$MATCH -# fi - item_end - done -} - -process_items() { - local id oid name other k v - typeset -gA id_links id_backlinks id_props - for name other in $links; do - item_make_id $name - id=$item_to_id[$name] - item_make_id $other - oid=$item_to_id[$other] - - (($+id_links[$id])) && id_links[$id]+=$_0 - id_links[$id]+=$oid - - (($+id_backlinks[$oid])) && id_backlinks[$oid]+=$_0 - id_backlinks[$oid]+=$id - - #printf '%s => %s [%d]\n' $id $oid $#id_links[$id] - #printf '%s => %s\n' "${(j: :)${(0)name}}" "${(j: :)${(0)other}}" - done - for name k v in "$item_props[@]"; do - id=$item_to_id[$name] - (($+id_props[$id/$k])) && [[ $id_props[$id/$k] != $v ]] && - die "Duplicate prop ${(qqq)k} in item ${(qqq)name}" - id_props[$id/$k]=$v - - done - for id in ${(k)id_to_item}; do - typeset -ga "item_${id}_links" - if (($+id_links[$id])); then - set -A "item_${id}_links" $id_links[$id] - else - fi - typeset -ga "item_${id}_backlinks" - if (($+id_backlinks[$id])); then - set -A "item_${id}_backlinks" $id_backlinks[$id] - else - fi - typeset -gA item_${id}_props - local -a kv=( ) - for k v in "${(kv@)id_props[(I)$id/*]}"; do - kv+=( $k $v ) - done - set -A item_${id}_props "$kv[@]" - done - typeset -gA id_can_show id_can_omit - for id name in ${(kv)id_to_item}; do - id_can_show[$id]=$(( $+item_title[$name] )) - done - for id in {1..$((next_item_id - 1))}; do - (( $+id_links[$id] || ! $id_can_show[$id] )) && continue - (( $+id_backlinks[$id] )) || continue - # keep this id, try omiting it's parents - id_can_omit[$id]=0 - for oid in ${(0)id_backlinks[$id]}; do - process_items_try_omit $oid - done - done - for id in {1..$((next_item_id - 1))}; do - id_can_omit[$id]=${id_can_omit[$id]:-0} - done -} -#typeset -f -t process_items - -process_items_try_omit() { - local n parent - local -a children - n=$1 - (( $+id_links[$n] )) && children=( ${(0)id_links[$n]} ) - #local -a parents #debug - #(( $+id_backlinks[$n] )) && parents=( ${(0)id_backlinks[$n]} ) - #printf >&2 '[%d] ↓ %s ↑ %s\n' $n ${(j:,:)children:--} ${(j:,:)parents:--} - [[ $#children == 1 ]] || return - id_can_omit[$n]=1 - (( $+id_backlinks[$n] )) || return - for parent in ${(0)id_backlinks[$n]}; do - process_items_try_omit $parent - done -} -#typeset -f -t process_items_try_omit - -_item_color() { - local n - n=$1 - if (($+id_selected && n == id_selected)); then - - printf '%s' $hl_success - elif ((!$id_can_show[$n])); then - - printf '%s' $hl_fatal - elif (($id_can_omit[$n])); then - - printf '%s' $hl_warn - fi -} - - -_item_addr() { - local n item - n=$1 - item=$id_to_item[$n] - - printf '%s\n' "$(_item_color $n)${(j: » :)${(0)item}}$hl_reset" -} - -print_tree_recurse() { - local n indent inum itxt subindent item title - n=$1 - indent=${2:-} - for inum in ${(s::)indent}; do - itxt+=$print_tree_indent_style[$inum] - done - item=$id_to_item[$n] - title=${item_title[$item]:-} - subindent=${${indent//3/2}//4/1} - printf '%s- %s « %s « %s\n' "$itxt" "$(_item_addr $n)" ${(qqq)title} $n - #printf '%s- %s « %s « %s\n' "$itxt" "$(_item_color $n)${(j: » :)${(0)item}}$hl_reset" ${(qqq)title} $n - if (( $+id_links[$n] )); then - local -a ls=( ${(0)id_links[$n]} ) - local i l - for i in {1..$#ls}; do - l=$ls[i] - if (( $i < $#ls )); then - - print_tree_recurse $l ${subindent}3 - else - - print_tree_recurse $l ${subindent}4 - fi - done - fi -} -#typeset -f -t print_tree_recurse - -print_subtree_recurse() { - local n parent - n=$1 - if (( $+id_backlinks[$n] )); then - for parent in ${(0)id_backlinks[$n]}; do - print_subtree_recurse $parent - done - else - print_tree_recurse $n - fi -} - -typeset -ga print_tree_indent_style=( - ' ' # 1 - ' | ' # 2 - ' |-' # 3 - ' `-' # 4 -) -print_tree() { - local -a stack ls - local n item title l - for n in {1..$((next_item_id - 1))}; do - (( $+id_backlinks[$n] )) && continue - - print_tree_recurse $n - done -} - -print_options() { - local n item title addr - for n in {1..$((next_item_id - 1))}; do - item=$id_to_item[$n] - addr=${(j: » :)${(0)item}} - #addr=$(_item_addr $n) - if ((!$id_can_show[$n])); then - continue - elif (($id_can_omit[$n])); then - continue - fi - title=${item_title[$item]:-N/A} - printf '%s\n' "$n$delim$title | $addr" - done -} - - -choose() { - local result - local -a selected - print_options | $dmenu_cmd | read result - if [[ $? == 0 && -n $result ]]; then - selected=( "${(@s: » :)result}" ) - printf 'selected: %s\n' "$(_item_addr $selected[1])" - activate $selected[1] - fi -} - -test_activation() { - local id item addr - local -a options - local -g id_selected - options=( ${${(f)"$(print_options)"}%% *} ) - for id in $options; do - id_selected=$id - typeset -ga plan_steps=( ) - plan_activation $id - print_subtree_recurse $id - pretend_activate - echo >&2 - done -} - -activate_x_window() { - i3-msg "[id=$1] focus" -} - -add_to_plan() { - plan_steps+=( "${(pj:\0:)@}" ) -} - -plan_activation() { - local id item x structure k v p - local -a parents full props_kv struct_values - local -A props - id=$1 - item=$id_to_item[$id] - full=( ${(0)item} ) - (( $+id_backlinks[$id] )) && parents=( ${(0)id_backlinks[$id]} ) - for x in ${(0)${id_to_item[$id]}}; do - (($#structure)) && structure+=' ' - structure+=${x%%=*} - struct_values+=( ${x#*=} ) - done - #for k v in "${(kv@)id_props[(I)$id/*]}"; do - # k=${k%*/} - # props[$k]=$v - #done - case $structure in - (X) - add_to_plan i3-msg "[id=${struct_values[1]}] focus" - ;; - (XPRA C X) - if (($#parents)); then - plan_activation $parents[1] - else - # TODO restore layout / activate waiting container? - add_to_plan run-in-container-xpra $struct_values[2] true - fi - ;; - - (C PTS) - (($#parents == 1)) || die "urxvt without window" - plan_activation $parents[1] - ;; - - (C TMUX PANE) - (($#parents == 1)) || die "tmux pane without session" - p=$parents[1] - if [[ $struct_values[3] != ${id_props[$p/active_pane]:-missing} ]]; then - add_to_plan c.exec $struct_values[1] \ - tmux select-pane $struct_values[3] \; \ - select-window -t $struct_values[2]:${id_props[$id/pane_window]} - fi - plan_activation $p - ;; - - (C TMUX) - if (($#parents)); then - plan_activation $parents[1] - else - add_to_plan c.tmux $struct_values[1] -s $struct_values[2] - fi - ;; - - (*) - set +x - err_msg "Could not resolve ${id_selected}" - print_subtree_recurse $id_selected - die "Unhandled structure: ${(qqq)structure}" - ;; - #(VIM/*) vim --servername $1 --remote-expr "ccx#SwitchBuffer($2)";; - esac -} -#typeset -f -t plan_activation - -pretend_activate() { - local i - if ! (($#plan_steps)); then - warn_msg "Nothing to do" - return - fi - for i in {$#plan_steps..1}; do - :: "${(@0)plan_steps[$i]}" - done -} - -do_activate() { - local i - if ! (($#plan_steps)); then - warn_msg "Nothing to do" - return - fi - for i in {$#plan_steps..1}; do - "${(@0)plan_steps[$i]}" - done -} - -activate() { - local id - id=$1 - typeset -ga plan_steps - - plan_activation $id - do_activate &! -} -#typeset -f -t activate - - -main() { - - load - #- print_tree >&2 - #echo - #- print_options - #- test_activation - - choose -} -main "$@" === removed file 'xsession-skel/homedir/bin/i3windowlist' --- old/xsession-skel/homedir/bin/i3windowlist 2024-08-03 22:38:44 +0000 +++ new/xsession-skel/homedir/bin/i3windowlist 1970-01-01 00:00:00 +0000 @@ -1,2 +0,0 @@ -#!/bin/sh -i3-msg -t get_tree | awk -f $HOME/i3_list_windows.awk -f $HOME/bin/JSON.bbawk -v STREAM=0 - === modified file 'xsession-skel/homedir/bin/shiftinsert' --- old/xsession-skel/homedir/bin/shiftinsert 2024-08-03 22:38:44 +0000 +++ new/xsession-skel/homedir/bin/shiftinsert 2024-07-27 01:48:41 +0000 @@ -1,157 +1,5 @@ #!/bin/zsh -setopt no_unset extended_glob warn_create_global - -typeset -g -A container_exec_linked -c_exec() { - local container=$1 display=${DISPLAY#:} - shift - if ! (( $+container_exec_linked[$container] )); then - s6-sudo /run/cmd.s link $container xsession.$display.$USER run/exec/exec || exit $? - container_exec_linked[$container]=1 - fi - s6-sudo /run/inbox/$container/run/exec/exec "$@" -} - -load_wininfo() { - local line - local -a l - i3windowlist | while IFS= read -r line; do - l=( "${(@ps:\t:)line}" ) - (( $l[1] == $1 )) || continue - wid=$l[1] - typeset -g w_host w_class w_instance w_title term_container term_pts - w_host=${(Q)l[2]} - w_class=${(Q)l[3]} - w_instance=${(Q)l[4]} - w_title=${(Q)l[5]} - return 0 - done - return 1 -} - -make_paste_command() { - if [[ $w_host == $HOST && $w_class == URxvt ]]; then - # local urxvt - local term_container term_pts - if [[ $w_instance == *:/dev/pts/* ]]; then - term_container=${${w_instance%%:/dev/pts/*}//:/.} - term_pts=${w_instance#*:/dev/pts/} - else - make_paste_command_fallback - return $? - fi - if [[ $w_title == *tmux::* ]]; then - make_paste_command_container_tmux $term_container $term_pts - return $? - fi - elif [[ $w_host == xpra && $w_title == *'«s=xpra c'* ]]; then - make_paste_command_xpra - return $? - fi - #return 1 - make_paste_command_fallback - return $? -} - -make_paste_command_container_tmux() { - local term_container term_pts line n - local -a l tmux_vars tmux_fmt - term_container=$1 - term_pts=$2 - tmux_vars=( - client_tty - session_name - window_index - pane_id - #client_flags - #client_termfeatures - #client_activity - #client_created - #client_readonly - ) - tmux_fmt=( "#{"$^tmux_vars"}" ) - c_exec $term_container tmux list-clients -F ${(pj:\t:)tmux_fmt} | \ - while IFS= read line; do - l=( "${(@ps:\t:)line}" ) - local -A info=( ) - for n in {1..$#tmux_vars}; do - info[$tmux_vars[$n]]=$l[$n] - done - [[ $info[client_tty] == /dev/pts/$term_pts ]] || continue - # TODO - local -a el=( - 'multisubstitute {' - ' importas -i container_name container_name' - ' importas -i pane_id pane_id' - '}' - 's6-sudo /run/inbox/${container_name}/run/exec/exec' - 'tmux load-buffer -b shiftinsert - ; paste-buffer -p -b shiftinsert -t $pane_id' - ) - typeset -ga paste_command - paste_command=( - env container_name=$term_container pane_id=$info[pane_id] - execlineb -c "${(@F)el}" - ) - return 0 - done - return 1 -} - -make_paste_command_xpra() { - local x= - local -A xpra_info=( ) - for x in "${(@s: :)${w_title##*«s=xpra }}"; do - [[ $x == ?=* ]] || die "Malformed xpra info: ${(qqq)x}" - xpra_info[${x%%=*}]=${x#?=} - done - local -a el=( - 'multisubstitute {' - ' importas -i wid wid' - ' importas -i xpra_w xpra_w' - ' importas -i xpra_d xpra_d' - '}' - 'if {' - ' s6-sudo /run/inbox/xpra.ccx/run/exec/exec' - ' in-xpra $xpra_d' - ' xclip -i -sel CLIPBOARD' - '}' - 'xdotool windowfocus $wid key --clearmodifiers --window $wid Shift+Insert' - ) - typeset -ga paste_command - paste_command=( - env xpra_d=${xpra_info[d]} xpra_w=${xpra_info[w]} wid=$wid - execlineb -c "${(@F)el}" - ) -} - -make_paste_command_fallback() { - local -a el=( - 'importas -i wid wid' - 'if { xclip -i }' - 'xdotool windowfocus $wid key --clearmodifiers --window $wid Shift+Insert' - ) - typeset -ga paste_command - paste_command=( - env wid=$wid - execlineb -c "${(@F)el}" - ) -} - -main() { - local wid clip - wid=$(xdotool getactivewindow) || exit $? - load_wininfo $wid || exit $? - make_paste_command || exit $? - clip | IFS= read -r -d '' clip - [[ -n $clip ]] || exit 1 - printf '%s' $clip | "$paste_command[@]" -} -typeset -f -t main - -main "$@" -exit $? -# old code - +setopt no_unset extended_glob # warn_create_global set -x wid=$(xdotool getactivewindow) || exit $? title=$(xdotool getwindowname $wid) || exit $? === removed file 'xsession-skel/homedir/i3_list_windows.awk' --- old/xsession-skel/homedir/i3_list_windows.awk 2024-08-03 22:38:44 +0000 +++ new/xsession-skel/homedir/i3_list_windows.awk 1970-01-01 00:00:00 +0000 @@ -1,153 +0,0 @@ -# Default callbacks. -# Mawk must always define all callbacks. -# Gawk and busybox awk must define callbacks when STREAM=1 only. -# More info in FAQ.md#5. - -# cb_parse_array_empty - parse an empty JSON array. -# Called in JSON.awk's main loop when STREAM=0 only. -# This example returns the standard representation of an empty array. -function cb_parse_array_empty(jpath) { - -# print "parse_array_empty("jpath")" >"/dev/stderr" - return "[]" -} - -# cb_parse_object_empty - parse an empty JSON object. -# Called in JSON.awk's main loop when STREAM=0 only. -# This example returns the standard representation of an empty object. -function cb_parse_object_empty(jpath) { - -# print "parse_object_empty("jpath")" >"/dev/stderr" - return "{}" -} - -# cb_parse_array_enter - begin parsing an array. -# Called in JSON.awk's main loop when STREAM=0 only. -# Use this function to initialize or output other values involved in -# processing each new JSON array. -function cb_parse_array_enter(jpath) { - -# print "cb_parse_array_enter("jpath") token("TOKEN")" >"/dev/stderr" - if ("" != jpath) - ; -} - -# cb_parse_array_exit - end parsing an array. -# Called in JSON.awk's main loop when STREAM=0 only. -# If status == 0 then global CB_VALUE holds the JSON text of the parsed array. -function cb_parse_array_exit(jpath, status) { - -# print "cb_parse_array_exit("jpath") status("status") token("TOKEN") value("CB_VALUE")" >"/dev/stderr" -} - -# cb_parse_object_enter - begin parsing an object. -# Called in JSON.awk's main loop when STREAM=0 only. -# Use this function to initialize or output other values involved in -# processing each new JSON object. -function cb_parse_object_enter(jpath) { - -# print "cb_parse_object_enter("jpath") token("TOKEN")" >"/dev/stderr" - if ("" != jpath) - ; -} - -# cb_parse_object_exit - end parsing an object. -# Called in JSON.awk's main loop when STREAM=0 only. -# If status == 0 then global CB_VALUE holds the JSON text of the parsed object. -function cb_parse_object_exit(jpath, status) { - -# print "cb_parse_object_exit("jpath") status("status") token("TOKEN") value("CB_VALUE")" >"/dev/stderr" -} - -# cb_append_jpath_component - format jpath components -# Called in JSON.awk's main loop when STREAM=0 only. -# This example formats jpaths exactly as JSON.awk does when STREAM=1. -function cb_append_jpath_component (jpath, component) { - -# print "cb_append_jpath_component("jpath") ("jpath") component("component")" >"/dev/stderr" - return (jpath != "" ? jpath "," : "") component -} - -# cb_append_jpath_value - format a jpath / value pair -# Called in JSON.awk's main loop when STREAM=0 only. -# This example formats the jpath / value pair exactly as JSON.awk does when -# STREAM=1. -function cb_append_jpath_value (jpath, value, x) { - if(match(jpath, /,"window"$/)) { - if(value != "null") { - i3_win[value] = substr(jpath, 0, RSTART-1) - #printf("i3_win['%s']='%s'\n", value, substr(jpath, RSTART-1)) - } - } else if(match(jpath, /,"window_properties","[^"]*"$/)) { - x = substr(jpath, 0, RSTART-1) - match(jpath, /"[^"]*"$/) - #printf("i3_prop['%s','%s']='%s'\n", x, substr(jpath, RSTART+1, RLENGTH-2), value) - i3_prop[x, substr(jpath, RSTART+1, RLENGTH-2)] = value - - } -# print "cb_append_jpath_value("jpath") ("jpath") value("value")" >"/dev/stderr" - return sprintf("[%s]\t%s", jpath, value) -} - -function tabprint(s) { - gsub("[\r\n\t]", "_", s) - printf("\t%s", s) -} -END { - for(wid in i3_win) { - printf("0x%x", wid) - tabprint(i3_prop[i3_win[wid], "machine"]) - tabprint(i3_prop[i3_win[wid], "class"]) - tabprint(i3_prop[i3_win[wid], "instance"]) - tabprint(i3_prop[i3_win[wid], "title"]) - printf("\n") - } -} - -# cb_jpaths - process cb_append_jpath_value outputs -# Called in JSON.awk's main loop when STREAM=0 only. -# This example illustrates printing jpaths to stdout as JSON.awk does when STREAM=1. -# See also cb_parse_array_enter and cb_parse_object_enter. -function cb_jpaths (ary, size, i) { - return - # When BRIEF mode is off by default JSON.awk prints the whole input JSON - # text as the last output line. This code block shows how to avoid that. - if (0 == BRIEF) { - # Don't print the last line, which contains the whole input, - # unless it's a simple value or an empty array/object. - if (match(ary[size], /\t[[{][[:space:]]*[^]}]/)) { - if (index(ary[size], "\t") == RSTART) { - size -= 1 - } - } - } - - # Print ary - array of size jpaths and their values. - for(i=1; i <= size; i++) { - print ary[i] - } -} - -# cb_fails - process all error messages at once after parsing -# has completed. Called in JSON.awk's END action when STREAM=0 only. -# This example illustrates printing parsing errors to stdout, -function cb_fails (ary, size, k) { - - # Print ary - associative array of parsing failures. - # ary's keys are the size input file names that JSON.awk read. - for(k in ary) { - print "cb_fails: invalid input file:", k - print FAILS[k] - } -} - -# cb_fail1 - process a single parse error as soon as it is -# encountered. Called in JSON.awk's main loop when STREAM=0 only. -# Return non-zero to let JSON.awk also print the message to stderr. -# This example illustrates printing the error message to stdout only. -function cb_fail1 (message) { - - print "cb_fail1: invalid input file:", FILENAME - print message -} -