]> code.delx.au - gnu-emacs/blobdiff - lisp/calculator.el
* electric.el (global-map): Really bind C-j.
[gnu-emacs] / lisp / calculator.el
index c9a7305471265d121c349f440c4e1185170d9c89..d6eb892f7fb2cf3dec56e212ae2062212bcabf96 100644 (file)
@@ -1,6 +1,6 @@
-;;; calculator.el --- a [not so] simple calculator for Emacs
+;;; calculator.el --- a [not so] simple calculator for Emacs  -*- lexical-binding: t -*-
 
-;; Copyright (C) 1998, 2000-2013 Free Software Foundation, Inc.
+;; Copyright (C) 1998, 2000-2014 Free Software Foundation, Inc.
 
 ;; Author: Eli Barzilay <eli@barzilay.org>
 ;; Keywords: tools, convenience
@@ -131,14 +131,15 @@ The displayer is a symbol, a string or an expression.  A symbol should
 be the name of a one-argument function, a string is used with a single
 argument and an expression will be evaluated with the variable `num'
 bound to whatever should be displayed.  If it is a function symbol, it
-should be able to handle special symbol arguments, currently 'left and
-'right which will be sent by special keys to modify display parameters
+should be able to handle special symbol arguments, currently `left' and
+`right' which will be sent by special keys to modify display parameters
 associated with the displayer function (for example to change the number
 of digits displayed).
 
 An exception to the above is the case of the list (std C) where C is a
 character, in this case the `calculator-standard-displayer' function
 will be used with this character for a format string."
+  :type '(choice (function) (string) (list (const std) character) (sexp))
   :group 'calculator)
 
 (defcustom calculator-displayers
@@ -241,6 +242,8 @@ Examples:
 ;;;=====================================================================
 ;;; Code:
 
+(eval-when-compile (require 'cl-lib))
+
 ;;;---------------------------------------------------------------------
 ;;; Variables
 
@@ -1124,11 +1127,10 @@ the 'left or 'right when one of the standard modes is used."
         (format calculator-displayer num))
        ((symbolp calculator-displayer)
         (funcall calculator-displayer num))
-       ((and (consp calculator-displayer)
-             (eq 'std (car calculator-displayer)))
+       ((eq 'std (car-safe calculator-displayer))
         (calculator-standard-displayer num (cadr calculator-displayer)))
        ((listp calculator-displayer)
-        (eval calculator-displayer))
+        (eval calculator-displayer `((num. ,num))))
        (t (prin1-to-string num t))))
     ;; operators are printed here
     (t (prin1-to-string (nth 1 num) t))))
@@ -1273,29 +1275,24 @@ arguments."
       ;; smaller than calculator-epsilon (1e-15).  I don't think this is
       ;; necessary now.
       (if (symbolp f)
-        (cond ((and X Y) (funcall f X Y))
-              (X         (funcall f X))
-              (t         (funcall f)))
+          (cond ((and X Y) (funcall f X Y))
+                (X         (funcall f X))
+                (t         (funcall f)))
         ;; f is an expression
-        (let* ((__f__ f) ; so we can get this value below...
-               (TX (calculator-truncate X))
+        (let* ((TX (calculator-truncate X))
                (TY (and Y (calculator-truncate Y)))
                (DX (if calculator-deg (/ (* X pi) 180) X))
-               (L  calculator-saved-list)
-               (Fbound (fboundp 'F))
-               (Fsave  (and Fbound (symbol-function 'F)))
-               (Dbound (fboundp 'D))
-               (Dsave  (and Dbound (symbol-function 'D))))
-          ;; a shortened version of flet
-          (fset 'F (function
-                    (lambda (&optional x y)
-                      (calculator-funcall __f__ x y))))
-          (fset 'D (function
-                    (lambda (x)
-                      (if calculator-deg (/ (* x 180) float-pi) x))))
-          (unwind-protect (eval f)
-            (if Fbound (fset 'F Fsave) (fmakunbound 'F))
-            (if Dbound (fset 'D Dsave) (fmakunbound 'D)))))
+               (L  calculator-saved-list))
+          (cl-letf (((symbol-function 'F)
+                     (lambda (&optional x y) (calculator-funcall f x y)))
+                    ((symbol-function 'D)
+                     (lambda (x) (if calculator-deg (/ (* x 180) float-pi) x))))
+            (eval f `((X . ,X)
+                      (Y . ,Y)
+                      (TX . ,TX)
+                      (TY . ,TY)
+                      (DX . ,DX)
+                      (L . ,L))))))
     (error 0)))
 
 ;;;---------------------------------------------------------------------
@@ -1621,6 +1618,8 @@ Optional string argument KEYS will force using it as the keys entered."
              (setq s (match-string 1 s)))
            (kill-new s)))))
 
+;; FIXME this should use register-read-with-preview, but it
+;; uses calculator-registers rather than register-alist.
 (defun calculator-set-register (reg)
   "Set a register value for REG."
   (interactive "cRegister to store into: ")
@@ -1663,6 +1662,8 @@ Used by `calculator-paste' and `get-register'."
                             (or (match-string 3 str) ""))))
      (ignore-errors (calculator-string-to-number str)))))
 
+;; FIXME this should use register-read-with-preview, but it
+;; uses calculator-registers rather than register-alist.
 (defun calculator-get-register (reg)
   "Get a value from a register REG."
   (interactive "cRegister to get value from: ")