aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Barzilay2015-11-29 15:24:27 -0500
committerEli Barzilay2015-11-29 17:30:52 -0500
commitf248292ede3940dde5e4ac29d96f8a0294788b0a (patch)
tree35eccd8580548628d7e399f6ad6f5644c5e2adf0
parent1b4570bc08b35ba98d48b3a8465948949cf5a31f (diff)
downloademacs-f248292ede3940dde5e4ac29d96f8a0294788b0a.tar.gz
emacs-f248292ede3940dde5e4ac29d96f8a0294788b0a.zip
* lisp/calculator.el: more improvements and bugfixes.
- Mark `calculator-paste-decimals' as obsolete. (It wasn't having an effect anyway.) - Simplify `calculator-number-to-string' by throwing most of the work onto `number-to-string', leaving just some tweaks for decimal inputs. This leads to some minor changes, for example, pasting "1x1" in hex mode would warn that "x" is ignored and result in "11" (and it wasn't done in decimal mode), whereas now it just ignores everything from the "x" and on and result in a "1" just like in decimal input mode. Also, overflows are left for `number-to-string' to deal with. - `calculator-paste' is very simple as a result. - Extend the simplified `calculator-paste': with a prefix argument it pastes a string as if the characters were entered. This can be used to reduce expressions, but note that it's a simple literal operation, so precedence can be messed, a number can be paster while entering a number, spaces and newlines matter, etc. - Fix a minor bug where "e+" in hex mode wouldn't use "+" as an operator. - Fix a bug in `calculator-put-value': avoid grouping in the display that is used to construct `calculator-curnum'. This would trigger when pasting or getting a value from a register in some radix mode with a large enough value. Another fix: make the output radix equal the input one, otherwise numbers could be converted twice.
-rw-r--r--lisp/calculator.el81
1 files changed, 30 insertions, 51 deletions
diff --git a/lisp/calculator.el b/lisp/calculator.el
index 3d44b6d86c5..f2e6a888c09 100644
--- a/lisp/calculator.el
+++ b/lisp/calculator.el
@@ -161,6 +161,8 @@ This makes it possible to paste big integers since they will be read as
161floats, otherwise the Emacs reader will fail on them." 161floats, otherwise the Emacs reader will fail on them."
162 :type 'boolean 162 :type 'boolean
163 :group 'calculator) 163 :group 'calculator)
164(make-obsolete-variable 'calculator-paste-decimals
165 "it is no longer used." nil)
164 166
165(defcustom calculator-copy-displayer nil 167(defcustom calculator-copy-displayer nil
166 "If non-nil, this is any value that can be used for 168 "If non-nil, this is any value that can be used for
@@ -855,39 +857,13 @@ The result should not exceed the screen width."
855 "Convert the given STR to a number, according to the value of 857 "Convert the given STR to a number, according to the value of
856`calculator-input-radix'." 858`calculator-input-radix'."
857 (if calculator-input-radix 859 (if calculator-input-radix
858 (let ((radix 860 (string-to-number str (cadr (assq calculator-input-radix
859 (cdr (assq calculator-input-radix 861 '((bin 2) (oct 8) (hex 16)))))
860 '((bin . 2) (oct . 8) (hex . 16))))) 862 (let* ((str (replace-regexp-in-string
861 (i -1) (value 0) (new-value 0)) 863 "\\.\\([^0-9].*\\)?$" ".0\\1" str))
862 ;; assume mostly valid input (e.g., characters in range) 864 (str (replace-regexp-in-string
863 (while (< (setq i (1+ i)) (length str)) 865 "[eE][+-]?\\([^0-9].*\\)?$" "e0\\1" str)))
864 (setq new-value 866 (string-to-number str))))
865 (let* ((ch (upcase (aref str i)))
866 (n (cond ((< ch ?0) nil)
867 ((<= ch ?9) (- ch ?0))
868 ((< ch ?A) nil)
869 ((<= ch ?Z) (- ch (- ?A 10)))
870 (t nil))))
871 (if (and n (<= 0 n) (< n radix))
872 (+ n (* radix value))
873 (progn
874 (calculator-message
875 "Warning: Ignoring bad input character `%c'." ch)
876 (sit-for 1)
877 value))))
878 (when (if (< new-value 0) (> value 0) (< value 0))
879 (calculator-message "Warning: Overflow in input."))
880 (setq value new-value))
881 value)
882 (car (read-from-string
883 (cond ((equal "." str) "0.0")
884 ((string-match-p "[eE][+-]?$" str) (concat str "0"))
885 ((string-match-p "\\.[0-9]\\|[eE]" str) str)
886 ((string-match-p "\\." str)
887 ;; do this because Emacs reads "23." as an integer
888 (concat str "0"))
889 ((stringp str) (concat str ".0"))
890 (t "0.0"))))))
891 867
892(defun calculator-push-curnum () 868(defun calculator-push-curnum ()
893 "Push the numeric value of the displayed number to the stack." 869 "Push the numeric value of the displayed number to the stack."
@@ -1329,7 +1305,8 @@ Used with +/- for entering them as digits in numbers like 1e-3 (there is
1329no need for negative numbers since these are handled by unary 1305no need for negative numbers since these are handled by unary
1330operators)." 1306operators)."
1331 (interactive) 1307 (interactive)
1332 (if (and (not calculator-display-fragile) 1308 (if (and (not calculator-input-radix)
1309 (not calculator-display-fragile)
1333 calculator-curnum 1310 calculator-curnum
1334 (string-match-p "[eE]$" calculator-curnum)) 1311 (string-match-p "[eE]$" calculator-curnum))
1335 (calculator-digit) 1312 (calculator-digit)
@@ -1497,25 +1474,27 @@ Used by `calculator-paste' and `get-register'."
1497 (or calculator-display-fragile 1474 (or calculator-display-fragile
1498 (not (numberp (car calculator-stack))))) 1475 (not (numberp (car calculator-stack)))))
1499 (calculator-clear-fragile) 1476 (calculator-clear-fragile)
1500 (setq calculator-curnum (let ((calculator-displayer "%S")) 1477 (setq calculator-curnum
1501 (calculator-number-to-string val))) 1478 (let ((calculator-displayer "%S")
1479 (calculator-radix-grouping-mode nil)
1480 (calculator-output-radix calculator-input-radix))
1481 (calculator-number-to-string val)))
1502 (calculator-update-display))) 1482 (calculator-update-display)))
1503 1483
1504(defun calculator-paste () 1484(defun calculator-paste (arg)
1505 "Paste a value from the `kill-ring'." 1485 "Paste a value from the `kill-ring'.
1506 (interactive) 1486
1507 (calculator-put-value 1487With a prefix argument, paste the raw string as a sequence of key
1508 (let ((str (replace-regexp-in-string 1488presses, which can be used to paste expressions. Note that this
1509 "^ *\\(.+[^ ]\\) *$" "\\1" (current-kill 0)))) 1489is literal; examples: spaces will store values, pasting \"1+2\"
1510 (when (and (not calculator-input-radix) 1490will not produce 3 if it's done you're entering a number or after
1511 calculator-paste-decimals 1491a multiplication."
1512 (string-match 1492 (interactive "P")
1513 "\\([0-9]+\\)\\(\\.[0-9]+\\)?\\(e[0-9]+\\)?" 1493 (let ((str (current-kill 0)))
1514 str)) 1494 (if arg
1515 (setq str (concat (or (match-string 1 str) "0") 1495 (setq unread-command-events
1516 (or (match-string 2 str) ".0") 1496 `(,@(listify-key-sequence str) ,@unread-command-events))
1517 (or (match-string 3 str) "")))) 1497 (calculator-put-value (calculator-string-to-number str)))))
1518 (ignore-errors (calculator-string-to-number str)))))
1519 1498
1520(defun calculator-register-read-with-preview (prompt) 1499(defun calculator-register-read-with-preview (prompt)
1521 "Similar to `register-read-with-preview' but for calculator 1500 "Similar to `register-read-with-preview' but for calculator