calc.el 132 KB
Newer Older
1
;;; calc.el --- the GNU Emacs calculator
2

Jay Belanger's avatar
Jay Belanger committed
3
;; Copyright (C) 1990, 1991, 1992, 1993, 2001, 2002, 2003, 2004,
Glenn Morris's avatar
Glenn Morris committed
4
;;   2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
5 6

;; Author: David Gillespie <daveg@synaptics.com>
Jay Belanger's avatar
Jay Belanger committed
7
;; Maintainer: Jay Belanger <jay.p.belanger@gmail.com>
8
;; Keywords: convenience, extensions
Eli Zaretskii's avatar
Eli Zaretskii committed
9 10 11

;; This file is part of GNU Emacs.

12
;; GNU Emacs is free software: you can redistribute it and/or modify
13
;; it under the terms of the GNU General Public License as published by
14 15
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
16

Eli Zaretskii's avatar
Eli Zaretskii committed
17
;; GNU Emacs is distributed in the hope that it will be useful,
18 19 20 21 22
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
23
;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
Eli Zaretskii's avatar
Eli Zaretskii committed
24

25
;;; Commentary:
Eli Zaretskii's avatar
Eli Zaretskii committed
26

27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
;; Calc is split into many files.  This file is the main entry point.
;; This file includes autoload commands for various other basic Calc
;; facilities.  The more advanced features are based in calc-ext, which
;; in turn contains autoloads for the rest of the Calc files.  This
;; odd set of interactions is designed to make Calc's loading time
;; be as short as possible when only simple calculations are needed.

;; Original author's address:
;;  Dave Gillespie, daveg@synaptics.com, uunet!synaptx!daveg.
;;  Synaptics, Inc., 2698 Orchard Parkway, San Jose, CA 95134.
;;
;; The old address daveg@csvax.cs.caltech.edu will continue to
;; work for the foreseeable future.
;;
;; Bug reports and suggestions are always welcome!  (Type M-x
;; report-calc-bug to send them).

;; All functions, macros, and Lisp variables defined here begin with one
;; of the prefixes "math", "Math", or "calc", with the exceptions of
;; "full-calc", "full-calc-keypad", "another-calc", "quick-calc",
;; "report-calc-bug", and "defmath".  User-accessible variables begin
;; with "var-".

;;; TODO:

;;   Fix rewrite mechanism to do less gratuitous rearrangement of terms.
;;   Implement a pattern-based "refers" predicate.
;;
;;   Make it possible to Undo a selection command.
;;   Figure out how to allow selecting rows of matrices.
;;   If cursor was in selection before, move it after j n, j p, j L, etc.
;;   Consider reimplementing calc-delete-selection using rewrites.
;;
;;   Implement line-breaking in non-flat compositions (is this desirable?).
;;   Implement matrix formatting with multi-line components.
;;
;;   Have "Z R" define a user command based on a set of rewrite rules.
;;   Support "incf" and "decf" in defmath definitions.
;;   Have defmath generate calls to calc-binary-op or calc-unary-op.
;;   Make some way to define algebraic functions using keyboard macros.
;;
;;   Allow calc-word-size=0 => Common Lisp-style signed bitwise arithmetic.
;;   Consider digamma function (and thus arb. prec. Euler's gamma constant).
;;   May as well make continued-fractions stuff available to the user.
;;
;;   How about matrix eigenvalues, SVD, pseudo-inverse, etc.?
;;   Should cache matrix inverses as well as decompositions.
;;   If dividing by a non-square matrix, use least-squares automatically.
;;   Consider supporting matrix exponentials.
;;
;;   Have ninteg detect and work around singularities at the endpoints.
;;   Use an adaptive subdivision algorithm for ninteg.
;;   Provide nsum and nprod to go along with ninteg.
;;
;;   Handle TeX-mode parsing of \matrix{ ... } where ... contains braces.
;;   Support AmS-TeX's \{d,t,}frac, \{d,t,}binom notations.
;;   Format and parse sums and products in Eqn and Math modes.
;;
;;   Get math-read-big-expr to read sums, products, etc.
;;   Change calc-grab-region to use math-read-big-expr.
;;   Have a way to define functions using := in Embedded Mode.
;;
;;   Support polar plotting with GNUPLOT.
;;   Make a calc-graph-histogram function.
;;
;;   Replace hokey formulas for complex functions with formulas designed
;;      to minimize roundoff while maintaining the proper branch cuts.
;;   Test accuracy of advanced math functions over whole complex plane.
;;   Extend Bessel functions to provide arbitrary precision.
;;   Extend advanced math functions to handle error forms and intervals.
;;   Provide a better implementation for math-sin-cos-raw.
;;   Provide a better implementation for math-hypot.
;;   Provide a better implementation for math-make-frac.
;;   Provide a better implementation for calcFunc-prfac.
;;   Provide a better implementation for calcFunc-factor.
;;
;;   Provide more examples in the tutorial section of the manual.
;;   Cover in the tutorial:  simplification modes, declarations,
;;       bitwise stuff, selections, matrix mapping, financial functions.
;;   Provide more Lisp programming examples in the manual.
;;   Finish the Internals section of the manual (and bring it up to date).
;;
;;   Tim suggests adding spreadsheet-like features.
;;   Implement language modes for Gnuplot, Lisp, Ada, APL, ...?
;;
;; For atan series, if x > tan(pi/12) (about 0.268) reduce using the identity
;;   atan(x) = atan((x * sqrt(3) - 1) / (sqrt(3) + x)) + pi/6.
;;
;; A better integration algorithm:
;;   Use breadth-first instead of depth-first search, as follows:
;;	The integral cache allows unfinished integrals in symbolic notation
;;	on the righthand side.  An entry with no unfinished integrals on the
;;	RHS is "complete"; references to it elsewhere are replaced by the
;;	integrated value.  More than one cache entry for the same integral
;;	may exist, though if one becomes complete, the others may be deleted.
;;	The integrator works by using every applicable rule (such as
;;	substitution, parts, linearity, etc.) to generate possible righthand
;;	sides, all of which are entered into the cache.  Now, as long as the
;;	target integral is not complete (and the time limit has not run out)
;;	choose an incomplete integral from the cache and, for every integral
;;	appearing in its RHS's, add those integrals to the cache using the
;;	same substitition, parts, etc. rules.  The cache should be organized
;;	as a priority queue, choosing the "simplest" incomplete integral at
;;	each step, or choosing randomly among equally simple integrals.
;;	Simplicity equals small size, and few steps removed from the original
;;	target integral.  Note that when the integrator finishes, incomplete
;;	integrals can be left in the cache, so the algorithm can start where
;;	it left off if another similar integral is later requested.
;;   Breadth-first search would avoid the nagging problem of, e.g., whether
;;   to use parts or substitution first, and which decomposition is best.
;;   All are tried, and any path that diverges will quickly be put on the
;;   back burner by the priority queue.
;;   Note: Probably a good idea to call math-simplify-extended before
;;   measuring a formula's simplicity.

142
;;; Code:
Eli Zaretskii's avatar
Eli Zaretskii committed
143

Eli Zaretskii's avatar
Eli Zaretskii committed
144
(require 'calc-macs)
Eli Zaretskii's avatar
Eli Zaretskii committed
145

146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
;; Declare functions which are defined elsewhere.
(declare-function calc-set-language "calc-lang" (lang &optional option no-refresh))
(declare-function calc-edit-finish "calc-yank" (&optional keep))
(declare-function calc-edit-cancel "calc-yank" ())
(declare-function calc-do-quick-calc "calc-aent" ())
(declare-function calc-do-calc-eval "calc-aent" (str separator args))
(declare-function calc-do-keypad "calc-keypd" (&optional full-display interactive))
(declare-function calcFunc-unixtime "calc-forms" (date &optional zone))
(declare-function math-parse-date "calc-forms" (math-pd-str))
(declare-function math-lessp "calc-ext" (a b))
(declare-function calc-embedded-finish-command "calc-embed" ())
(declare-function calc-embedded-select-buffer "calc-embed" ())
(declare-function calc-embedded-mode-line-change "calc-embed" ())
(declare-function calc-push-list-in-macro "calc-prog" (vals m sels))
(declare-function calc-replace-selections "calc-sel" (n vals m))
(declare-function calc-record-list "calc-misc" (vals &optional prefix))
(declare-function calc-normalize-fancy "calc-ext" (val))
(declare-function calc-do-handle-whys "calc-misc" ())
(declare-function calc-top-selected "calc-sel" (&optional n m))
(declare-function calc-sel-error "calc-sel" ())
(declare-function calc-pop-stack-in-macro "calc-prog" (n mm))
(declare-function calc-embedded-stack-change "calc-embed" ())
(declare-function calc-refresh-evaltos "calc-ext" (&optional which-var))
(declare-function calc-do-refresh "calc-misc" ())
(declare-function calc-binary-op-fancy "calc-ext" (name func arg ident unary))
(declare-function calc-unary-op-fancy "calc-ext" (name func arg))
(declare-function calc-delete-selection "calc-sel" (n))
(declare-function calc-alg-digit-entry "calc-aent" ())
(declare-function calc-alg-entry "calc-aent" (&optional initial prompt))
(declare-function calc-dots "calc-incom" ())
(declare-function calc-temp-minibuffer-message "calc-misc" (m))
(declare-function math-read-radix-digit "calc-misc" (dig))
(declare-function calc-digit-dots "calc-incom" ())
(declare-function math-normalize-fancy "calc-ext" (a))
180
(declare-function math-normalize-nonstandard "calc-ext" ())
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
(declare-function math-recompile-eval-rules "calc-alg" ())
(declare-function math-apply-rewrites "calc-rewr" (expr rules &optional heads math-apply-rw-ruleset))
(declare-function calc-record-why "calc-misc" (&rest stuff))
(declare-function math-dimension-error "calc-vec" ())
(declare-function calc-incomplete-error "calc-incom" (a))
(declare-function math-float-fancy "calc-arith" (a))
(declare-function math-neg-fancy "calc-arith" (a))
(declare-function math-zerop "calc-misc" (a))
(declare-function calc-add-fractions "calc-frac" (a b))
(declare-function math-add-objects-fancy "calc-arith" (a b))
(declare-function math-add-symb-fancy "calc-arith" (a b))
(declare-function math-mul-zero "calc-arith" (a b))
(declare-function calc-mul-fractions "calc-frac" (a b))
(declare-function math-mul-objects-fancy "calc-arith" (a b))
(declare-function math-mul-symb-fancy "calc-arith" (a b))
(declare-function math-reject-arg "calc-misc" (&optional a p option))
(declare-function math-div-by-zero "calc-arith" (a b))
(declare-function math-div-zero "calc-arith" (a b))
(declare-function math-make-frac "calc-frac" (num den))
(declare-function calc-div-fractions "calc-frac" (a b))
(declare-function math-div-objects-fancy "calc-arith" (a b))
(declare-function math-div-symb-fancy "calc-arith" (a b))
(declare-function math-compose-expr "calccomp" (a prec))
(declare-function math-comp-width "calccomp" (c))
(declare-function math-composition-to-string "calccomp" (c &optional width))
(declare-function math-stack-value-offset-fancy "calccomp" ())
(declare-function math-format-flat-expr-fancy "calc-ext" (a prec))
(declare-function math-adjust-fraction "calc-ext" (a))
(declare-function math-format-binary "calc-bin" (a))
(declare-function math-format-radix "calc-bin" (a))
(declare-function math-group-float "calc-ext" (str))
(declare-function math-mod "calc-misc" (a b))
(declare-function math-format-number-fancy "calc-ext" (a prec))
(declare-function math-format-bignum-fancy "calc-ext" (a))
(declare-function math-read-number-fancy "calc-ext" (s))
(declare-function calc-do-grab-region "calc-yank" (top bot arg))
(declare-function calc-do-grab-rectangle "calc-yank" (top bot arg &optional reduce))
(declare-function calc-do-embedded "calc-embed" (calc-embed-arg end obeg oend))
(declare-function calc-do-embedded-activate "calc-embed" (calc-embed-arg cbuf))
(declare-function math-do-defmath "calc-prog" (func args body))
(declare-function calc-load-everything "calc-ext" ())


Jay Belanger's avatar
calc.el  
Jay Belanger committed
224
(defgroup calc nil
225
  "GNU Calc."
Jay Belanger's avatar
calc.el  
Jay Belanger committed
226
  :prefix "calc-"
227 228
  :tag    "Calc"
  :group  'applications)
Jay Belanger's avatar
calc.el  
Jay Belanger committed
229

Eli Zaretskii's avatar
Eli Zaretskii committed
230
;;;###autoload
231
(defcustom calc-settings-file
Jay Belanger's avatar
calc.el  
Jay Belanger committed
232
  (convert-standard-filename "~/.calc.el")
233
  "File in which to record permanent settings."
Jay Belanger's avatar
calc.el  
Jay Belanger committed
234 235 236 237 238 239 240 241 242 243 244 245 246
  :group 'calc
  :type '(file))

(defcustom calc-language-alist
  '((latex-mode . latex)
    (tex-mode   . tex)
    (plain-tex-mode . tex)
    (context-mode . tex)
    (nroff-mode . eqn)
    (pascal-mode . pascal)
    (c-mode . c)
    (c++-mode . c)
    (fortran-mode . fortran)
247 248
    (f90-mode . fortran)
    (texinfo-mode . calc-normal-language))
249
  "Alist of major modes with appropriate Calc languages."
Jay Belanger's avatar
calc.el  
Jay Belanger committed
250
  :group 'calc
251
  :type '(alist :key-type (symbol :tag "Major mode")
252
                :value-type (symbol :tag "Calc language")))
Jay Belanger's avatar
calc.el  
Jay Belanger committed
253

254
(defcustom calc-embedded-announce-formula
Jay Belanger's avatar
calc.el  
Jay Belanger committed
255
  "%Embed\n\\(% .*\n\\)*"
256
  "A regular expression which is sure to be followed by a calc-embedded formula."
Jay Belanger's avatar
calc.el  
Jay Belanger committed
257 258 259
  :group 'calc
  :type '(regexp))

260
(defcustom calc-embedded-announce-formula-alist
261
  '((c++-mode     . "//Embed\n\\(// .*\n\\)*")
262
    (c-mode       . "/\\*Embed\\*/\n\\(/\\* .*\\*/\n\\)*")
263
    (f90-mode     . "!Embed\n\\(! .*\n\\)*")
264
    (fortran-mode . "C Embed\n\\(C .*\n\\)*")
265 266 267 268 269 270 271
    (html-helper-mode . "<!-- Embed -->\n\\(<!-- .* -->\n\\)*")
    (html-mode    . "<!-- Embed -->\n\\(<!-- .* -->\n\\)*")
    (nroff-mode   . "\\\\\"Embed\n\\(\\\\\" .*\n\\)*")
    (pascal-mode  . "{Embed}\n\\({.*}\n\\)*")
    (sgml-mode    . "<!-- Embed -->\n\\(<!-- .* -->\n\\)*")
    (xml-mode     . "<!-- Embed -->\n\\(<!-- .* -->\n\\)*")
    (texinfo-mode . "@c Embed\n\\(@c .*\n\\)*"))
272
  "Alist of major modes with appropriate values for `calc-embedded-announce-formula'."
273 274 275 276
  :group 'calc
  :type '(alist :key-type (symbol :tag "Major mode")
                :value-type (regexp :tag "Regexp to announce formula")))

277
(defcustom calc-embedded-open-formula
Jay Belanger's avatar
calc.el  
Jay Belanger committed
278
  "\\`\\|^\n\\|\\$\\$?\\|\\\\\\[\\|^\\\\begin[^{].*\n\\|^\\\\begin{.*[^x]}.*\n\\|^@.*\n\\|^\\.EQ.*\n\\|\\\\(\\|^%\n\\|^\\.\\\\\"\n"
279
  "A regular expression for the opening delimiter of a formula used by calc-embedded."
Jay Belanger's avatar
calc.el  
Jay Belanger committed
280 281 282
  :group 'calc
  :type '(regexp))

283
(defcustom calc-embedded-close-formula
Jay Belanger's avatar
calc.el  
Jay Belanger committed
284
  "\\'\\|\n$\\|\\$\\$?\\|\\\\]\\|^\\\\end[^{].*\n\\|^\\\\end{.*[^x]}.*\n\\|^@.*\n\\|^\\.EN.*\n\\|\\\\)\\|\n%\n\\|^\\.\\\\\"\n"
285
  "A regular expression for the closing delimiter of a formula used by calc-embedded."
Jay Belanger's avatar
calc.el  
Jay Belanger committed
286 287 288
  :group 'calc
  :type '(regexp))

289 290
(defcustom calc-embedded-open-close-formula-alist
  nil
291
  "Alist of major modes with pairs of formula delimiters used by calc-embedded."
292 293 294 295 296
  :group 'calc
  :type '(alist :key-type (symbol :tag "Major mode")
                :value-type (list (regexp :tag "Opening formula delimiter")
                                  (regexp :tag "Closing formula delimiter"))))

297 298 299
(defcustom calc-embedded-word-regexp
  "[-+]?[0-9]+\\(\\.[0-9]+\\)?\\([eE][-+]?[0-9]+\\)?"
  "A regular expression determining a word for calc-embedded-word."
Jay Belanger's avatar
calc.el  
Jay Belanger committed
300 301 302
  :group 'calc
  :type '(regexp))

303
(defcustom calc-embedded-word-regexp-alist
304
  nil
305
  "Alist of major modes with word regexps used by calc-embedded-word."
306 307
  :group 'calc
  :type '(alist :key-type (symbol :tag "Major mode")
308
                :value-type (regexp :tag "Regexp for word")))
309

310
(defcustom calc-embedded-open-plain
Jay Belanger's avatar
calc.el  
Jay Belanger committed
311
  "%%% "
312
  "A string which is the opening delimiter for a \"plain\" formula.
Jay Belanger's avatar
calc.el  
Jay Belanger committed
313 314 315 316 317
If calc-show-plain mode is enabled, this is inserted at the front of
each formula."
  :group 'calc
  :type '(string))

318
(defcustom calc-embedded-close-plain
Jay Belanger's avatar
calc.el  
Jay Belanger committed
319
  " %%%\n"
320
  "A string which is the closing delimiter for a \"plain\" formula.
Jay Belanger's avatar
calc.el  
Jay Belanger committed
321 322 323 324
See calc-embedded-open-plain."
  :group 'calc
  :type '(string))

325
(defcustom calc-embedded-open-close-plain-alist
326
  '((c++-mode     "// %% "   " %%\n")
327
    (c-mode       "/* %% "   " %% */\n")
328
    (f90-mode     "! %% "    " %%\n")
329
    (fortran-mode "C %% "    " %%\n")
330 331 332 333 334 335 336
    (html-helper-mode "<!-- %% " " %% -->\n")
    (html-mode "<!-- %% " " %% -->\n")
    (nroff-mode   "\\\" %% " " %%\n")
    (pascal-mode  "{%% "    " %%}\n")
    (sgml-mode     "<!-- %% " " %% -->\n")
    (xml-mode     "<!-- %% " " %% -->\n")
    (texinfo-mode "@c %% "   " %%\n"))
337
  "Alist of major modes with pairs of delimiters for \"plain\" formulas."
338 339 340 341 342
  :group 'calc
  :type '(alist :key-type (symbol :tag "Major mode")
                :value-type (list (string :tag "Opening \"plain\" delimiter")
                                  (string :tag "Closing \"plain\" delimiter"))))

343
(defcustom calc-embedded-open-new-formula
Jay Belanger's avatar
calc.el  
Jay Belanger committed
344
  "\n\n"
345
  "A string which is inserted at front of formula by calc-embedded-new-formula."
Jay Belanger's avatar
calc.el  
Jay Belanger committed
346 347 348
  :group 'calc
  :type '(string))

349
(defcustom calc-embedded-close-new-formula
Jay Belanger's avatar
calc.el  
Jay Belanger committed
350
  "\n\n"
351
  "A string which is inserted at end of formula by calc-embedded-new-formula."
Jay Belanger's avatar
calc.el  
Jay Belanger committed
352 353 354
  :group 'calc
  :type '(string))

355 356
(defcustom calc-embedded-open-close-new-formula-alist
  nil
357
  "Alist of major modes with pairs of new formula delimiters used by calc-embedded."
358 359 360 361 362
  :group 'calc
  :type '(alist :key-type (symbol :tag "Major mode")
                :value-type (list (string :tag "Opening new formula delimiter")
                                  (string :tag "Closing new formula delimiter"))))

363
(defcustom calc-embedded-open-mode
Jay Belanger's avatar
calc.el  
Jay Belanger committed
364
  "% "
365
  "A string which should precede calc-embedded mode annotations.
Jay Belanger's avatar
calc.el  
Jay Belanger committed
366 367 368 369
This is not required to be present for user-written mode annotations."
  :group 'calc
  :type '(string))

370
(defcustom calc-embedded-close-mode
Jay Belanger's avatar
calc.el  
Jay Belanger committed
371
  "\n"
372
  "A string which should follow calc-embedded mode annotations.
Jay Belanger's avatar
calc.el  
Jay Belanger committed
373 374 375 376
This is not required to be present for user-written mode annotations."
  :group 'calc
  :type '(string))

377
(defcustom calc-embedded-open-close-mode-alist
378
  '((c++-mode     "// "   "\n")
379
    (c-mode       "/* "   " */\n")
380
    (f90-mode     "! "    "\n")
381
    (fortran-mode "C "    "\n")
382 383 384 385 386 387 388
    (html-helper-mode "<!-- " " -->\n")
    (html-mode    "<!-- " " -->\n")
    (nroff-mode   "\\\" " "\n")
    (pascal-mode  "{ "    " }\n")
    (sgml-mode    "<!-- " " -->\n")
    (xml-mode     "<!-- " " -->\n")
    (texinfo-mode "@c "   "\n"))
389
  "Alist of major modes with pairs of strings to delimit annotations."
390 391 392 393 394
  :group 'calc
  :type '(alist :key-type (symbol :tag "Major mode")
                :value-type (list (string :tag "Opening annotation delimiter")
                                  (string :tag "Closing annotation delimiter"))))

395
(defcustom calc-gnuplot-name
Jay Belanger's avatar
calc.el  
Jay Belanger committed
396
  "gnuplot"
397
  "Name of GNUPLOT program, for calc-graph features."
Jay Belanger's avatar
calc.el  
Jay Belanger committed
398 399 400
  :group 'calc
  :type '(string))

401
(defcustom calc-gnuplot-plot-command
Jay Belanger's avatar
calc.el  
Jay Belanger committed
402
  nil
403
  "Name of command for displaying GNUPLOT output; %s = file name to print."
Jay Belanger's avatar
calc.el  
Jay Belanger committed
404 405 406
  :group 'calc
  :type '(choice (string) (sexp)))

407
(defcustom calc-gnuplot-print-command
Jay Belanger's avatar
calc.el  
Jay Belanger committed
408
  "lp %s"
409
  "Name of command for printing GNUPLOT output; %s = file name to print."
Jay Belanger's avatar
calc.el  
Jay Belanger committed
410 411
  :group 'calc
  :type '(choice (string) (sexp)))
Eli Zaretskii's avatar
Eli Zaretskii committed
412

413 414
(defcustom calc-multiplication-has-precedence
  t
415
  "If non-nil, multiplication has precedence over division
416 417 418 419
in normal mode."
  :group 'calc
  :type 'boolean)

Jay Belanger's avatar
Jay Belanger committed
420
(defvar calc-bug-address "jay.p.belanger@gmail.com"
421
  "Address of the maintainer of Calc, for use by `report-calc-bug'.")
Eli Zaretskii's avatar
Eli Zaretskii committed
422

423 424 425
(defvar calc-scan-for-dels t
  "If t, scan keymaps to find all DEL-like keys.
if nil, only DEL itself is mapped to calc-pop.")
Eli Zaretskii's avatar
Eli Zaretskii committed
426

427 428 429
(defvar calc-stack '((top-of-stack 1 nil))
  "Calculator stack.
Entries are 3-lists:  Formula, Height (in lines), Selection (or nil).")
Eli Zaretskii's avatar
Eli Zaretskii committed
430

431 432 433
(defvar calc-stack-top 1
  "Index into `calc-stack' of \"top\" of stack.
This is 1 unless `calc-truncate-stack' has been used.")
Eli Zaretskii's avatar
Eli Zaretskii committed
434

435 436 437 438 439 440 441 442 443 444
(defvar calc-display-sci-high 0
  "Floating-point numbers with this positive exponent or higher above the
current precision are displayed in scientific notation in calc-mode.")

(defvar calc-display-sci-low -3
  "Floating-point numbers with this negative exponent or lower are displayed
scientific notation in calc-mode.")

(defvar calc-other-modes nil
  "List of used-defined strings to append to Calculator mode line.")
Eli Zaretskii's avatar
Eli Zaretskii committed
445

446 447
(defvar calc-Y-help-msgs nil
  "List of strings for Y prefix help.")
Eli Zaretskii's avatar
Eli Zaretskii committed
448

449 450
(defvar calc-loaded-settings-file nil
  "t if `calc-settings-file' has been loaded yet.")
Eli Zaretskii's avatar
Eli Zaretskii committed
451

Jay Belanger's avatar
Jay Belanger committed
452 453 454 455 456

(defvar calc-mode-var-list '()
  "List of variables used in customizing GNU Calc.")

(defmacro defcalcmodevar (var defval &optional doc)
Jay Belanger's avatar
Jay Belanger committed
457 458 459
  "Declare VAR as a Calc variable, with default value DEFVAL
and doc-string DOC.
The variable VAR will be added to `calc-mode-var-list'."
Jay Belanger's avatar
Jay Belanger committed
460 461 462 463 464
  `(progn
     (defvar ,var ,defval ,doc)
     (add-to-list 'calc-mode-var-list (list (quote ,var) ,defval))))

(defun calc-mode-var-list-restore-default-values ()
Jay Belanger's avatar
Jay Belanger committed
465
  "Restore the default values of the variables in `calc-mode-var-list'."
Jay Belanger's avatar
Jay Belanger committed
466 467 468 469
  (mapcar (function (lambda (v) (set (car v) (nth 1 v))))
          calc-mode-var-list))

(defun calc-mode-var-list-restore-saved-values ()
Jay Belanger's avatar
Jay Belanger committed
470
  "Restore the user-saved values of the variables in `calc-mode-var-list'."
Jay Belanger's avatar
Jay Belanger committed
471 472
  (let ((newvarlist '()))
    (save-excursion
473 474 475 476 477 478 479 480 481 482 483
      (let (pos
            (file (substitute-in-file-name calc-settings-file)))
        (when (and
               (file-regular-p file)
               (set-buffer (find-file-noselect file))
               (goto-char (point-min))
               (search-forward ";;; Mode settings stored by Calc" nil t)
               (progn
                 (forward-line 1)
                 (setq pos (point))
                 (search-forward "\n;;; End of mode settings" nil t)))
Jay Belanger's avatar
Jay Belanger committed
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499
          (beginning-of-line)
          (calc-mode-var-list-restore-default-values)
          (eval-region pos (point))
          (let ((varlist calc-mode-var-list))
            (while varlist
              (let ((var (car varlist)))
                (setq newvarlist
                      (cons (list (car var) (symbol-value (car var)))
                            newvarlist)))
              (setq varlist (cdr varlist)))))))
    (if newvarlist
        (mapcar (function (lambda (v) (set (car v) (nth 1 v))))
                newvarlist)
      (calc-mode-var-list-restore-default-values))))

(defcalcmodevar calc-always-load-extensions nil
500
  "If non-nil, load the calc-ext module automatically when Calc is loaded.")
Jay Belanger's avatar
Jay Belanger committed
501 502 503 504 505 506 507 508 509

(defcalcmodevar  calc-line-numbering t
  "If non-nil, display line numbers in Calculator stack.")

(defcalcmodevar calc-line-breaking t
  "If non-nil, break long values across multiple lines in Calculator stack.")

(defcalcmodevar calc-display-just nil
  "If nil, stack display is left-justified.
510 511
If `right', stack display is right-justified.
If `center', stack display is centered.")
Eli Zaretskii's avatar
Eli Zaretskii committed
512

Jay Belanger's avatar
Jay Belanger committed
513 514
(defcalcmodevar calc-display-origin nil
  "Horizontal origin of displayed stack entries.
515 516 517 518
In left-justified mode, this is effectively indentation.  (Default 0).
In right-justified mode, this is effectively window width.
In centered mode, center of stack entry is placed here.")

Jay Belanger's avatar
Jay Belanger committed
519 520
(defcalcmodevar calc-number-radix 10
  "Radix for entry and display of numbers in calc-mode, 2-36.")
521

Jay Belanger's avatar
Jay Belanger committed
522 523
(defcalcmodevar calc-leading-zeros nil
  "If non-nil, leading zeros are provided to pad integers to calc-word-size.")
524

Jay Belanger's avatar
Jay Belanger committed
525 526
(defcalcmodevar calc-group-digits nil
  "If non-nil, group digits in large displayed integers by inserting spaces.
527 528 529
If an integer, group that many digits at a time.
If t, use 4 for binary and hex, 3 otherwise.")

Jay Belanger's avatar
Jay Belanger committed
530 531
(defcalcmodevar calc-group-char ","
  "The character (in the form of a string) to be used for grouping digits.
532 533
This is used only when calc-group-digits mode is on.")

Jay Belanger's avatar
Jay Belanger committed
534 535
(defcalcmodevar calc-point-char "."
  "The character (in the form of a string) to be used as a decimal point.")
536

Jay Belanger's avatar
Jay Belanger committed
537 538
(defcalcmodevar calc-frac-format '(":" nil)
  "Format of displayed fractions; a string of one or two of \":\" or \"/\".")
539

Jay Belanger's avatar
Jay Belanger committed
540 541
(defcalcmodevar calc-prefer-frac nil
  "If non-nil, prefer fractional over floating-point results.")
542

Jay Belanger's avatar
Jay Belanger committed
543 544
(defcalcmodevar calc-hms-format "%s@ %s' %s\""
  "Format of displayed hours-minutes-seconds angles, a format string.
545 546
String must contain three %s marks for hours, minutes, seconds respectively.")

Jay Belanger's avatar
Jay Belanger committed
547 548 549
(defcalcmodevar calc-date-format '((H ":" mm C SS pp " ")
                                  Www " " Mmm " " D ", " YYYY)
  "Format of displayed date forms.")
550

Jay Belanger's avatar
Jay Belanger committed
551 552
(defcalcmodevar calc-float-format '(float 0)
  "Format to use for display of floating-point numbers in calc-mode.
553 554 555 556 557 558 559 560 561 562 563 564
Must be a list of one of the following forms:
 (float 0)      Floating point format, display full precision.
 (float N)      N > 0: Floating point format, at most N significant figures.
 (float -N)     -N < 0: Floating point format, calc-internal-prec - N figs.
 (fix N)        N >= 0: Fixed point format, N places after decimal point.
 (sci 0)        Scientific notation, full precision.
 (sci N)        N > 0: Scientific notation, N significant figures.
 (sci -N)       -N < 0: Scientific notation, calc-internal-prec - N figs.
 (eng 0)        Engineering notation, full precision.
 (eng N)        N > 0: Engineering notation, N significant figures.
 (eng -N)       -N < 0: Engineering notation, calc-internal-prec - N figs.")

Jay Belanger's avatar
Jay Belanger committed
565 566
(defcalcmodevar calc-full-float-format '(float 0)
  "Format to use when full precision must be displayed.")
567

Jay Belanger's avatar
Jay Belanger committed
568 569
(defcalcmodevar calc-complex-format nil
  "Format to use for display of complex numbers in calc-mode.  Must be one of:
570 571 572 573
  nil            Use (x, y) form.
  i              Use x + yi form.
  j              Use x + yj form.")

Jay Belanger's avatar
Jay Belanger committed
574 575
(defcalcmodevar calc-complex-mode 'cplx
  "Preferred form, either `cplx' or `polar', for complex numbers.")
Eli Zaretskii's avatar
Eli Zaretskii committed
576

Jay Belanger's avatar
Jay Belanger committed
577 578
(defcalcmodevar calc-infinite-mode nil
  "If nil, 1 / 0 is left unsimplified.
579 580 581
If 0, 1 / 0 is changed to inf (zeros are considered positive).
Otherwise, 1 / 0 is changed to uinf (undirected infinity).")

Jay Belanger's avatar
Jay Belanger committed
582 583
(defcalcmodevar calc-display-strings nil
  "If non-nil, display vectors of byte-sized integers as strings.")
Eli Zaretskii's avatar
Eli Zaretskii committed
584

Jay Belanger's avatar
Jay Belanger committed
585 586
(defcalcmodevar calc-matrix-just 'center
  "If nil, vector elements are left-justified.
587 588 589
If `right', vector elements are right-justified.
If `center', vector elements are centered.")

Jay Belanger's avatar
Jay Belanger committed
590 591
(defcalcmodevar calc-break-vectors nil
  "If non-nil, display vectors one element per line.")
Eli Zaretskii's avatar
Eli Zaretskii committed
592

Jay Belanger's avatar
Jay Belanger committed
593 594
(defcalcmodevar calc-full-vectors t
  "If non-nil, display long vectors in full.  If nil, use abbreviated form.")
595

Jay Belanger's avatar
Jay Belanger committed
596 597
(defcalcmodevar calc-full-trail-vectors t
  "If non-nil, display long vectors in full in the trail.")
Eli Zaretskii's avatar
Eli Zaretskii committed
598

Jay Belanger's avatar
Jay Belanger committed
599 600
(defcalcmodevar calc-vector-commas ","
  "If non-nil, separate elements of displayed vectors with this string.")
601

Jay Belanger's avatar
Jay Belanger committed
602 603
(defcalcmodevar calc-vector-brackets "[]"
  "If non-nil, surround displayed vectors with these characters.")
604

Jay Belanger's avatar
Jay Belanger committed
605 606
(defcalcmodevar calc-matrix-brackets '(R O)
  "A list of code-letter symbols that control \"big\" matrix display.
607 608 609 610
If `R' is present, display inner brackets for matrices.
If `O' is present, display outer brackets for matrices (above/below).
If `C' is present, display outer brackets for matrices (centered).")

Jay Belanger's avatar
Jay Belanger committed
611 612
(defcalcmodevar calc-language nil
  "Language or format for entry and display of stack values.  Must be one of:
613 614 615 616 617 618 619 620
  nil		Use standard Calc notation.
  flat		Use standard Calc notation, one-line format.
  big		Display formulas in 2-d notation (enter w/std notation).
  unform	Use unformatted display: add(a, mul(b,c)).
  c		Use C language notation.
  pascal	Use Pascal language notation.
  fortran	Use Fortran language notation.
  tex		Use TeX notation.
621
  latex         Use LaTeX notation.
622
  eqn		Use eqn notation.
623 624 625
  yacas         Use Yacas notation.
  maxima        Use Maxima notation.
  giac          Use Giac notation.
626 627
  math		Use Mathematica(tm) notation.
  maple		Use Maple notation.")
Eli Zaretskii's avatar
Eli Zaretskii committed
628

Jay Belanger's avatar
Jay Belanger committed
629 630
(defcalcmodevar calc-language-option nil
  "Numeric prefix argument for the command that set `calc-language'.")
Eli Zaretskii's avatar
Eli Zaretskii committed
631

Jay Belanger's avatar
Jay Belanger committed
632 633
(defcalcmodevar calc-left-label ""
  "Label to display at left of formula.")
Eli Zaretskii's avatar
Eli Zaretskii committed
634

Jay Belanger's avatar
Jay Belanger committed
635 636
(defcalcmodevar calc-right-label ""
  "Label to display at right of formula.")
Eli Zaretskii's avatar
Eli Zaretskii committed
637

Jay Belanger's avatar
Jay Belanger committed
638 639
(defcalcmodevar calc-word-size 32
  "Minimum number of bits per word, if any, for binary operations in calc-mode.")
Eli Zaretskii's avatar
Eli Zaretskii committed
640

Jay Belanger's avatar
Jay Belanger committed
641 642
(defcalcmodevar calc-previous-modulo nil
  "Most recently used value of M in a modulo form.")
Eli Zaretskii's avatar
Eli Zaretskii committed
643

Jay Belanger's avatar
Jay Belanger committed
644 645
(defcalcmodevar calc-simplify-mode nil
  "Type of simplification applied to results.
646 647 648 649 650 651 652
If `none', results are not simplified when pushed on the stack.
If `num', functions are simplified only when args are constant.
If nil, only fast simplifications are applied.
If `binary', `math-clip' is applied if appropriate.
If `alg', `math-simplify' is applied.
If `ext', `math-simplify-extended' is applied.
If `units', `math-simplify-units' is applied.")
Eli Zaretskii's avatar
Eli Zaretskii committed
653

Jay Belanger's avatar
Jay Belanger committed
654 655
(defcalcmodevar calc-auto-recompute t
  "If non-nil, recompute evalto's automatically when necessary.")
Eli Zaretskii's avatar
Eli Zaretskii committed
656

Jay Belanger's avatar
Jay Belanger committed
657
(defcalcmodevar calc-display-raw nil
658
  "If non-nil, display shows unformatted Lisp exprs. (For debugging)")
Eli Zaretskii's avatar
Eli Zaretskii committed
659

Jay Belanger's avatar
Jay Belanger committed
660 661
(defcalcmodevar calc-internal-prec 12
  "Number of digits of internal precision for calc-mode calculations.")
Eli Zaretskii's avatar
Eli Zaretskii committed
662

Jay Belanger's avatar
Jay Belanger committed
663 664
(defcalcmodevar calc-angle-mode 'deg
  "If deg, angles are in degrees; if rad, angles are in radians.
665
If hms, angles are in degrees-minutes-seconds.")
Eli Zaretskii's avatar
Eli Zaretskii committed
666

Jay Belanger's avatar
Jay Belanger committed
667 668
(defcalcmodevar calc-algebraic-mode nil
  "If non-nil, numeric entry accepts whole algebraic expressions.
669
If nil, algebraic expressions must be preceded by \"'\".")
Eli Zaretskii's avatar
Eli Zaretskii committed
670

Jay Belanger's avatar
Jay Belanger committed
671 672
(defcalcmodevar calc-incomplete-algebraic-mode nil
  "Like calc-algebraic-mode except only affects ( and [ keys.")
673

Jay Belanger's avatar
Jay Belanger committed
674 675
(defcalcmodevar calc-symbolic-mode nil
  "If non-nil, inexact numeric computations like sqrt(2) are postponed.
676 677
If nil, computations on numbers always yield numbers where possible.")

Jay Belanger's avatar
Jay Belanger committed
678 679
(defcalcmodevar calc-matrix-mode nil
  "If `matrix', variables are assumed to be matrix-valued.
680
If a number, variables are assumed to be NxN matrices.
681
If `sqmatrix', variables are assumed to be square matrices of an unspecified size.
682 683 684
If `scalar', variables are assumed to be scalar-valued.
If nil, symbolic math routines make no assumptions about variables.")

Jay Belanger's avatar
Jay Belanger committed
685 686
(defcalcmodevar calc-shift-prefix nil
  "If non-nil, shifted letter keys are prefix keys rather than normal meanings.")
687

Jay Belanger's avatar
Jay Belanger committed
688 689
(defcalcmodevar calc-window-height 7
  "Initial height of Calculator window.")
690

Jay Belanger's avatar
Jay Belanger committed
691 692
(defcalcmodevar calc-display-trail t
  "If non-nil, M-x calc creates a window to display Calculator trail.")
693

Jay Belanger's avatar
Jay Belanger committed
694 695
(defcalcmodevar calc-show-selections t
  "If non-nil, selected sub-formulas are shown by obscuring rest of formula.
696 697
If nil, selected sub-formulas are highlighted by obscuring the sub-formulas.")

Jay Belanger's avatar
Jay Belanger committed
698 699
(defcalcmodevar calc-use-selections t
  "If non-nil, commands operate only on selected portions of formulas.
700 701
If nil, selections displayed but ignored.")

Jay Belanger's avatar
Jay Belanger committed
702 703
(defcalcmodevar calc-assoc-selections t
  "If non-nil, selection hides deep structure of associative formulas.")
704

Jay Belanger's avatar
Jay Belanger committed
705 706
(defcalcmodevar calc-display-working-message 'lots
  "If non-nil, display \"Working...\" for potentially slow Calculator commands.")
707

Jay Belanger's avatar
Jay Belanger committed
708 709
(defcalcmodevar calc-auto-why 'maybe
  "If non-nil, automatically execute a \"why\" command to explain odd results.")
710

Jay Belanger's avatar
Jay Belanger committed
711 712
(defcalcmodevar calc-timing nil
  "If non-nil, display timing information on each slow command.")
713

Jay Belanger's avatar
Jay Belanger committed
714
(defcalcmodevar calc-mode-save-mode 'local)
715

Jay Belanger's avatar
Jay Belanger committed
716 717
(defcalcmodevar calc-standard-date-formats
  '("N"
718 719 720 721 722 723 724 725 726
    "<H:mm:SSpp >Www Mmm D, YYYY"
    "D Mmm YYYY<, h:mm:SS>"
    "Www Mmm BD< hh:mm:ss> YYYY"
    "M/D/Y< H:mm:SSpp>"
    "D.M.Y< h:mm:SS>"
    "M-D-Y< H:mm:SSpp>"
    "D-M-Y< h:mm:SS>"
    "j<, h:mm:SS>"
    "YYddd< hh:mm:ss>"))
727

Jay Belanger's avatar
Jay Belanger committed
728 729
(defcalcmodevar calc-autorange-units nil
  "If non-nil, automatically set unit prefixes to keep units in a reasonable range.")
730

731 732
(defcalcmodevar calc-was-keypad-mode nil
  "Non-nil if Calc was last invoked in keypad mode.")
733

734 735
(defcalcmodevar calc-full-mode nil
  "Non-nil if Calc was last invoked in full-screen mode.")
736

737 738
(defcalcmodevar calc-user-parse-tables nil
  "Alist of languages with user-defined parse rules.")
739

740 741
(defcalcmodevar calc-gnuplot-default-device "default"
  "The default device name for GNUPLOT plotting.")
742

743 744
(defcalcmodevar calc-gnuplot-default-output "STDOUT"
  "The default output file for GNUPLOT plotting.")
745

746 747
(defcalcmodevar calc-gnuplot-print-device "postscript"
  "The default device name for GNUPLOT printing.")
748

749 750
(defcalcmodevar calc-gnuplot-print-output "auto"
  "The default output for GNUPLOT printing.")
751

752 753
(defcalcmodevar calc-gnuplot-geometry nil
  "The default geometry for the GNUPLOT window.")
754

755 756
(defcalcmodevar calc-graph-default-resolution 15
  "The default number of data points when plotting curves.")
757

758 759
(defcalcmodevar calc-graph-default-resolution-3d 5
  "The default number of x- and y- data points when plotting surfaces.")
760

761 762 763
(defcalcmodevar calc-invocation-macro nil
  "A user defined macro for starting Calc.
Used by `calc-user-invocation'.")
Jay Belanger's avatar
Jay Belanger committed
764 765 766

(defcalcmodevar calc-show-banner t
  "*If non-nil, show a friendly greeting above the stack.")
Eli Zaretskii's avatar
Eli Zaretskii committed
767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822

(defconst calc-local-var-list '(calc-stack
				calc-stack-top
				calc-undo-list
				calc-redo-list
				calc-always-load-extensions
				calc-mode-save-mode
				calc-display-raw
				calc-line-numbering
				calc-line-breaking
				calc-display-just
				calc-display-origin
				calc-left-label
				calc-right-label
				calc-auto-why
				calc-algebraic-mode
				calc-incomplete-algebraic-mode
				calc-symbolic-mode
				calc-matrix-mode
				calc-inverse-flag
				calc-hyperbolic-flag
				calc-keep-args-flag
				calc-angle-mode
				calc-number-radix
				calc-leading-zeros
				calc-group-digits
				calc-group-char
				calc-point-char
				calc-frac-format
				calc-prefer-frac
				calc-hms-format
				calc-date-format
				calc-standard-date-formats
				calc-float-format
				calc-full-float-format
				calc-complex-format
				calc-matrix-just
				calc-full-vectors
				calc-full-trail-vectors
				calc-break-vectors
				calc-vector-commas
				calc-vector-brackets
				calc-matrix-brackets
				calc-complex-mode
				calc-infinite-mode
				calc-display-strings
				calc-simplify-mode
				calc-auto-recompute
				calc-autorange-units
				calc-show-plain
				calc-show-selections
				calc-use-selections
				calc-assoc-selections
				calc-word-size
				calc-internal-prec))

823 824 825 826 827 828 829 830 831 832 833 834 835 836
(defvar calc-mode-hook nil
  "Hook run when entering calc-mode.")

(defvar calc-trail-mode-hook nil
  "Hook run when entering calc-trail-mode.")

(defvar calc-start-hook nil
  "Hook run when calc is started.")

(defvar calc-end-hook nil
  "Hook run when calc is quit.")

(defvar calc-load-hook nil
  "Hook run when calc.el is loaded.")
Eli Zaretskii's avatar
Eli Zaretskii committed
837

838 839 840 841 842 843
(defvar calc-window-hook nil
  "Hook called to create the Calc window.")

(defvar calc-trail-window-hook nil
  "Hook called to create the Calc trail window.")

844 845 846 847 848 849 850 851 852
(defvar calc-embedded-new-buffer-hook nil
  "Hook run when starting embedded mode in a new buffer.")

(defvar calc-embedded-new-formula-hook nil
  "Hook run when starting embedded mode in a new formula.")

(defvar calc-embedded-mode-hook nil
  "Hook run when starting embedded mode.")

853 854
;; Set up the autoloading linkage.
(let ((name (and (fboundp 'calc-dispatch)
855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880
                 (eq (car-safe (symbol-function 'calc-dispatch)) 'autoload)
                 (nth 1 (symbol-function 'calc-dispatch))))
      (p load-path))

  ;; If Calc files exist on the load-path, we're all set.
  (while (and p (not (file-exists-p
                      (expand-file-name "calc-misc.elc" (car p)))))
    (setq p (cdr p)))
  (or p

      ;; If Calc is autoloaded using a path name, look there for Calc files.
      ;; This works for both relative ("calc/calc.elc") and absolute paths.
      (and name (file-name-directory name)
           (let ((p2 load-path)
                 (name2 (concat (file-name-directory name)
                                "calc-misc.elc")))
             (while (and p2 (not (file-exists-p
                                  (expand-file-name name2 (car p2)))))
               (setq p2 (cdr p2)))
             (when p2
               (setq load-path (nconc load-path
                                      (list
                                       (directory-file-name
                                        (file-name-directory
                                         (expand-file-name
                                          name (car p2))))))))))))
Eli Zaretskii's avatar
Eli Zaretskii committed
881

882 883 884
;; The following modes use specially-formatted data.
(put 'calc-mode 'mode-class 'special)
(put 'calc-trail-mode 'mode-class 'special)
885

886 887 888
;; Define "inexact-result" as an e-lisp error symbol.
(put 'inexact-result 'error-conditions '(error inexact-result calc-error))
(put 'inexact-result 'error-message "Calc internal error (inexact-result)")
889

890 891 892 893 894
;; Define "math-overflow" and "math-underflow" as e-lisp error symbols.
(put 'math-overflow 'error-conditions '(error math-overflow calc-error))
(put 'math-overflow 'error-message "Floating-point overflow occurred")
(put 'math-underflow 'error-conditions '(error math-underflow calc-error))
(put 'math-underflow 'error-message "Floating-point underflow occurred")
895

896 897 898 899 900 901 902 903 904 905
(defvar calc-trail-pointer nil
  "The \"current\" entry in trail buffer.")
(defvar calc-trail-overlay nil
  "The value of overlay-arrow-string.")
(defvar calc-undo-list nil
  "The list of previous operations for undo.")
(defvar calc-redo-list nil
  "The list of recent undo operations.")
(defvar calc-main-buffer nil
  "A pointer to Calculator buffer.")
906 907
(defvar calc-buffer-list nil
  "A list of all Calc buffers.")
908 909 910 911
(defvar calc-trail-buffer nil
  "A pointer to Calc Trail buffer.")
(defvar calc-why nil
  "Explanations of most recent errors.")
912
(defvar calc-next-why nil)
913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928
(defvar calc-inverse-flag nil
  "If non-nil, next operation is Inverse.")
(defvar calc-hyperbolic-flag nil
  "If non-nil, next operation is Hyperbolic.")
(defvar calc-keep-args-flag nil
  "If non-nil, next operation should not remove its arguments from stack.")
(defvar calc-function-open "("
  "Open-parenthesis string for function call notation.")
(defvar calc-function-close ")"
  "Close-parenthesis string for function call notation.")
(defvar calc-language-output-filter nil
  "Function through which to pass strings after formatting.")
(defvar calc-language-input-filter nil
  "Function through which to pass strings before parsing.")
(defvar calc-radix-formatter nil
  "Formatting function used for non-decimal numbers.")
929 930 931 932
(defvar calc-lang-slash-idiv nil
  "A list of languages in which / might represent integer division.")
(defvar calc-lang-allow-underscores nil
  "A list of languages which allow underscores in variable names.")
933 934
(defvar calc-lang-allow-percentsigns nil
  "A list of languages which allow percent signs in variable names.")
935 936 937 938 939 940
(defvar calc-lang-c-type-hex nil
  "Languages in which octal and hex numbers are written with leading 0 and 0x,")
(defvar calc-lang-brackets-are-subscripts nil
  "Languages in which subscripts are indicated by brackets.")
(defvar calc-lang-parens-are-subscripts nil
  "Languages in which subscripts are indicated by parentheses.")
941

942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965
(defvar calc-last-kill nil
  "The last number killed in calc-mode.")
(defvar calc-dollar-values nil
  "Values to be used for '$'.")
(defvar calc-dollar-used nil
  "The highest order of '$' that occurred.")
(defvar calc-hashes-used nil
  "The highest order of '#' that occurred.")
(defvar calc-quick-prev-results nil
  "Previous results from Quick Calc.")
(defvar calc-said-hello nil
  "Non-nil if the welcomd message has been displayed.")
(defvar calc-executing-macro nil
  "Non-nil if a keyboard macro is executing from the \"K\" key.")
(defvar calc-any-selections nil
  "Non-nil if there are selections present.")
(defvar calc-help-phase 0
  "The number of consecutive \"?\" keystrokes.")
(defvar calc-full-help-flag nil
  "Non-nil if `calc-full-help' is being executed.")
(defvar calc-refresh-count 0
  "The number of `calc-refresh' calls.")
(defvar calc-display-dirty nil
  "Non-nil if the stack display might not reflect the latest mode settings.")
966 967
(defvar calc-prepared-composition nil)
(defvar calc-selection-cache-default-entry nil)
968 969 970 971 972 973 974 975
(defvar calc-embedded-info nil
  "If non-nil, a vector consisting of information for embedded mode.")
(defvar calc-embedded-active nil
  "Alist of buffers with sorted lists of calc-embedded-infos.")
(defvar calc-standalone-flag nil
  "Non-nil if Emacs started with standalone Calc.")
(defvar var-EvalRules nil
  "User defined rules that Calc will apply automatically.")
976 977
(defvar math-eval-rules-cache-tag t)
(defvar math-radix-explicit-format t)
978 979 980 981
(defvar math-expr-function-mapping nil
  "Alist of language specific functions with Calc functions.")
(defvar math-expr-variable-mapping nil
  "Alist of language specific variables with Calc variables.")
982 983 984 985 986 987 988 989 990 991
(defvar math-read-expr-quotes nil)
(defvar math-working-step nil)
(defvar math-working-step-2 nil)
(defvar var-i '(special-const (math-imaginary 1)))
(defvar var-pi '(special-const (math-pi)))
(defvar var-e '(special-const (math-e)))
(defvar var-phi '(special-const (math-phi)))
(defvar var-gamma '(special-const (math-gamma-const)))
(defvar var-Modes '(special-const (math-get-modes-vec)))

992 993
(mapc (lambda (v) (or (boundp v) (set v nil)))
      calc-local-var-list)
Eli Zaretskii's avatar
Eli Zaretskii committed
994

995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023
(defvar calc-mode-map
  (let ((map (make-keymap)))
    (suppress-keymap map t)
    (define-key map "+" 'calc-plus)
    (define-key map "-" 'calc-minus)
    (define-key map "*" 'calc-times)
    (define-key map "/" 'calc-divide)
    (define-key map "%" 'calc-mod)
    (define-key map "&" 'calc-inv)
    (define-key map "^" 'calc-power)
    (define-key map "\M-%" 'calc-percent)
    (define-key map "e" 'calcDigit-start)
    (define-key map "i" 'calc-info)
    (define-key map "n" 'calc-change-sign)
    (define-key map "q" 'calc-quit)
    (define-key map "Y" 'nil)
    (define-key map "Y?" 'calc-shift-Y-prefix-help)
    (define-key map "?" 'calc-help)
    (define-key map " " 'calc-enter)
    (define-key map "'" 'calc-algebraic-entry)
    (define-key map "$" 'calc-auto-algebraic-entry)
    (define-key map "\"" 'calc-auto-algebraic-entry)
    (define-key map "\t" 'calc-roll-down)
    (define-key map "\M-\t" 'calc-roll-up)
    (define-key map "\C-m" 'calc-enter)
    (define-key map "\M-\C-m" 'calc-last-args-stub)
    (define-key map "\C-j" 'calc-over)
    (define-key map "\C-y" 'calc-yank)
    (define-key map [mouse-2] 'calc-yank)
1024

1025 1026 1027 1028
    (mapc (lambda (x) (define-key map (char-to-string x) 'undefined))
          "lOW")
    (mapc (lambda (x) (define-key map (char-to-string x) 'calc-missing-key))
          (concat "ABCDEFGHIJKLMNPQRSTUVXZabcdfghjkmoprstuvwxyz"
1029 1030 1031 1032
                  ":\\|!()[]<>{},;=~`\C-k\C-w\C-_"))
    (define-key map "\M-w" 'calc-missing-key)
    (define-key map "\M-k" 'calc-missing-key)
    (define-key map "\M-\C-w" 'calc-missing-key)
1033 1034 1035
    (mapc (lambda (x) (define-key map (char-to-string x) 'calcDigit-start))
          "_0123456789.#@")
    map)
1036 1037 1038
  "The key map for Calc.")


1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065

(defvar calc-digit-map
  (let ((map (make-keymap)))
    (if (featurep 'xemacs)
        (map-keymap (function
                     (lambda (keys bind)
                       (define-key map keys
                         (if (eq bind 'undefined)
                             'undefined 'calcDigit-nondigit))))
                    calc-mode-map)
      (let ((cmap (nth 1 calc-mode-map))
            (dmap (nth 1 map))
            (i 0))
        (while (< i 128)
          (aset dmap i
                (if (eq (aref cmap i) 'undefined)
                    'undefined 'calcDigit-nondigit))
          (setq i (1+ i)))))
    (mapc (lambda (x) (define-key map (char-to-string x) 'calcDigit-key))
          "_0123456789.e+-:n#@oh'\"mspM")
    (mapc (lambda (x) (define-key map (char-to-string x) 'calcDigit-letter))
          "abcdfgijklqrtuvwxyzABCDEFGHIJKLNOPQRSTUVWXYZ")
    (define-key map "'" 'calcDigit-algebraic)
    (define-key map "`" 'calcDigit-edit)
    (define-key map "\C-g" 'abort-recursive-edit)
    map)
  "The key map for entering Calc digits.")
Eli Zaretskii's avatar
Eli Zaretskii committed
1066

1067 1068 1069 1070 1071 1072 1073
(mapc (lambda (x)
	(condition-case err
	    (progn
	      (define-key calc-digit-map x 'calcDigit-backspace)
	      (define-key calc-mode-map x 'calc-pop)
	      (define-key calc-mode-map
		  (if (vectorp x)
1074
		      (if (featurep 'xemacs)