summaryrefslogtreecommitdiff
path: root/Functions
diff options
context:
space:
mode:
Diffstat (limited to 'Functions')
-rw-r--r--Functions/Calendar/age2
-rw-r--r--Functions/Chpwd/cdr37
-rw-r--r--Functions/Chpwd/zsh_directory_name_generic151
-rw-r--r--Functions/MIME/zsh-mime-setup2
-rw-r--r--Functions/Misc/add-zsh-hook2
-rw-r--r--Functions/Misc/zcalc4
-rw-r--r--Functions/Misc/zed35
-rw-r--r--Functions/Misc/zrecompile2
-rw-r--r--Functions/TCP/tcp_open2
-rw-r--r--Functions/TCP/tcp_read2
-rw-r--r--Functions/TCP/tcp_send2
-rw-r--r--Functions/TCP/tcp_shoot4
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_git65
-rw-r--r--Functions/VCS_Info/VCS_INFO_quilt31
-rw-r--r--Functions/VCS_Info/vcs_info2
-rw-r--r--Functions/Zle/bracketed-paste-magic29
-rw-r--r--Functions/Zle/bracketed-paste-url-magic44
-rw-r--r--Functions/Zle/edit-command-line9
-rw-r--r--Functions/Zle/match-word-context9
-rw-r--r--Functions/Zle/smart-insert-last-word10
20 files changed, 368 insertions, 76 deletions
diff --git a/Functions/Calendar/age b/Functions/Calendar/age
index 17cf4d13e..50755d610 100644
--- a/Functions/Calendar/age
+++ b/Functions/Calendar/age
@@ -1,4 +1,4 @@
-# Match the age of a file, for use as a glob qualifer. Can
+# Match the age of a file, for use as a glob qualifier. Can
# take one or two arguments, which can be supplied by one of two
# ways (always the same for both arguments):
#
diff --git a/Functions/Chpwd/cdr b/Functions/Chpwd/cdr
index 4f399106b..4bed88b13 100644
--- a/Functions/Chpwd/cdr
+++ b/Functions/Chpwd/cdr
@@ -51,6 +51,13 @@
# (and only /). Usually the first entry should be left as the current
# directory.
#
+# "cdr -p 'pattern'" prunes anything matching the given extended glob
+# pattern from the directory list. The match is against the fully
+# expanded directory path and the full string must match (use wildcards
+# at the ends if needed). If output is going to a terminal, the
+# function will print the new list for the user to confrim; this can be
+# skipped by giving -P instead of -p.
+#
# Details of directory handling
# =============================
#
@@ -217,11 +224,11 @@ setopt extendedglob
autoload -Uz chpwd_recent_filehandler chpwd_recent_add
-integer list set_reply i bad edit
-local opt dir
+integer list set_reply i bad edit force_prune
+local opt dir prune
local -aU dirs
-while getopts "elr" opt; do
+while getopts "elp:P:r" opt; do
case $opt in
(e)
edit=1
@@ -231,6 +238,12 @@ while getopts "elr" opt; do
list=1
;;
+ ([pP])
+ prune=$OPTARG
+ edit=1
+ [[ $opt = P ]] && force_prune=1
+ ;;
+
(r)
set_reply=1
;;
@@ -278,10 +291,22 @@ if [[ $PWD != $reply[1] ]]; then
fi
if (( edit )); then
- local compcontext='directories:directory:_path_files -/'
-IFS='
+ if [[ -n $prune ]]; then
+ reply=(${reply:#$~prune})
+ if [[ force_prune -eq 0 && -t 1 ]]; then
+ print -nrl "New list:" $reply 'Accept? '
+ if ! read -q; then
+ print
+ return 1
+ fi
+ print
+ fi
+ else
+ local compcontext='directories:directory:_path_files -/'
+ IFS='
' vared reply || return 1
-chpwd_recent_filehandler $reply
+ fi
+ chpwd_recent_filehandler $reply
fi
# Skip current directory if present (may have been pruned).
diff --git a/Functions/Chpwd/zsh_directory_name_generic b/Functions/Chpwd/zsh_directory_name_generic
new file mode 100644
index 000000000..9430c95e4
--- /dev/null
+++ b/Functions/Chpwd/zsh_directory_name_generic
@@ -0,0 +1,151 @@
+## zsh_directory_name_generic
+#
+# This function is useful as a hook function for the zsh_directory_name
+# facility.
+#
+# See the zsh-contrib manual page for more.
+
+emulate -L zsh
+setopt extendedglob
+local -a match mbegin mend
+
+# The variable containing the top level mapping.
+local _zdn_topvar
+
+zmodload -i zsh/parameter
+zstyle -s ":zdn:${funcstack[2]}:" mapping _zdn_topvar || _zdn_topvar=zdn_top
+
+if (( ! ${(P)#_zdn_topvar} )); then
+ print -r -- "$0: $_zdn_topver is not set" >&2
+ return 1
+fi
+
+local _zdn_var=$_zdn_topvar
+local -A _zdn_assoc
+
+if [[ $1 = n ]]; then
+ # Turning a name into a directory.
+ local _zdn_name=$2
+ local -a _zdn_words
+ local _zdn_dir _zdn_cpt
+
+ _zdn_words=(${(s.:.)_zdn_name})
+ while (( ${#_zdn_words} )); do
+ if [[ -z ${_zdn_var} ]]; then
+ print -r -- "$0: too many components in directory name \`$_zdn_name'" >&2
+ return 1
+ fi
+
+ # Subscripting (P)_zdn_var directly seems not to work.
+ _zdn_assoc=(${(Pkv)_zdn_var})
+ _zdn_cpt=${_zdn_assoc[${_zdn_words[1]}]}
+ shift _zdn_words
+
+ if [[ -z $_zdn_cpt ]]; then
+ # If top level component, just try another expansion
+ if [[ $_zdn_var != $_zdn_top ]]; then
+ # Committed to this expansion, so report failure.
+ print -r -- "$0: no expansion for directory name \`$_zdn_name'" >&2
+ fi
+ return 1
+ fi
+ if [[ $_zdn_cpt = (#b)(*)/:([[:IDENT:]]##) ]]; then
+ _zdn_cpt=$match[1]
+ _zdn_var=$match[2]
+ else
+ # may be empty
+ _zdn_var=${${_zdn_assoc[:default:]}##*/:}
+ fi
+ _zdn_dir=${_zdn_dir:+$_zdn_dir/}$_zdn_cpt
+ done
+ if (( ${#_zdn_dir} )); then
+ typeset -ag reply
+ reply=($_zdn_dir)
+ return 0
+ fi
+elif [[ $1 = d ]]; then
+ # Turning a directory into a name.
+ local _zdn_dir=$2
+ local _zdn_rest=$_zdn_dir
+ local -a _zdn_cpts
+ local _zdn_pref _zdn_pref_raw _zdn_matched _zdn_cpt _zdn_name
+
+ while [[ -n $_zdn_var && -n $_zdn_rest ]]; do
+ _zdn_assoc=(${(Pkv)_zdn_var})
+ # Sorting in descending order will ensure prefixes
+ # come after longer strings with that perfix, so
+ # we match more specific directory names preferentially.
+ _zdn_cpts=(${(Ov)_zdn_assoc})
+ _zdn_cpt=''
+ for _zdn_pref_raw in $_zdn_cpts; do
+ _zdn_pref=${_zdn_pref_raw%/:*}
+ [[ -z $_zdn_pref ]] && continue
+ if [[ $_zdn_rest = $_zdn_pref(#b)(/|)(*) ]]; then
+ _zdn_cpt=${(k)_zdn_assoc[(r)$_zdn_pref_raw]}
+ # if we matched a /, too, add it...
+ _zdn_matched+=$_zdn_pref$match[1]
+ _zdn_rest=$match[2]
+ break
+ fi
+ done
+ if [[ -n $_zdn_cpt ]]; then
+ _zdn_name+=${_zdn_name:+${_zdh_name}:}$_zdn_cpt
+ if [[ ${_zdn_assoc[$_zdn_cpt]} = (#b)*/:([[:IDENT:]]##) ]]; then
+ _zdn_var=$match[1]
+ else
+ _zdn_var=${${_zdn_assoc[:default:]}##*/:}
+ fi
+ else
+ break
+ fi
+ done
+ if [[ -n $_zdn_name ]]; then
+ # matched something, so report that.
+ integer _zdn_len=${#_zdn_matched}
+ [[ $_zdn_matched[-1] = / ]] && (( _zdn_len-- ))
+ typeset -ag reply
+ reply=($_zdn_name $_zdn_len)
+ return 0
+ fi
+ # else let someone else have a go.
+elif [[ $1 = c ]]; then
+ # Completion
+
+ if [[ -n $SUFFIX ]]; then
+ _message "Can't complete in the middle of a dynamic directory name"
+ else
+ local -a _zdn_cpts
+ local _zdn_word _zdn_cpt _zdn_desc _zdn_sofar expl
+
+ while [[ -n ${_zdn_var} && ${PREFIX} = (#b)([^:]##):* ]]; do
+ _zdn_word=$match[1]
+ compset -P '[^:]##:'
+ _zdn_assoc=(${(Pkv)_zdn_var})
+ _zdn_cpt=${_zdn_assoc[$_zdn_word]}
+ # We only complete at the end so must match here
+ [[ -z $_zdn_cpt ]] && return 1
+ if [[ $_zdn_cpt = (#b)(*)/:([[:IDENT:]]##) ]]; then
+ _zdn_cpt=$match[1]
+ _zdn_var=$match[2]
+ else
+ _zdn_var=${${_zdn_assoc[:default:]}##*/:}
+ fi
+ _zdn_sofar+=${_zdn_sofar:+${_zdn_sofar}/}$_zdn_cpt
+ done
+ if [[ -n $_zdn_var ]]; then
+ _zdn_assoc=(${(Pkv)_zdn_var})
+ local -a _zdn_cpts
+ for _zdn_cpt _zdn_desc in ${(kv)_zdn_assoc}; do
+ [[ $_zdn_cpt = :* ]] && continue
+ _zdn_cpts+=(${_zdn_cpt}:${_zdn_desc%/:[[:IDENT:]]##})
+ done
+ _describe -t dirnames "directory name under ${_zdn_sofar%%/}" \
+ _zdn_cpts -S: -r ':]'
+ return
+ fi
+ fi
+fi
+
+# Failed
+return 1
+## end
diff --git a/Functions/MIME/zsh-mime-setup b/Functions/MIME/zsh-mime-setup
index 23e44fdc0..35f6e6b6b 100644
--- a/Functions/MIME/zsh-mime-setup
+++ b/Functions/MIME/zsh-mime-setup
@@ -1,7 +1,7 @@
emulate -L zsh
setopt extendedglob cbases
-local opt o_verbose o_list
+local opt o_verbose o_list i
autoload -Uz zsh-mime-handler
diff --git a/Functions/Misc/add-zsh-hook b/Functions/Misc/add-zsh-hook
index ee37d674d..fc39659ae 100644
--- a/Functions/Misc/add-zsh-hook
+++ b/Functions/Misc/add-zsh-hook
@@ -82,9 +82,11 @@ if (( del )); then
else
if (( ${(P)+hook} )); then
if (( ${${(P)hook}[(I)$fn]} == 0 )); then
+ typeset -ga $hook
set -A $hook ${(P)hook} $fn
fi
else
+ typeset -ga $hook
set -A $hook $fn
fi
autoload $autoopts -- $fn
diff --git a/Functions/Misc/zcalc b/Functions/Misc/zcalc
index 63f67adb0..17700e48b 100644
--- a/Functions/Misc/zcalc
+++ b/Functions/Misc/zcalc
@@ -120,6 +120,10 @@ autoload -Uz zmathfuncdef
float PI E
(( PI = 4 * atan(1), E = exp(1) ))
+if [[ -f "${ZDOTDIR:-$HOME}/.zcalcrc" ]]; then
+ . "${ZDOTDIR:-$HOME}/.zcalcrc" || return 1
+fi
+
# Process command line
while [[ -n $1 && $1 = -(|[#-]*|f|e) ]]; do
optlist=${1[2,-1]}
diff --git a/Functions/Misc/zed b/Functions/Misc/zed
index 010b69bee..eb8f557ea 100644
--- a/Functions/Misc/zed
+++ b/Functions/Misc/zed
@@ -6,31 +6,20 @@
# Use ^X^W to save, ^C to abort.
# Option -f: edit shell functions. (Also if called as fned.)
-local var opt zed_file_name
+local var opts 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 "fbx:" opt; do
- case $opt in
- (f)
- fun=1
- ;;
-
- (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 ))
+zparseopts -D -A opts f b x:
+fun=$+opts[-f]
+bind=$+opts[-b]
+if [[ $opts[-x] == <-> ]]; then
+ expand=(-x $opts[-x])
+elif (( $+opts[-x] )); then
+ print -r "Integer expected after -x: $opts[-x]" >&2
+ return 1
+fi
[[ $0 = fned ]] && fun=1
(( bind )) && okargs=0
@@ -80,10 +69,10 @@ fi
setopt localoptions nobanghist
if ((fun)) then
- var="$(functions $expand $1)"
+ var="$(functions $expand -- $1)"
# If function is undefined but autoloadable, load it
if [[ $var = *\#\ undefined* ]] then
- var="$(autoload +X $1; functions $1)"
+ var="$(autoload +X $1; functions -- $1)"
elif [[ -z $var ]] then
var="$1() {
}"
diff --git a/Functions/Misc/zrecompile b/Functions/Misc/zrecompile
index 8fe990086..d9fc55020 100644
--- a/Functions/Misc/zrecompile
+++ b/Functions/Misc/zrecompile
@@ -52,7 +52,7 @@ while getopts ":tqp" opt; do
fi
esac
done
-shift OPTIND-${#tmp:-1}
+shift OPTIND-${#tmp}-1
if [[ -n $check ]]; then
ret=1
diff --git a/Functions/TCP/tcp_open b/Functions/TCP/tcp_open
index 091217788..a04403c76 100644
--- a/Functions/TCP/tcp_open
+++ b/Functions/TCP/tcp_open
@@ -152,7 +152,7 @@ fi
if (( $# )); then
print "Usage: $0 [-z] [-a fd | -f fd | host port [ session ] ]
- $0 [-z] [ -s session | -l sesslist ] ..." >&2
+ $0 [-z] [ -s session | -l sesslist ] ..." >&2
return 1
fi
diff --git a/Functions/TCP/tcp_read b/Functions/TCP/tcp_read
index f880395dd..ba9185ed5 100644
--- a/Functions/TCP/tcp_read
+++ b/Functions/TCP/tcp_read
@@ -116,7 +116,7 @@ while getopts "abdl:qs:t:T:u:" opt; do
read_fds[$((read_fd))]=1
done
;;
- (*) [[ $opt != \? ]] && print Unhandled option, complain: $opt >&2
+ (*) [[ $opt != \? ]] && print "Unhandled option, complain: $opt" >&2
return 1
;;
esac
diff --git a/Functions/TCP/tcp_send b/Functions/TCP/tcp_send
index c976a2fb7..86dda6403 100644
--- a/Functions/TCP/tcp_send
+++ b/Functions/TCP/tcp_send
@@ -29,7 +29,7 @@ while getopts "acl:nqs:" opt; do
fi
sessions+=($OPTARG)
;;
- (*) [[ $opt != '?' ]] && print Unhandled option, complain: $opt >&2
+ (*) [[ $opt != '?' ]] && print "Unhandled option, complain: $opt" >&2
return 1
;;
esac
diff --git a/Functions/TCP/tcp_shoot b/Functions/TCP/tcp_shoot
index 8ff9866ba..c485c140a 100644
--- a/Functions/TCP/tcp_shoot
+++ b/Functions/TCP/tcp_shoot
@@ -4,8 +4,8 @@ setopt extendedglob
local REPLY tfd
if [[ $# -ne 2 ]]; then
- print "Usage: tcp_dump host port
-Connect to the given host and port; send standard input.">&2
+ print "Usage: $0 host port
+Connect to the given host and port; send standard input." >&2
return 1
fi
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
index 638ea4572..704c1890e 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
@@ -87,13 +87,18 @@ VCS_INFO_git_getbranch () {
gitbranch="$(${(z)gitsymref} 2> /dev/null)"
[[ -z ${gitbranch} ]] && [[ -r ${actiondir}/head-name ]] \
&& gitbranch="$(< ${actiondir}/head-name)"
+ [[ -z ${gitbranch} ]] && gitbranch="$(< ${gitdir}/ORIG_HEAD)"
elif [[ -f "${gitdir}/MERGE_HEAD" ]] ; then
gitbranch="$(${(z)gitsymref} 2> /dev/null)"
- [[ -z ${gitbranch} ]] && gitbranch="$(< ${gitdir}/MERGE_HEAD)"
+ [[ -z ${gitbranch} ]] && gitbranch="$(< ${gitdir}/ORIG_HEAD)"
elif [[ -d "${gitdir}/rebase-merge" ]] ; then
gitbranch="$(< ${gitdir}/rebase-merge/head-name)"
+ if [[ $gitbranch == 'detached HEAD' ]]; then
+ # get a sha1
+ gitbranch="$(< ${gitdir}/rebase-merge/orig-head)"
+ fi
elif [[ -d "${gitdir}/.dotest-merge" ]] ; then
gitbranch="$(< ${gitdir}/.dotest-merge/head-name)"
@@ -217,18 +222,32 @@ elif [[ -d "${gitdir}/rebase-merge" ]]; then
elif [[ -d "${gitdir}/rebase-apply" ]]; then
# Fake patch names for all but current patch
patchdir="${gitdir}/rebase-apply"
- local cur=$(< "${patchdir}/next")
- local p subject
- for p in $(seq $(($cur - 1))); do
- git_patches_applied+=("$(printf "%04d" $p) ?")
- done
- subject="${$(< "${patchdir}/msg-clean")[(f)1]}"
- if [[ -f "${patchdir}/original-commit" ]]; then
- git_patches_applied+=("$(< ${patchdir}/original-commit) $subject")
- else
- git_patches_applied+=("? $subject")
+ local next="${patchdir}/next"
+ if [[ -f $next ]]; then
+ local cur=$(< $next)
+ local p subject
+ for ((p = 1; p < cur; p++)); do
+ git_patches_applied+=("$(printf "%04d" $p) ?")
+ done
+ if [[ -f "${patchdir}/msg-clean" ]]; then
+ subject="${$(< "${patchdir}/msg-clean")[(f)1]}"
+ fi
+ if [[ -f "${patchdir}/original-commit" ]]; then
+ if [[ -n $subject ]]; then
+ git_patches_applied+=("$(< ${patchdir}/original-commit) $subject")
+ else
+ git_patches_applied+=("$(< ${patchdir}/original-commit)")
+ fi
+ else
+ if [[ -n $subject ]]; then
+ git_patches_applied+=("? $subject")
+ else
+ git_patches_applied+=("?")
+ fi
+ fi
+ local last="$(< "${patchdir}/last")"
+ git_patches_unapplied=( {$cur..$last} )
fi
- git_patches_unapplied=($(seq $cur $(< "${patchdir}/last")))
VCS_INFO_git_handle_patches
elif [[ -f "${gitdir}/MERGE_HEAD" ]]; then
@@ -248,6 +267,28 @@ elif [[ -f "${gitdir}/MERGE_HEAD" ]]; then
# Not touching git_patches_unapplied
VCS_INFO_git_handle_patches
+elif [[ -f "${gitdir}/CHERRY_PICK_HEAD" ]]; then
+ # 'git cherry-pick' without -n, that conflicted. (With -n, git doesn't
+ # record the CHERRY_PICK_HEAD information anywhere, as of git 2.6.2.)
+ #
+ # ### 'git cherry-pick foo bar baz' only records the "remaining" part of
+ # ### the queue in the .git dir: if 'bar' has a conflict, the .git dir
+ # ### has a record of 'baz' being queued, but no record of 'foo' having been
+ # ### part of the queue as well. Therefore, the %n/%c applied/unapplied
+ # ### expandos will be memoryless: the "applied" counter will always
+ # ### be "1". The %u/%c tuple will assume the values [(1,2), (1,1), (1,0)],
+ # ### whereas the correct sequence would be [(1,2), (2,1), (3,0)].
+ local subject
+ IFS='' read -r subject < "${gitdir}/MERGE_MSG"
+ git_patches_applied=( "$(<${gitdir}/CHERRY_PICK_HEAD) ${subject}" )
+ if [[ -f "${gitdir}/sequencer/todo" ]]; then
+ # Get the next patches, and remove the one that's in CHERRY_PICK_HEAD.
+ git_patches_unapplied=( ${${(M)${(f)"$(<"${gitdir}/sequencer/todo")"}:#pick *}#pick } )
+ git_patches_unapplied[1]=()
+ else
+ git_patches_unapplied=()
+ fi
+ VCS_INFO_git_handle_patches
else
gitmisc=''
fi
diff --git a/Functions/VCS_Info/VCS_INFO_quilt b/Functions/VCS_Info/VCS_INFO_quilt
index bc71cfb7d..c3c3d864d 100644
--- a/Functions/VCS_Info/VCS_INFO_quilt
+++ b/Functions/VCS_Info/VCS_INFO_quilt
@@ -119,6 +119,7 @@ function VCS_INFO_quilt() {
applied=()
fi
patches=$(<$pc/.quilt_patches)
+ patches=`builtin cd -q "${pc:h}" && print -r - ${patches:A}`
fi
if zstyle -t "${context}" get-unapplied; then
# This zstyle call needs to be moved further up if `quilt' needs
@@ -144,6 +145,36 @@ function VCS_INFO_quilt() {
unapplied=()
fi
+ if [[ -n $patches ]]; then
+ () {
+ local i line
+ for ((i=1; i<=$#applied; i++)); do
+ if [[ -f "$patches/$applied[$i]" ]] &&
+ read -r line < "$patches/$applied[$i]" &&
+ [[ $line != (#b)(---|Index:)* ]] &&
+ true
+ ;
+ then
+ applied[$i]+=" $line"
+ else
+ applied[$i]+=" ?"
+ fi
+ done
+ for ((i=1; i<=$#unapplied; i++)); do
+ if [[ -f "$patches/$unapplied[$i]" ]] &&
+ read -r line < "$patches/$unapplied[$i]" &&
+ [[ $line != (#b)(---|Index:)* ]] &&
+ true
+ ;
+ then
+ unapplied[$i]+=" $line"
+ else
+ unapplied[$i]+=" ?"
+ fi
+ done
+ }
+ fi
+
all=( ${(Oa)applied} ${unapplied} )
if VCS_INFO_hook 'gen-applied-string' "${applied[@]}"; then
diff --git a/Functions/VCS_Info/vcs_info b/Functions/VCS_Info/vcs_info
index 350b189e9..628dde9b1 100644
--- a/Functions/VCS_Info/vcs_info
+++ b/Functions/VCS_Info/vcs_info
@@ -11,6 +11,7 @@
setopt localoptions noksharrays extendedglob NO_shwordsplit
local file func sys
local -a static_functions
+local -i maxexports
static_functions=(
VCS_INFO_adjust
@@ -38,6 +39,7 @@ for func in ${static_functions} ; do
done
[[ -n ${(Mk)parameters:#vcs_info_msg_<->_} ]] && unset ${parameters[(I)vcs_info_msg_<->_]}
+VCS_INFO_maxexports
VCS_INFO_set --nvcs '-preinit-'
vcs_info_setsys
diff --git a/Functions/Zle/bracketed-paste-magic b/Functions/Zle/bracketed-paste-magic
index 464c6b339..2b2bc630d 100644
--- a/Functions/Zle/bracketed-paste-magic
+++ b/Functions/Zle/bracketed-paste-magic
@@ -116,10 +116,14 @@ quote-paste() {
# Now the actual function
bracketed-paste-magic() {
- # Fast exit in the vi-mode cut-buffer context
if [[ "$LASTWIDGET" = *vi-set-buffer ]]; then
+ # Fast exit in the vi-mode cut-buffer context
zle .bracketed-paste
return
+ else
+ # Capture the pasted text in $PASTED
+ local PASTED REPLY
+ zle .bracketed-paste PASTED
fi
# Really necessary to go to this much effort?
@@ -127,10 +131,9 @@ bracketed-paste-magic() {
emulate -L zsh
local -a bpm_hooks bpm_inactive
- local PASTED bpm_func bpm_active bpm_keymap=$KEYMAP
+ local bpm_func bpm_active bpm_keymap=$KEYMAP
- # Set PASTED and run the paste-init functions
- zle .bracketed-paste PASTED
+ # Run the paste-init functions
if zstyle -a :bracketed-paste-magic paste-init bpm_hooks; then
for bpm_func in $bpm_hooks; do
if (( $+functions[$bpm_func] )); then
@@ -164,25 +167,17 @@ bracketed-paste-magic() {
integer bpm_limit=$UNDO_LIMIT_NO bpm_undo=$UNDO_CHANGE_NO
UNDO_LIMIT_NO=$UNDO_CHANGE_NO
- local mbchar
- integer ismb
while [[ -n $PASTED ]] && zle .read-command; do
- mbchar=$KEYS
- ismb=0
- while [[ $mbchar = [[:INCOMPLETE:]]* ]] && zle .read-command; do
- mbchar+=$KEYS
- ismb=1
- done
- PASTED=${PASTED#$mbchar}
- if [[ ismb -ne 0 || $mbchar = ${(~j:|:)${(b)bpm_inactive}} ]]; then
- LBUFFER+=$mbchar
+ PASTED=${PASTED#$KEYS}
+ if [[ $KEYS = ${(~j:|:)${(b)bpm_inactive}} ]]; then
+ zle .self-insert
else
case $REPLY in
(${~bpm_active}) function () {
emulate -L $bpm_emulate; set -$bpm_opts
zle $REPLY
};;
- (*) LBUFFER+=$mbchar;
+ (*) zle .self-insert;;
esac
fi
done
@@ -221,7 +216,7 @@ bracketed-paste-magic() {
zle .split-undo
# Arrange to display highlighting if necessary
- if [[ -n ${(M)zle_highlight:#paste:*} ]]; then
+ if [[ -z $zle_highlight || -n ${(M)zle_highlight:#paste:*} ]]; then
zle -R
zle .read-command && zle -U - $KEYS
fi
diff --git a/Functions/Zle/bracketed-paste-url-magic b/Functions/Zle/bracketed-paste-url-magic
new file mode 100644
index 000000000..06dee2657
--- /dev/null
+++ b/Functions/Zle/bracketed-paste-url-magic
@@ -0,0 +1,44 @@
+# bracketed-paste-url-magic quotes pasted urls automatically, if the
+# paste exactly starts with a url, eg no spaces or other characters precede it
+#
+# If the numeric argument is provided (eg, pressing alt-0 or alt-1 in emacs mode,
+# or just the number by itself in vi command mode), then
+# 0 is the default and means auto detect urls
+# 1 means always quote
+# any other value means never quote
+#
+# To use this widget, put this in your startup files (eg, .zshrc)
+#
+# autoload -Uz bracketed-paste-url-magic
+# zle -N bracketed-paste bracketed-paste-url-magic
+#
+# You can customize which schemas are to be quoted by using
+#
+# zstyle :bracketed-paste-url-magic schema http https ftp
+#
+# The default can be seen just below.
+
+local -a schema
+zstyle -a :bracketed-paste-url-magic schema schema || schema=(http https ftp ftps file ssh sftp)
+
+local wantquote=${NUMERIC:-0}
+local content
+local start=$#LBUFFER
+
+zle .$WIDGET -N content
+
+if (( $wantquote == 0 )); then
+ if [[ $content = (${(~j:|:)schema})://* ]]; then
+ wantquote=1
+ fi
+fi
+
+if (( $wantquote == 1 )); then
+ content=${(q-)content}
+fi
+
+LBUFFER+=$content
+
+YANK_START=$start
+YANK_END=$#LBUFFER
+zle -f yank
diff --git a/Functions/Zle/edit-command-line b/Functions/Zle/edit-command-line
index 2c7f34b8b..103a1c1a5 100644
--- a/Functions/Zle/edit-command-line
+++ b/Functions/Zle/edit-command-line
@@ -11,13 +11,16 @@
# 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})";;
+ (*vim*)
+ integer byteoffset=$(( $#PREBUFFER + $#LBUFFER + 1 ))
+ ${=editor} -c "normal! ${byteoffset}go" -- $1;;
+ (*emacs*)
+ local lines=( ${(f):-"$PREBUFFER$LBUFFER"} )
+ ${=editor} +${#lines}:$((${#lines[-1]} + 1)) $1;;
(*) ${=editor} $1;;
esac
diff --git a/Functions/Zle/match-word-context b/Functions/Zle/match-word-context
index 7f1154498..8793483f4 100644
--- a/Functions/Zle/match-word-context
+++ b/Functions/Zle/match-word-context
@@ -7,7 +7,7 @@ setopt extendedglob
local -a worcon bufwords
local pat tag lastword word backword forword
-integer iword
+integer iword between
zstyle -a $curcontext word-context worcon || return 0
@@ -25,13 +25,18 @@ if [[ $lastword = ${bufwords[iword]} ]]; then
# If the word immediately left of the cursor is complete,
# we're not on it for forward operations.
forword=${bufwords[iword+1]}
+ # If, furthermore, we're on whitespace, then we're between words.
+ # It can't be significant whitespace because the previous word is complete.
+ [[ $RBUFFER[1] = [[:space:]] ]] && between=1
else
# We're on a word.
forword=${bufwords[iword]}
fi
backword=${bufwords[iword]}
-if [[ $curcontext = *back* ]]; then
+if [[ between -ne 0 && $curcontext = *between* ]]; then
+ word=' '
+elif [[ $curcontext = *back* ]]; then
word=$backword
else
word=$forword
diff --git a/Functions/Zle/smart-insert-last-word b/Functions/Zle/smart-insert-last-word
index 67adea760..cf8715dfe 100644
--- a/Functions/Zle/smart-insert-last-word
+++ b/Functions/Zle/smart-insert-last-word
@@ -60,7 +60,7 @@ then
lcursor=$_ilw_lcursor
else
NUMERIC=1
- _ilw_lcursor=$lcursor
+ typeset -g _ilw_lcursor=$lcursor
fi
# Handle the up to three arguments of .insert-last-word
if (( $+1 ))
@@ -73,8 +73,8 @@ then
(( NUMERIC )) || LBUFFER[lcursor+1,cursor+1]=''
numeric=$((-(${2:--numeric})))
fi
-_ilw_hist=$HISTNO
-_ilw_count=$NUMERIC
+typeset -g _ilw_hist=$HISTNO
+typeset -g _ilw_count=$NUMERIC
if [[ -z "$numeric" ]]
then
@@ -119,7 +119,7 @@ fi
(( NUMERIC > $#lastcmd )) && return 1
LBUFFER[lcursor+1,cursor+1]=$lastcmd[-NUMERIC]
-_ilw_cursor=$CURSOR
+typeset -g _ilw_cursor=$CURSOR
# This is necessary to update UNDO_CHANGE_NO immediately
-zle split-undo && _ilw_changeno=$UNDO_CHANGE_NO
+zle split-undo && typeset -g _ilw_changeno=$UNDO_CHANGE_NO