Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: zcalc escapes and completion



Various zcalc enhancements:

- escapes (i.e. commands other than expressions to evaluate) are
now standardised as beginning with ":", which can't introduce a formula.
However, I've left all the current commands for compatibility.

- :! does a shell escape

- :raw uses raw math expression output with no formatting

- add a completion function to complete special commands as well as
math.  ":!" works properly, so you don't have to leave zcalc to type
commands.

Index: Completion/Zsh/Type/.distfiles
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/Zsh/Type/.distfiles,v
retrieving revision 1.3
diff -u -r1.3 .distfiles
--- Completion/Zsh/Type/.distfiles	15 Mar 2008 23:21:02 -0000	1.3
+++ Completion/Zsh/Type/.distfiles	13 Jun 2008 13:48:49 -0000
@@ -20,4 +20,5 @@
 _parameters
 _suffix_alias_files
 _vars
+_zcalc_line
 '
Index: Completion/Zsh/Type/_zcalc_line
===================================================================
RCS file: Completion/Zsh/Type/_zcalc_line
diff -N Completion/Zsh/Type/_zcalc_line
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Completion/Zsh/Type/_zcalc_line	13 Jun 2008 13:48:49 -0000
@@ -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 "$@"
Index: Doc/Zsh/contrib.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/contrib.yo,v
retrieving revision 1.79
diff -u -r1.79 contrib.yo
--- Doc/Zsh/contrib.yo	17 May 2008 22:42:16 -0000	1.79
+++ Doc/Zsh/contrib.yo	13 Jun 2008 13:48:50 -0000
@@ -1825,8 +1825,8 @@
 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 @@
 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 @@
 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()
 
Index: Functions/Misc/zcalc
===================================================================
RCS file: /cvsroot/zsh/zsh/Functions/Misc/zcalc,v
retrieving revision 1.15
diff -u -r1.15 zcalc
--- Functions/Misc/zcalc	13 Dec 2007 22:20:59 -0000	1.15
+++ Functions/Misc/zcalc	13 Jun 2008 13:48:50 -0000
@@ -96,16 +96,16 @@
 # 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 @@
 
   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
+    ;;
+
+    ((:|)q)
+    # Exit
+    return 0
     ;;
-    (norm) # restore output format to default
+
+    ((:|)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 @@
   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



Messages sorted by: Reverse Date, Date, Thread, Author