]> code.delx.au - gnu-emacs/blobdiff - lisp/calc/calc-yank.el
* lisp/mouse.el (mouse-select-region-move-to-beginning): Add :group.
[gnu-emacs] / lisp / calc / calc-yank.el
index 923df5d577f1531d452c7f4172ab51157b78bbdd..ed70666eb4554a6f1367c0c03fd6177c0e89983c 100644 (file)
@@ -1,9 +1,8 @@
 ;;; calc-yank.el --- kill-ring functionality for Calc
 
-;; Copyright (C) 1990-1993, 2001-2015 Free Software Foundation, Inc.
+;; Copyright (C) 1990-1993, 2001-2016 Free Software Foundation, Inc.
 
 ;; Author: David Gillespie <daveg@synaptics.com>
-;; Maintainer: Jay Belanger <jay.p.belanger@gmail.com>
 
 ;; This file is part of GNU Emacs.
 
   (interactive "r")
   (calc-kill-region top bot t))
 
+(defun math-number-regexp (radix-num)
+  "Return a regexp which will match a Calc number base RADIX-NUM."
+  (let* ((digit-range
+          (cond
+           ;; radix 2 to 10
+           ((and (<= 2 radix-num)
+                 (>= 10 radix-num))
+            (concat "[0-"
+                    (number-to-string (1- radix-num))
+                    "]"))
+           ;; radix 11
+           ((= 11 radix-num) "[0-9aA]")
+           ;; radix 12+
+           (t
+            (concat "[0-9"
+                    "a-" (format "%c" (+ (- ?a 11) radix-num))
+                    "A-" (format "%c" (+ (- ?A 11) radix-num))
+                    "]"))))
+         (integer-regexp (concat digit-range "+"))
+         (decimal-regexp (concat digit-range "+\\." digit-range "*")))
+    (concat
+     " *\\("
+     ;; "e" notation
+     "[-_+]?" decimal-regexp "[eE][-+]?[0-9]+"
+     "\\|"
+     "[-_+]?" integer-regexp "[eE][-+]?[0-9]+"
+     "\\|"
+     ;; Integer+fractions
+     "[-_+]?" integer-regexp "*[:/]" integer-regexp "[:/]" integer-regexp
+     "\\|"
+     ;; Fractions
+     "[-_+]?" integer-regexp "[:/]" integer-regexp
+     "\\|"
+     ;; Decimal point
+     "[-_+]?" decimal-regexp
+     "\\|"
+     ;; Integers
+     "[-_+]?" integer-regexp
+     "\\) *\\(\n\\|\\'\\)")))
+
 ;; This function uses calc-last-kill if possible to get an exact result,
 ;; otherwise it just parses the yanked string.
 ;; Modified to use Emacs 19 extended concept of kill-ring. -- daveg 12/15/96
 ;;;###autoload
-(defun calc-yank ()
-  (interactive)
+(defun calc-yank (radix)
+  "Yank a value into the Calculator buffer.
+
+Valid numeric prefixes for RADIX: 0, 2, 6, 8
+No radix notation is prepended for any other numeric prefix.
+
+If RADIX is 2, prepend \"2#\"  - Binary.
+If RADIX is 8, prepend \"8#\"  - Octal.
+If RADIX is 0, prepend \"10#\" - Decimal.
+If RADIX is 6, prepend \"16#\" - Hexadecimal.
+
+If RADIX is a non-nil list (created using \\[universal-argument]), the user
+will be prompted to enter the radix in the minibuffer.
+
+If RADIX is nil or if the yanked string already has a calc radix prefix, the
+yanked string will be passed on directly to the Calculator buffer without any
+alteration."
+  (interactive "P")
   (calc-wrapper
    (calc-pop-push-record-list
     0 "yank"
-    (let ((thing (if (fboundp 'current-kill)
-                    (current-kill 0 t)
-                  (car kill-ring-yank-pointer))))
-      (if (eq (car-safe calc-last-kill) thing)
-         (cdr calc-last-kill)
-       (if (stringp thing)
-           (let ((val (math-read-exprs (calc-clean-newlines thing))))
-             (if (eq (car-safe val) 'error)
-                 (progn
-                   (setq val (math-read-exprs thing))
-                   (if (eq (car-safe val) 'error)
-                       (error "Bad format in yanked data")
-                     val))
-               val))))))))
+    (let* (radix-num
+           radix-notation
+           valid-num-regexp
+           (thing-raw
+            (if (fboundp 'current-kill)
+                (current-kill 0 t)
+              (car kill-ring-yank-pointer)))
+           (thing
+            (if (or (null radix)
+                    ;; Match examples: -2#10, 10\n(10#10,01)
+                    (string-match-p "^[-(]*[0-9]\\{1,2\\}#" thing-raw))
+                thing-raw
+              (progn
+                (if (listp radix)
+                    (progn
+                      (setq radix-num
+                            (read-number
+                             "Set radix for yanked content (2-36): "))
+                      (when (not (and (integerp radix-num)
+                                      (<= 2 radix-num)
+                                      (>= 36 radix-num)))
+                        (error (concat "The radix has to be an "
+                                       "integer between 2 and 36."))))
+                  (setq radix-num
+                        (cond ((eq radix 2) 2)
+                              ((eq radix 8) 8)
+                              ((eq radix 0) 10)
+                              ((eq radix 6) 16)
+                              (t (message
+                                  (concat "No radix prepended "
+                                          "for invalid *numeric* "
+                                          "prefix %0d.")
+                                  radix)
+                                 nil))))
+                (if radix-num
+                    (progn
+                      (setq radix-notation
+                            (concat (number-to-string radix-num) "#"))
+                      (setq valid-num-regexp
+                            (math-number-regexp radix-num))
+                      ;; Ensure that the radix-notation is prefixed
+                      ;; correctly even for multi-line yanks like below,
+                      ;;   111
+                      ;;   1111
+                      (replace-regexp-in-string
+                       valid-num-regexp
+                       (concat radix-notation "\\&")
+                       thing-raw))
+                  thing-raw)))))
+      (if (eq (car-safe calc-last-kill) thing-raw)
+          (cdr calc-last-kill)
+        (if (stringp thing)
+            (let ((val (math-read-exprs (calc-clean-newlines thing))))
+              (if (eq (car-safe val) 'error)
+                  (progn
+                    (setq val (math-read-exprs thing))
+                    (if (eq (car-safe val) 'error)
+                        (error "Bad format in yanked data")
+                      val))
+                val))))))))
 
 ;;; The Calc set- and get-register commands are modified versions of functions
 ;;; in register.el
@@ -603,9 +704,9 @@ To cancel the edit, simply kill the *Calc Edit* buffer."
     (insert (propertize
              (concat
               (or title title "Calc Edit Mode. ")
-              "Press `C-c C-c'"
+              (format-message "Press `C-c C-c'")
               (if allow-ret "" " or RET")
-              " to finish, `C-x k RET' to cancel.\n\n")
+              (format-message " to finish, `C-x k RET' to cancel.\n\n"))
              'font-lock-face 'italic 'read-only t 'rear-nonsticky t 'front-sticky t))
     (make-local-variable 'calc-edit-top)
     (setq calc-edit-top (point))))