73 lines
2.6 KiB
Bash
73 lines
2.6 KiB
Bash
#!/usr/bin/env zsh
|
|
#
|
|
# Quote the shell word to the left of the cursor with double or single quotes.
|
|
# Prefer quotes with the shorter result or double quotes if there is no
|
|
# difference. If already quoted, change quotes. If there is an unterminated
|
|
# quote, terminate it and quote the resulting word with the same kind of quotes.
|
|
# Keep the cursor on the content it was pointing to before the widget was
|
|
# invoked.
|
|
#
|
|
# Here are a few examples. The caret shows the position of the cursor.
|
|
# *Initial* is the content of the buffer before the widget is executed.
|
|
# *Once* is the content of the buffer after the widget is executed.
|
|
# *Twice* is the content of the buffer after the widget is executed twice.
|
|
#
|
|
# | Initial | Once | Twice | Note
|
|
# |----------|------------|------------|-------------------
|
|
# | foo | "foo" | 'foo' | prefer double quotes
|
|
# | ^ | ^ | ^ |
|
|
# | foo | "foo" | 'foo' | keep cursor on the same word char
|
|
# | ^ | ^ | ^ |
|
|
# | foo | "foo" | 'foo' |
|
|
# | ^ | ^ | ^ |
|
|
# | foo bar | "foo" bar | 'foo' bar | cursor on a space => quote prev word
|
|
# | ^ | ^ | ^ |
|
|
# | foo bar | foo "bar" | foo 'bar' |
|
|
# | ^ | ^ | ^ |
|
|
# | "foo" | 'foo' | "foo" | replace quotes if already quoted
|
|
# | ^ | ^ | ^ |
|
|
# | 'foo' | "foo" | 'foo' | replace quotes if already quoted
|
|
# | ^ | ^ | ^ |
|
|
# | foo\" | 'foo"' | "foo\"" | single quotes because it's shorter
|
|
# | ^ | ^ | ^ |
|
|
# | "foo | "foo" | 'foo' |
|
|
# | ^ | ^ | ^ |
|
|
# | 'foo | 'foo' | "foo" | single quotes to match
|
|
# | ^ | ^ | ^ |
|
|
# | foo" | "foo" | 'foo' |
|
|
# | ^ | ^ | ^ |
|
|
# | foo' | 'foo' | "foo" |
|
|
# | ^ | ^ | ^ |
|
|
# | foo" | "foo" | 'foo' |
|
|
# | ^ | ^ | ^ |
|
|
|
|
emulate -L zsh
|
|
|
|
local reply
|
|
-z4h-find-prev-zword || return 0
|
|
|
|
local -i start='reply[1]'
|
|
(( start <= 0 )) && return
|
|
local -i end='reply[2]'
|
|
local word=$BUFFER[start,end]
|
|
|
|
local -i q
|
|
if -z4h-is-valid-list ": $word'"; then
|
|
word+="'"
|
|
local -i q=1
|
|
elif -z4h-is-valid-list ": $word\""; then
|
|
word+='"'
|
|
local -i q=2
|
|
fi
|
|
|
|
local unquoted=${(Q)word}
|
|
local quoted=(${(qq)unquoted} ${(qqq)unquoted})
|
|
if (( ! q )); then
|
|
if [[ $quoted[1] != $word ]] && (( $#quoted[1] < $#quoted[2] )) ||
|
|
[[ $quoted[2] == $word ]]; then
|
|
(( q = 1 ))
|
|
else
|
|
(( q = 2 ))
|
|
fi
|
|
fi
|
|
-z4h-replace-buf $start $end $quoted[q]
|