about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--Completion/Zsh/Context/.distfiles19
-rw-r--r--Completion/Zsh/Context/_zcalc_line83
-rw-r--r--Doc/Zsh/contrib.yo48
-rw-r--r--Functions/Misc/zcalc57
5 files changed, 179 insertions, 34 deletions
diff --git a/ChangeLog b/ChangeLog
index 2e7c778e9..339086f37 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2008-06-13  Peter Stephenson  <pws@csr.com>
 
+	* 25152: Completion/Zsh/Context/{.distfiles,_zcalc_line}
+	(moved from Type because this is where it should be),
+	Doc/Zsh/contrib.yo, Functions/Misc/zcalc: improved zcalc
+	escape commands with ":" including ":!" and ":raw"; more complete
+	zcalc completion with special context.
+
 	* unposted: Completion/{Unix,Linux}/Command/{strace,.distfiles}: move
 
 	* users/12911: Tomasz Pala <gotar@polanet.pl>:
diff --git a/Completion/Zsh/Context/.distfiles b/Completion/Zsh/Context/.distfiles
index 59777c30d..8b4acfc7a 100644
--- a/Completion/Zsh/Context/.distfiles
+++ b/Completion/Zsh/Context/.distfiles
@@ -1,7 +1,18 @@
 DISTFILES_SRC='
 .distfiles
-_assign           _autocd
-_brace_parameter  _equal            _math             _subscript
-_condition        _first            _parameter        _tilde
-_default          _in_vared         _redirect         _value
+_assign
+_autocd
+_brace_parameter
+_condition
+_default
+_equal
+_first
+_in_vared
+_math
+_parameter
+_redirect
+_subscript
+_tilde
+_value
+_zcalc_line
 '
diff --git a/Completion/Zsh/Context/_zcalc_line b/Completion/Zsh/Context/_zcalc_line
new file mode 100644
index 000000000..6ce3d82bf
--- /dev/null
+++ b/Completion/Zsh/Context/_zcalc_line
@@ -0,0 +1,83 @@
+#compdef -zcalc-line-
+
+# This handles completion of a zcalc command line read via vared.
+
+_zcalc_line_escapes() {
+  local -a cmds
+  cmds=(
+    "!:shell escape"
+    "q:quit"
+    "norm:normal output format"
+    "sci:scientific output format"
+    "fix:fixed point output format"
+    "eng:engineering (power of 1000) output format"
+    "raw:raw output format"
+    "local:make variables local"
+    "function:define math function"
+  )
+  cmds=("\:"${^cmds})
+  _describe -t command-escapes "command escapes" cmds -Q
+}
+
+_zcalc_line() {
+  local expl
+
+  if [[ CURRENT -eq 1 && $words[1] != ":!"* ]]; then
+    local -a alts
+    if [[ $words[1] = (|:*) ]]; then
+      alts=("command-escapes:command escape:_zcalc_line_escapes")
+    fi
+    if [[ $words[1] = (|[^:]*) ]]; then
+      alts+=("math:math formula:_math")
+    fi
+    _alternative $alts
+    return
+  fi
+
+  case $words[1] in
+    (":!"*)
+    if [[ $words[1] = ":!" ]]; then
+      shift words
+      (( CURRENT >1 && CURRENT-- ))
+    else
+      words[1]=${words[1]##:\!}
+      if (( CURRENT == 1 )); then
+	compset -P ":\!"
+      fi
+    fi
+    _normal
+    ;;
+
+    (:function)
+    # completing already defined user math functions is in fact exactly
+    # the wrong thing to do since currently zmathfuncdef won't overwrite,
+    # but it may jog the user's memory...
+    if (( CURRENT == 2 )); then
+      _wanted math-functions expl 'math function' \
+	compadd -- ${${(k)functions:#^zsh_math_func_*}##zsh_math_func_}
+    else
+      _math
+    fi
+    ;;
+
+    (:local)
+    _parameter
+    ;;
+
+    (:(fix|sci|eng))
+    if (( CURRENT == 2 )); then
+      _message "precision"
+    fi
+    ;&
+
+    (:*)
+    _message "no more arguments"
+    ;;
+
+    ([^:]*)
+    _math
+    ;;
+  esac
+}
+
+_zcalc_line "$@"
diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo
index 1c8b2f92c..042a5bd9c 100644
--- a/Doc/Zsh/contrib.yo
+++ b/Doc/Zsh/contrib.yo
@@ -1825,8 +1825,8 @@ calculation is stored.  For example, the result of the calculation on the
 line preceded by `tt(4> )' is available as tt($4).  The last value
 calculated is available as tt(ans).  Full command line editing, including
 the history of previous calculations, is available; the history is saved in
-the file tt(~/.zcalc_history).  To exit, enter a blank line or type `tt(q)'
-on its own.
+the file tt(~/.zcalc_history).  To exit, enter a blank line or type `tt(:q)'
+on its own (`tt(q)' is allowed for historical compatibility).
 
 If arguments are given to tt(zcalc) on start up, they are used to prime the
 first few positional parameters.  A visual indication of this is given when
@@ -1846,37 +1846,51 @@ 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> )'.
 
+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.
+
 The output precision may be specified within zcalc by special commands
-familiar from many calculators:
+familiar from many calculators.
 startitem()
-item(tt(norm))(
+item(tt(:norm))(
 The default output format.  It corresponds to the printf tt(%g)
 specification.  Typically this shows six decimal digits.
 )
-item(tt(sci) var(digits))(
+item(tt(:sci) var(digits))(
 Scientific notation, corresponding to the printf tt(%g) output format with
 the precision given by var(digits).  This produces either fixed point or
 exponential notation depending on the value output.
 )
-item(tt(fix) var(digits))(
+item(tt(:fix) var(digits))(
 Fixed point notation, corresponding to the printf tt(%f) output format with
 the precision given by var(digits).
 )
-item(tt(eng) var(digits))(
+item(tt(:eng) var(digits))(
 Exponential notation, corresponding to the printf tt(%E) output format with
 the precision given by var(digits).
 )
+item(tt(:raw))(
+Raw output:  this is the default form of the output from a math
+evaluation.  This may show more precision than the number actually
+possesses.
+)
 enditem()
 
 Other special commands:
 startitem()
-item(tt(local) var(arg) ...)(
+item(tt(:!)var(line...))(
+Execute var(line...) as a normal shell command line.  Note that it
+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
 may be used, too, but they will be taken from or put into the global
 scope.
 )
-item(tt(function) var(name) [ var(body) ])(
+item(tt(:function) var(name) [ var(body) ])(
 Define a mathematical function or (with no var(body)) delete it.
 The function is defined using tt(zmathfuncdef), see below.
 
@@ -1887,14 +1901,14 @@ example(function cube $1 * $1 * $1)
 defines a function to cube the sole argument.
 )
 item(tt([#)var(base)tt(]))(
-When this syntax appears on a line by itself, the default output radix
-is set to var(base).  Use, for example, `tt([#16])' to display hexadecimal
-output preceded by an indication of the base, or `tt([##16])' just to
-display the raw number in the given base.  Bases themselves are 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.
-
+This is not a special command, rather part of normal arithmetic
+syntax; however, when this form appears on a line by itself the default
+output radix is set to var(base).  Use, for example, `tt([#16])' to display
+hexadecimal output preceded by an indication of the base, or `tt([##16])'
+just to display the raw number in the given base.  Bases themselves are
+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.
 )
 enditem()
 
diff --git a/Functions/Misc/zcalc b/Functions/Misc/zcalc
index 1c07e3798..2ec67a67d 100644
--- a/Functions/Misc/zcalc
+++ b/Functions/Misc/zcalc
@@ -96,16 +96,16 @@ setopt extendedglob
 # 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 compcontext="-math-"
+local compcontext="-zcalc-line-"
 integer num outdigits outform=1
 
 # 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' '')
 
 zmodload -i zsh/mathfunc 2>/dev/null
-autoload zmathfuncdef
+autoload -U zmathfuncdef
 
 : ${ZCALCPROMPT="%1v> "}
 
@@ -176,35 +176,62 @@ while vared -cehp "${(%)ZCALCPROMPT}" line; do
 
   print -s -- $line
 
-  case ${${line##[[:blank:]]#}%%[[:blank:]]#} in
-    (q) # Exit if `q' on its own.
-      return 0
+  line="${${line##[[:blank:]]#}%%[[:blank:]]#}"
+  case "$line" in
+    # Escapes begin with a colon
+    (:!*)
+    # shell escape
+    eval ${line##:\![[:blank:]]#}
+    line=
+    continue
     ;;
-    (norm) # restore output format to default
+
+    ((:|)q)
+    # Exit
+    return 0
+    ;;
+
+    ((:|)norm) # restore output format to default
       outform=1
     ;;
-    (sci[[:blank:]]#(#b)(<->)(#B))
+
+    ((:|)sci[[:blank:]]#(#b)(<->)(#B))
       outdigits=$match[1]
       outform=2
     ;;
-    (fix[[:blank:]]#(#b)(<->)(#B))
+
+    ((:|)fix[[:blank:]]#(#b)(<->)(#B))
       outdigits=$match[1]
       outform=3
     ;;
-    (eng[[:blank:]]#(#b)(<->)(#B))
+
+    ((:|)eng[[:blank:]]#(#b)(<->)(#B))
       outdigits=$match[1]
       outform=4
     ;;
-    (local([[:blank:]]##*|))
+
+    (:raw)
+    outform=5
+    ;;
+
+    ((:|)local([[:blank:]]##*|))
       eval $line
       line=
       continue
     ;;
-    (function[[:blank:]]##(#b)([^[:blank:]]##)(|[[:blank:]]##([^[:blank:]]*)))
+
+    ((:|)function[[:blank:]]##(#b)([^[:blank:]]##)(|[[:blank:]]##([^[:blank:]]*)))
       zmathfuncdef $match[1] $match[3]
       line=
       continue
     ;;
+
+    (:*)
+    print "Unrecognised escape"
+    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
@@ -222,7 +249,11 @@ while vared -cehp "${(%)ZCALCPROMPT}" line; do
   if [[ -n $base ]]; then
     print -- $(( $base $ans ))
   elif [[ $ans = *.* ]] || (( outdigits )); then
-    printf "$forms[outform]\n" $outdigits $ans
+    if [[ -z $forms[outform] ]]; then
+      print -- $(( $ans ))
+    else
+      printf "$forms[outform]\n" $outdigits $ans
+    fi
   else
     printf "%d\n" $ans
   fi