Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: do not interpret special characters
- X-seq: zsh-users 12677
 
- From: Peter Stephenson <pws@xxxxxxx>
 
- To: zsh-users@xxxxxxxxxx
 
- Subject: Re: do not interpret special characters
 
- Date: Thu, 6 Mar 2008 14:52:01 +0000
 
- In-reply-to: <20080303084847.GA25626@xxxxxxxxxxxx>
 
- Mailing-list: contact zsh-users-help@xxxxxxxxxx; run by ezmlm
 
- Organization: CSR
 
- References: <20080303084847.GA25626@xxxxxxxxxxxx>
 
On Mon, 3 Mar 2008 09:48:47 +0100
Eric Smith <Eric.Smith@xxxxxxxxxxxx> wrote:
> How do I temporarily set zsh not to interpret and ~ < characters
> on the command line but to pass them directly to my script? 
> (for now I - tediously -  use backslash)
You can alter the line in accept-line,
  accept-line() {
    emulate -L zsh
    setopt extendedglob
    local MATCH MBEGIN MEND
    BUFFER=${BUFFER//(#m)((#s)|[^\\])[<~]/$MATCH[1,-2]\\$MATCH[-1]}
    zle .accept-line
  }
  zle -N accept-line
Obviously this has a dire effect on anything other than the simplest
command lines.  You turn it off with:
  zle -A .accept-line accept-line
However, I haven't been able to think of a general way of detecting whether
the < or ~ is already quoted (the above is just a hack to look for a
preceding backslash).  Using the utility function split-shell-arguments
that's now distributed with the shell you can quote *all* metacharacters,
if you don't mind the quoting on the line being rewritten in the shell
history:
  accept-line() {
    emulate -L zsh
    setopt extendedglob
    local -a reply
    local REPLY REPLY2 unquote
    integer i
    autoload -U split-shell-arguments
    split-shell-arguments
    for (( i = 2; i <= ${#reply}; i += 2 )); do
      unquote=${(Q)reply[i]}
      if [[ $unquote != ${(q)unquote} ]]; then
        # if there's anything worth quoting, use double quotes
        reply[i]="${(qqq)unquote}"
      fi
    done
    BUFFER=${(j..)reply}
    zle .accept-line
  }
  zle -N accept-line
Note you'll get extra "" pairs if the original splitting thought the
words were different despite the lack of whitespace.  That's fixable
by checking the odd words in $reply which are the white space ($reply[1] is
at the start of the line, $reply[-1] at the end).  (This is why I didn't
use '' since that will break with RC_QUOTES set.)
I discovered a bug looking at this:
  unquote=">"
  print -r -- ${(Q)unquote}
prints nothing with the latest version of the shell.  Something funny is
happening in string token extraction that I don't understand (there's some
obscure trick and there are no comments explaining what it's supposed to be
doing).  I'll report on this separately.
-- 
Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070
Messages sorted by:
Reverse Date,
Date,
Thread,
Author