Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: strictly literal command lines?
- X-seq: zsh-users 14532
- From: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
- To: zsh-users@xxxxxxx
- Subject: Re: strictly literal command lines?
- Date: Tue, 03 Nov 2009 21:29:12 -0800
- In-reply-to: <2d460de70911031601o69b4bf40u9ba8a4939618e8fe@xxxxxxxxxxxxxx>
- List-help: <mailto:zsh-users-help@zsh.org>
- List-id: Zsh Users List <zsh-users.zsh.org>
- List-post: <mailto:zsh-users@zsh.org>
- Mailing-list: contact zsh-users-help@xxxxxxx; run by ezmlm
- References: <87k4y79xxp.fsf@xxxxxxxxx> <237967ef0911031316n64d6e1c4q671a2bfc0b496287@xxxxxxxxxxxxxx> <2d460de70911031601o69b4bf40u9ba8a4939618e8fe@xxxxxxxxxxxxxx>
On Nov 4, 1:01am, Richard Hartmann wrote:
}
} While url-quote-magic is extremely handy, a way to force literal
} interpretation could make sense and ease handling, sometimes.
Which is why the shell grammar has quotation marks. ;-)
More seriously, what does "literal interpretation" mean? If it
includes whitespace, then how do you distinguish words (especially
the command word from the argument words)? Does it include only
command separators, or is it any non-whitespace? Do quotes become
literal as well -- in which case whitespace inside what appears to
be a quoted string becomes neither quoted nor literal? If quotes
don't become literal, what happens to variable references inside
double quotes inside "literal interpretation"? What happens to
backslashes and the characters following backslashes?
Nevertheless, here's a widget that you might find handy. I tied it
to the CSH_JUNKIE_QUOTES option because when that option is not set,
an unbalanced quote should continue the word on the next line; but
you can easily remove that dependency if you prefer.
accept-line-and-close-quote () {
if [[ -o cshjunkiequotes ]]
then
local L="$({: ${(XQ)BUFFER}} 2>&1)"
case $L in
(* unmatched \") BUFFER+=\" ;;
(* unmatched \') BUFFER+=\' ;;
esac
fi
zle .accept-line "$@"
}
zle -N accept-line accept-line-and-close-quote
This lets you type only the first quote and automatically matches it
when you accept the line.
Or maybe you'd rather type only the second quote ... this does not need
any special options set (though I don't promise that some settings won't
break it).
autoload match-words-by-style
magic-matching-quote () {
setopt localoptions no_ksharrays
zle .self-insert "$@" || return
local Q="${LBUFFER[-1]}"
if [[ "$Q" = [\"\'] ]]
then
local curcontext=":zle:$WIDGET"
match-words-by-style
(( ${#matched_words[2]} > 1 )) || return 0
local L="$({: ${(XQ)matched_words[2]}} 2>&1)"
if [[ "$L" = *unmatched* ]]
then
matched_words[2]="$Q$matched_words[2]"
fi
LBUFFER="${(j::)matched_words[1,3]}"
fi
}
zstyle ':zle:magic-matching-quote' word-style whitespace
bindkey \" magic-matching-quote
bindkey \' magic-matching-quote
Note that magic-matching-quote works only with "whitespace" or "shell"
word-styles, as the other styles parse out the quotes. (You may be
able to adjust this with skip-chars and other styles.) Using this
widget makes it rather difficult to insert quotes in the middles of
strings.
So here's another alternative, which extends magic-space to cause it
to recognize an immediately-preceding unbalanced quote and match it.
This makes it simpler to type mixtures of quotes, but probably still
gets some cases wrong.
magic-space-match-quote () {
setopt localoptions no_ksharrays
local Q="${LBUFFER[-1]}"
zle .magic-space "$@" || return
if [[ "$Q" == [\"\'] ]]
then
local curcontext=":zle:$WIDGET"
match-words-by-style
(( ${#matched_words[2]} > 1 )) || return 0
local L="$({: ${(XQ)matched_words[2]}} 2>&1)"
if [[ "$L" == *" unmatched $Q" ]]
then
matched_words[2]="$Q$matched_words[2]"
fi
LBUFFER="${(j::)matched_words[1,3]}"
fi
}
zle -N magic-space magic-space-match-quote
bindkey ' ' magic-space
zstyle ':zle:magic-space' word-style whitespace
I don't recommend using accept-line-and-close-quote in combination with
either of these magic-* functions; depending on where on the line your
mismatched quote is, simply closing it at end of line might radically
change your word boundaries. You can probably figure out how to adapt
magic-space-match-quote to be a stand-in for accept-line.
--
Messages sorted by:
Reverse Date,
Date,
Thread,
Author