Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
"cat -v" in zsh (and a minor bug)
- X-seq: zsh-users 2616
- From: "Bart Schaefer" <schaefer@xxxxxxxxxxxxxxxxxxxxxxx>
- To: zsh-users@xxxxxxxxxxxxxx
- Subject: "cat -v" in zsh (and a minor bug)
- Date: Sat, 25 Sep 1999 18:48:31 +0000
- Mailing-list: contact zsh-users-help@xxxxxxxxxxxxxx; run by ezmlm
A friend recently asked me how to get the equivalent of
visible=$(echo "$string" | cat -v)
without requiring the extra processes.
Entirely coincidentally, a patch for 3.1.6 was just posted to make ${(V)var}
return the value of $var in "visible" format; so after the next release, the
following will be moot. However, there's a cute trick below that's of some
interest; read on past the end of the function (the bug report is there too).
In the meanwhile, or in 3.0.x, the following makes $visible from $string.
# function string-to-visible {
# emulate -LR zsh 2>/dev/null || emulate -R zsh && setopt localoptions
# typeset string="$*"
typeset a q z
typeset -i i=0
typeset -i8 oct
z=('' '') # Prepare for cute trick
visible=()
while (( i <= $#string ))
do
a="$string[i]"
q=''
if (( #a < 0 || #a > 127 )); then
(( oct = #a & 127 ))
q='M-'
else
(( oct = #a ))
fi
if (( oct < 32 )); then
(( oct = oct + #\A - 1 ))
q="$q^" # Replace ^ with C- for emacs-style
fi
if (( $#q )); then
a=${(e)q::='${(pj:'"$q\\${oct#*#}"':)z}'} # Cute trick!
fi
visible[i]=$a
(( ++i ))
done
visible="${(j::)visible}"
# }
About that trick ... a few weeks ago Sven posted a patch for ${(%)var} to
cause prompt expansion to happen on $var. Someone remarked that it would
be nice to have "print" command escapes interpreted similarly. That's what
the cute trick, above, accomplishes: The (p) flag causes print escapes to
be recognized in the rest of the flags. The $z array provides two empty
strings that can be joined. So the trick is to stick the value, in which
you want print escapes expanded, between the colons in ${(pj::)z}. But
parameter expansion doesn't happen inside the flags of another expansion,
so we have to construct the whole ${(pj:...:)z} string that we want as a
new value, and then evaluate that with ${(e)...}.
The rest of the function is just conversion of each ascii character to the
appropriate octal value for "print" to turn into a printable character.
The bug is demonstrated by:
a='å' # That's meta-a, or 228 decimal
(( #a == #\å )) || echo oops
The problem is that #a is unsigned but #\a is signed, so for values above
127 decimal the #\a form returns a negative number.
--
Bart Schaefer Brass Lantern Enterprises
http://www.well.com/user/barts http://www.brasslantern.com
Messages sorted by:
Reverse Date,
Date,
Thread,
Author