Skip Navigation

  • Yeah, from the first line

    Zsh, an extended version of the Bourne Shell (sh)

    This screams AI-generated.

  • It's a little more complex than needed, for the pixelated background I used xcolor names and then modulated them darker, but then relented and used hexcodes for the text in the foreground.

  • I've written multiple Zsh plugins, so I've gotten familiar with a lot of Zsh's features. I've probably read every line in man zshexpn twice by now having referenced it so much.

    Zsh expansions can look gnarly because parameter expansion forms can be nested. Where Bash has to do:

     
        
    tmp=${foo%$suffix}
    len=${#tmp}
    
    
      

    Zsh can do it in one:

     
        
    len=${#${foo%$suffix}}
    
    
      

    Once you add PE forms which don't exist in Bash, parameter expansion flags, array subscript flags, globbing qualifiers and modifiers, you can get something which looks absolutely unreadable.

  • Nice work! I've definitely had some fun with convert recently, as you might tell from the community banner.

    It is an image showing the script I used to create it 😛.

  • This one was impressively spot-on.

  • It may have gotten some details wrong, but the summary is spot-on.

    (%) enables prompt expansion. %~ is a string, which when prompt expanded, is $PWD with tilde expansion.

  • First, a look at man termcap:

     
        
           ch   Move cursor horizontally only to column %1
           ct   Clear tabs
    
    
      

    (j::) actually joins with no seperator. The character following the j is used to capture the separator. Nearly any character or paired bracket can be used, but colons are common. Other ways to write this which might have been more obvious: (j''), (j[]), (j<>). To actually join with colons, something like (j.:.) would have been used.

    Zsh agressively sets tabstops to every 8 characters. This is in a function which I trap to the WINCH signal, to set the termstops to 4 using the $termcap sequences rather than the external command tput:

     
        
    .on_winch(){
    	# tabs
    	local -a s
    	repeat COLUMNS/$1 s+=(${termcap[RI]/\%p1\%d/$1}$termcap[st])
    
    	# final
    	print -rn $termcap[sc]${termcap[ch]//(\%i|\%p1|\%d)}$termcap[ct]${(j::)s}$termcap[rc]
    }
    .on_winch 4
    trap '.on_winch 4' WINCH
    
      
  • ascending order

    O is descending order. o is ascending order. In particular (Oa) keeps the array order, but flips it.

    The @ symbol is used to indicate the array vriable argv.

    Not here. As a PE flag, @ puts array elements in separate words, even if the parameter is enclosed in quotes.

    The #MATCH gives the codepoint of the (first) character in $MATCH. The (#) flag turns codepoints into characters.

    This is in a joke function called ], which is like [ but you have to specify the elements in reverse order and end it with a [. This uses bit-fiddling to swap [ and ] in the last parameter because I'm a masochist.

  • It impressively identified exactly what eoo meant, and handled the array splicing, but it tripped over Zsh's globbing syntax.

    /(#m)^-*: This is a pattern match within a substitution. It matches any occurrences of hyphens (-) at the beginning of each element.

    1. The : in ${foo:/pat/repl} requires pat to match the whole element
    2. The ^ actually negates the match, rather than anchors it to the start. ^-* matches any element not beginning with a hyphen.
    3. The (#m) flag captures the whole match in the parameter $MATCH.
    4. ${MATCH:a} transforms relative paths to absolute paths.

    I use this as a wrapper around nvim --remote to make sure any non-options (i.e.: files) I pass have absolute paths rather than relative paths.

  • I have 350 items in my BW vault. I am not memorizing that many passwords, I'd rather use my brain for something else.

  • Here's all the ones I was considering. I only posted the first two here. I'll add the explanations later.

     
        
    ZDOTDIR="${${(%):-%x}:P:h}"                                              # posted 
    reply=( ${(M)dirs:#*/$~pattern}(Noe['REPLY=${(l[3][0])#REPLY:t}'][1]) )  # posted
    typeset -a $1=("${(@ps[$2])"${2:-"$(<&0)"}"}")
    local d=("${(@s[/])${(%):-%~}}")
    print -rn $termcap[sc]${termcap[ch]//(\%i|\%p1|\%d)}$termcap[ct]${(j::)s}$termcap[rc]
    [ "${(Oa@)argv[1,-2]}" "${argv[-1]//(#m)[\[\]]/${(#)$((6 ^ #MATCH))}}"   # this one is definitely not useful
    set -- "${@[0,eoo]:/(#m)^-*/${MATCH:a}}" "${@[eoo+1,-1]:a}"
    
      
  • There are two massive points no one has mentioned yet.

    • Quoting every expansion isn't necessary in Zsh. Parameters don't split or glob by default.
    • $array actually expands to every element in an array.

    Compare this between Bash and Zsh:

     
        
    a=('/* hello */' 'world!' '  ')
    printf '"%s" ' $a
    
    
      
  • I'm a fan of this; it's how Slide handled it.

    I also prefer Slide's method of collapsing comments; it only collapses the child comments, not the one you pressed on. (although it also has an option to collapse it too)

  • Most Reddit apps I used worked like this by default. It's not my preference either (I liked Slide because I could swap the tap and long-press actions) but I'm not complaining.

  • Nice! This one was probably the most likely to be found, I actually got this trick from somewhere else online before I understood what it was doing. If you're curious, I've got a few other lines of nested Zsh expansions I picked out but didn't post.

  • Here's one with a bit more context (and actually in Bash, rather than Zsh:

     sh
        
    typeset -A any
    while ((${#anys})); do
    	any[${anys:0:1}]="/${anys:0:1}/!d;"
    	anys=${anys:1}
    done
    anys=${any[*]}
    
    
      
    • Iterate through the characters in $anys
    • For each character $c, define any[$c] to be the string /$c/!d (e.g.: any[x]='/x/!d')
    • Concatenate the values in ${any[@]}

    This is building a sed command to delete all lines which don't contain every character of the string $anys. The associative array and concatenation is to ensure I don't repeat myself when building the command. This is used in a program called dewordle, which prints all remaining words in a dictionary given the current known information in a game of wordle.

  •  sh
        
    reply=( ${(M)dirs:#*/$~pattern}(Noe['REPLY=${(l[3][0])#REPLY:t}'][1]) )
    
      

    • $~pattern interpret globbing characters (like *, ?, or [a-z]) in the parameter $pattern,
    • ${(M)dirs:#*/$~pattern} filter the array $dirs to those matching */$~pattern.
    • ${...}(...) everything in (...) are globbing qualifiers
    • (N) enable nullglob
    • (oe[...]) sort by the result of the shell snippet, where $REPLY is used as input and output
    • ${...REPLY:t} remove all leading path components from $REPLY
    • ${...#REPLY:t} substitute the length of that string
    • ${(l[3][0])#REPLY:t} left-pad with zeroes to a length of 3
    • reply=( ... ) save as $reply

    This line is in a function which dynamically expands ~[g:abc] to one of my git repos, choosing the shortest directory matching path/to/abc*, or if no match is found, the shortest matching *abc*. So between /long/path/to/abcdef and /short/abcdefg, it would choose the first one (provided both of those were in the search paths I configured).

  •  sh
        
    ZDOTDIR="${${(%):-%x}:P:h}"
    
      

    • ${(%)...} enable prompt sequences
    • %x a prompt sequence which expands to the current file being executed
    • :P resolve symlinks
    • :h the parent directory

    This line is in my ~/.config/zsh/.zshenv, which I symlink into my home directory. This resolves the symlink and sets $ZDOTDIR to the directory in which my zsh config files actually live, that way they aren't all in my home directory.

  • linux

    Jump
  • I think I'm legally required to now.