From f96a0167289d41d583b01b17482bba0641be2805 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Sun, 14 Feb 2016 14:37:53 +0000 Subject: users/21256 + workers/37965: New math functions min(), max(), sum(), provided by a new autoloadable function 'zmathfunc'. --- Doc/Zsh/contrib.yo | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'Doc/Zsh/contrib.yo') diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 07a5eb08e..f8754fbcc 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -3796,6 +3796,23 @@ enditem() See the comments in the function for a few extra tips. ) +findex(max) +findex(min) +findex(sum) +findex(zmathfunc) +xitem(tt(min+LPAR())var(arg)tt(, ...+RPAR())) +xitem(tt(max+LPAR())var(arg)tt(, ...+RPAR())) +xitem(tt(sum+LPAR())var(arg)tt(, ...+RPAR())) +item(tt(zmathfunc))( +The function tt(zmathfunc) defines the three mathematical functions +tt(min), tt(max), and tt(sum). The functions tt(min) and tt(max) take +one or more arguments. The function tt(sum) takes zero or more arguments. +Arguments can be of different types (ints and floats). + +Not to be confused with the tt(zsh/mathfunc) module, described in +ifzman(the section `The zsh/mathfunc Module' in zmanref(zshmodules))\ +ifnzman(noderef(The zsh/mathfunc Module)). +) findex(zmathfuncdef) item(tt(zmathfuncdef) [ var(mathfunc) [ var(body) ] ])( A convenient front end to tt(functions -M). -- cgit v1.2.3 From 43e595712ce29e402bf11b27ef4262229f21bbdb Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Fri, 18 Mar 2016 21:22:58 +0000 Subject: unposted: Document run-help-* helper functions. --- ChangeLog | 5 +++++ Doc/Zsh/contrib.yo | 23 ++++++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) (limited to 'Doc/Zsh/contrib.yo') diff --git a/ChangeLog b/ChangeLog index ba4e49f1d..169fcce9b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2016-03-18 Daniel Shahaf + + * unposted: Doc/Zsh/contrib.yo: Document run-help-* helper + functions. + 2016-03-18 Mikael Magnusson * 38179: Completion/Unix/Command/_adb: Fix completion by mostly diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index f8754fbcc..923bb29a9 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -4047,12 +4047,29 @@ your search path, in order to be found and used by tt(run-help). startitem() findex(run-help-git) +findex(run-help-ip) +findex(run-help-openssl) +findex(run-help-p4) +findex(run-help-sudo) findex(run-help-svk) findex(run-help-svn) -xitem(tt(run-help-git)) -xitem(tt(run-help-svk)) +xitem(run-help-git) +xitem(run-help-ip) +xitem(run-help-openssl) +xitem(run-help-p4) +xitem(run-help-sudo) +xitem(run-help-svk) item(tt(run-help-svn))( -Assistant functions for the tt(git), tt(svk), and tt(svn) commands. +Assistant functions for the +tt(git), +tt(ip), +tt(openssl), +tt(p4), +tt(sudo), +tt(svk), +and +tt(svn), +commands. ) enditem() ) -- cgit v1.2.3 From 8e2ec4517fcce11475d579abb827d851f858d9aa Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Sun, 12 Jun 2016 18:50:10 -0700 Subject: 38670: New function for managing ZLE special widgets, modeled after Functions/Misc/add-zsh-hook. --- ChangeLog | 6 ++ Doc/Zsh/contrib.yo | 56 ++++++++++++++- Functions/Zle/add-zle-hook-widget | 140 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 Functions/Zle/add-zle-hook-widget (limited to 'Doc/Zsh/contrib.yo') diff --git a/ChangeLog b/ChangeLog index 8c8a08948..8952bd009 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2016-06-12 Barton E. Schaefer + + * 38670: Doc/Zsh/contrib.yo, Functions/Zle/add-zle-hook-widget: + New function for managing ZLE special widgets, modeled after + Functions/Misc/add-zsh-hook. + 2016-06-09 Oliver Kiddle * 38579: Functions/Zle/bracketed-paste-magic: simplify saving diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 923bb29a9..dd643a140 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -292,11 +292,11 @@ cindex(hook function utility) startitem() findex(add-zsh-hook) -item(tt(add-zsh-hook) [ tt(-dD) ] [ tt(-Uzk) ] var(hook) var(function))( +item(tt(add-zsh-hook) [ tt(-L) | tt(-dD) ] [ tt(-Uzk) ] var(hook) var(function))( Several functions are special to the shell, as described in the section ifnzman(Special Functions, noderef(Functions))\ ifzman(SPECIAL FUNCTIONS, see zmanref(zshmisc)), -in that they are automatic called at a specific point during shell execution. +in that they are automatically called at specific points during shell execution. Each has an associated array consisting of names of functions to be called at the same point; these are so-called `hook functions'. The shell function tt(add-zsh-hook) provides a simple way of adding or @@ -312,6 +312,9 @@ var(function) is name of an ordinary shell function. If no options are given this will be added to the array of functions to be executed in the given context. +If the option tt(-L) is given, the current values for the hook arrays +are listed with tt(typeset). + If the option tt(-d) is given, the var(function) is removed from the array of functions to be executed. @@ -323,6 +326,55 @@ The options tt(-U), tt(-z) and tt(-k) are passed as arguments to tt(autoload) for var(function). For functions contributed with zsh, the options tt(-Uz) are appropriate. ) +findex(add-zle-hook-widget) +item(tt(add-zle-hook-widget) [ tt(-L) | tt(-dD) ] [ tt(-Uzk) ] var(hook) var(widgetname))( +Several widget names are special to the line editor, as described in the section +ifnzman(Special Widgets, noderef(Zle Widgets))\ +ifzman(Special Widgets, see zmanref(zshzle)), +in that they are automatically called at specific points during editing. +Unlike function hooks, these do not use a predefined array of other names +to call at the same point; the shell function tt(add-zle-hook-widget) +maintains a similar array and arranges for the special widget to invoke +those additional widgets. + +var(hook) is one of tt(isearch-exit), tt(isearch-update), +tt(line-pre-redraw), tt(line-init), tt(line-finish), tt(history-line-set), +or tt(keymap-select), corresponding to each of the special widgets +tt(zle-isearch-exit), etc. + +var(widgetname) is the name of a ZLE widget. If no options are given this +is added to the array of widgets to be invoked in the given hook context. +Note that the hooks are called as widgets, that is, with +`tt(zle var(widgetname) -Nw)' rather than as a function call. + +The arrays of var(widgetname) are maintained in several tt(zstyle) +contexts, one for each var(hook) context, with a style of `tt(widgets)'. +If the tt(-L) option is given, this set of styles is listed with +`tt(zstyle -L)'. These styles may be updated directly with tt(zstyle) +commands, but the special widgets that refer to the styles are created +only if tt(add-zle-hook-widget) is called to add at least one widget. + +If the option tt(-d) is given, the var(widgename) is removed from +the array of widgets to be executed. + +If the option tt(-D) is given, the var(widgetname) is treated as a pattern +and any matching names of widgets are removed from the array. + +If var(widgetname) does not name an existing widget when added to the +array, it is assumed that a shell function also named var(widgetname) is +meant to provide the implementation of the widget. This name is therefore +marked for autoloading, and the options tt(-U), tt(-z) and tt(-k) are +passed as arguments to tt(autoload) as with tt(add-zsh-hook). The +widget is also created with `tt(zle -N var(widgetname))' to cause the +corresponding function to be loaded the first time the hook is called. + +In addition, var(widgetname) may be of the form var(index)tt(:)var(name). +In this case var(index) is an integer which determines the order in +which the widget var(name) will be called relative to other widgets in +the array. Widgets having the same var(index) are called in unspecified +order, and all widgets declared with an index are called before any +widgets that have no index. +) enditem() texinode(Recent Directories)(Other Directory Functions)(Utilities)(User Contributions) diff --git a/Functions/Zle/add-zle-hook-widget b/Functions/Zle/add-zle-hook-widget new file mode 100644 index 000000000..eeb0191f0 --- /dev/null +++ b/Functions/Zle/add-zle-hook-widget @@ -0,0 +1,140 @@ +# Add to HOOK the given WIDGET +# +# HOOK is one of isearch-exit, isearch-update, line-pre-redraw, line-init, +# line-finish, history-line-set, keymap-select (the zle- prefix is not +# required). +# +# WIDGET may be of the form INDEX:NAME in which case the INDEX determines +# the order in which the widget executes relative to other hook widgets. +# +# With -d, remove the widget from the hook instead; delete the hook +# variable if it is empty. +# +# -D behaves like -d, but pattern characters are active in the +# widget name, so any matching widget will be deleted from the hook. +# +# Without -d, if the WIDGET is not already defined, a function having the +# same name is marked for autoload; -U is passed down to autoload if that +# is given, as are -z and -k. (This is harmless if the function is +# already defined.) The WIDGET is then created with zle -N. + +emulate -L zsh + +# Setup - create the base functions for hook widgets that call the others + +zmodload zsh/parameter || { + print -u2 "Need parameter module for zle hooks" + return 1 +} + +local -a hooktypes=( isearch-exit isearch-update + line-pre-redraw line-init line-finish + history-line-set keymap-select ) +# Stash in zstyle to make it global +zstyle zle-hook types $hooktypes + +for hook in $hooktypes +do + function zle-$hook { + local -a hook_widgets + local hook + # Values of these styles look like number:name + # and we run them in number order + # $funcstack is more reliable than $0 + # Also, ksh_arrays is annoying + emulate zsh -c 'zstyle -a $funcstack[2] widgets hook_widgets' + for hook in "${@${(@on)hook_widgets}#*:}" + do + zle "$hook" -Nw || return + done + return 0 + } +done + +# Redefine ourself with the setup left out + +function add-zle-hook-widget { + local -a hooktypes + zstyle -a zle-hook types hooktypes + + # This part copied from add-zsh-hook + local usage="Usage: $0 hook widgetname\nValid hooks are:\n $hooktypes" + + local opt + local -a autoopts + integer del list help + + while getopts "dDhLUzk" opt; do + case $opt in + (d) + del=1 + ;; + + (D) + del=2 + ;; + + (h) + help=1 + ;; + + (L) + list=1 + ;; + + ([Uzk]) + autoopts+=(-$opt) + ;; + + (*) + return 1 + ;; + esac + done + shift $(( OPTIND - 1 )) + + if (( list )); then + zstyle -L "zle-(${1:-${(@j:|:)hooktypes}})" widgets + return $? + elif (( help || $# != 2 || ${hooktypes[(I)${1#zle-}]} == 0 )); then + print -u$(( 2 - help )) $usage + return $(( 1 - help )) + fi + + local -aU extant_hooks + local hook="zle-${1#zle-}" + local fn="$2" + + if (( del )); then + # delete, if hook is set + if zstyle -g extant_hooks "$hook" widgets; then + if (( del == 2 )); then + set -A extant_hooks ${extant_hooks:#(<->:|)${~fn}} + else + set -A extant_hooks ${extant_hooks:#(<->:|)$fn} + fi + # unset if no remaining entries + if (( ${#extant_hooks} )); then + zstyle "$hook" widgets "${extant_hooks[@]}" + else + zstyle -d "$hook" widgets + fi + fi + else + zstyle -g extant_hooks "$hook" widgets + extant_hooks+=("$fn") + zstyle -- "$hook" widgets "${extant_hooks[@]}" + if [[ -z "${widgets[$fn]}" ]]; then + autoload "${autoopts[@]}" -- "$fn" + zle -N "$fn" + fi + if [[ -z "${widgets[$hook]}" ]]; then + zle -N "$hook" + fi + fi +} + +# Handle zsh autoloading conventions +if [[ "$zsh_eval_context" = *loadautofunc && ! -o kshautoload ]]; then + add-zle-hook-widget "$@" +fi -- cgit v1.2.3 From 944ab1a7aae3fc4d8517e3c97acc4e292db1cb6a Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Thu, 16 Jun 2016 08:48:12 +0900 Subject: 38684: fix format in contrib.yo --- ChangeLog | 4 ++++ Doc/Zsh/contrib.yo | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'Doc/Zsh/contrib.yo') diff --git a/ChangeLog b/ChangeLog index 83f346520..c03be8c4c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2016-06-16 Jun-ichi Takimoto + + * 38684: Doc/Zsh/contrib.yo: fix format + 2016-06-14 Eric Cook * 38676: Marko Myllynen: Completion/Linux/Command/_pidof: diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index dd643a140..2164c04c9 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -345,7 +345,7 @@ tt(zle-isearch-exit), etc. var(widgetname) is the name of a ZLE widget. If no options are given this is added to the array of widgets to be invoked in the given hook context. Note that the hooks are called as widgets, that is, with -`tt(zle var(widgetname) -Nw)' rather than as a function call. +`tt(zle )var(widgetname)tt( -Nw)' rather than as a function call. The arrays of var(widgetname) are maintained in several tt(zstyle) contexts, one for each var(hook) context, with a style of `tt(widgets)'. @@ -365,7 +365,7 @@ array, it is assumed that a shell function also named var(widgetname) is meant to provide the implementation of the widget. This name is therefore marked for autoloading, and the options tt(-U), tt(-z) and tt(-k) are passed as arguments to tt(autoload) as with tt(add-zsh-hook). The -widget is also created with `tt(zle -N var(widgetname))' to cause the +widget is also created with `tt(zle -N )var(widgetname)' to cause the corresponding function to be loaded the first time the hook is called. In addition, var(widgetname) may be of the form var(index)tt(:)var(name). @@ -2146,7 +2146,7 @@ tt(match-word-context). This should not usually need to be called directly. ) tindex(bracketed-paste-magic) -item(bracketed-paste-magic)( +item(tt(bracketed-paste-magic))( The tt(bracketed-paste) widget (see ifzman(subsection Miscellaneous in zmanref(zshzle))ifnzman(noderef(Miscellaneous) in noderef(Zle Widgets))) inserts pasted text literally into the editor buffer rather than interpret -- cgit v1.2.3 From 4cacf1624f0393c43a9a2c3259957b8d78eb7609 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 16 Jun 2016 11:39:42 +0100 Subject: 38693: Add RPN mode to zcalc --- ChangeLog | 3 + Doc/Zsh/contrib.yo | 42 ++++++++++++- Functions/Misc/zcalc | 136 +++++++++++++++++++++++++++++++++------- Functions/Zle/zcalc-auto-insert | 3 +- 4 files changed, 160 insertions(+), 24 deletions(-) (limited to 'Doc/Zsh/contrib.yo') diff --git a/ChangeLog b/ChangeLog index b567cf6f0..2ac9ceb63 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2016-06-16 Peter Stephenson + * 38693: Doc/Zsh/contrib.yo, Functions/Misc/zcalc, + Functions/Zle/zcalc-auto-insert: Add RPN mode to zcalc. + * unposted: Doc/Zsh/params.yo: fix parentheses for getrusage(). 2016-06-16 Jun-ichi Takimoto diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 2164c04c9..64d93f9dc 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -2993,6 +2993,9 @@ the variable tt(ZCALC_AUTO_INSERT_PREFIX). Hence, for example, typing `tt(PLUS()12)' followed by return adds 12 to the previous result. +If zcalc is in RPN mode (tt(-r) option) the effect of this binding is +automatically suppressed as operators alone on a line are meaningful. + When not in zcalc, the key simply inserts the symbol itself. ) enditem() @@ -3706,7 +3709,7 @@ sect(Mathematical Functions) startitem() findex(zcalc) -item(tt(zcalc) [ tt(-ef) ] [ var(expression) ... ])( +item(tt(zcalc) [ tt(-erf) ] [ var(expression) ... ])( A reasonably powerful calculator based on zsh's arithmetic evaluation facility. The syntax is similar to that of formulae in most programming languages; see @@ -3772,6 +3775,39 @@ If the option `tt(-f)' is set, all numbers are treated as floating point, hence for example the expression `tt(3/4)' evaluates to 0.75 rather than 0. Options must appear in separate words. +If the option `tt(-r)' is set, RPN (Reverse Polish Notation) mode is +entered. This has various additional properties: +startitem() +item(Stack)( +Evaluated values are maintained in a stack; this is contained in +an array named tt(stack) with the most recent value in tt(${stack[1]}). +) +item(Operators and functions)( +If the line entered matches an operator (tt(+), tt(-), tt(*), +tt(/), tt(**), tt(^), tt(|) or tt(&)) or a function supplied by the +tt(zsh/mathfunc) library, the bottom element or elements of the stack +are popped to use as the argument or arguments. The higher elements +of stack (least recent) are used as earlier arguments. The result is +then pushed into tt(${stack[1]}). +) +item(Expressions)( +Other expressions are evaluated normally, printed, and added to the +stack as numeric values. The syntax within expressions on a single line +is normal shell arithmetic (not RPN). +) +item(Stack listing)( +If an integer follows the option tt(-r) with no space, then +on every evaluation that many elements of the stack, where available, +are printed instead of just the most recent result. Hence, for example, +tt(zcalc -r4) shows tt($stack[4]) to tt($stack[1]) each time results +are printed. +) +item(Duplication)( +The pseudo-operator tt(=) causes the most recent element of +the stack to be duplicated onto the stack. +) +enditem() + The prompt is configurable via the parameter tt(ZCALCPROMPT), which undergoes standard prompt expansion. The index of the current entry is stored locally in the first element of the array tt(psvar), which can be @@ -3844,6 +3880,10 @@ always specified in decimal. `tt([#])' restores the normal output format. Note that setting an output base suppresses floating point output; use `tt([#])' to return to normal operation. ) +item(tt($)var(var))( +Print out the value of var literally; does not affect the calculation. +To use the value of var, omit the leading `tt($)'. +) enditem() See the comments in the function for a few extra tips. diff --git a/Functions/Misc/zcalc b/Functions/Misc/zcalc index 857007a94..eb240b2ec 100644 --- a/Functions/Misc/zcalc +++ b/Functions/Misc/zcalc @@ -96,6 +96,20 @@ emulate -L zsh setopt extendedglob +zcalc_show_value() { + if [[ -n $base ]]; then + print -- $(( $base $1 )) + elif [[ $1 = *.* ]] || (( outdigits )); then + if [[ -z $forms[outform] ]]; then + print -- $(( $1 )) + else + printf "$forms[outform]\n" $outdigits $1 + fi + else + printf "%d\n" $1 + fi +} + # For testing in ZLE functions. local ZCALC_ACTIVE=1 @@ -103,15 +117,20 @@ local ZCALC_ACTIVE=1 # begin with _. local line ans base defbase forms match mbegin mend psvar optlist opt arg local compcontext="-zcalc-line-" -integer num outdigits outform=1 expression_mode -local -a expressions +integer num outdigits outform=1 expression_mode rpn_mode matched show_stack i +integer max_stack +local -a expressions stack match mbegin mend # We use our own history file with an automatic pop on exit. history -ap "${ZDOTDIR:-$HOME}/.zcalc_history" forms=( '%2$g' '%.*g' '%.*f' '%.*E' '') -zmodload -i zsh/mathfunc 2>/dev/null +local mathfuncs +if zmodload -i zsh/mathfunc 2>/dev/null; then + zmodload -P mathfuncs -FL zsh/mathfunc + mathfuncs="("${(j.|.)${mathfuncs##f:}}")" +fi autoload -Uz zmathfuncdef if (( ! ${+ZCALCPROMPT} )); then @@ -127,7 +146,7 @@ if [[ -f "${ZDOTDIR:-$HOME}/.zcalcrc" ]]; then fi # Process command line -while [[ -n $1 && $1 = -(|[#-]*|f|e) ]]; do +while [[ -n $1 && $1 = -(|[#-]*|f|e|r(<->|)) ]]; do optlist=${1[2,-1]} shift [[ $optlist = (|-) ]] && break @@ -158,6 +177,14 @@ while [[ -n $1 && $1 = -(|[#-]*|f|e) ]]; do (e) # Arguments are expressions (( expression_mode = 1 )); ;; + (r) # RPN mode. + (( rpn_mode = 1 )) + ZCALC_ACTIVE=rpn + if [[ $optlist = (#b)(<->)* ]]; then + (( show_stack = ${match[1]} )) + optlist=${optlist[${#match[1]}+1,-2]} + fi + ;; esac done done @@ -281,30 +308,95 @@ while (( expression_mode )) || continue ;; + (\$[[:IDENT:]]##) + # Display only, no calculation + line=${line##\$} + print -r -- ${(P)line} + line= + continue + ;; + (*) - # Latest value is stored as a string, because it might be floating - # point or integer --- we don't know till after the evaluation, and - # arrays always store scalars anyway. - # - # Since it's a string, we'd better make sure we know which - # base it's in, so don't change that until we actually print it. - eval "ans=\$(( $line ))" - # on error $ans is not set; let user re-edit line - [[ -n $ans ]] || continue + line=${${line##[[:blank:]]##}%%[[:blank:]]##} + if (( rpn_mode )); then + matched=1 + case $line in + (=) + if (( ${#stack} < 1 )); then + print -r -- "${line}: not enough values on stack" >&2 + line= + continue + fi + ans=${stack[1]} + ;; + + (+|-|\^|\||\&|\*|\*\*|/) + # Operators with two arguments + if (( ${#stack} < 2 )); then + print -r -- "${line}: not enough values on stack" >&2 + line= + continue + fi + eval "(( ans = \${stack[2]} $line \${stack[1]} ))" + shift 2 stack + ;; + + (ldexp|jn|yn|scalb) + # Functions with two arguments + if (( ${#stack} < 2 )); then + print -r -- "${line}: not enough values on stack" >&2 + line= + continue + fi + eval "(( ans = ${line}(\${stack[2]},\${stack[1]}) ))" + shift 2 stack + ;; + + (${~mathfuncs}) + # Functions with a single argument. + # This is actually a superset, but we should have matched + # any that shouldn't be in it in previous cases. + if (( ${#stack} < 1 )); then + print -r -- "${line}: not enough values on stack" >&2 + line= + continue + fi + eval "(( ans = ${line}(\${stack[1]}) ))" + shift stack + ;; + + (*) + # Treat as expression evaluating to new value to go on stack. + matched=0 + ;; + esac + else + matched=0 + fi + if (( ! matched )); then + # Latest value is stored` as a string, because it might be floating + # point or integer --- we don't know till after the evaluation, and + # arrays always store scalars anyway. + # + # Since it's a string, we'd better make sure we know which + # base it's in, so don't change that until we actually print it. + eval "ans=\$(( $line ))" + # on error $ans is not set; let user re-edit line + [[ -n $ans ]] || continue + fi argv[num++]=$ans psvar[1]=$num + stack=($ans $stack) ;; esac - if [[ -n $base ]]; then - print -- $(( $base $ans )) - elif [[ $ans = *.* ]] || (( outdigits )); then - if [[ -z $forms[outform] ]]; then - print -- $(( $ans )) - else - printf "$forms[outform]\n" $outdigits $ans - fi + if (( show_stack )); then + (( max_stack = (show_stack > ${#stack}) ? ${#stack} : show_stack )) + for (( i = max_stack; i > 0; i-- )); do + printf "%3d: " $i + zcalc_show_value ${stack[i]} + done else - printf "%d\n" $ans + zcalc_show_value $ans fi line= done diff --git a/Functions/Zle/zcalc-auto-insert b/Functions/Zle/zcalc-auto-insert index c9a5c8867..e1affd1c3 100644 --- a/Functions/Zle/zcalc-auto-insert +++ b/Functions/Zle/zcalc-auto-insert @@ -1,6 +1,7 @@ # Bind to a binary operator keystroke for use with zcalc +# Not useful in RPN mode. -if [[ -n $ZCALC_ACTIVE ]]; then +if [[ -n $ZCALC_ACTIVE && $ZCALC_ACTIVE != rpn ]]; then if [[ $CURSOR -eq 0 || $LBUFFER[-1] = "(" ]]; then LBUFFER+=${ZCALC_AUTO_INSERT_PREFIX:-"ans "} fi -- cgit v1.2.3 From 0b8ab3a21a15c12b22f39cd19ce5ef90fdc31ad1 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Sun, 19 Jun 2016 19:50:37 -0700 Subject: 38715: add-zle-hook-widget: assorted ksharrays fixes; assign an index to any hook that is added without one, to preserve append ordering --- ChangeLog | 6 ++++ Doc/Zsh/contrib.yo | 30 +++++++++-------- Functions/Zle/add-zle-hook-widget | 69 ++++++++++++++++++++++++++------------- 3 files changed, 69 insertions(+), 36 deletions(-) (limited to 'Doc/Zsh/contrib.yo') diff --git a/ChangeLog b/ChangeLog index cc547e5fc..52a655069 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2016-06-19 Barton E. Schaefer + + * 38715: Doc/Zsh/contrib.yo, Functions/Zle/add-zle-hook-widget: + assorted ksharrays fixes; assign an index to any hook that is + added without one, to preserve append ordering + 2016-06-18 Barton E. Schaefer * unposted: Functions/Misc/zed: localoptions noksharrays diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 64d93f9dc..b9c1c0a80 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -345,14 +345,16 @@ tt(zle-isearch-exit), etc. var(widgetname) is the name of a ZLE widget. If no options are given this is added to the array of widgets to be invoked in the given hook context. Note that the hooks are called as widgets, that is, with -`tt(zle )var(widgetname)tt( -Nw)' rather than as a function call. +example(tt(zle )var(widgetname)tt( -Nw "$@")) +rather than as a function call. -The arrays of var(widgetname) are maintained in several tt(zstyle) -contexts, one for each var(hook) context, with a style of `tt(widgets)'. -If the tt(-L) option is given, this set of styles is listed with -`tt(zstyle -L)'. These styles may be updated directly with tt(zstyle) -commands, but the special widgets that refer to the styles are created -only if tt(add-zle-hook-widget) is called to add at least one widget. +In typical usage, var(widgetname) has the form var(index)tt(:)var(name). +In this case var(index) is an integer which determines the order in which +the widget var(name) will be called relative to other widgets in the +array. Widgets having the same var(index) are called in unspecified +order. However, var(widgetname) may omit the index, in which case an +index is computed for it to arrange for it to be called in the order +in which it was added to the array. If the option tt(-d) is given, the var(widgename) is removed from the array of widgets to be executed. @@ -368,12 +370,14 @@ passed as arguments to tt(autoload) as with tt(add-zsh-hook). The widget is also created with `tt(zle -N )var(widgetname)' to cause the corresponding function to be loaded the first time the hook is called. -In addition, var(widgetname) may be of the form var(index)tt(:)var(name). -In this case var(index) is an integer which determines the order in -which the widget var(name) will be called relative to other widgets in -the array. Widgets having the same var(index) are called in unspecified -order, and all widgets declared with an index are called before any -widgets that have no index. + +The arrays of var(widgetname) are currently maintained in tt(zstyle) +contexts, one for each var(hook) context, with a style of `tt(widgets)'. +If the tt(-L) option is given, this set of styles is listed with +`tt(zstyle -L)'. This implementation may change, and the special widgets +that refer to the styles are created only if tt(add-zle-hook-widget) is +called to add at least one widget, so if this function is used for any +hooks, then all hooks should be managed only via this function. ) enditem() diff --git a/Functions/Zle/add-zle-hook-widget b/Functions/Zle/add-zle-hook-widget index eeb0191f0..608a77607 100644 --- a/Functions/Zle/add-zle-hook-widget +++ b/Functions/Zle/add-zle-hook-widget @@ -6,6 +6,7 @@ # # WIDGET may be of the form INDEX:NAME in which case the INDEX determines # the order in which the widget executes relative to other hook widgets. +# Othewise the widget is assigned an index that appends it to the array. # # With -d, remove the widget from the hook instead; delete the hook # variable if it is empty. @@ -17,38 +18,45 @@ # same name is marked for autoload; -U is passed down to autoload if that # is given, as are -z and -k. (This is harmless if the function is # already defined.) The WIDGET is then created with zle -N. +# +# The -L option lists the hooks and their associated widgets. emulate -L zsh -# Setup - create the base functions for hook widgets that call the others - -zmodload zsh/parameter || { - print -u2 "Need parameter module for zle hooks" +# This is probably more safeguarding than necessary +zmodload -e zsh/zle || return 1 +{ zmodload zsh/parameter && zmodload zsh/zleparameter } || { + print -u2 "Need parameter modules for zle hooks" return 1 } -local -a hooktypes=( isearch-exit isearch-update - line-pre-redraw line-init line-finish - history-line-set keymap-select ) +# Setup - create the base functions for hook widgets that call the others + +local -a hooktypes=( zle-isearch-exit zle-isearch-update + zle-line-pre-redraw zle-line-init zle-line-finish + zle-history-line-set zle-keymap-select ) # Stash in zstyle to make it global -zstyle zle-hook types $hooktypes +zstyle zle-hook types ${hooktypes#zle-} for hook in $hooktypes do - function zle-$hook { + function azhw:$hook { local -a hook_widgets local hook # Values of these styles look like number:name # and we run them in number order - # $funcstack is more reliable than $0 - # Also, ksh_arrays is annoying - emulate zsh -c 'zstyle -a $funcstack[2] widgets hook_widgets' - for hook in "${@${(@on)hook_widgets}#*:}" - do - zle "$hook" -Nw || return + zstyle -a $WIDGET widgets hook_widgets + for hook in "${(@)${(@on)hook_widgets[@]}#<->:}"; do + zle "$hook" -Nw "$@" || return done return 0 } + # Check for an existing widget, add it as the first hook + if [[ ${widgets[$hook]} = user:* ]]; then + zle -A "$hook" "${widgets[$hook]}" + zstyle -- "$hook" widgets 0:"${widgets[$hook]}" + zle -N "$hook" azhw:"$hook" + fi done # Redefine ourself with the setup left out @@ -93,25 +101,27 @@ function add-zle-hook-widget { done shift $(( OPTIND - 1 )) + 1=${1#zle-} # Strip prefix not stored in zle-hook types style + if (( list )); then - zstyle -L "zle-(${1:-${(@j:|:)hooktypes}})" widgets + zstyle -L "zle-(${1:-${(@j:|:)hooktypes[@]}})" widgets return $? - elif (( help || $# != 2 || ${hooktypes[(I)${1#zle-}]} == 0 )); then + elif (( help || $# != 2 || ${hooktypes[(I)$1]} == 0 )); then print -u$(( 2 - help )) $usage return $(( 1 - help )) fi local -aU extant_hooks - local hook="zle-${1#zle-}" + local hook="zle-$1" local fn="$2" if (( del )); then # delete, if hook is set if zstyle -g extant_hooks "$hook" widgets; then if (( del == 2 )); then - set -A extant_hooks ${extant_hooks:#(<->:|)${~fn}} + set -A extant_hooks ${extant_hooks[@]:#(<->:|)${~fn}} else - set -A extant_hooks ${extant_hooks:#(<->:|)$fn} + set -A extant_hooks ${extant_hooks[@]:#(<->:|)$fn} fi # unset if no remaining entries if (( ${#extant_hooks} )); then @@ -121,15 +131,28 @@ function add-zle-hook-widget { fi fi else + integer i=${#options[ksharrays]}-2 zstyle -g extant_hooks "$hook" widgets - extant_hooks+=("$fn") + if [[ "$fn" != <->:* ]]; then + if [[ -z ${(M)extant_hooks[@]:#(<->:|)$fn} ]]; then + # no index and not already hooked + # assign largest existing index plus 10 + i=${${(On@)${(@M)extant_hooks[@]#<->:}%:}[i]}+10 + else + return 0 + fi + else + i=${${(M)fn#<->:}%:} + fn=${fn#<->:} + fi + extant_hooks+=("${i}:${fn}") zstyle -- "$hook" widgets "${extant_hooks[@]}" if [[ -z "${widgets[$fn]}" ]]; then autoload "${autoopts[@]}" -- "$fn" - zle -N "$fn" + zle -N -- "$fn" fi if [[ -z "${widgets[$hook]}" ]]; then - zle -N "$hook" + zle -N "$hook" azhw:"$hook" fi fi } -- cgit v1.2.3 From 5103c85abb239a12a3d29da9b41515cd4af19a9f Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 21 Jun 2016 16:34:55 +0100 Subject: 38736: various RPN mode enhancements for zcalc --- ChangeLog | 4 ++ Completion/Zsh/Type/_module_math_func | 2 +- Completion/Zsh/Type/_user_math_func | 2 +- Doc/Zsh/contrib.yo | 23 ++++++++++- Functions/Misc/zcalc | 78 +++++++++++++++++++++++++++++------ 5 files changed, 93 insertions(+), 16 deletions(-) (limited to 'Doc/Zsh/contrib.yo') diff --git a/ChangeLog b/ChangeLog index fd58e7aa6..4ca92814a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2016-06-21 Peter Stephenson + * 38736: Completion/Zsh/Type/_module_math_func, + Completion/Zsh/Type/_user_math_func, Doc/Zsh/contrib.yo, + Functions/Misc/zcalc: various RPN mode enhancments for zcalc. + * 38734: Src/loop.c, Test/A01grammar.ztst: fix final case clauses terminating with ;&. diff --git a/Completion/Zsh/Type/_module_math_func b/Completion/Zsh/Type/_module_math_func index 4df8d9714..6be9c006a 100644 --- a/Completion/Zsh/Type/_module_math_func +++ b/Completion/Zsh/Type/_module_math_func @@ -6,4 +6,4 @@ local -a funcs funcs=(${${${(f)"$(zmodload -Fl zsh/mathfunc 2>/dev/null)"}:#^+f:*}##+f:}) _wanted module-math-functions expl 'math function from zsh/mathfunc' \ - compadd -S '(' "$@" -a funcs + compadd -S '(' -q "$@" -a funcs diff --git a/Completion/Zsh/Type/_user_math_func b/Completion/Zsh/Type/_user_math_func index 16774f70b..35a49d50e 100644 --- a/Completion/Zsh/Type/_user_math_func +++ b/Completion/Zsh/Type/_user_math_func @@ -6,4 +6,4 @@ local -a funcs funcs=(${${${(f)"$(functions -M)"}##functions -M }%% *}) _wanted user-math-functions expl 'user math function' \ - compadd -S '(' "$@" -a funcs + compadd -S '(' -q "$@" -a funcs diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index b9c1c0a80..c875c95da 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -3806,10 +3806,23 @@ are printed instead of just the most recent result. Hence, for example, tt(zcalc -r4) shows tt($stack[4]) to tt($stack[1]) each time results are printed. ) -item(Duplication)( +item(Duplication: tt(=))( The pseudo-operator tt(=) causes the most recent element of the stack to be duplicated onto the stack. ) +item(tt(pop))( +The pseudo-function tt(pop) causes the most recent element of +the stack to be popped. A `tt(<)' on its own has the same effect. +) +item(tt(<)var(ident))( +The expression tt(<) followed (with no space) by a shell identifier +causes the most recent element of the stack to be popped and +assigned to the identifier. +) +item(Exchange: tt(xy))( +The pseudo-function tt(xy) causes the most recent two elements of +the stack to be exchanged. +) enditem() The prompt is configurable via the parameter tt(ZCALCPROMPT), which @@ -3872,7 +3885,13 @@ Note that tt(zcalc) takes care of all quoting. Hence for example: example(:f cube $1 * $1 * $1) -defines a function to cube the sole argument. +defines a function to cube the sole argument. Functions so defined, or +indeed any functions defined directly or indirectly using tt(functions +-M), are available to execute by typing only the name on the line in RPN +mode; this pops the appropriate number of arguments off the stack +to pass to the function, i.e. 1 in the case of the example tt(cube) +function. If there are optional arguments only the mandatory +arguments are supplied by this means. ) item(tt([#)var(base)tt(]))( This is not a special command, rather part of normal arithmetic diff --git a/Functions/Misc/zcalc b/Functions/Misc/zcalc index eb240b2ec..fa1a8f600 100644 --- a/Functions/Misc/zcalc +++ b/Functions/Misc/zcalc @@ -100,7 +100,8 @@ zcalc_show_value() { if [[ -n $base ]]; then print -- $(( $base $1 )) elif [[ $1 = *.* ]] || (( outdigits )); then - if [[ -z $forms[outform] ]]; then + # With normal output, ensure trailing "." doesn't get lost. + if [[ -z $forms[outform] || ($outform -eq 1 && $1 = *.) ]]; then print -- $(( $1 )) else printf "$forms[outform]\n" $outdigits $1 @@ -115,10 +116,10 @@ local ZCALC_ACTIVE=1 # TODO: make local variables that shouldn't be visible in expressions # begin with _. -local line ans base defbase forms match mbegin mend psvar optlist opt arg +local line ans base defbase forms match mbegin mend psvar optlist opt arg tmp local compcontext="-zcalc-line-" -integer num outdigits outform=1 expression_mode rpn_mode matched show_stack i -integer max_stack +integer num outdigits outform=1 expression_mode rpn_mode matched show_stack i n +integer max_stack push local -a expressions stack match mbegin mend # We use our own history file with an automatic pop on exit. @@ -131,6 +132,13 @@ if zmodload -i zsh/mathfunc 2>/dev/null; then zmodload -P mathfuncs -FL zsh/mathfunc mathfuncs="("${(j.|.)${mathfuncs##f:}}")" fi +local -A userfuncs +for line in ${(f)"$(functions -M)"}; do + match=(${=line}) + # get minimum number of arguments + userfuncs[${match[3]}]=${match[4]} +done +line= autoload -Uz zmathfuncdef if (( ! ${+ZCALCPROMPT} )); then @@ -298,6 +306,7 @@ while (( expression_mode )) || ((function|:f(unc(tion|)|))[[:blank:]]##(#b)([^[:blank:]]##)(|[[:blank:]]##([^[:blank:]]*))) zmathfuncdef $match[1] $match[3] + userfuncs[$match[1]]=${$(functions -Mm $match[1])[4]} line= continue ;; @@ -318,19 +327,38 @@ while (( expression_mode )) || (*) line=${${line##[[:blank:]]##}%%[[:blank:]]##} - if (( rpn_mode )); then + if [[ rpn_mode -ne 0 && $line != '' ]]; then + push=1 matched=1 case $line in - (=) + (\=|pop|\<[[:IDENT:]]#) if (( ${#stack} < 1 )); then print -r -- "${line}: not enough values on stack" >&2 line= continue fi - ans=${stack[1]} + case $line in + (=) + ans=${stack[1]} + ;; + (pop|\<) + push=0 + shift stack + ;; + (\<[[:IDENT:]]##) + (( ${line##\<} = ${stack[1]} )) + push=0 + shift stack + ;; + (*) + print "BUG in special RPN functions" >&2 + line= + continue + ;; + esac ;; - (+|-|\^|\||\&|\*|\*\*|/) + (+|-|\^|\||\&|\*|/|\*\*|\>\>|\<\&2 @@ -341,15 +369,22 @@ while (( expression_mode )) || shift 2 stack ;; - (ldexp|jn|yn|scalb) + (ldexp|jn|yn|scalb|xy) # Functions with two arguments if (( ${#stack} < 2 )); then print -r -- "${line}: not enough values on stack" >&2 line= continue fi - eval "(( ans = ${line}(\${stack[2]},\${stack[1]}) ))" - shift 2 stack + if [[ $line = xy ]]; then + tmp=${stack[1]} + stack[1]=${stack[2]} + stack[2]=$tmp + push=0 + else + eval "(( ans = ${line}(\${stack[2]},\${stack[1]}) ))" + shift 2 stack + fi ;; (${~mathfuncs}) @@ -365,6 +400,25 @@ while (( expression_mode )) || shift stack ;; + (${(kj.|.)~userfuncs}) + # Get minimum number of arguments to user function + n=${userfuncs[$line]} + if (( ${#stack} < n )); then + print -r -- "${line}: not enough vlaues ($n) on stack" >&2 + line= + continue + fi + line+="(" + # least recent elements on stack are earlier arguments + for (( i = n; i > 0; i-- )); do + line+=${stack[i]} + (( i > 1 )) && line+="," + done + line+=")" + shift $n stack + eval "(( ans = $line ))" + ;; + (*) # Treat as expression evaluating to new value to go on stack. matched=0 @@ -386,7 +440,7 @@ while (( expression_mode )) || fi argv[num++]=$ans psvar[1]=$num - stack=($ans $stack) + (( push )) && stack=($ans $stack) ;; esac if (( show_stack )); then -- cgit v1.2.3 From 26c01f57113cc76e20ec562ffcec60a1ab9f8b1e Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 21 Jun 2016 17:26:35 +0100 Subject: 38737: clean up zcalc variables. Undocumented variables now start with "_". --- ChangeLog | 3 + Doc/Zsh/contrib.yo | 17 ++- Functions/Misc/zcalc | 289 ++++++++++++++++++++++++++------------------------- 3 files changed, 163 insertions(+), 146 deletions(-) (limited to 'Doc/Zsh/contrib.yo') diff --git a/ChangeLog b/ChangeLog index 4ca92814a..b95b0fe31 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2016-06-21 Peter Stephenson + * 38737: Functions/Misc/zcalc, Doc/Zsh/contrib.yo: document some + zcalc variable usage and make other variables start with "_". + * 38736: Completion/Zsh/Type/_module_math_func, Completion/Zsh/Type/_user_math_func, Doc/Zsh/contrib.yo, Functions/Misc/zcalc: various RPN mode enhancments for zcalc. diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index c875c95da..53ae96dad 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -3764,8 +3764,14 @@ first few positional parameters. A visual indication of this is given when the calculator starts. The constants tt(PI) (3.14159...) and tt(E) (2.71828...) are provided. -Parameter assignment is possible, but note that all parameters will be put -into the global namespace. +Parameter assignment is possible, but note that all parameters will be +put into the global namespace unless the tt(:local) special command is +used. The function creates local variables whose names start with +tt(_), so users should avoid doing so. The variables tt(ans) (the last +answer) and tt(stack) (the stack in RPN mode) may be referred to +directly; tt(stack) is an array but elements of it are numeric. Various +other special variables are used locally with their standard meaning, +for example tt(compcontext), tt(match), tt(mbegin), tt(mend), tt(psvar). The output base can be initialised by passing the option `tt(-#)var(base)', for example `tt(zcalc -#16)' (the `tt(#)' may have to be quoted, depending @@ -3831,6 +3837,10 @@ stored locally in the first element of the array tt(psvar), which can be referred to in tt(ZCALCPROMPT) as `tt(%1v)'. The default prompt is `tt(%1v> )'. +The variable tt(ZCALC_ACTIVE) is set within the function and can +be tested by nested functions; it has the value tt(rpn) if RPN mode is +active, else 1. + A few special commands are available; these are introduced by a colon. For backward compatibility, the colon may be omitted for certain commands. Completion is available if tt(compinit) has been run. @@ -3870,8 +3880,7 @@ is executed in the context of the function, i.e. with local variables. Space is optional after tt(:!). ) item(tt(:local) var(arg) ...)( -Declare variables local to the function. Note that certain variables -are used by the function for its own purposes. Other variables +Declare variables local to the function. Other variables may be used, too, but they will be taken from or put into the global scope. ) diff --git a/Functions/Misc/zcalc b/Functions/Misc/zcalc index fa1a8f600..86b1e4a5b 100644 --- a/Functions/Misc/zcalc +++ b/Functions/Misc/zcalc @@ -97,14 +97,14 @@ emulate -L zsh setopt extendedglob zcalc_show_value() { - if [[ -n $base ]]; then - print -- $(( $base $1 )) - elif [[ $1 = *.* ]] || (( outdigits )); then + if [[ -n $_base ]]; then + print -- $(( $_base $1 )) + elif [[ $1 = *.* ]] || (( _outdigits )); then # With normal output, ensure trailing "." doesn't get lost. - if [[ -z $forms[outform] || ($outform -eq 1 && $1 = *.) ]]; then + if [[ -z $_forms[_outform] || ($_outform -eq 1 && $1 = *.) ]]; then print -- $(( $1 )) else - printf "$forms[outform]\n" $outdigits $1 + printf "$_forms[_outform]\n" $_outdigits $1 fi else printf "%d\n" $1 @@ -116,29 +116,31 @@ local ZCALC_ACTIVE=1 # TODO: make local variables that shouldn't be visible in expressions # begin with _. -local line ans base defbase forms match mbegin mend psvar optlist opt arg tmp +local _line ans _base _defbase _forms match mbegin mend +local psvar _optlist _opt _arg _tmp local compcontext="-zcalc-line-" -integer num outdigits outform=1 expression_mode rpn_mode matched show_stack i n -integer max_stack push -local -a expressions stack match mbegin mend +integer _num _outdigits _outform=1 _expression_mode +integer _rpn_mode _matched _show_stack _i _n +integer _max_stack _push +local -a _expressions stack # We use our own history file with an automatic pop on exit. history -ap "${ZDOTDIR:-$HOME}/.zcalc_history" -forms=( '%2$g' '%.*g' '%.*f' '%.*E' '') +_forms=( '%2$g' '%.*g' '%.*f' '%.*E' '') -local mathfuncs +local _mathfuncs if zmodload -i zsh/mathfunc 2>/dev/null; then - zmodload -P mathfuncs -FL zsh/mathfunc - mathfuncs="("${(j.|.)${mathfuncs##f:}}")" + zmodload -P _mathfuncs -FL zsh/mathfunc + _mathfuncs="("${(j.|.)${_mathfuncs##f:}}")" fi -local -A userfuncs -for line in ${(f)"$(functions -M)"}; do - match=(${=line}) +local -A _userfuncs +for _line in ${(f)"$(functions -M)"}; do + match=(${=_line}) # get minimum number of arguments - userfuncs[${match[3]}]=${match[4]} + _userfuncs[${match[3]}]=${match[4]} done -line= +_line= autoload -Uz zmathfuncdef if (( ! ${+ZCALCPROMPT} )); then @@ -155,118 +157,118 @@ fi # Process command line while [[ -n $1 && $1 = -(|[#-]*|f|e|r(<->|)) ]]; do - optlist=${1[2,-1]} + _optlist=${1[2,-1]} shift - [[ $optlist = (|-) ]] && break - while [[ -n $optlist ]]; do - opt=${optlist[1]} - optlist=${optlist[2,-1]} - case $opt in + [[ $_optlist = (|-) ]] && break + while [[ -n $_optlist ]]; do + _opt=${_optlist[1]} + _optlist=${_optlist[2,-1]} + case $_opt in ('#') # Default base - if [[ -n $optlist ]]; then - arg=$optlist - optlist= + if [[ -n $_optlist ]]; then + _arg=$_optlist + _optlist= elif [[ -n $1 ]]; then - arg=$1 + _arg=$1 shift else print -- "-# requires an argument" >&2 return 1 fi - if [[ $arg != (|\#)[[:digit:]]## ]]; then + if [[ $_arg != (|\#)[[:digit:]]## ]]; then print -- "-# requires a decimal number as an argument" >&2 return 1 fi - defbase="[#${arg}]" + _defbase="[#${_arg}]" ;; (f) # Force floating point operation setopt forcefloat ;; (e) # Arguments are expressions - (( expression_mode = 1 )); + (( _expression_mode = 1 )); ;; (r) # RPN mode. - (( rpn_mode = 1 )) + (( _rpn_mode = 1 )) ZCALC_ACTIVE=rpn - if [[ $optlist = (#b)(<->)* ]]; then - (( show_stack = ${match[1]} )) - optlist=${optlist[${#match[1]}+1,-2]} + if [[ $_optlist = (#b)(<->)* ]]; then + (( _show_stack = ${match[1]} )) + _optlist=${_optlist[${#match[1]}+1,-2]} fi ;; esac done done -if (( expression_mode )); then - expressions=("$@") +if (( _expression_mode )); then + _expressions=("$@") argv=() fi -for (( num = 1; num <= $#; num++ )); do +for (( _num = 1; _num <= $#; _num++ )); do # Make sure all arguments have been evaluated. # The `$' before the second argv forces string rather than numeric # substitution. - (( argv[$num] = $argv[$num] )) - print "$num> $argv[$num]" + (( argv[$_num] = $argv[$_num] )) + print "$_num> $argv[$_num]" done -psvar[1]=$num -local prev_line cont_prompt -while (( expression_mode )) || - vared -cehp "${cont_prompt}${ZCALCPROMPT}" line; do - if (( expression_mode )); then - (( ${#expressions} )) || break - line=$expressions[1] - shift expressions +psvar[1]=$_num +local _prev_line _cont_prompt +while (( _expression_mode )) || + vared -cehp "${_cont_prompt}${ZCALCPROMPT}" _line; do + if (( _expression_mode )); then + (( ${#_expressions} )) || break + _line=$_expressions[1] + shift _expressions fi - if [[ $line = (|*[^\\])('\\')#'\' ]]; then - prev_line+=$line[1,-2] - cont_prompt="..." - line= + if [[ $_line = (|*[^\\])('\\')#'\' ]]; then + _prev_line+=$_line[1,-2] + _cont_prompt="..." + _line= continue fi - line="$prev_line$line" - prev_line= - cont_prompt= + _line="$_prev_line$_line" + _prev_line= + _cont_prompt= # Test whether there are as many open as close - # parentheses in the line so far. - if [[ ${#line//[^\(]} -gt ${#line//[^\)]} ]]; then - prev_line+=$line - cont_prompt="..." - line= + # parentheses in the _line so far. + if [[ ${#_line//[^\(]} -gt ${#_line//[^\)]} ]]; then + _prev_line+=$_line + _cont_prompt="..." + _line= continue fi - [[ -z $line ]] && break + [[ -z $_line ]] && break # special cases # Set default base if `[#16]' or `[##16]' etc. on its own. # Unset it if `[#]' or `[##]'. - if [[ $line = (#b)[[:blank:]]#('[#'(\#|)((<->|)(|_|_<->))']')[[:blank:]]#(*) ]]; then + if [[ $_line = (#b)[[:blank:]]#('[#'(\#|)((<->|)(|_|_<->))']')[[:blank:]]#(*) ]]; then if [[ -z $match[6] ]]; then if [[ -z $match[3] ]]; then - defbase= + _defbase= else - defbase=$match[1] + _defbase=$match[1] fi - print -s -- $line - print -- $(( ${defbase} ans )) - line= + print -s -- $_line + print -- $(( ${_defbase} ans )) + _line= continue else - base=$match[1] + _base=$match[1] fi else - base=$defbase + _base=$_defbase fi - print -s -- $line + print -s -- $_line - line="${${line##[[:blank:]]#}%%[[:blank:]]#}" - case "$line" in + _line="${${_line##[[:blank:]]#}%%[[:blank:]]#}" + case "$_line" in # Escapes begin with a colon (:(\\|)\!*) # shell escape: handle completion's habit of quoting the ! - eval ${line##:(\\|)\![[:blank:]]#} - line= + eval ${_line##:(\\|)\![[:blank:]]#} + _line= continue ;; @@ -276,83 +278,83 @@ while (( expression_mode )) || ;; ((:|)norm) # restore output format to default - outform=1 + _outform=1 ;; ((:|)sci[[:blank:]]#(#b)(<->)(#B)) - outdigits=$match[1] - outform=2 + _outdigits=$match[1] + _outform=2 ;; ((:|)fix[[:blank:]]#(#b)(<->)(#B)) - outdigits=$match[1] - outform=3 + _outdigits=$match[1] + _outform=3 ;; ((:|)eng[[:blank:]]#(#b)(<->)(#B)) - outdigits=$match[1] - outform=4 + _outdigits=$match[1] + _outform=4 ;; (:raw) - outform=5 + _outform=5 ;; ((:|)local([[:blank:]]##*|)) - eval $line - line= + eval $_line + _line= continue ;; ((function|:f(unc(tion|)|))[[:blank:]]##(#b)([^[:blank:]]##)(|[[:blank:]]##([^[:blank:]]*))) zmathfuncdef $match[1] $match[3] - userfuncs[$match[1]]=${$(functions -Mm $match[1])[4]} - line= + _userfuncs[$match[1]]=${$(functions -Mm $match[1])[4]} + _line= continue ;; (:*) print "Unrecognised escape" - line= + _line= continue ;; (\$[[:IDENT:]]##) # Display only, no calculation - line=${line##\$} - print -r -- ${(P)line} - line= + _line=${_line##\$} + print -r -- ${(P)_line} + _line= continue ;; (*) - line=${${line##[[:blank:]]##}%%[[:blank:]]##} - if [[ rpn_mode -ne 0 && $line != '' ]]; then - push=1 - matched=1 - case $line in + _line=${${_line##[[:blank:]]##}%%[[:blank:]]##} + if [[ _rpn_mode -ne 0 && $_line != '' ]]; then + _push=1 + _matched=1 + case $_line in (\=|pop|\<[[:IDENT:]]#) if (( ${#stack} < 1 )); then - print -r -- "${line}: not enough values on stack" >&2 - line= + print -r -- "${_line}: not enough values on stack" >&2 + _line= continue fi - case $line in + case $_line in (=) ans=${stack[1]} ;; (pop|\<) - push=0 + _push=0 shift stack ;; (\<[[:IDENT:]]##) - (( ${line##\<} = ${stack[1]} )) - push=0 + (( ${_line##\<} = ${stack[1]} )) + _push=0 shift stack ;; (*) print "BUG in special RPN functions" >&2 - line= + _line= continue ;; esac @@ -361,98 +363,101 @@ while (( expression_mode )) || (+|-|\^|\||\&|\*|/|\*\*|\>\>|\<\&2 - line= + print -r -- "${_line}: not enough values on stack" >&2 + _line= continue fi - eval "(( ans = \${stack[2]} $line \${stack[1]} ))" + eval "(( ans = \${stack[2]} $_line \${stack[1]} ))" shift 2 stack ;; (ldexp|jn|yn|scalb|xy) # Functions with two arguments if (( ${#stack} < 2 )); then - print -r -- "${line}: not enough values on stack" >&2 - line= + print -r -- "${_line}: not enough values on stack" >&2 + _line= continue fi - if [[ $line = xy ]]; then - tmp=${stack[1]} + if [[ $_line = xy ]]; then + _tmp=${stack[1]} stack[1]=${stack[2]} - stack[2]=$tmp - push=0 + stack[2]=$_tmp + _push=0 else - eval "(( ans = ${line}(\${stack[2]},\${stack[1]}) ))" + eval "(( ans = ${_line}(\${stack[2]},\${stack[1]}) ))" shift 2 stack fi ;; - (${~mathfuncs}) + (${~_mathfuncs}) # Functions with a single argument. # This is actually a superset, but we should have matched # any that shouldn't be in it in previous cases. if (( ${#stack} < 1 )); then - print -r -- "${line}: not enough values on stack" >&2 - line= + print -r -- "${_line}: not enough values on stack" >&2 + _line= continue fi - eval "(( ans = ${line}(\${stack[1]}) ))" + eval "(( ans = ${_line}(\${stack[1]}) ))" shift stack ;; - (${(kj.|.)~userfuncs}) + (${(kj.|.)~_userfuncs}) # Get minimum number of arguments to user function - n=${userfuncs[$line]} - if (( ${#stack} < n )); then - print -r -- "${line}: not enough vlaues ($n) on stack" >&2 - line= + _n=${_userfuncs[$_line]} + if (( ${#stack} < n_ )); then + print -r -- "${_line}: not enough values ($_n) on stack" >&2 + _line= continue fi - line+="(" + _line+="(" # least recent elements on stack are earlier arguments - for (( i = n; i > 0; i-- )); do - line+=${stack[i]} - (( i > 1 )) && line+="," + for (( _i = _n; _i > 0; _i-- )); do + _line+=${stack[_i]} + (( _i > 1 )) && _line+="," done - line+=")" - shift $n stack - eval "(( ans = $line ))" + _line+=")" + shift $_n stack + eval "(( ans = $_line ))" ;; (*) # Treat as expression evaluating to new value to go on stack. - matched=0 + _matched=0 ;; esac else - matched=0 + _matched=0 fi - if (( ! matched )); then + if (( ! _matched )); then # Latest value is stored` as a string, because it might be floating # point or integer --- we don't know till after the evaluation, and # arrays always store scalars anyway. # # Since it's a string, we'd better make sure we know which # base it's in, so don't change that until we actually print it. - eval "ans=\$(( $line ))" - # on error $ans is not set; let user re-edit line + if ! eval "ans=\$(( $_line ))"; then + _line= + continue + fi + # on error $ans is not set; let user re-edit _line [[ -n $ans ]] || continue fi - argv[num++]=$ans - psvar[1]=$num - (( push )) && stack=($ans $stack) + argv[_num++]=$ans + psvar[1]=$_num + (( _push )) && stack=($ans $stack) ;; esac - if (( show_stack )); then - (( max_stack = (show_stack > ${#stack}) ? ${#stack} : show_stack )) - for (( i = max_stack; i > 0; i-- )); do - printf "%3d: " $i - zcalc_show_value ${stack[i]} + if (( _show_stack )); then + (( _max_stack = (_show_stack > ${#stack}) ? ${#stack} : _show_stack )) + for (( _i = _max_stack; _i > 0; _i-- )); do + printf "%3d: " $_i + zcalc_show_value ${stack[_i]} done else zcalc_show_value $ans fi - line= + _line= done return 0 -- cgit v1.2.3 From a73ae70e8217d7163aecdbdad4d8af08eced8a55 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 29 Jun 2016 17:05:06 +0200 Subject: 38770: vi upper/lowercase widgets and shell widget example that reads a vi movement --- ChangeLog | 4 ++++ Doc/Zsh/contrib.yo | 11 +++++++++++ Doc/Zsh/zle.yo | 14 ++++++++++++++ Functions/Zle/vi-pipe | 31 +++++++++++++++++++++++++++++++ Src/Zle/iwidgets.list | 2 ++ Src/Zle/zle_keymap.c | 5 ++++- Src/Zle/zle_vi.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 Functions/Zle/vi-pipe (limited to 'Doc/Zsh/contrib.yo') diff --git a/ChangeLog b/ChangeLog index 4f0a49397..831ea4e69 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2016-06-29 Oliver Kiddle + * 38770: Src/Zle/zle_keymap.c, Src/Zle/zle_vi.c, Doc/Zsh/zle.yo, + Doc/Zsh/contrib.yo, Functions/Zle/vi-pipe: vi upper/lowercase + widgets and shell widget example that reads a vi movement + * 38752: Src/builtin.c: add comments to explain use of stdout instead of stderr for the which builtin diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 53ae96dad..f1208e843 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -2968,6 +2968,17 @@ and aliases `tt(globurl)' to `tt(noglob urlglobber)'. This function takes a local URL apart, attempts to pattern-match the local file portion of the URL path, and then puts the results back into URL format again. ) +tindex(vi-pipe) +item(tt(vi-pipe))( +This function reads a movement command from the keyboard and then +prompts for an external command. The part of the buffer covered by +the movement is piped to the external command and then replaced by +the command's output. If the movement command is bound to vi-pipe, +the current line is used. + +The function serves as an example for reading a vi movement command +from within a user-defined widget. +) tindex(which-command) item(tt(which-command))( This function is a drop-in replacement for the builtin widget diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo index 80d3f39d8..1bae0ccf7 100644 --- a/Doc/Zsh/zle.yo +++ b/Doc/Zsh/zle.yo @@ -1781,6 +1781,13 @@ tindex(down-case-word) item(tt(down-case-word) (tt(ESC-L ESC-l)) (unbound) (unbound))( Convert the current word to all lowercase and move past it. ) +tindex(vi-down-case) +item(tt(vi-down-case)) ((unbound) (tt(gu)) (unbound))( +Read a movement command from the keyboard, and convert all characters +from the cursor position to the endpoint of the movement to lowercase. +If the movement command is tt(vi-down-case), swap the case of all +characters on the current line. +) tindex(kill-word) item(tt(kill-word) (tt(ESC-D ESC-d)) (unbound) (unbound))( Kill the current word. @@ -1946,6 +1953,13 @@ tindex(vi-unindent) item(tt(vi-unindent) (unbound) (tt(<)) (unbound))( Unindent a number of lines. ) +tindex(vi-up-case) +item(tt(vi-up-case)) ((unbound) (tt(gU)) (unbound))( +Read a movement command from the keyboard, and convert all characters +from the cursor position to the endpoint of the movement to lowercase. +If the movement command is tt(vi-up-case), swap the case of all +characters on the current line. +) tindex(up-case-word) item(tt(up-case-word) (tt(ESC-U ESC-u)) (unbound) (unbound))( Convert the current word to all caps and move past it. diff --git a/Functions/Zle/vi-pipe b/Functions/Zle/vi-pipe new file mode 100644 index 000000000..2d2e29587 --- /dev/null +++ b/Functions/Zle/vi-pipe @@ -0,0 +1,31 @@ +# Example of a widget that takes a vi motion + +# Filter part of buffer corresponding to a vi motion through an external +# program. + +# To enable with vi compatible bindings use: +# autoload -Uz vi-pipe +# bindkey -a '!' vi-pipe + +autoload -Uz read-from-minibuffer +local _save_cut="$CUTBUFFER" REPLY + +# Use the standard vi-delete to accept a vi motion. +zle .vi-delete || return +read-from-minibuffer "!" +local _save_cur=$CURSOR + +# cut buffer contains the deleted text and can be modified +CUTBUFFER="$(eval $REPLY <<<$CUTBUFFER)" + +# put the modified text back in position. +if [[ CURSOR -eq 0 || $BUFFER[CURSOR] = $'\n' ]]; then + # at the beginning of a line, vi-delete won't have moved the cursor + # back to a previous line + zle .vi-put-before -n 1 +else + zle .vi-put-after -n 1 +fi + +# restore cut buffer and cursor to the start of the range +CUTBUFFER="$_save_cut" CURSOR="$_save_cur" diff --git a/Src/Zle/iwidgets.list b/Src/Zle/iwidgets.list index 2b2654c5d..58310cd74 100644 --- a/Src/Zle/iwidgets.list +++ b/Src/Zle/iwidgets.list @@ -143,6 +143,7 @@ "vi-delete", videlete, ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_VIOPER "vi-delete-char", videletechar, ZLE_KEEPSUFFIX "vi-digit-or-beginning-of-line", vidigitorbeginningofline, 0 +"vi-down-case", vidowncase, ZLE_LASTCOL | ZLE_VIOPER "vi-down-line-or-history", vidownlineorhistory, ZLE_LINEMOVE "vi-end-of-line", viendofline, ZLE_LASTCOL "vi-fetch-history", vifetchhistory, ZLE_LINEMOVE @@ -188,6 +189,7 @@ "vi-swap-case", viswapcase, ZLE_LASTCOL "vi-undo-change", viundochange, ZLE_KEEPSUFFIX "vi-unindent", viunindent, ZLE_LASTCOL | ZLE_VIOPER +"vi-up-case", viupcase, ZLE_LASTCOL | ZLE_VIOPER "vi-up-line-or-history", viuplineorhistory, ZLE_LINEMOVE "vi-yank", viyank, ZLE_LASTCOL | ZLE_VIOPER "vi-yank-eol", viyankeol, 0 diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c index f547dbf17..3db4207d9 100644 --- a/Src/Zle/zle_keymap.c +++ b/Src/Zle/zle_keymap.c @@ -1374,8 +1374,11 @@ default_bindings(void) bindkey(amap, "ge", refthingy(t_vibackwardwordend), NULL); bindkey(amap, "gE", refthingy(t_vibackwardblankwordend), NULL); bindkey(amap, "gg", refthingy(t_beginningofbufferorhistory), NULL); - bindkey(amap, "g~", refthingy(t_vioperswapcase), NULL); + bindkey(amap, "gu", refthingy(t_vidowncase), NULL); + bindkey(amap, "gU", refthingy(t_viupcase), NULL); bindkey(amap, "g~~", NULL, "g~g~"); + bindkey(amap, "guu", NULL, "gugu"); + bindkey(amap, "gUU", NULL, "gUgU"); /* emacs mode: arrow keys */ add_cursor_key(emap, TCUPCURSOR, t_uplineorhistory, 'A'); diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c index 953af2401..baa2064e9 100644 --- a/Src/Zle/zle_vi.c +++ b/Src/Zle/zle_vi.c @@ -729,6 +729,52 @@ vioperswapcase(UNUSED(char **args)) return ret; } +/**/ +int +viupcase(UNUSED(char **args)) +{ + int oldcs, c2, ret = 1; + + /* get the range */ + startvichange(1); + if ((c2 = getvirange(0)) != -1) { + oldcs = zlecs; + /* covert the case of all letters within range */ + while (zlecs < c2) { + zleline[zlecs] = ZC_toupper(zleline[zlecs]); + INCCS(); + } + /* go back to the first line of the range */ + zlecs = oldcs; + ret = 0; + } + vichgflag = 0; + return ret; +} + +/**/ +int +vidowncase(UNUSED(char **args)) +{ + int oldcs, c2, ret = 1; + + /* get the range */ + startvichange(1); + if ((c2 = getvirange(0)) != -1) { + oldcs = zlecs; + /* convert the case of all letters within range */ + while (zlecs < c2) { + zleline[zlecs] = ZC_tolower(zleline[zlecs]); + INCCS(); + } + /* go back to the first line of the range */ + zlecs = oldcs; + ret = 0; + } + vichgflag = 0; + return ret; +} + /**/ int virepeatchange(UNUSED(char **args)) -- cgit v1.2.3 From a7d5d239e6ab729515083a88cfaf955e078c1685 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 4 Jul 2016 12:08:14 +0100 Subject: 38783: zcalc tweaks for RPN mode. Make it more straightforward to exchange variables with stack. --- ChangeLog | 5 +++++ Doc/Zsh/contrib.yo | 16 ++++++++++++---- Functions/Misc/zcalc | 26 ++++++++++++++++++-------- 3 files changed, 35 insertions(+), 12 deletions(-) (limited to 'Doc/Zsh/contrib.yo') diff --git a/ChangeLog b/ChangeLog index 831ea4e69..952b240c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2016-07-04 Peter Stephenson + + * 38783: Doc/Zsh/contrib.yo, Functions/Misc/zcalc: tweaks for + variable and stack interation in RPN mode. + 2016-06-29 Oliver Kiddle * 38770: Src/Zle/zle_keymap.c, Src/Zle/zle_vi.c, Doc/Zsh/zle.yo, diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index f1208e843..d4a453849 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -3829,16 +3829,24 @@ the stack to be duplicated onto the stack. ) item(tt(pop))( The pseudo-function tt(pop) causes the most recent element of -the stack to be popped. A `tt(<)' on its own has the same effect. +the stack to be popped. A `tt(>)' on its own has the same effect. +) +item(tt(>)var(ident))( +The expression tt(>) followed (with no space) by a shell identifier +causes the most recent element of the stack to be popped and +assigned to the variable with that name. The variable is +local to the tt(zcalc) function. ) item(tt(<)var(ident))( The expression tt(<) followed (with no space) by a shell identifier -causes the most recent element of the stack to be popped and -assigned to the identifier. +causes the value of the variable with that name to be pushed +onto the stack. var(ident) may be an integer, in which +case the previous result with that number (as shown before +the tt(>) in th standard standard tt(zcalc) prompt) is put on the stack. ) item(Exchange: tt(xy))( The pseudo-function tt(xy) causes the most recent two elements of -the stack to be exchanged. +the stack to be exchanged. `tt(<>)' has the same effect. ) enditem() diff --git a/Functions/Misc/zcalc b/Functions/Misc/zcalc index 86b1e4a5b..480373345 100644 --- a/Functions/Misc/zcalc +++ b/Functions/Misc/zcalc @@ -94,7 +94,7 @@ # sequentially just as if read automatically. emulate -L zsh -setopt extendedglob +setopt extendedglob typesetsilent zcalc_show_value() { if [[ -n $_base ]]; then @@ -301,7 +301,7 @@ while (( _expression_mode )) || ;; ((:|)local([[:blank:]]##*|)) - eval $_line + eval ${_line##:} _line= continue ;; @@ -333,7 +333,11 @@ while (( _expression_mode )) || _push=1 _matched=1 case $_line in - (\=|pop|\<[[:IDENT:]]#) + (\<[[:IDENT:]]##) + ans=${(P)${_line##\<}} + ;; + + (\=|pop|\>[[:IDENT:]]#) if (( ${#stack} < 1 )); then print -r -- "${_line}: not enough values on stack" >&2 _line= @@ -343,12 +347,18 @@ while (( _expression_mode )) || (=) ans=${stack[1]} ;; - (pop|\<) + (pop|\>) _push=0 shift stack ;; - (\<[[:IDENT:]]##) - (( ${_line##\<} = ${stack[1]} )) + (\>[[:IDENT:]]##) + if [[ ${_line##\>} = (_*|stack|ans|PI|E) ]]; then + print "${_line##\>}: reserved variable" >&2 + _line= + continue + fi + local ${_line##\>} + (( ${_line##\>} = ${stack[1]} )) _push=0 shift stack ;; @@ -371,14 +381,14 @@ while (( _expression_mode )) || shift 2 stack ;; - (ldexp|jn|yn|scalb|xy) + (ldexp|jn|yn|scalb|xy|\<\>) # Functions with two arguments if (( ${#stack} < 2 )); then print -r -- "${_line}: not enough values on stack" >&2 _line= continue fi - if [[ $_line = xy ]]; then + if [[ $_line = (xy|\<\>) ]]; then _tmp=${stack[1]} stack[1]=${stack[2]} stack[2]=$_tmp -- cgit v1.2.3 From e3884c60ed1a247af1e1578710629f2ca79630d8 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Sun, 17 Jul 2016 12:04:48 -0700 Subject: 38866: update add-zle-hook-widget doc for 38850, bug fixes Edge case handling, wrap in anonymous function for kshautoload management. --- ChangeLog | 8 ++++++ Doc/Zsh/contrib.yo | 18 +++++-------- Functions/Zle/add-zle-hook-widget | 57 ++++++++++++++++++++++++--------------- 3 files changed, 51 insertions(+), 32 deletions(-) (limited to 'Doc/Zsh/contrib.yo') diff --git a/ChangeLog b/ChangeLog index f092e815b..bb33f16b2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2016-07-17 Barton E. Schaefer + + * 38866: Doc/Zsh/contrib.yo: update add-zle-hook-widget for 38850. + + * 38866 (+ tweak 38872): Functions/Zle/add-zle-hook-widget: fix + edge case handling, wrap in anonymous function for kshautoload + management. + 2016-07-17 Daniel Shahaf * users/21752: Doc/Zsh/mod_zleparameter.yo: Extend diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index d4a453849..1d2b7ca6e 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -340,23 +340,20 @@ those additional widgets. var(hook) is one of tt(isearch-exit), tt(isearch-update), tt(line-pre-redraw), tt(line-init), tt(line-finish), tt(history-line-set), or tt(keymap-select), corresponding to each of the special widgets -tt(zle-isearch-exit), etc. +tt(zle-isearch-exit), etc. The special widget names are also accepted +as the var(hook) argument. var(widgetname) is the name of a ZLE widget. If no options are given this is added to the array of widgets to be invoked in the given hook context. Note that the hooks are called as widgets, that is, with example(tt(zle )var(widgetname)tt( -Nw "$@")) -rather than as a function call. -In typical usage, var(widgetname) has the form var(index)tt(:)var(name). -In this case var(index) is an integer which determines the order in which -the widget var(name) will be called relative to other widgets in the -array. Widgets having the same var(index) are called in unspecified -order. However, var(widgetname) may omit the index, in which case an -index is computed for it to arrange for it to be called in the order -in which it was added to the array. +vindex(WIDGET, in hooks) +Note that this means that the `tt(WIDGET)' special parameter tracks the +var(widgetname) when the widget function is called, rather than tracking +the name of the corresponding special hook widget. -If the option tt(-d) is given, the var(widgename) is removed from +If the option tt(-d) is given, the var(widgetname) is removed from the array of widgets to be executed. If the option tt(-D) is given, the var(widgetname) is treated as a pattern @@ -370,7 +367,6 @@ passed as arguments to tt(autoload) as with tt(add-zsh-hook). The widget is also created with `tt(zle -N )var(widgetname)' to cause the corresponding function to be loaded the first time the hook is called. - The arrays of var(widgetname) are currently maintained in tt(zstyle) contexts, one for each var(hook) context, with a style of `tt(widgets)'. If the tt(-L) option is given, this set of styles is listed with diff --git a/Functions/Zle/add-zle-hook-widget b/Functions/Zle/add-zle-hook-widget index 760e26d29..04be50478 100644 --- a/Functions/Zle/add-zle-hook-widget +++ b/Functions/Zle/add-zle-hook-widget @@ -18,6 +18,8 @@ # # The -L option lists the hooks and their associated widgets. +() { # Preserve caller global option settings + emulate -L zsh # This is probably more safeguarding than necessary @@ -35,25 +37,23 @@ local -a hooktypes=( zle-isearch-exit zle-isearch-update # Stash in zstyle to make it global zstyle zle-hook types ${hooktypes#zle-} -for hook in $hooktypes -do - function azhw:$hook { - local -a hook_widgets - local hook - # Values of these styles look like number:name - # and we run them in number order - zstyle -a $WIDGET widgets hook_widgets - for hook in "${(@)${(@on)hook_widgets[@]}#<->:}"; do - if [[ "$hook" = user:* ]]; then - # Preserve $WIDGET within the renamed widget - zle "$hook" -N "$@" - else - zle "$hook" -Nw "$@" - fi || return - done - return 0 - } -done +# Relying on multifuncdef option here +function azhw:${^hooktypes} { + local -a hook_widgets + local hook + # Values of these styles look like number:name + # and we run them in number order + zstyle -a $WIDGET widgets hook_widgets + for hook in "${(@)${(@on)hook_widgets[@]}#<->:}"; do + if [[ "$hook" = user:* ]]; then + # Preserve $WIDGET within the renamed widget + zle "$hook" -N "$@" + else + zle "$hook" -Nw "$@" + fi || return + done + return 0 +} # Redefine ourself with the setup left out @@ -127,12 +127,25 @@ function add-zle-hook-widget { fi fi else + # Check whether attempting to add a widget named for the hook + if [[ "$fn" = "$hook" ]]; then + if [[ -n "${widgets[$fn]}" ]]; then + print -u2 "Cannot hook $fn to itself" + return 1 + fi + # No point in building the array until another is added + autoload "${autoopts[@]}" -- "$fn" + zle -N "$fn" + return 0 + fi integer i=${#options[ksharrays]}-2 zstyle -g extant_hooks "$hook" widgets # Check for an existing widget, add it as the first hook if [[ ${widgets[$hook]} != "user:azhw:$hook" ]]; then - zle -A "$hook" "${widgets[$hook]}" - extant_hooks=(0:"${widgets[$hook]}" "${extant_hooks[@]}") + if [[ -n ${widgets[$hook]} ]]; then + zle -A "$hook" "${widgets[$hook]}" + extant_hooks=(0:"${widgets[$hook]}" "${extant_hooks[@]}") + fi zle -N "$hook" azhw:"$hook" fi # Add new widget only if not already in the hook list @@ -155,6 +168,8 @@ function add-zle-hook-widget { fi } +} "$@" # Resume caller global options + # Handle zsh autoloading conventions: # - "file" appears last in zsh_eval_context when "source"-ing # - "evalautofunc" appears with kshautoload set or autoload -k -- cgit v1.2.3 From 932ff2b6f8990b027facc93fb23bc1dc0163707e Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Sun, 24 Jul 2016 22:18:34 +0200 Subject: 38929: new vim style text object using match-words-by-style mechanism --- ChangeLog | 3 + Doc/Zsh/contrib.yo | 12 ++-- Functions/Zle/select-word-match | 121 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 Functions/Zle/select-word-match (limited to 'Doc/Zsh/contrib.yo') diff --git a/ChangeLog b/ChangeLog index 20c401b04..086298775 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2016-07-24 Oliver Kiddle + * 38929: Doc/Zsh/contrib.yo, Functions/Zle/select-word-match: + new vim style text object using match-words-by-style mechanism + * 38935: Matthew Martin: Completion/Unix/Command/_tcpdump: update for Free and Open BSD diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 1d2b7ca6e..c3dec34cd 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -1940,6 +1940,8 @@ tindex(transpose-words-match) tindex(capitalize-word-match) tindex(up-case-word-match) tindex(down-case-word-match) +tindex(delete-whole-word-match) +tindex(select-word-match) tindex(select-word-style) tindex(match-word-context) tindex(match-words-by-style) @@ -1947,12 +1949,14 @@ xitem(tt(forward-word-match), tt(backward-word-match)) xitem(tt(kill-word-match), tt(backward-kill-word-match)) xitem(tt(transpose-words-match), tt(capitalize-word-match)) xitem(tt(up-case-word-match), tt(down-case-word-match)) +xitem(tt(delete-whole-word-match), tt(select-word-match)) item(tt(select-word-style), tt(match-word-context), tt(match-words-by-style))( -The eight `tt(-match)' functions are drop-in replacements for the +The first eight `tt(-match)' functions are drop-in replacements for the builtin widgets without the suffix. By default they behave in a similar way. However, by the use of styles and the function tt(select-word-style), -the way words are matched can be altered. For comparison, the widgets -described in ifzman(zmanref(zshzle) under Text Objects)\ +the way words are matched can be altered. tt(select-word-match) is intended +to be used as a text object in vi mode but with custom word styles. For +comparison, the widgets described in ifzman(zmanref(zshzle) under Text Objects)\ ifnzman(noderef(Text Objects)) use fixed definitions of words, compatible with the tt(vim) editor. @@ -1960,7 +1964,7 @@ The simplest way of configuring the functions is to use tt(select-word-style), which can either be called as a normal function with the appropriate argument, or invoked as a user-defined widget that will prompt for the first character of the word style to be used. The first -time it is invoked, the eight tt(-match) functions will automatically +time it is invoked, the first eight tt(-match) functions will automatically replace the builtin versions, so they do not need to be loaded explicitly. The word styles available are as follows. Only the first character diff --git a/Functions/Zle/select-word-match b/Functions/Zle/select-word-match new file mode 100644 index 000000000..24620c995 --- /dev/null +++ b/Functions/Zle/select-word-match @@ -0,0 +1,121 @@ +# Select the entire word around the cursor. Intended for use as +# a vim-style text object in vi mode but with customisable +# word boundaries. +# +# For example: +# autoload -U select-word-match +# zle -N select-in-camel select-word-match +# bindkey -M viopp ic select-in-camel +# zstyle ':zle:*-camel' word-style normal-subword + +emulate -L zsh +setopt extendedglob + +local curcontext=:zle:$WIDGET +local -a matched_words +# Start and end of range of characters +integer pos1 pos2 num=${NUMERIC:-1} +local style word + +# choose between inner word or a word style of widget +for style in $1 ${${WIDGET#*-}[1]} $KEYS[1] "i"; do + [[ $style = [ai] ]] && break +done + +autoload -Uz match-words-by-style + +while (( num-- )); do + if (( MARK > CURSOR )); then + # if cursor is at the start of the selection, just move back a word + match-words-by-style + if [[ $style = i && -n $matched_words[3] ]]; then + word=$matched_words[3] + else + word=$matched_words[2]$matched_words[3] + fi + if [[ -n $word ]]; then + (( CURSOR -= ${#word} )) + else + return 1 + fi + elif (( MARK >= 0 && MARK < CURSOR )); then + # cursor at the end, move forward a word + (( CURSOR+1 == $#BUFFER )) && return 1 + (( CURSOR++ )) + match-words-by-style + if [[ -n $matched_words[4] ]]; then + if [[ $style = i ]]; then + # just skip the whitespace + word=$matched_words[4] + else + # skip the whitespace plus word + word=$matched_words[4]$matched_words[5] + fi + else + if [[ $style = i ]]; then + # skip the word + word=$matched_words[5] + else + # skip word and following whitespace + word=$matched_words[5]$matched_words[6] + fi + fi + (( CURSOR += ${#word} - 1 )) + else + match-words-by-style + + if [[ -n "${matched_words[3]}" ]]; then + # There's whitespace before the cursor, so the word we are selecting + # starts at the cursor position. + pos1=$CURSOR + else + # No whitespace before us, so select any wordcharacters there. + pos1="${#matched_words[1]}" + fi + + if [[ -n "${matched_words[4]}" ]]; then + if [[ -n "${matched_words[3]}" ]] || (( CURSOR == 0 )); then + # whitespace either side, select it + (( pos1 = CURSOR - ${#matched_words[3]} )) + (( pos2 = CURSOR + ${#matched_words[4]} )) + else + # There's whitespace at the cursor position, so only select + # up to the cursor position. + (( pos2 = CURSOR + 1 )) + fi + else + # No whitespace at the cursor position, so select the + # current character and any following wordcharacters. + (( pos2 = CURSOR + ${#matched_words[5]} )) + fi + + if [[ $style = a ]]; then + if [[ -n "${matched_words[4]}" && ( -n "${matched_words[3]}" || CURSOR -eq 0 ) ]]; then + # in the middle of whitespace so grab a word + if [[ -n "${matched_words[5]}" ]]; then + (( pos2 += ${#matched_words[5]} )) # preferably the one after + else + (( pos1 -= ${#matched_words[2]} )) # otherwise the one before + fi + elif [[ -n "${matched_words[6]}" ]]; then + (( pos2 += ${#matched_words[6]} )) + elif [[ -n "${matched_words[3]}" ]]; then + # couldn't grab whitespace forwards so try backwards + (( pos1 -= ${#matched_words[3]} )) + elif (( pos1 > 0 )); then + # There might have been whitespace before the word + (( CURSOR = pos1 )) + match-words-by-style + if [[ -n "${matched_words[3]}" ]]; then + (( pos1 -= ${#matched_words[3]} )) + fi + fi + fi + + (( MARK = pos1, CURSOR = pos2-1 )) + fi +done + +if [[ $KEYMAP == vicmd ]] && (( !REGION_ACTIVE )); then + (( CURSOR++ )) # Need to include cursor position for operators +fi -- cgit v1.2.3 From 26361e438b41862f5495ae263bc004cfffbd6b44 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 28 Jul 2016 09:50:03 +0100 Subject: 38953: Fix some issues with match-words-by-style. Add keyword retrieval of words. Improve test for start of word in subwords for use in delete-whole-word. If line after cursor is empty, white space is treated as ws-after-cursor. --- ChangeLog | 5 ++++ Doc/Zsh/contrib.yo | 11 +++++++++ Functions/Zle/delete-whole-word-match | 15 ++++++------ Functions/Zle/match-words-by-style | 45 +++++++++++++++++++++++++++++------ 4 files changed, 61 insertions(+), 15 deletions(-) (limited to 'Doc/Zsh/contrib.yo') diff --git a/ChangeLog b/ChangeLog index 88cf4cd19..03a2e29fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2016-07-28 Peter Stephenson + * 38953: Doc/Zsh/contrib.yo, + Functions/Zle/delete-whole-word-match, + Functions/Zle/match-words-by-style: Fix some problems with + match-words-by-style and add keyword retrieval of matched data. + * users/21793: README, Src/glob.c: remove ancient undocumented pre-"f" glob qualifer feature that unqualified integers were treated as octal file mode. diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index c3dec34cd..8db7395d0 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -2132,6 +2132,17 @@ non-word characters following that word (7) the remainder of the line. Any of the elements may be an empty string; the calling function should test for this to decide whether it can perform its function. +If the variable tt(matched_words) is defined by the caller to +tt(match-words-by-style) as an associative array (tt(local -A +matched_words)), then the seven values given above should be retrieved +from it as elements named tt(start), tt(word-before-cursor), +tt(ws-before-cursor), tt(ws-after-cursor), tt(word-after-cursor), +tt(ws-after-word), and tt(end). In addition the element +tt(is-word-start) is 1 if the cursor is on the start of a word or +subword, or on white space before it (the cases can be distinguished by +testing the tt(ws-after-cursor) element) and 0 otherwise. This form is +recommended for future compatibility. + It is possible to pass options with arguments to tt(match-words-by-style) to override the use of styles. The options are: startsitem() diff --git a/Functions/Zle/delete-whole-word-match b/Functions/Zle/delete-whole-word-match index aece86065..3d52dd3d7 100644 --- a/Functions/Zle/delete-whole-word-match +++ b/Functions/Zle/delete-whole-word-match @@ -12,30 +12,29 @@ emulate -L zsh setopt extendedglob local curcontext=:zle:$WIDGET -local -a matched_words +local -A matched_words # Start and end of range of characters to remove. integer pos1 pos2 autoload -Uz match-words-by-style match-words-by-style -if [[ -n "${matched_words[3]}" ]]; then - # There's whitespace before the cursor, so the word we are deleting - # starts at the cursor position. +if (( ${matched_words[is-word-start]} )); then + # The word we are deleting starts at the cursor position. pos1=$CURSOR else - # No whitespace before us, so delete any wordcharacters there. - pos1="${#matched_words[1]}" + # Not, so delete any wordcharacters before, too + pos1="${#matched_words[start]}" fi -if [[ -n "${matched_words[4]}" ]]; then +if [[ -n "${matched_words[ws-after-cursor]}" ]]; then # There's whitespace at the cursor position, so only delete # up to the cursor position. (( pos2 = CURSOR + 1 )) else # No whitespace at the cursor position, so delete the # current character and any following wordcharacters. - (( pos2 = CURSOR + ${#matched_words[5]} + 1 )) + (( pos2 = CURSOR + ${#matched_words[word-after-cursor]} + 1 )) fi # Move the cursor then delete the block in one go for the diff --git a/Functions/Zle/match-words-by-style b/Functions/Zle/match-words-by-style index 6cdec7551..fc59c2764 100644 --- a/Functions/Zle/match-words-by-style +++ b/Functions/Zle/match-words-by-style @@ -5,8 +5,16 @@ # # # where the cursor position is always after the third item and `after' -# is to be interpreted as `after or on'. Some -# of the array elements will be empty; this depends on the style. +# is to be interpreted as `after or on'. +# +# matched_words may be an associative array, in which case the +# values above are now given by the elements named start, word-before-cursor, +# ws-before-cursor, ws-after-cursor, word-after-cursor, ws-after-word, +# end. In addition, the element is-word-start is 1 if the cursor +# is on the start of a word; this is non-trivial in the case of subword +# (camel case) matching as there may be no white space to test. +# +# Some of the array elements will be empty; this depends on the style. # For example # foo bar rod stick # ^ @@ -224,11 +232,18 @@ charskip=${(l:skip::?:)} eval pat2='${RBUFFER##(#b)('${charskip}${spacepat}')('\ ${wordpat2}')('${spacepat}')}' +if [[ -n $match[2] ]]; then + ws2=$match[1] + word2=$match[2] + ws3=$match[3] +else + # No more words, so anything left is white space after cursor. + ws2=$RBUFFER + pat2= +fi -ws2=$match[1] -word2=$match[2] -ws3=$match[3] - +integer wordstart +[[ ( -n $ws1 || -n $ws2 ) && -n $word2 ]] && wordstart=1 if [[ $wordstyle = *subword* ]]; then # Do we have a group of upper case characters at the start # of word2 (that don't form the entire word)? @@ -249,6 +264,7 @@ if [[ $wordstyle = *subword* ]]; then # if it wants. elif [[ $word2 = (#b)(?[^${~subwordrange}]##)[${~subwordrange}]* ]]; then (( epos = ${#match[1]} )) + (( wordstart = 1 )) else (( epos = 0 )) fi @@ -262,4 +278,19 @@ if [[ $wordstyle = *subword* ]]; then fi fi -matched_words=("$pat1" "$word1" "$ws1" "$ws2" "$word2" "$ws3" "$pat2") +# matched_words should be local to caller. +# Just fix type here. +if [[ ${(t)matched_words} = *association* ]]; then + matched_words=( + start "$pat1" + word-before-cursor "$word1" + ws-before-cursor "$ws1" + ws-after-cursor "$ws2" + word-after-cursor "$word2" + ws-after-word "$ws3" + end "$pat2" + is-word-start $wordstart + ) +else + matched_words=("$pat1" "$word1" "$ws1" "$ws2" "$word2" "$ws3" "$pat2") +fi -- cgit v1.2.3 From b816bb42cfc4d0fa05abb63ebf4098af05a3d593 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 28 Jul 2016 16:16:25 +0200 Subject: 38957: make use of updates to match-words-by-style and better support completion of word-style styles for zstyle --- ChangeLog | 5 ++++ Completion/Zsh/Command/_zstyle | 7 ++++-- Doc/Zsh/contrib.yo | 2 +- Functions/Zle/select-word-match | 55 ++++++++++++++++++++--------------------- 4 files changed, 38 insertions(+), 31 deletions(-) (limited to 'Doc/Zsh/contrib.yo') diff --git a/ChangeLog b/ChangeLog index 6a5b0e5c4..1d68cf75d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2016-07-28 Oliver Kiddle + * 38957: Functions/Zle/select-word-match, + Completion/Zsh/Command/_zstyle, Doc/Zsh/contrib.yo: + make use of updates to match-words-by-style and better support + completion of word-style styles for zstyle + * 38956: Completion/Zsh/Command/_bindkey, Completion/Zsh/Command/_vared, Completion/Zsh/Command/_zle, Completion/Zsh/Function/_add-zle-hook-widget, diff --git a/Completion/Zsh/Command/_zstyle b/Completion/Zsh/Command/_zstyle index 9a6d61891..20ff47f87 100644 --- a/Completion/Zsh/Command/_zstyle +++ b/Completion/Zsh/Command/_zstyle @@ -173,6 +173,7 @@ styles=( url-seps e: whence e: word-chars e: + word-class e: word-style e:word-style word-context e: @@ -241,11 +242,13 @@ while (( $#state )); do case "$state[1]" in (contexts) if [[ ! -prefix :*: ]]; then - _wanted contexts expl context compadd -P : -qS : completion vcs_info zftp + _wanted contexts expl context compadd -P : -qS : chpwd completion vcs_info zftp zle elif compset -P :completion:; then contexts=( functions _completers cmdorcont argument tag ) elif compset -P :vcs_info:; then contexts=( vcs-string user-context repo-root-name ) + elif compset -P :zle:; then + _wanted widgets expl widget _widgets -qS : fi if (( $#contexts )); then for ostate in $contexts; do @@ -521,7 +524,7 @@ while (( $#state )); do ;; (word-style) - _wanted word-styles expl 'word style' compadd normal shell space + _wanted word-styles expl 'word style' compadd {normal,specified,unspecified,shell,whitespace}-subword ;; (vcs-string) diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 8db7395d0..00ed08029 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -2105,7 +2105,7 @@ Here are some examples of use of the tt(word-context) style to extend the context. example(zstyle ':zle:*' word-context \ - "*/*" file "[[:space:]]" whitespace + "*/*" filename "[[:space:]]" whitespace zstyle ':zle:transpose-words:whitespace' word-style shell zstyle ':zle:transpose-words:filename' word-style normal zstyle ':zle:transpose-words:filename' word-chars '') diff --git a/Functions/Zle/select-word-match b/Functions/Zle/select-word-match index 24620c995..8440852ab 100644 --- a/Functions/Zle/select-word-match +++ b/Functions/Zle/select-word-match @@ -12,7 +12,7 @@ emulate -L zsh setopt extendedglob local curcontext=:zle:$WIDGET -local -a matched_words +local -A matched_words # Start and end of range of characters integer pos1 pos2 num=${NUMERIC:-1} local style word @@ -28,10 +28,10 @@ while (( num-- )); do if (( MARK > CURSOR )); then # if cursor is at the start of the selection, just move back a word match-words-by-style - if [[ $style = i && -n $matched_words[3] ]]; then - word=$matched_words[3] + if [[ $style = i && -n $matched_words[ws-before-cursor] ]]; then + word=$matched_words[ws-before-cursor] else - word=$matched_words[2]$matched_words[3] + word=$matched_words[word-before-cursor]$matched_words[ws-before-cursor] fi if [[ -n $word ]]; then (( CURSOR -= ${#word} )) @@ -43,41 +43,40 @@ while (( num-- )); do (( CURSOR+1 == $#BUFFER )) && return 1 (( CURSOR++ )) match-words-by-style - if [[ -n $matched_words[4] ]]; then + if [[ -n $matched_words[ws-after-cursor] ]]; then if [[ $style = i ]]; then # just skip the whitespace - word=$matched_words[4] + word=$matched_words[ws-after-cursor] else # skip the whitespace plus word - word=$matched_words[4]$matched_words[5] + word=$matched_words[ws-after-cursor]$matched_words[word-after-cursor] fi else if [[ $style = i ]]; then # skip the word - word=$matched_words[5] + word=$matched_words[word-after-cursor] else # skip word and following whitespace - word=$matched_words[5]$matched_words[6] + word=$matched_words[word-after-cursor]$matched_words[ws-after-word] fi fi (( CURSOR += ${#word} - 1 )) else match-words-by-style - if [[ -n "${matched_words[3]}" ]]; then - # There's whitespace before the cursor, so the word we are selecting - # starts at the cursor position. + if (( ${matched_words[is-word-start]} )); then + # The word we are selecting starts at the cursor position. pos1=$CURSOR else # No whitespace before us, so select any wordcharacters there. - pos1="${#matched_words[1]}" + pos1="${#matched_words[start]}" fi - if [[ -n "${matched_words[4]}" ]]; then - if [[ -n "${matched_words[3]}" ]] || (( CURSOR == 0 )); then + if [[ -n "${matched_words[ws-after-cursor]}" ]]; then + if [[ -n "${matched_words[ws-before-cursor]}" ]] || (( CURSOR == 0 )); then # whitespace either side, select it - (( pos1 = CURSOR - ${#matched_words[3]} )) - (( pos2 = CURSOR + ${#matched_words[4]} )) + (( pos1 = CURSOR - ${#matched_words[ws-before-cursor]} )) + (( pos2 = CURSOR + ${#matched_words[ws-after-cursor]} )) else # There's whitespace at the cursor position, so only select # up to the cursor position. @@ -86,28 +85,28 @@ while (( num-- )); do else # No whitespace at the cursor position, so select the # current character and any following wordcharacters. - (( pos2 = CURSOR + ${#matched_words[5]} )) + (( pos2 = CURSOR + ${#matched_words[word-after-cursor]} )) fi if [[ $style = a ]]; then - if [[ -n "${matched_words[4]}" && ( -n "${matched_words[3]}" || CURSOR -eq 0 ) ]]; then + if [[ -n "${matched_words[ws-after-cursor]}" && ( -n "${matched_words[ws-before-cursor]}" || CURSOR -eq 0 ) ]]; then # in the middle of whitespace so grab a word - if [[ -n "${matched_words[5]}" ]]; then - (( pos2 += ${#matched_words[5]} )) # preferably the one after + if [[ -n "${matched_words[word-after-cursor]}" ]]; then + (( pos2 += ${#matched_words[word-after-cursor]} )) # preferably the one after else - (( pos1 -= ${#matched_words[2]} )) # otherwise the one before + (( pos1 -= ${#matched_words[word-before-cursor]} )) # otherwise the one before fi - elif [[ -n "${matched_words[6]}" ]]; then - (( pos2 += ${#matched_words[6]} )) - elif [[ -n "${matched_words[3]}" ]]; then + elif [[ -n "${matched_words[ws-after-word]}" ]]; then + (( pos2 += ${#matched_words[ws-after-word]} )) + elif [[ -n "${matched_words[ws-before-cursor]}" ]]; then # couldn't grab whitespace forwards so try backwards - (( pos1 -= ${#matched_words[3]} )) + (( pos1 -= ${#matched_words[ws-before-cursor]} )) elif (( pos1 > 0 )); then # There might have been whitespace before the word (( CURSOR = pos1 )) match-words-by-style - if [[ -n "${matched_words[3]}" ]]; then - (( pos1 -= ${#matched_words[3]} )) + if [[ -n "${matched_words[ws-before-cursor]}" ]]; then + (( pos1 -= ${#matched_words[ws-before-cursor]} )) fi fi fi -- cgit v1.2.3 From 7154052ebe3d810390164a05c39ff83f98a1d858 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Sat, 30 Jul 2016 16:16:22 +0000 Subject: 39046 + 39061: New :P history modifier. --- ChangeLog | 10 ++++++++++ Completion/Base/Completer/_external_pwds | 2 +- Completion/Zsh/Type/_history_modifiers | 5 +++-- Doc/Zsh/contrib.yo | 2 +- Doc/Zsh/expn.yo | 9 +++++++++ Functions/MIME/zsh-mime-handler | 2 +- Functions/VCS_Info/VCS_INFO_quilt | 2 +- Functions/Zle/expand-absolute-path | 2 +- NEWS | 11 +++++++++++ Src/params.c | 2 +- Src/subst.c | 13 +++++++++++++ Src/utils.c | 14 ++++++++------ Test/D02glob.ztst | 8 ++++++++ 13 files changed, 68 insertions(+), 14 deletions(-) (limited to 'Doc/Zsh/contrib.yo') diff --git a/ChangeLog b/ChangeLog index 65263033a..d3a7d3356 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2016-08-22 Daniel Shahaf + + * 39046 + 39061: Completion/Base/Completer/_external_pwds, + Completion/Zsh/Type/_history_modifiers, Doc/Zsh/contrib.yo, + Doc/Zsh/expn.yo, Functions/MIME/zsh-mime-handler, + Functions/VCS_Info/VCS_INFO_quilt, + Functions/Zle/expand-absolute-path, NEWS, Src/params.c, + Src/subst.c, Src/utils.c, Test/D02glob.ztst: New :P history + modifier. + 2016-08-20 Jun-ichi Takimoto * 39064: configure.ac, Src/Modules/mathfuc.c: use scalbn() instead diff --git a/Completion/Base/Completer/_external_pwds b/Completion/Base/Completer/_external_pwds index 4ad50f02b..79e3ba0eb 100644 --- a/Completion/Base/Completer/_external_pwds +++ b/Completion/Base/Completer/_external_pwds @@ -22,7 +22,7 @@ case $OSTYPE in ) ;; linux*) - dirs=( /proc/${^$(pidof zsh):#$$}/cwd(N:A) ) + dirs=( /proc/${^$(pidof zsh):#$$}/cwd(N:P) ) dirs=( $^dirs(N^@) ) ;; *) diff --git a/Completion/Zsh/Type/_history_modifiers b/Completion/Zsh/Type/_history_modifiers index 658f9f346..1a049d6cb 100644 --- a/Completion/Zsh/Type/_history_modifiers +++ b/Completion/Zsh/Type/_history_modifiers @@ -64,8 +64,8 @@ while true; do ) if (( ! global )); then list+=( - "a:absolute path" - "A:absolute path resolving symbolic links" + "a:absolute path, resolve '..' lexically" + "A:as ':a', then resolve symlinks" "c:PATH search for command" "g:globally apply s or &" "h:head - strip trailing path element" @@ -73,6 +73,7 @@ while true; do "r:root - strip suffix" "e:leave only extension" "Q:strip quotes" + "P:realpath, resolve '..' physically" "l:lower case all words" "u:upper case all words" ) diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 00ed08029..63df292ac 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -3477,7 +3477,7 @@ will ensure that any files found in that area will be executed as MIME types even if they are executable. As this example shows, the complete file name is matched against the pattern, regardless of how the file was passed to the handler. The file is resolved to a full path using -the tt(:A) modifier described in +the tt(:P) modifier described in ifzman(the subsection Modifiers in zmanref(zshexpn))\ ifnzman(noderef(Modifiers)); this means that symbolic links are resolved where possible, so that diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index ca4b94f5e..ecb1877a2 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -240,6 +240,7 @@ function, symbolic links are not resolved, so on those systems `tt(a)' and `tt(A)' are equivalent. Note: tt(foo:A) and tt(realpath+LPAR()foo+RPAR()) are different on some inputs. +For tt(realpath+LPAR()foo+RPAR()) semantics, see the `tt(P)` modifier. ) item(tt(c))( Resolve a command name into an absolute path by searching the command @@ -265,6 +266,14 @@ item(tt(p))( Print the new command but do not execute it. Only works with history expansion. ) +item(tt(P))( +Turn a file name into an absolute path, like tt(realpath+LPAR()3+RPAR()). +The resulting path will be absolute, have neither `tt(.)' nor `tt(..)' components, +and refer to the same directory entry as the input filename. + +Unlike tt(realpath+LPAR()3+RPAR()), non-existent trailing components are +permitted and preserved. +) item(tt(q))( Quote the substituted words, escaping further substitutions. Works with history expansion and parameter expansion, though for parameters diff --git a/Functions/MIME/zsh-mime-handler b/Functions/MIME/zsh-mime-handler index 24e5184fc..288a0796d 100644 --- a/Functions/MIME/zsh-mime-handler +++ b/Functions/MIME/zsh-mime-handler @@ -127,7 +127,7 @@ for pattern in $exec_asis; do files=(${dirpref}${~pattern}) if [[ -n ${files[(r)$1]} ]]; then for pattern in $exec_never; do - [[ ${1:A} = ${~pattern} ]] && break 2 + [[ ${1:P} = ${~pattern} ]] && break 2 done if (( list )); then for (( i = 1; i <= $#; i++ )); do diff --git a/Functions/VCS_Info/VCS_INFO_quilt b/Functions/VCS_Info/VCS_INFO_quilt index e7cd89f78..6adf0a358 100644 --- a/Functions/VCS_Info/VCS_INFO_quilt +++ b/Functions/VCS_Info/VCS_INFO_quilt @@ -170,7 +170,7 @@ function VCS_INFO_quilt() { applied=() fi patches=$(<$pc/.quilt_patches) - patches=`builtin cd -q "${pc:h}" && print -r - ${patches:A}` + patches=`builtin cd -q "${pc:h}" && print -r - ${patches:P}` fi if zstyle -t "${context}" get-unapplied; then # This zstyle call needs to be moved further up if `quilt' needs diff --git a/Functions/Zle/expand-absolute-path b/Functions/Zle/expand-absolute-path index b85757600..4887f3c60 100644 --- a/Functions/Zle/expand-absolute-path +++ b/Functions/Zle/expand-absolute-path @@ -10,7 +10,7 @@ autoload -Uz modify-current-argument if (( ! ${+functions[glob-expand-absolute-path]} )); then glob-expand-absolute-path() { local -a files - files=(${~1}(N:A)) + files=(${~1}(N:P)) (( ${#files} )) || return REPLY=${(D)files[1]} } diff --git a/NEWS b/NEWS index 15822ad34..65b246d33 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,17 @@ CHANGES FROM PREVIOUS VERSIONS OF ZSH Note also the list of incompatibilities in the README file. +Changes from 5.2 to 5.3 +----------------------- + +The new word modifier ':P' computes the physical path of the argument. +It is different from the existing ':a' modifier which always resolves +'/before/here/../after' to '/before/after', and differs from the +existing ':A' modifier which resolves symlinks only after 'here/..' is +removed, even when /before/here is itself a symbolic link. It is +recommended to review uses of ':A' and, if appropriate, convert them +to ':P' as soon as compatibility with 5.2 is no longer a requirement. + Changes from 5.1.1 to 5.2 ------------------------- diff --git a/Src/params.c b/Src/params.c index 0eda7848f..842b2f0d1 100644 --- a/Src/params.c +++ b/Src/params.c @@ -4336,7 +4336,7 @@ void homesetfn(UNUSED(Param pm), char *x) { zsfree(home); - if (x && isset(CHASELINKS) && (home = xsymlink(x))) + if (x && isset(CHASELINKS) && (home = xsymlink(x, 0))) zsfree(x); else home = x ? x : ztrdup(""); diff --git a/Src/subst.c b/Src/subst.c index c61551bf6..15eb59b64 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -4081,6 +4081,7 @@ modify(char **str, char **ptr) case 'u': case 'q': case 'Q': + case 'P': c = **ptr; break; @@ -4287,6 +4288,12 @@ modify(char **str, char **ptr) untokenize(copy); } break; + case 'P': + if (*copy != '/') { + copy = zhtricat(metafy(zgetcwd(), -1, META_HEAPDUP), "/", copy); + } + copy = xsymlink(copy, 1); + break; } tc = *tt; *tt = '\0'; @@ -4363,6 +4370,12 @@ modify(char **str, char **ptr) untokenize(*str); } break; + case 'P': + if (**str != '/') { + *str = zhtricat(metafy(zgetcwd(), -1, META_HEAPDUP), "/", *str); + } + *str = xsymlink(*str, 1); + break; } } if (rec < 0) { diff --git a/Src/utils.c b/Src/utils.c index 0a5954f65..45fd19286 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -801,9 +801,9 @@ findpwd(char *s) char *t; if (*s == '/') - return xsymlink(s); + return xsymlink(s, 0); s = tricat((pwd[1]) ? pwd : "", "/", s); - t = xsymlink(s); + t = xsymlink(s, 0); zsfree(s); return t; } @@ -969,11 +969,13 @@ xsymlinks(char *s, int full) /* * expand symlinks in s, and remove other weird things: * note that this always expands symlinks. + * + * 'heap' indicates whether to malloc() or allocate on the heap. */ /**/ char * -xsymlink(char *s) +xsymlink(char *s, int heap) { if (*s != '/') return NULL; @@ -981,8 +983,8 @@ xsymlink(char *s) if (xsymlinks(s + 1, 1) < 0) zwarn("path expansion failed, using root directory"); if (!*xbuf) - return ztrdup("/"); - return ztrdup(xbuf); + return heap ? dupstring("/") : ztrdup("/"); + return heap ? dupstring(xbuf) : ztrdup(xbuf); } /**/ @@ -1260,7 +1262,7 @@ getnameddir(char *name) /* Retrieve an entry from the password table/database for this user. */ struct passwd *pw; if ((pw = getpwnam(name))) { - char *dir = isset(CHASELINKS) ? xsymlink(pw->pw_dir) + char *dir = isset(CHASELINKS) ? xsymlink(pw->pw_dir, 0) : ztrdup(pw->pw_dir); if (dir) { adduserdir(name, dir, ND_USERNAME, 1); diff --git a/Test/D02glob.ztst b/Test/D02glob.ztst index 7befbc21f..1385d57d9 100644 --- a/Test/D02glob.ztst +++ b/Test/D02glob.ztst @@ -678,3 +678,11 @@ rm glob.tmp/link 0:modifier ':A' resolves '..' components before symlinks # There should be no output + + ln -s dir3/subdir glob.tmp/link + () { + print ${1:P} + } glob.tmp/link/../../hello/world + rm glob.tmp/link +0:modifier ':P' resolves symlinks before '..' components +*>*glob.tmp/hello/world -- cgit v1.2.3 From 4f2a1810f2fa1d74008e03a09d66eaff3e5edc9e Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Thu, 29 Sep 2016 09:50:09 +0000 Subject: 39495: add-zle-hook-widget: Add end-of-options guard to hook invocation. Currently, the only special widget that takes arguments is zle-keymap-select. --- ChangeLog | 3 +++ Doc/Zsh/contrib.yo | 2 +- Functions/Misc/add-zle-hook-widget | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'Doc/Zsh/contrib.yo') diff --git a/ChangeLog b/ChangeLog index 9df255631..b1b000025 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2016-09-30 Daniel Shahaf + * 39495: Doc/Zsh/contrib.yo, Functions/Misc/add-zle-hook-widget: + add-zle-hook-widget: Add end-of-options guard to hook invocation. + * 39480: Completion/Debian/Command/_bug: _reportbug: Complete absolute filenames, too. diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 63df292ac..189a084ba 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -346,7 +346,7 @@ as the var(hook) argument. var(widgetname) is the name of a ZLE widget. If no options are given this is added to the array of widgets to be invoked in the given hook context. Note that the hooks are called as widgets, that is, with -example(tt(zle )var(widgetname)tt( -Nw "$@")) +example(tt(zle )var(widgetname)tt( -Nw -- "$@")) vindex(WIDGET, in hooks) Note that this means that the `tt(WIDGET)' special parameter tracks the diff --git a/Functions/Misc/add-zle-hook-widget b/Functions/Misc/add-zle-hook-widget index 572de2561..d8a3950fb 100644 --- a/Functions/Misc/add-zle-hook-widget +++ b/Functions/Misc/add-zle-hook-widget @@ -47,9 +47,9 @@ function azhw:${^hooktypes} { for hook in "${(@)${(@on)hook_widgets[@]}#<->:}"; do if [[ "$hook" = user:* ]]; then # Preserve $WIDGET within the renamed widget - zle "$hook" -N "$@" + zle "$hook" -N -- "$@" else - zle "$hook" -Nw "$@" + zle "$hook" -Nw -- "$@" fi || return done return 0 -- cgit v1.2.3 From b4cc190db9a8419ca8c5a39ae45c95cb9db0ff84 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Fri, 30 Sep 2016 15:26:27 +0000 Subject: 39522: add-zsh-hook/add-zle-hook-widget: Promise append semantics. The sentence about "as widgets" is removed since there is a whole paragraph about that later on. --- ChangeLog | 3 +++ Doc/Zsh/contrib.yo | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'Doc/Zsh/contrib.yo') diff --git a/ChangeLog b/ChangeLog index 06efc60b2..a1699ac24 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2016-10-07 Daniel Shahaf + * 39522: Doc/Zsh/contrib.yo: add-zsh-hook/add-zle-hook-widget: + Promise append semantics. + * 39489: Completion/Unix/Type/_path_files: Interpret -P as literally, rather than as a pattern. diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 189a084ba..653d1bc98 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -311,6 +311,7 @@ still be manipulated as a hook. var(function) is name of an ordinary shell function. If no options are given this will be added to the array of functions to be executed in the given context. +Functions are invoked in the order they were added. If the option tt(-L) is given, the current values for the hook arrays are listed with tt(typeset). @@ -345,7 +346,7 @@ as the var(hook) argument. var(widgetname) is the name of a ZLE widget. If no options are given this is added to the array of widgets to be invoked in the given hook context. -Note that the hooks are called as widgets, that is, with +Widgets are invoked in the order they were added, with example(tt(zle )var(widgetname)tt( -Nw -- "$@")) vindex(WIDGET, in hooks) -- cgit v1.2.3 From 5dbfbd8bd016832c46c63b095cb60d043b37d379 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Wed, 21 Sep 2016 03:54:41 +0000 Subject: unposted: Minor documentation fixes (markup, grammar, etc). --- ChangeLog | 3 +++ Doc/Zsh/compsys.yo | 7 ++++--- Doc/Zsh/contrib.yo | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) (limited to 'Doc/Zsh/contrib.yo') diff --git a/ChangeLog b/ChangeLog index 0592589fc..5caf8735f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2016-10-27 Daniel Shahaf + * unposted: Doc/Zsh/compsys.yo, Doc/Zsh/contrib.yo: Minor + documentation fixes (markup, grammar, etc). + * 39739: Completion/Unix/Command/_head, Completion/Unix/Command/_tail: Complete negative integers for -n/-c in the GNU variant. (after 39479) diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index 42482760b..ceb98c7bc 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -1115,14 +1115,14 @@ tt(default) tag. The most notable styles of this type are tt(menu), tt(list-colors) and styles controlling completion listing such as tt(list-packed) and tt(last-prompt). When tested for the tt(default) tag, only the var(function) field of the context will be set so that -a style using the default tag will normally be defined along the lines of: +a style using the tt(default) tag will normally be defined along the lines of: example(zstyle ':completion:*:default' menu ...) startitem() kindex(accept-exact, completion style) item(tt(accept-exact))( -This is tested for the default tag in addition to the tags valid for +This is tested for the tt(default) tag in addition to the tags valid for the current context. If it is set to `true' and any of the trial matches is the same as the string on the command line, this match will immediately be accepted (even if it would otherwise be considered @@ -3252,6 +3252,7 @@ for the current context; remember that the context for completers is less specific than that for contextual completion as the full context has not yet been determined. Elements of the array may have one of the following forms: + startsitem() sitem(tt($)var(hash))( var(hash) is the name of an associative array. Note this is not a full @@ -5013,7 +5014,7 @@ particular tag is to be tried, the tt(_requested) function should be called (see above). If `tt(-C) var(name)' is given, var(name) is temporarily stored in the -argument field (the fifth) of the context in the tt(curcontext) parameter +var(argument) field (the fifth) of the context in the tt(curcontext) parameter during the call to tt(_tags); the field is restored on exit. This allows tt(_tags) to use a more specific context without having to change and reset the diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 653d1bc98..623507283 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -1051,7 +1051,7 @@ tt(:vcs_info:-init-:*:-all-) context. Say, tt(~/.zsh) is a directory under version control, in which you do not want tt(vcs_info) to be active, do: -example(zstyle ':vcs_info:*' disable-patterns "$HOME/.zsh+LPAR()|/*+RPAR()") +example(zstyle ':vcs_info:*' disable-patterns "${+LPAR()b+RPAR()HOME}/.zsh+LPAR()|/*+RPAR()") ) kindex(use-quilt) item(tt(use-quilt))( @@ -1070,7 +1070,7 @@ tt(Quilt Support) for details. ) kindex(quiltcommand) item(tt(quiltcommand))( -When tt(quilt) itself is called in quilt support the value of this style +When tt(quilt) itself is called in quilt support, the value of this style is used as the command name. ) kindex(check-for-changes) -- cgit v1.2.3 From 110ffae9fefa1367af4fdcc90a456de23b92436c Mon Sep 17 00:00:00 2001 From: Eitan Adler Date: Mon, 28 Nov 2016 22:53:24 -0800 Subject: 40035: Cosmetic fixes for comments and documentation. Mostly fixes to doubled words. --- ChangeLog | 7 +++++-- Completion/Base/Utility/_arguments | 2 +- Completion/Unix/Command/_git | 2 +- Completion/Unix/Type/_zfs_dataset | 2 +- Completion/Zsh/Command/_zstyle | 2 +- Completion/Zsh/Function/_zargs | 2 +- Doc/Zsh/builtins.yo | 2 +- Doc/Zsh/compsys.yo | 4 ++-- Doc/Zsh/contrib.yo | 2 +- Etc/ChangeLog-4.3 | 2 +- Src/Zle/zle_refresh.c | 2 +- Src/glob.c | 2 +- Src/hist.c | 2 +- Src/input.c | 2 +- Src/subst.c | 2 +- Src/zsh.h | 2 +- Util/helpfiles | 2 +- 17 files changed, 22 insertions(+), 19 deletions(-) (limited to 'Doc/Zsh/contrib.yo') diff --git a/ChangeLog b/ChangeLog index a016ce0e6..0d5f61198 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2016-11-29 Peter Stephenson + * 40035: Eitan Adler: Cosmetic fixes mostly for duplication in + comments and documentation. + * 40026: Src/Zle/zle_tricky.c: More care with redirection completion. Fixes for completion after > in "!> ." that should add to sanity. @@ -3523,7 +3526,7 @@ 2015-09-28 Barton E. Schaefer - * 36669: Src/lex.c: fix ${(z)...} of an an incomplete math + * 36669: Src/lex.c: fix ${(z)...} of an incomplete math expression by restoring "((" at the front of the token 2015-09-28 Daniel Shahaf @@ -9517,7 +9520,7 @@ 2013-07-20 Peter Stephenson * 31545: Src/exec.c, Src/parse.c: if FD_CLOEXEC is available, - so mark dump file file descriptors, avoiding possible + so mark dump file descriptors, avoiding possible multiple use of file descriptors. 2013-07-19 Peter Stephenson diff --git a/Completion/Base/Utility/_arguments b/Completion/Base/Utility/_arguments index 82c969629..d2c0d33de 100644 --- a/Completion/Base/Utility/_arguments +++ b/Completion/Base/Utility/_arguments @@ -105,7 +105,7 @@ if (( long )); then continue else # Still no comment, add the previous options anyway. - # Add a ':' after the option anyways, to make the the matching of + # Add a ':' after the option anyways, to make the matching of # the options lateron work as intended. # It will be removed again later. lopts+=("${^tmp[@]}":) diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git index 283c50cc0..da049bd23 100644 --- a/Completion/Unix/Command/_git +++ b/Completion/Unix/Command/_git @@ -6114,7 +6114,7 @@ __git_recent_branches() { local -aU valid_ref_names_munged=( ${"${(f)"$(_call_program valid-ref-names 'git for-each-ref --format="%(refname)" refs/heads/')"}"#refs/heads/} ) # 1. Obtain names of recently-checked-out branches from the reflog. - # 2. Remove ref names that that no longer exist from the list. + # 2. Remove ref names that no longer exist from the list. # (We must do this because #3 would otherwise croak on them.) __git_recent_branches__names; branches=( ${(@)reply:*valid_ref_names_munged} ) diff --git a/Completion/Unix/Type/_zfs_dataset b/Completion/Unix/Type/_zfs_dataset index 6c625e9ec..6bef04e45 100644 --- a/Completion/Unix/Type/_zfs_dataset +++ b/Completion/Unix/Type/_zfs_dataset @@ -4,7 +4,7 @@ local -a type expl_type_arr rsrc rdst paths_allowed local -a typearg datasetlist expl mlist local expl_type -# -e takes an argument which is passed as as the "descr" argument to _wanted +# -e takes an argument which is passed as the "descr" argument to _wanted # -p indicates that filesystem paths, not just dataset names, are allowed # -r1 indicates that we're completing the source of a rename # -r2 indicates that we're completing the destination of a rename diff --git a/Completion/Zsh/Command/_zstyle b/Completion/Zsh/Command/_zstyle index d6f285271..0e828225e 100644 --- a/Completion/Zsh/Command/_zstyle +++ b/Completion/Zsh/Command/_zstyle @@ -266,7 +266,7 @@ while (( $#state )); do _wanted contexts expl "$state_descr" compadd -a patterns ;; - # 'metapatterns': patterns that are are matched not against contexts, but + # 'metapatterns': patterns that are matched not against contexts, but # against patterns. (metapatterns) zstyle -g patterns diff --git a/Completion/Zsh/Function/_zargs b/Completion/Zsh/Function/_zargs index c24b276f2..f974ab646 100644 --- a/Completion/Zsh/Function/_zargs +++ b/Completion/Zsh/Function/_zargs @@ -4,7 +4,7 @@ local arguments eofstr pos=$((CURRENT)) numeofs=0 ret=1 cmdpos=1 #this doesn't handle '--' on the command line, only -- #it also by extension doesn't handle eofstr being the empty string -#it also also doesn't handle eofstr being -e or --eof, and everything will +#it also doesn't handle eofstr being -e or --eof, and everything will # probably also be confused if the command at the end takes a -e, --eof= or -- eofstr=${${${${words[(r)(--eof=*|-e*)]}#--eof=}#-e}:---} while { diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index 169a31ea3..7b04d0648 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -570,7 +570,7 @@ with emulations to be set to their values in tt(sh). tt(fno) then calls tt(fni); because tt(fni) is also marked for sticky tt(sh) emulation, no option changes take place on entry to or exit from it. Hence the option tt(cshnullglob), turned off by tt(sh) emulation, will -be turned on within tt(fni) and remain on on return to tt(fno). On exit +be turned on within tt(fni) and remain on return to tt(fno). On exit from tt(fno), the emulation mode and all options will be restored to the state they were in before entry to the temporary emulation. diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index ceb98c7bc..60ef9ee2c 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -144,8 +144,8 @@ directory mentioned in the tt(fpath) parameter, and should be autoloaded few utility functions, arrange for all the necessary shell functions to be autoloaded, and will then re-define all widgets that do completion to use the new system. If you use the tt(menu-select) widget, which is part of the -tt(zsh/complist) module, you should make sure that that module is loaded -before the call to tt(compinit) so that that widget is also +tt(zsh/complist) module, you should make sure that the module is loaded +before the call to tt(compinit) so that the widget is also re-defined. If completion styles (see below) are set up to perform expansion as well as completion by default, and the TAB key is bound to tt(expand-or-complete), tt(compinit) will rebind it to tt(complete-word); diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index 623507283..f764eb7c6 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -3854,7 +3854,7 @@ The expression tt(<) followed (with no space) by a shell identifier causes the value of the variable with that name to be pushed onto the stack. var(ident) may be an integer, in which case the previous result with that number (as shown before -the tt(>) in th standard standard tt(zcalc) prompt) is put on the stack. +the tt(>) in the standard tt(zcalc) prompt) is put on the stack. ) item(Exchange: tt(xy))( The pseudo-function tt(xy) causes the most recent two elements of diff --git a/Etc/ChangeLog-4.3 b/Etc/ChangeLog-4.3 index 1be618b48..6d85e40af 100644 --- a/Etc/ChangeLog-4.3 +++ b/Etc/ChangeLog-4.3 @@ -1182,7 +1182,7 @@ 2011-08-16 Wayne Davison - * 29650: Src/jobs.c: don't lose the the time info after a + * 29650: Src/jobs.c: don't lose the time info after a suspend+restore. 2011-08-15 Peter Stephenson diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index e78f1e562..8d173cda1 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -946,7 +946,7 @@ addmultiword(REFRESH_ELEMENT *base, ZLE_STRING_T tptr, int ichars) /* * Swap the old and new video buffers, plus any associated multiword - * buffers. The new buffer becomes the old one; the new new buffer + * buffers. The new buffer becomes the old one; the new buffer * will be filled with the command line next time. */ static void diff --git a/Src/glob.c b/Src/glob.c index 33bf2ae18..623e6f1d6 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -1174,7 +1174,7 @@ checkglobqual(char *str, int sl, int nobareglob, char **sp) } /* Main entry point to the globbing code for filename globbing. * - * np points to a node in the list list which will be expanded * + * np points to a node in the list which will be expanded * * into a series of nodes. */ /**/ diff --git a/Src/hist.c b/Src/hist.c index 5be7d2524..97fd34039 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -1038,7 +1038,7 @@ hbegin(int dohist) /* * pws: We used to test for "|| (inbufflags & INP_ALIAS)" * in this test, but at this point we don't have input - * set up up so this can trigger unnecessarily. + * set up so this can trigger unnecessarily. * I don't see how the test at this point could ever be * useful, since we only get here when we're initialising * the history mechanism, before we've done any input. diff --git a/Src/input.c b/Src/input.c index eb968ea72..fe94b8ef7 100644 --- a/Src/input.c +++ b/Src/input.c @@ -51,7 +51,7 @@ * Note that the input string is itself used as the input buffer: it is not * copied, nor is it every written back to, so using a constant string * should work. Consequently, when passing areas of memory from the heap - * it is necessary that that heap last as long as the operation of reading + * it is necessary that the heap last as long as the operation of reading * the string. After the string is read, the stack should be popped with * inpop(), which effectively flushes any unread input as well as restoring * the previous input state. diff --git a/Src/subst.c b/Src/subst.c index c7c552257..a26ebb1d6 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -2368,7 +2368,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * This is the inner handling for the case referred to above * where we have something like ${${(P)name}...}. * - * Treat this as as a normal value here; all transformations on + * Treat this as a normal value here; all transformations on * result are in outer instance. */ aspar = 0; diff --git a/Src/zsh.h b/Src/zsh.h index a5d4455e3..63cada827 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -1589,7 +1589,7 @@ struct zpc_disables_save { /* * Bit vector of ZPC_COUNT disabled characters. * We'll live dangerously and assumed ZPC_COUNT is no greater - * than the number of bits an an unsigned int. + * than the number of bits an unsigned int. */ unsigned int disables; }; diff --git a/Util/helpfiles b/Util/helpfiles index 699ca8321..9e837fe2d 100755 --- a/Util/helpfiles +++ b/Util/helpfiles @@ -19,7 +19,7 @@ # This script is called automatically during `make install' # unless specified otherwise. -# For usage and and more information see zshcontrib(1). +# For usage and more information see zshcontrib(1). sub Usage { print(STDERR "Usage: helpfiles zshbuiltins.1 dest-dir [link-file]\n"); -- cgit v1.2.3