summaryrefslogtreecommitdiff
path: root/Functions
diff options
context:
space:
mode:
Diffstat (limited to 'Functions')
-rw-r--r--Functions/Misc/nslookup3
-rw-r--r--Functions/Misc/zargs4
-rw-r--r--Functions/Misc/zed17
-rw-r--r--Functions/Prompts/prompt_adam1_setup7
-rw-r--r--Functions/Prompts/prompt_bart_setup39
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr2
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_git4
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_hg2
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_p42
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_svk2
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_svn2
-rw-r--r--Functions/VCS_Info/VCS_INFO_formats4
-rw-r--r--Functions/VCS_Info/VCS_INFO_hook4
-rw-r--r--Functions/VCS_Info/VCS_INFO_quilt6
-rw-r--r--Functions/VCS_Info/VCS_INFO_set6
-rw-r--r--Functions/VCS_Info/vcs_info9
-rw-r--r--Functions/VCS_Info/vcs_info_lastmsg2
-rw-r--r--Functions/VCS_Info/vcs_info_printsys2
-rw-r--r--Functions/Zle/bracketed-paste-magic192
-rw-r--r--Functions/Zle/edit-command-line15
-rw-r--r--Functions/Zle/incremental-complete-word2
-rw-r--r--Functions/Zle/narrow-to-region90
-rw-r--r--Functions/Zle/read-from-minibuffer5
-rw-r--r--Functions/Zle/smart-insert-last-word12
-rw-r--r--Functions/Zle/url-quote-magic6
25 files changed, 359 insertions, 80 deletions
diff --git a/Functions/Misc/nslookup b/Functions/Misc/nslookup
index 150bd035c..8c11909d5 100644
--- a/Functions/Misc/nslookup
+++ b/Functions/Misc/nslookup
@@ -26,8 +26,7 @@ zstyle -s ':nslookup' pager tmp &&
zpty nslookup command nslookup "${(q)@}"
-zpty -r nslookup line '*
-> '
+zpty -r nslookup line '*> '
print -nr "$line"
while line=''; vared -he "$pmpt[@]" line; do
diff --git a/Functions/Misc/zargs b/Functions/Misc/zargs
index 71fd42835..28ebca78f 100644
--- a/Functions/Misc/zargs
+++ b/Functions/Misc/zargs
@@ -73,7 +73,7 @@
emulate -L zsh || return 1
local -a opts eof n s l P i
-local ZARGS_VERSION="1.4"
+local ZARGS_VERSION="1.5"
if zparseopts -a opts -D -- \
-eof::=eof e::=eof \
@@ -254,7 +254,7 @@ then
bg='&'
if zmodload -i zsh/parameter 2>/dev/null
then
- wait='wait %${(k)^jobstates[(R)running:*]}'
+ wait='wait ${${jobstates[(R)running:*]/#*:/}/%=*/}'
else
wait='wait'
fi
diff --git a/Functions/Misc/zed b/Functions/Misc/zed
index c2caaf3f5..010b69bee 100644
--- a/Functions/Misc/zed
+++ b/Functions/Misc/zed
@@ -9,8 +9,9 @@
local var opt zed_file_name
# We do not want timeout while we are editing a file
integer TMOUT=0 okargs=1 fun bind
+local -a expand
-while getopts "fb" opt; do
+while getopts "fbx:" opt; do
case $opt in
(f)
fun=1
@@ -19,6 +20,14 @@ while getopts "fb" opt; do
(b)
bind=1
;;
+
+ (x)
+ if [[ $OPTARG != <-> ]]; then
+ print -r "Integer expected after -x: $OPTARG" >&2
+ return 1
+ fi
+ expand=(-x $OPTARG)
+ ;;
esac
done
shift $(( OPTIND - 1 ))
@@ -29,8 +38,8 @@ shift $(( OPTIND - 1 ))
if (( $# != okargs )); then
echo 'Usage:
zed filename
-zed -f function
-zed -b'
+zed -f [ -x N ] function
+zed -b' >&2
return 1
fi
@@ -71,7 +80,7 @@ fi
setopt localoptions nobanghist
if ((fun)) then
- var="$(functions $1)"
+ var="$(functions $expand $1)"
# If function is undefined but autoloadable, load it
if [[ $var = *\#\ undefined* ]] then
var="$(autoload +X $1; functions $1)"
diff --git a/Functions/Prompts/prompt_adam1_setup b/Functions/Prompts/prompt_adam1_setup
index 034641fb8..aca0e59f1 100644
--- a/Functions/Prompts/prompt_adam1_setup
+++ b/Functions/Prompts/prompt_adam1_setup
@@ -14,8 +14,6 @@ This theme works best with a dark background.
Recommended fonts for this theme: nexus or vga or similar. If you
don't have any of these, then specify the `plain' option to use 7-bit
replacements for the 8-bit characters.
-
-And you probably thought adam1 was overkill.
EOF
}
@@ -27,8 +25,9 @@ prompt_adam1_setup () {
base_prompt="%K{$prompt_adam1_color1}%n@%m%k "
post_prompt="%b%f%k"
- base_prompt_no_color=$(echo "$base_prompt" | perl -pe "s/%(K{.*?}|k)//g")
- post_prompt_no_color=$(echo "$post_prompt" | perl -pe "s/%(K{.*?}|k)//g")
+ setopt localoptions extendedglob
+ base_prompt_no_color="${base_prompt//(%K{[^\\\}]#\}|%k)/}"
+ post_prompt_no_color="${post_prompt//(%K{[^\\\}]#\}|%k)/}"
add-zsh-hook precmd prompt_adam1_precmd
}
diff --git a/Functions/Prompts/prompt_bart_setup b/Functions/Prompts/prompt_bart_setup
index 6cbbb71c7..45fcffed4 100644
--- a/Functions/Prompts/prompt_bart_setup
+++ b/Functions/Prompts/prompt_bart_setup
@@ -48,9 +48,13 @@ prompt_bart_help () {
When RPS1 (RPROMPT) is set before this prompt is selected and a
fifth color is specified, that color is turned on before RPS1 is
displayed and reset after it. Other color changes within RPS1, if
- any, remain in effect.
+ any, remain in effect. This also applies to RPS2 (RPROMPT2).
+ If a fifth color is specified and there is no RPS2, PS2 (PROMPT2)
+ is colored and moved to RPS2. Changes to RPS1/RPS2 are currently
+ not reverted when the theme is switched off. These work best with
+ the TRANSIENT_RPROMPT option, which must be set separately.
- This prompt hijacks psvar[7] through [9] to avoid having to reset
+ This theme hijacks psvar[7] through [9] to avoid having to reset
the entire PS1 string on every command. It uses TRAPWINCH to set
the position of the upper right prompt on a window resize, so the
prompt may not match the window width until the next command.
@@ -107,9 +111,9 @@ prompt_bart_precmd () {
((PSCOL == 1)) || { PSCOL=1 ; prompt_bart_ps1 }
if [[ -o promptcr ]]
then
- # Emulate the 4.3.x promptsp option if it isn't available
- eval '[[ -o promptsp ]] 2>/dev/null' ||
- print -nP "${(l.COLUMNS.. .)}\e[s${(pl.COLUMNS..\b.)}%E\e[u" >$TTY
+ # Emulate the 4.3.x promptsp option if it isn't available
+ eval '[[ -o promptsp ]] 2>/dev/null' ||
+ print -nP "${(l.COLUMNS.. .)}\e[s${(pl.COLUMNS..\b.)}%E\e[u" >$TTY
else IFS='[;' read -s -d R escape\?$'\e[6n' lineno PSCOL <$TTY
fi
((PSCOL == 1)) || prompt_bart_ps1
@@ -146,7 +150,7 @@ prompt_bart_ps1 () {
# Assemble the new prompt
ps1=( ${(f)PS1} ) # Split the existing prompt at newlines
ps1=(
- "%$[COLUMNS-PSCOL]>..>" # Begin truncation (upper left prompt)
+ "%$[COLUMNS-PSCOL]>..>" # Begin truncation (upper left prompt)
"$host"
"$hist1" # Empty when too wide for one line
"$dir"
@@ -176,8 +180,8 @@ prompt_bart_setup () {
# A few extra niceties ...
repeat 1 case "$1:l" in
(off|disable)
- add-zsh-hook -D precmd "prompt_*_precmd"
- add-zsh-hook -D preexec "prompt_*_preexec"
+ add-zsh-hook -D precmd "prompt_*_precmd"
+ add-zsh-hook -D preexec "prompt_*_preexec"
functions[TRAPWINCH]="${functions[TRAPWINCH]//prompt_bart_winch}"
[[ $prompt_theme[1] = bart ]] && PS1=${${(f)PS1}[-1]}
return 1
@@ -201,9 +205,22 @@ prompt_bart_setup () {
prompt_bart_ps1
- # No RPS1 by default because prompt_off_setup doesn't fix it.
- (($#RPS1 && $# > 4)) && RPS1="%F{$5}$RPS1%f"
-
+ if (($# > 4))
+ then
+ # No RPS1 by default because prompt_off_setup doesn't fix it.
+ if (($#RPS1))
+ then
+ RPS1="%F{$5}$RPS1%f"
+ fi
+ # RPS2 is less obvious so don't mind that it's not restored.
+ if (($#RPS2))
+ then
+ RPS2="%F{$5}$RPS2%f"
+ else
+ RPS2="%F{$5}<${${PS2//\%_/%^}%> }%f"
+ PS2=''
+ fi
+ fi
# Paste our special commands into precmd and TRAPWINCH
add-zsh-hook precmd prompt_bart_precmd
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr b/Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr
index cae1a3b08..e8c8e81de 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_bzr
@@ -6,7 +6,7 @@
setopt localoptions noksharrays extendedglob NO_shwordsplit
local bzrbase bzrbr bzr_changes bzr_type
local -a bzrinfo
-local -xA hook_com bzr_info
+local -A hook_com bzr_info
VCS_INFO_bzr_get_info() {
bzrinfo=( ${(s.:.)$( ${vcs_comm[cmd]} version-info --custom \
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
index c348da2a7..3fc861eeb 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
@@ -210,7 +210,9 @@ elif [[ -d "${gitdir}/rebase-merge" ]]; then
# remove action
git_patches_applied+=("${${(s: :)p}[2,-1]}")
done
- git_patches_unapplied=(${(f)"$(grep -v '^$' "${patchdir}/git-rebase-todo" | grep -v '^#')"})
+ if [[ -f "${patchdir}/git-rebase-todo" ]] ; then
+ git_patches_unapplied=(${(f)"$(grep -v '^$' "${patchdir}/git-rebase-todo" | grep -v '^#')"})
+ fi
VCS_INFO_git_handle_patches
elif [[ -d "${gitdir}/rebase-apply" ]]; then
# Fake patch names for all but current patch
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg b/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg
index 1274ca337..f35ad5965 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg
@@ -16,7 +16,7 @@ local -a hgid_args defrevformat defbranchformat \
hgbmarks mqpatches mqseries mqguards mqunapplied hgmisc \
i_patchguards i_negguards i_posguards
-local -xA hook_com
+local -A hook_com
hgbase=${vcs_comm[basedir]}
rrn=${hgbase:t}
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_p4 b/Functions/VCS_Info/Backends/VCS_INFO_get_data_p4
index 430cfa6f0..329884982 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_p4
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_p4
@@ -6,7 +6,7 @@
setopt localoptions extendedglob
local p4base a b
local -A p4info
-local -xA hook_com
+local -A hook_com
${vcs_comm[cmd]} info | while IFS=: read a b; do p4info[${a// /_}]="${b## #}"; done
p4base=${vcs_comm[basedir]}
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_svk b/Functions/VCS_Info/Backends/VCS_INFO_get_data_svk
index 6107a14f3..1d2d22ffb 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_svk
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_svk
@@ -4,7 +4,7 @@
setopt localoptions NO_shwordsplit
local svkbranch svkbase
-local -xA hook_com
+local -A hook_com
svkbase=${vcs_comm[basedir]}
rrn=${svkbase:t}
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_svn b/Functions/VCS_Info/Backends/VCS_INFO_get_data_svn
index e56afee02..e1334f661 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_svn
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_svn
@@ -8,7 +8,7 @@ setopt localoptions noksharrays extendedglob NO_shwordsplit
local svnbase svnbranch a b rrn
local -i rc
local -A svninfo parentinfo cwdinfo
-local -xA hook_com
+local -A hook_com
svnbase=".";
svninfo=()
diff --git a/Functions/VCS_Info/VCS_INFO_formats b/Functions/VCS_Info/VCS_INFO_formats
index 138091944..4d0dd75c2 100644
--- a/Functions/VCS_Info/VCS_INFO_formats
+++ b/Functions/VCS_Info/VCS_INFO_formats
@@ -5,7 +5,7 @@
setopt localoptions noksharrays NO_shwordsplit
local msg tmp
local -i i
-local -xA hook_com
+local -A hook_com
# The _origs are needed because hooks can change values and there would
# be no way to get the originals back for later hooks (a hook is run for
# each message, that's being created).
@@ -68,7 +68,7 @@ if [[ -n ${hook_com[unstaged]} ]] ; then
fi
if [[ ${quiltmode} != 'standalone' ]] && VCS_INFO_hook "pre-addon-quilt"; then
- local -x REPLY
+ local REPLY
VCS_INFO_quilt addon
hook_com[quilt]="${REPLY}"
unset REPLY
diff --git a/Functions/VCS_Info/VCS_INFO_hook b/Functions/VCS_Info/VCS_INFO_hook
index 479f5968b..94ae63017 100644
--- a/Functions/VCS_Info/VCS_INFO_hook
+++ b/Functions/VCS_Info/VCS_INFO_hook
@@ -3,8 +3,8 @@
## Distributed under the same BSD-ish license as zsh itself.
local hook static func
-local -x context hook_name
-local -xi ret
+local context hook_name
+local -i ret
local -a hooks tmp
local -i debug
diff --git a/Functions/VCS_Info/VCS_INFO_quilt b/Functions/VCS_Info/VCS_INFO_quilt
index 34ff1edbf..bc71cfb7d 100644
--- a/Functions/VCS_Info/VCS_INFO_quilt
+++ b/Functions/VCS_Info/VCS_INFO_quilt
@@ -86,9 +86,9 @@ function VCS_INFO_quilt() {
local mode="$1"
local patches pc tmp qstring root
local -i ret
- local -x context
+ local context
local -a applied unapplied all applied_string unapplied_string quiltcommand quilt_env
- local -Ax hook_com
+ local -A hook_com
context=":vcs_info:${vcs}.quilt-${mode}:${usercontext}:${rrn}"
zstyle -t "${context}" use-quilt || return 1
@@ -183,7 +183,7 @@ function VCS_INFO_quilt() {
VCS_INFO_set
;;
(addon)
- # When VCS_INFO_quilt() is called with "addon" a "local -x REPLY" variable
+ # When VCS_INFO_quilt() is called with "addon" a "local REPLY" variable
# should be in place. That variable can be unset after it's being used.
REPLY="${qstring}"
;;
diff --git a/Functions/VCS_Info/VCS_INFO_set b/Functions/VCS_Info/VCS_INFO_set
index 5087be43f..484c7937d 100644
--- a/Functions/VCS_Info/VCS_INFO_set
+++ b/Functions/VCS_Info/VCS_INFO_set
@@ -8,7 +8,7 @@ local -i i j
if [[ $1 == '--nvcs' ]] ; then
[[ $2 == '-preinit-' ]] && (( maxexports == 0 )) && (( maxexports = 1 ))
for i in {0..$((maxexports - 1))} ; do
- typeset -gx vcs_info_msg_${i}_=
+ typeset -g vcs_info_msg_${i}_=
done
VCS_INFO_nvcsformats $2
[[ $2 != '-preinit-' ]] && VCS_INFO_hook "no-vcs"
@@ -17,12 +17,12 @@ fi
(( ${#msgs} - 1 < 0 )) && return 0
for i in {0..$(( ${#msgs} - 1 ))} ; do
(( j = i + 1 ))
- typeset -gx vcs_info_msg_${i}_=${msgs[$j]}
+ typeset -g vcs_info_msg_${i}_=${msgs[$j]}
done
if (( i < maxexports )) ; then
for j in {$(( i + 1 ))..${maxexports}} ; do
- [[ -n ${(P)${:-vcs_info_msg_${j}_}} ]] && typeset -gx vcs_info_msg_${j}_=
+ [[ -n ${(P)${:-vcs_info_msg_${j}_}} ]] && typeset -g vcs_info_msg_${j}_=
done
fi
return 0
diff --git a/Functions/VCS_Info/vcs_info b/Functions/VCS_Info/vcs_info
index 46938691d..350b189e9 100644
--- a/Functions/VCS_Info/vcs_info
+++ b/Functions/VCS_Info/vcs_info
@@ -51,10 +51,11 @@ vcs_info () {
local pat
local -i found retval
local -a enabled disabled dps
- local -x usercontext vcs rrn quiltmode LC_MESSAGES
- local -ix maxexports
- local -ax msgs
- local -Ax vcs_comm hook_com backend_misc user_data
+ local usercontext vcs rrn quiltmode
+ local -x LC_MESSAGES
+ local -i maxexports
+ local -a msgs
+ local -A vcs_comm hook_com backend_misc user_data
LC_MESSAGES=C
if [[ -n ${LC_ALL} ]]; then
diff --git a/Functions/VCS_Info/vcs_info_lastmsg b/Functions/VCS_Info/vcs_info_lastmsg
index ddfaaf88b..438567cef 100644
--- a/Functions/VCS_Info/vcs_info_lastmsg
+++ b/Functions/VCS_Info/vcs_info_lastmsg
@@ -5,7 +5,7 @@
emulate -L zsh
local -i i
-local -ix maxexports
+local -i maxexports
VCS_INFO_maxexports
for i in {0..$((maxexports - 1))} ; do
diff --git a/Functions/VCS_Info/vcs_info_printsys b/Functions/VCS_Info/vcs_info_printsys
index f29061463..b44b9c9b4 100644
--- a/Functions/VCS_Info/vcs_info_printsys
+++ b/Functions/VCS_Info/vcs_info_printsys
@@ -7,7 +7,7 @@ setopt extendedglob
local sys
local -a disabled enabled
-local -Ax vcs_comm
+local -A vcs_comm
zstyle -a ":vcs_info:-init-:${1:-default}:-all-" "enable" enabled
(( ${#enabled} == 0 )) && enabled=( all )
diff --git a/Functions/Zle/bracketed-paste-magic b/Functions/Zle/bracketed-paste-magic
new file mode 100644
index 000000000..da106d1ac
--- /dev/null
+++ b/Functions/Zle/bracketed-paste-magic
@@ -0,0 +1,192 @@
+# Starting with zsh-5.0.9, ZLE began to recognize the "bracketed paste"
+# capability of terminal emulators, that is, the sequences $'\e[200~' to
+# start a paste and $'\e[201~' to indicate the end of the pasted text.
+# Pastes are handled by the bracketed-paste widget and insert literally
+# into the editor buffer rather than being interpreted as keystrokes.
+#
+# This disables some common usages where the self-insert widget has been
+# replaced in order to accomplish some extra processing. An example is
+# the contributed url-quote-magic widget. The bracketed-paste-magic
+# widget replaces bracketed-paste with a wrapper that re-enables these
+# self-insert actions, and other actions as selected by the zstyles
+# described below.
+#
+# Setup:
+# autoload -Uz bracketed-paste-magic
+# zle -N bracketed-paste bracketed-paste-magic
+
+# The following zstyles may be set to control processing of pasted text.
+#
+# active-widgets
+# Looked up in the context :bracketed-paste-magic to obtain a list of
+# patterns that match widget names that should be activated during the
+# paste. All other key sequences are processed as self-insert-unmeta.
+# The default is 'self-*' so any user-defined widgets named with that
+# prefix are active along with the builtin self-insert. If this style is
+# not set (note: it must be explicitly deleted after loading this
+# function, otherwise it becomes set by default) or has no value, no
+# widgets are active and the pasted text is inserted literally. If the
+# value includes undefined-key, any unknown sequences are discarded from
+# the pasted text.
+#
+# inactive-keys
+# This is the inverse of active-widgets, it lists key sequences that
+# always use self-insert-unmeta even when bound to an active-widget.
+# Note that this is a list of literal key sequences, not patterns.
+# This style is in context :bracketed-paste-magic and has no default.
+#
+# paste-init
+# paste-finish
+# Also looked up in the context :bracketed-paste-magic, these styles
+# each are a list of function names. They are executed in widget
+# context but are called as functions (NOT as widgets with "zle name").
+# They also run in zsh emulation context set by bracketed-paste-magic.
+# As with hooks, the functions are called in order until one of them
+# returns a nonzero exit status. The parameter PASTED contains the
+# current state of the pasted text, other ZLE parameters are as usual.
+# Although a nonzero status stops each list of functions, it does NOT
+# abort the entire paste operation; use "zle send-break" for that.
+
+# IMPORTANT: During processing of the paste (after paste-init and
+# before paste-finish), BUFFER starts empty and history is restricted,
+# so cursor motions etc. may not pass outside of the pasted content.
+# However, the paste-init functions have access to the full history and
+# the original BUFFER, so they may for example move words from BUFFER
+# into PASTED to make those words visible to the active-widgets.
+
+# Establish default values for styles, but only if not already set
+zstyle -m :bracketed-paste-magic active-widgets '*' ||
+ zstyle ':bracketed-paste-magic' active-widgets 'self-*'
+
+# Helper/example paste-init for exposing a word prefix inside PASTED.
+# Useful with url-quote-magic if you have http://... on the line and
+# are pasting additional text on the end of the URL.
+#
+# Usage:
+# zstyle :bracketed-paste-magic paste-init backward-extend-paste
+#
+# TODO: rewrite this using match-words-by-style
+#
+backward-extend-paste() {
+ : emulate -LR zsh # Already set by bracketed-paste-magic
+ integer bep_mark=$MARK bep_region=$REGION_ACTIVE
+ if (( REGION_ACTIVE && MARK < CURSOR )); then
+ zle .exchange-point-and-mark
+ fi
+ if (( CURSOR )); then
+ local -a bep_words=( ${(z)LBUFFER} )
+ if [[ -n $bep_words[-1] && $LBUFFER = *$bep_words[-1] ]]; then
+ PASTED=$bep_words[-1]$PASTED
+ LBUFFER=${LBUFFER%${bep_words[-1]}}
+ fi
+ fi
+ if (( MARK > bep_mark )); then
+ zle .exchange-point-and-mark
+ fi
+ REGION_ACTIVE=$bep_region
+}
+
+# Example paste-finish for quoting the pasted text.
+#
+# Usage e.g.:
+# zstyle :bracketed-paste-magic paste-finish quote-paste
+# zstyle :bracketed-paste-magic:finish quote-style qqq
+#
+# Using "zstyle -e" to examine $PASTED lets you choose different quotes
+# depending on context.
+#
+# To forcibly turn off numeric prefix quoting, use e.g.:
+# zstyle :bracketed-paste-magic:finish quote-style none
+#
+quote-paste() {
+ : emulate -LR zsh # Already set by bracketed-paste-magic
+ local qstyle
+ # If there's a quoting style, be sure .bracketed-paste leaves it alone
+ zstyle -s :bracketed-paste-magic:finish quote-style qstyle && NUMERIC=1
+ case $qstyle in
+ (b) PASTED=${(b)PASTED};;
+ (q-) PASTED=${(q-)PASTED};;
+ (\\|q) PASTED=${(q)PASTED};;
+ (\'|qq) PASTED=${(qq)PASTED};;
+ (\"|qqq) PASTED=${(qqq)PASTED};;
+ (\$|qqqq) PASTED=${(qqqq)PASTED};;
+ (Q) PASTED=${(Q)PASTED};;
+ esac
+}
+
+# Now the actual function
+
+bracketed-paste-magic() {
+ emulate -LR zsh
+ local -a bpm_hooks bpm_inactive
+ local PASTED bpm_func bpm_active
+
+ # Set PASTED and run the paste-init functions
+ zle .bracketed-paste PASTED
+ if zstyle -a :bracketed-paste-magic paste-init bpm_hooks; then
+ for bpm_func in $bpm_hooks; do
+ if (( $+functions[$bpm_func] )); then
+ $bpm_func || break
+ fi
+ done
+ fi
+
+ # Save context, create a clean slate for the paste
+ integer bpm_mark=$MARK bpm_cursor=$CURSOR bpm_region=$REGION_ACTIVE
+ integer bpm_numeric=${NUMERIC:-1}
+ local bpm_buffer=$BUFFER
+ fc -p -a /dev/null 0 0
+ BUFFER=
+
+ zstyle -a :bracketed-paste-magic inactive-keys bpm_inactive
+ if zstyle -s :bracketed-paste-magic active-widgets bpm_active '|'; then
+ # There are active widgets. Reprocess $PASTED as keystrokes.
+ NUMERIC=1
+ zle -U - $PASTED
+ while [[ -n $PASTED ]] && zle .read-command; do
+ PASTED=${PASTED#$KEYS}
+ if [[ $KEYS = ${(~j:|:)${(b)bpm_inactive}} ]]; then
+ zle .self-insert-unmeta
+ else
+ case $REPLY in
+ (${~bpm_active}) zle $REPLY;;
+ (*) zle .self-insert-unmeta;;
+ esac
+ fi
+ done
+ PASTED=$BUFFER
+ fi
+
+ # Restore state
+ BUFFER=$bpm_buffer
+ MARK=$bpm_mark
+ CURSOR=$bpm_cursor
+ REGION_ACTIVE=$bpm_region
+ NUMERIC=$bpm_numeric
+ fc -P
+
+ # PASTED has been updated, run the paste-finish functions
+ if zstyle -a :bracketed-paste-magic paste-finish bpm_hooks; then
+ for bpm_func in $bpm_hooks; do
+ if (( $+functions[$bpm_func] )); then
+ $bpm_func || break
+ fi
+ done
+ fi
+
+ # Reprocess $PASTED as an actual paste this time
+ zle -U - $PASTED$'\e[201~' # append paste-end marker
+ zle .bracketed-paste
+ zle .split-undo
+
+ # Arrange to display highlighting if necessary
+ if [[ -n ${(M)zle_highlight:#paste:*} ]]; then
+ zle -R
+ zle .read-command && zle -U - $KEYS
+ fi
+}
+
+# Handle zsh autoloading conventions
+if [[ $zsh_eval_context = *loadautofunc && ! -o kshautoload ]]; then
+ bracketed-paste-magic "$@"
+fi
diff --git a/Functions/Zle/edit-command-line b/Functions/Zle/edit-command-line
index 100af9601..2c7f34b8b 100644
--- a/Functions/Zle/edit-command-line
+++ b/Functions/Zle/edit-command-line
@@ -8,7 +8,20 @@
() {
exec </dev/tty
- ${=${VISUAL:-${EDITOR:-vi}}} $1
+
+ # Compute the cursor's position in bytes, not characters.
+ setopt localoptions nomultibyte
+ integer byteoffset=$(( $#PREBUFFER + $#LBUFFER + 1 ))
+
+ # Open the editor, placing the cursor at the right place if we know how.
+ local editor=${${VISUAL:-${EDITOR:-vi}}}
+ case $editor in
+ (*vim*) ${=editor} -c "normal! ${byteoffset}go" -- $1;;
+ (*emacs*) ${=editor} $1 -eval "(goto-char ${byteoffset})";;
+ (*) ${=editor} $1;;
+ esac
+
+ # Replace the buffer with the editor output.
print -Rz - "$(<$1)"
} =(<<<"$PREBUFFER$BUFFER")
diff --git a/Functions/Zle/incremental-complete-word b/Functions/Zle/incremental-complete-word
index 67a9d4744..ccc007543 100644
--- a/Functions/Zle/incremental-complete-word
+++ b/Functions/Zle/incremental-complete-word
@@ -69,7 +69,7 @@ incremental-complete-word() {
'#key' -ne '#\\C-g' ]]; do
twid=$wid
if [[ "$key" = ${~stop} ]]; then
- zle -U "$key"
+ zle -U - "$key"
return
elif [[ "$key" = ${~brk} ]]; then
return
diff --git a/Functions/Zle/narrow-to-region b/Functions/Zle/narrow-to-region
index 86fd7ac13..261d821a9 100644
--- a/Functions/Zle/narrow-to-region
+++ b/Functions/Zle/narrow-to-region
@@ -5,39 +5,52 @@
# Optionally accepts exactly two arguments, which are used instead of
# $CURSOR and $MARK as limits to the range.
#
+# Upon exit, $MARK is always the start of the edited range and $CURSOR
+# the end of the range, even if they began in the opposite order.
+#
# Other options:
-# -p pretext show `pretext' instead of the buffer text before the region.
-# -P posttext show `posttext' instead of the buffer text after the region.
-# Either or both may be empty.
+# -p pretext show "pretext" instead of the buffer text before the region.
+# -P posttext show "posttext" instead of the buffer text after the region.
+# Either or both may be empty.
# -n Only replace the text before or after the region with
# the -p or -P options if the text was not empty.
+# -l lbufvar $lbufvar is assigned the value of $LBUFFER and
+# -r rbufvar $rbufvar is assigned the value of $RBUFFER
+# from any recursive edit (i.e. not with -S or -R). Neither
+# lbufvar nor rbufvar may begin with the prefix "_ntr_".
# -S statevar
# -R statevar
-# Save or restore the state in/from the parameter named statevar. In
-# either case no recursive editing takes place; this will typically be
-# done within the calling function between calls with -S and -R. The
-# statevar may not begin with the prefix _ntr_ which is reserved for
-# parameters within narrow-to-region.
+# Save or restore the state in/from the parameter named statevar. In
+# either case no recursive editing takes place; this will typically be
+# done within the calling function between calls with -S and -R. The
+# statevar may not begin with the prefix "_ntr_" which is reserved for
+# parameters within narrow-to-region.
-emulate -L zsh
-setopt extendedglob
+# set the minimum of options to avoid changing behaviour away from
+# user preferences from within recursive-edit
+setopt localoptions noshwordsplit noksharrays
-local _ntr_lbuffer _ntr_rbuffer
+local _ntr_newbuf _ntr_lbuf_return _ntr_rbuf_return
local _ntr_predisplay=$PREDISPLAY _ntr_postdisplay=$POSTDISPLAY
+integer _ntr_savelim=UNDO_LIMIT_NO _ntr_changeno _ntr_histno=HISTNO
integer _ntr_start _ntr_end _ntr_swap _ntr_cursor=$CURSOR _ntr_mark=$MARK
integer _ntr_stat
local _ntr_opt _ntr_pretext _ntr_posttext _ntr_usepretext _ntr_useposttext
-local _ntr_nonempty _ntr_save _ntr_restore
+local _ntr_nonempty _ntr_save _ntr_restore _ntr_lbuffer _ntr_rbuffer
-while getopts "np:P:R:S:" _ntr_opt; do
+while getopts "l:np:P:r:R:S:" _ntr_opt; do
case $_ntr_opt in
+ (l) _ntr_lbuf_return=$OPTARG
+ ;;
(n) _ntr_nonempty=1
;;
(p) _ntr_pretext=$OPTARG _ntr_usepretext=1
;;
(P) _ntr_posttext=$OPTARG _ntr_useposttext=1
;;
+ (r) _ntr_rbuf_return=$OPTARG
+ ;;
(R) _ntr_restore=$OPTARG
;;
(S) _ntr_save=$OPTARG
@@ -49,7 +62,8 @@ while getopts "np:P:R:S:" _ntr_opt; do
done
(( OPTIND > 1 )) && shift $(( OPTIND - 1 ))
-if [[ $_ntr_restore = _ntr_* || $_ntr_save = _ntr_* ]]; then
+if [[ $_ntr_restore = _ntr_* || $_ntr_save = _ntr_* ||
+ $_ntr_lbuf_return = _ntr_* || $_ntr_rbuf_return = _ntr_* ]]; then
zle -M "$0: _ntr_ prefix is reserved" >&2
return 1
fi
@@ -58,7 +72,7 @@ if [[ -n $_ntr_save || -z $_ntr_restore ]]; then
if (( $# )); then
if (( $# != 2 )); then
- zle -M "$0: supply zero or two arguments"
+ zle -M "$0: supply zero or two arguments" >&2
return 1
fi
_ntr_start=$1
@@ -74,50 +88,68 @@ if [[ -n $_ntr_save || -z $_ntr_restore ]]; then
_ntr_end=_ntr_swap
fi
- (( _ntr_end++, _ntr_cursor -= _ntr_start, _ntr_mark -= _ntr_start ))
+ (( _ntr_cursor -= _ntr_start, _ntr_mark -= _ntr_start ))
_ntr_lbuffer=${BUFFER[1,_ntr_start]}
if [[ -z $_ntr_usepretext || ( -n $_ntr_nonempty && -z $_ntr_lbuffer ) ]]
then
_ntr_pretext=$_ntr_lbuffer
fi
- _ntr_rbuffer=${BUFFER[_ntr_end,-1]}
+ _ntr_rbuffer=${BUFFER[_ntr_end+1,-1]}
if [[ -z $_ntr_useposttext || ( -n $_ntr_nonempty && -z $_ntr_rbuffer ) ]]
then
_ntr_posttext=$_ntr_rbuffer
fi
+ _ntr_changeno=$UNDO_CHANGE_NO
PREDISPLAY="$_ntr_predisplay$_ntr_pretext"
POSTDISPLAY="$_ntr_posttext$_ntr_postdisplay"
- BUFFER=${BUFFER[_ntr_start+1,_ntr_end-1]}
- CURSOR=$_ntr_cursor
- MARK=$_ntr_mark
if [[ -n $_ntr_save ]]; then
- eval "$_ntr_save=(${(qq)_ntr_predisplay} ${(qq)_ntr_postdisplay}
-${(qq)_ntr_lbuffer} ${(qq)_ntr_rbuffer})" || return 1
+ builtin typeset -ga $_ntr_save
+ set -A $_ntr_save "${_ntr_predisplay}" "${_ntr_postdisplay}" \
+ "${_ntr_savelim}" "${_ntr_changeno}" \
+ "${_ntr_start}" "${_ntr_end}" "${_ntr_histno}" || return 1
fi
+
+ BUFFER=${BUFFER[_ntr_start+1,_ntr_end]}
+ CURSOR=$_ntr_cursor
+ MARK=$_ntr_mark
+ zle split-undo
+ UNDO_LIMIT_NO=$UNDO_CHANGE_NO
fi
if [[ -z $_ntr_save && -z $_ntr_restore ]]; then
zle recursive-edit
_ntr_stat=$?
+
+ [[ -n $_ntr_lbuf_return ]] &&
+ builtin typeset -g ${_ntr_lbuf_return}="${LBUFFER}"
+ [[ -n $_ntr_rbuf_return ]] &&
+ builtin typeset -g ${_ntr_rbuf_return}="${RBUFFER}"
fi
if [[ -n $_ntr_restore || -z $_ntr_save ]]; then
if [[ -n $_ntr_restore ]]; then
- if ! eval "_ntr_predisplay=\${${_ntr_restore}[1]}
-_ntr_postdisplay=\${${_ntr_restore}[2]}
-_ntr_lbuffer=\${${_ntr_restore}[3]}
-_ntr_rbuffer=\${${_ntr_restore}[4]}"; then
- zle -M Failed.
+ if ! { _ntr_predisplay="${${(@P)_ntr_restore}[1]}"
+ _ntr_postdisplay="${${(@P)_ntr_restore}[2]}"
+ _ntr_savelim="${${(@P)_ntr_restore}[3]}"
+ _ntr_changeno="${${(@P)_ntr_restore}[4]}"
+ _ntr_start="${${(@P)_ntr_restore}[5]}"
+ _ntr_end="${${(@P)_ntr_restore}[6]}"
+ _ntr_histno="${${(@P)_ntr_restore}[7]}" }; then
+ zle -M Failed. >&2
return 1
fi
fi
+ _ntr_newbuf="$BUFFER"
+ HISTNO=_ntr_histno
+ zle undo $_ntr_changeno
PREDISPLAY=$_ntr_predisplay
POSTDISPLAY=$_ntr_postdisplay
- LBUFFER="$_ntr_lbuffer$LBUFFER"
- RBUFFER="$RBUFFER$_ntr_rbuffer"
+ BUFFER[_ntr_start+1,_ntr_end]="$_ntr_newbuf"
+ (( MARK = _ntr_start, CURSOR = _ntr_start + ${#_ntr_newbuf} ))
+ UNDO_LIMIT_NO=_ntr_savelim
fi
return $_ntr_stat
diff --git a/Functions/Zle/read-from-minibuffer b/Functions/Zle/read-from-minibuffer
index 8fec1105e..09dc68f97 100644
--- a/Functions/Zle/read-from-minibuffer
+++ b/Functions/Zle/read-from-minibuffer
@@ -20,7 +20,7 @@ done
(( OPTIND > 1 )) && shift $(( OPTIND - 1 ))
local readprompt="$1" lbuf_init="$2" rbuf_init="$3"
-integer changeno=$UNDO_CHANGE_NO
+integer savelim=$UNDO_LIMIT_NO changeno=$UNDO_CHANGE_NO
{
# Use anonymous function to make sure special values get restored,
@@ -43,6 +43,8 @@ integer changeno=$UNDO_CHANGE_NO
else
local NUMERIC
unset NUMERIC
+ zle split-undo
+ UNDO_LIMIT_NO=$UNDO_CHANGE_NO
zle recursive-edit -K main
stat=$?
(( stat )) || REPLY=$BUFFER
@@ -52,6 +54,7 @@ integer changeno=$UNDO_CHANGE_NO
# This removes the edits relating to the read from the undo history.
# These aren't useful once we get back to the main editing buffer.
zle undo $changeno
+ UNDO_LIMIT_NO=savelim
}
return $stat
diff --git a/Functions/Zle/smart-insert-last-word b/Functions/Zle/smart-insert-last-word
index 27b0849ee..67adea760 100644
--- a/Functions/Zle/smart-insert-last-word
+++ b/Functions/Zle/smart-insert-last-word
@@ -47,13 +47,15 @@ setopt extendedglob nohistignoredups
zle auto-suffix-retain
# Not strictly necessary:
-# (($+_ilw_hist)) || integer -g _ilw_hist _ilw_count _ilw_cursor _ilw_lcursor
+# (($+_ilw_hist)) || integer -g _ilw_hist _ilw_count _ilw_cursor _ilw_lcursor _ilw_changeno
integer cursor=$CURSOR lcursor=$CURSOR
local lastcmd pattern numeric=$NUMERIC
# Save state for repeated calls
-if (( HISTNO == _ilw_hist && cursor == _ilw_cursor )); then
+if (( HISTNO == _ilw_hist && cursor == _ilw_cursor &&
+ UNDO_CHANGE_NO == _ilw_changeno ))
+then
NUMERIC=$[_ilw_count+1]
lcursor=$_ilw_lcursor
else
@@ -61,7 +63,8 @@ else
_ilw_lcursor=$lcursor
fi
# Handle the up to three arguments of .insert-last-word
-if (( $+1 )); then
+if (( $+1 ))
+then
if (( $+3 )); then
((NUMERIC = -($1)))
else
@@ -117,3 +120,6 @@ fi
LBUFFER[lcursor+1,cursor+1]=$lastcmd[-NUMERIC]
_ilw_cursor=$CURSOR
+
+# This is necessary to update UNDO_CHANGE_NO immediately
+zle split-undo && _ilw_changeno=$UNDO_CHANGE_NO
diff --git a/Functions/Zle/url-quote-magic b/Functions/Zle/url-quote-magic
index fbcc7c19c..362d15c44 100644
--- a/Functions/Zle/url-quote-magic
+++ b/Functions/Zle/url-quote-magic
@@ -8,6 +8,12 @@
# autoload -Uz url-quote-magic
# zle -N self-insert url-quote-magic
+# As of zsh-5.0.9, the following may also be necessary in order to apply
+# quoting to copy-pasted URLs:
+# autload -Uz bracketed-paste-magic
+# zle -N bracketed-paste bracketed-paste-magic
+# See also backward-extend-paste in bracketed-paste-magic source file.
+
# A number of zstyles may be set to control the quoting behavior.
#
# url-metas