calc.el 129 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 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
Jay Belanger's avatar
Jay Belanger committed
9
;; Version: 2.1
Eli Zaretskii's avatar
Eli Zaretskii committed
10 11 12

;; This file is part of GNU Emacs.

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

Eli Zaretskii's avatar
Eli Zaretskii committed
18
;; GNU Emacs is distributed in the hope that it will be useful,
19 20 21 22 23
;; 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
24
;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
Eli Zaretskii's avatar
Eli Zaretskii committed
25

26
;;; Commentary:
Eli Zaretskii's avatar
Eli Zaretskii committed
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 142
;; 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.

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

Eli Zaretskii's avatar
Eli Zaretskii committed
145
(require 'calc-macs)
Eli Zaretskii's avatar
Eli Zaretskii committed
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 180
;; 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))
181
(declare-function math-normalize-nonstandard "calc-ext" ())
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 224
(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
225
(defgroup calc nil
226
  "GNU Calc."
Jay Belanger's avatar
calc.el  
Jay Belanger committed
227
  :prefix "calc-"
228 229
  :tag    "Calc"
  :group  'applications)
Jay Belanger's avatar
calc.el  
Jay Belanger committed
230

Eli Zaretskii's avatar
Eli Zaretskii committed
231
;;;###autoload
232
(defcustom calc-settings-file
Jay Belanger's avatar
calc.el  
Jay Belanger committed
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
  (convert-standard-filename "~/.calc.el")
  "*File in which to record permanent settings."
  :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)
248 249
    (f90-mode . fortran)
    (texinfo-mode . calc-normal-language))
Jay Belanger's avatar
calc.el  
Jay Belanger committed
250 251
  "*Alist of major modes with appropriate Calc languages."
  :group 'calc
252
  :type '(alist :key-type (symbol :tag "Major mode")
253
                :value-type (symbol :tag "Calc language")))
Jay Belanger's avatar
calc.el  
Jay Belanger committed
254

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

261
(defcustom calc-embedded-announce-formula-alist
262
  '((c++-mode     . "//Embed\n\\(// .*\n\\)*")
263
    (c-mode       . "/\\*Embed\\*/\n\\(/\\* .*\\*/\n\\)*")
264
    (f90-mode     . "!Embed\n\\(! .*\n\\)*")
265
    (fortran-mode . "C Embed\n\\(C .*\n\\)*")
266 267 268 269 270 271 272
    (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\\)*"))
273 274 275 276 277
  "*Alist of major modes with appropriate values for `calc-embedded-announce-formula'."
  :group 'calc
  :type '(alist :key-type (symbol :tag "Major mode")
                :value-type (regexp :tag "Regexp to announce formula")))

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

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

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

298
(defcustom calc-embedded-open-word
Jay Belanger's avatar
calc.el  
Jay Belanger committed
299 300 301 302 303
  "^\\|[^-+0-9.eE]"
  "*A regular expression for the opening delimiter of a formula used by calc-embedded-word."
  :group 'calc
  :type '(regexp))

304
(defcustom calc-embedded-close-word
Jay Belanger's avatar
calc.el  
Jay Belanger committed
305 306 307 308 309
  "$\\|[^-+0-9.eE]"
  "*A regular expression for the closing delimiter of a formula used by calc-embedded-word."
  :group 'calc
  :type '(regexp))

310 311 312 313 314 315 316 317
(defcustom calc-embedded-open-close-word-alist
  nil
  "*Alist of major modes with pairs of word delimiters used by calc-embedded."
  :group 'calc
  :type '(alist :key-type (symbol :tag "Major mode")
                :value-type (list (regexp :tag "Opening word delimiter")
                                  (regexp :tag "Closing word delimiter"))))

318
(defcustom calc-embedded-open-plain
Jay Belanger's avatar
calc.el  
Jay Belanger committed
319 320 321 322 323 324 325
  "%%% "
  "*A string which is the opening delimiter for a \"plain\" formula.
If calc-show-plain mode is enabled, this is inserted at the front of
each formula."
  :group 'calc
  :type '(string))

326
(defcustom calc-embedded-close-plain
Jay Belanger's avatar
calc.el  
Jay Belanger committed
327 328 329 330 331 332
  " %%%\n"
  "*A string which is the closing delimiter for a \"plain\" formula.
See calc-embedded-open-plain."
  :group 'calc
  :type '(string))

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

351
(defcustom calc-embedded-open-new-formula
Jay Belanger's avatar
calc.el  
Jay Belanger committed
352 353 354 355 356
  "\n\n"
  "*A string which is inserted at front of formula by calc-embedded-new-formula."
  :group 'calc
  :type '(string))

357
(defcustom calc-embedded-close-new-formula
Jay Belanger's avatar
calc.el  
Jay Belanger committed
358 359 360 361 362
  "\n\n"
  "*A string which is inserted at end of formula by calc-embedded-new-formula."
  :group 'calc
  :type '(string))

363 364 365 366 367 368 369 370
(defcustom calc-embedded-open-close-new-formula-alist
  nil
  "*Alist of major modes with pairs of new formula delimiters used by calc-embedded."
  :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"))))

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

378
(defcustom calc-embedded-close-mode
Jay Belanger's avatar
calc.el  
Jay Belanger committed
379 380 381 382 383 384
  "\n"
  "*A string which should follow calc-embedded mode annotations.
This is not required to be present for user-written mode annotations."
  :group 'calc
  :type '(string))

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

403
(defcustom calc-gnuplot-name
Jay Belanger's avatar
calc.el  
Jay Belanger committed
404 405 406 407 408
  "gnuplot"
  "*Name of GNUPLOT program, for calc-graph features."
  :group 'calc
  :type '(string))

409
(defcustom calc-gnuplot-plot-command
Jay Belanger's avatar
calc.el  
Jay Belanger committed
410 411 412 413 414
  nil
  "*Name of command for displaying GNUPLOT output; %s = file name to print."
  :group 'calc
  :type '(choice (string) (sexp)))

415
(defcustom calc-gnuplot-print-command
Jay Belanger's avatar
calc.el  
Jay Belanger committed
416 417 418 419
  "lp %s"
  "*Name of command for printing GNUPLOT output; %s = file name to print."
  :group 'calc
  :type '(choice (string) (sexp)))
Eli Zaretskii's avatar
Eli Zaretskii committed
420

421 422 423 424 425 426 427
(defcustom calc-multiplication-has-precedence
  t
  "*If non-nil, multiplication has precedence over division
in normal mode."
  :group 'calc
  :type 'boolean)

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

431 432 433
(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
434

435 436 437
(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
438

439 440 441
(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
442

443 444 445 446 447 448 449 450 451 452
(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
453

454 455
(defvar calc-Y-help-msgs nil
  "List of strings for Y prefix help.")
Eli Zaretskii's avatar
Eli Zaretskii committed
456

457 458
(defvar calc-loaded-settings-file nil
  "t if `calc-settings-file' has been loaded yet.")
Eli Zaretskii's avatar
Eli Zaretskii committed
459

Jay Belanger's avatar
Jay Belanger committed
460 461 462 463 464

(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
465 466 467
  "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
468 469 470 471 472
  `(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
473
  "Restore the default values of the variables in `calc-mode-var-list'."
Jay Belanger's avatar
Jay Belanger committed
474 475 476 477
  (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
478
  "Restore the user-saved values of the variables in `calc-mode-var-list'."
Jay Belanger's avatar
Jay Belanger committed
479 480
  (let ((newvarlist '()))
    (save-excursion
481 482 483 484 485 486 487 488 489 490 491
      (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
492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507
          (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
508
  "If non-nil, load the calc-ext module automatically when Calc is loaded.")
Jay Belanger's avatar
Jay Belanger committed
509 510 511 512 513 514 515 516 517

(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.
518 519
If `right', stack display is right-justified.
If `center', stack display is centered.")
Eli Zaretskii's avatar
Eli Zaretskii committed
520

Jay Belanger's avatar
Jay Belanger committed
521 522
(defcalcmodevar calc-display-origin nil
  "Horizontal origin of displayed stack entries.
523 524 525 526
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
527 528
(defcalcmodevar calc-number-radix 10
  "Radix for entry and display of numbers in calc-mode, 2-36.")
529

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

Jay Belanger's avatar
Jay Belanger committed
533 534
(defcalcmodevar calc-group-digits nil
  "If non-nil, group digits in large displayed integers by inserting spaces.
535 536 537
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
538 539
(defcalcmodevar calc-group-char ","
  "The character (in the form of a string) to be used for grouping digits.
540 541
This is used only when calc-group-digits mode is on.")

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

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

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

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

Jay Belanger's avatar
Jay Belanger committed
555 556 557
(defcalcmodevar calc-date-format '((H ":" mm C SS pp " ")
                                  Www " " Mmm " " D ", " YYYY)
  "Format of displayed date forms.")
558

Jay Belanger's avatar
Jay Belanger committed
559 560
(defcalcmodevar calc-float-format '(float 0)
  "Format to use for display of floating-point numbers in calc-mode.
561 562 563 564 565 566 567 568 569 570 571 572
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
573 574
(defcalcmodevar calc-full-float-format '(float 0)
  "Format to use when full precision must be displayed.")
575

Jay Belanger's avatar
Jay Belanger committed
576 577
(defcalcmodevar calc-complex-format nil
  "Format to use for display of complex numbers in calc-mode.  Must be one of:
578 579 580 581
  nil            Use (x, y) form.
  i              Use x + yi form.
  j              Use x + yj form.")

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

Jay Belanger's avatar
Jay Belanger committed
585 586
(defcalcmodevar calc-infinite-mode nil
  "If nil, 1 / 0 is left unsimplified.
587 588 589
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
590 591
(defcalcmodevar calc-display-strings nil
  "If non-nil, display vectors of byte-sized integers as strings.")
Eli Zaretskii's avatar
Eli Zaretskii committed
592

Jay Belanger's avatar
Jay Belanger committed
593 594
(defcalcmodevar calc-matrix-just 'center
  "If nil, vector elements are left-justified.
595 596 597
If `right', vector elements are right-justified.
If `center', vector elements are centered.")

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

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

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

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

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

Jay Belanger's avatar
Jay Belanger committed
613 614
(defcalcmodevar calc-matrix-brackets '(R O)
  "A list of code-letter symbols that control \"big\" matrix display.
615 616 617 618
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
619 620
(defcalcmodevar calc-language nil
  "Language or format for entry and display of stack values.  Must be one of:
621 622 623 624 625 626 627 628
  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.
629
  latex         Use LaTeX notation.
630
  eqn		Use eqn notation.
631 632 633
  yacas         Use Yacas notation.
  maxima        Use Maxima notation.
  giac          Use Giac notation.
634 635
  math		Use Mathematica(tm) notation.
  maple		Use Maple notation.")
Eli Zaretskii's avatar
Eli Zaretskii committed
636

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

Jay Belanger's avatar
Jay Belanger committed
640 641
(defcalcmodevar calc-left-label ""
  "Label to display at left of formula.")
Eli Zaretskii's avatar
Eli Zaretskii committed
642

Jay Belanger's avatar
Jay Belanger committed
643 644
(defcalcmodevar calc-right-label ""
  "Label to display at right of formula.")
Eli Zaretskii's avatar
Eli Zaretskii committed
645

Jay Belanger's avatar
Jay Belanger committed
646 647
(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
648

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

Jay Belanger's avatar
Jay Belanger committed
652 653
(defcalcmodevar calc-simplify-mode nil
  "Type of simplification applied to results.
654 655 656 657 658 659 660
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
661

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

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

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

Jay Belanger's avatar
Jay Belanger committed
671 672
(defcalcmodevar calc-angle-mode 'deg
  "If deg, angles are in degrees; if rad, angles are in radians.
673
If hms, angles are in degrees-minutes-seconds.")
Eli Zaretskii's avatar
Eli Zaretskii committed
674

Jay Belanger's avatar
Jay Belanger committed
675 676
(defcalcmodevar calc-algebraic-mode nil
  "If non-nil, numeric entry accepts whole algebraic expressions.
677
If nil, algebraic expressions must be preceded by \"'\".")
Eli Zaretskii's avatar
Eli Zaretskii committed
678

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

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

Jay Belanger's avatar
Jay Belanger committed
686 687
(defcalcmodevar calc-matrix-mode nil
  "If `matrix', variables are assumed to be matrix-valued.
688
If a number, variables are assumed to be NxN matrices.
689
If `sqmatrix', variables are assumed to be square matrices of an unspecified size.
690 691 692
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
693 694
(defcalcmodevar calc-shift-prefix nil
  "If non-nil, shifted letter keys are prefix keys rather than normal meanings.")
695

Jay Belanger's avatar
Jay Belanger committed
696 697
(defcalcmodevar calc-window-height 7
  "Initial height of Calculator window.")
698

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

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

Jay Belanger's avatar
Jay Belanger committed
706 707
(defcalcmodevar calc-use-selections t
  "If non-nil, commands operate only on selected portions of formulas.
708 709
If nil, selections displayed but ignored.")

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

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

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

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

Jay Belanger's avatar
Jay Belanger committed
722
(defcalcmodevar calc-mode-save-mode 'local)
723

Jay Belanger's avatar
Jay Belanger committed
724 725
(defcalcmodevar calc-standard-date-formats
  '("N"
726 727 728 729 730 731 732 733 734
    "<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>"))
735

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

739 740
(defcalcmodevar calc-was-keypad-mode nil
  "Non-nil if Calc was last invoked in keypad mode.")
741

742 743
(defcalcmodevar calc-full-mode nil
  "Non-nil if Calc was last invoked in full-screen mode.")
744

745 746
(defcalcmodevar calc-user-parse-tables nil
  "Alist of languages with user-defined parse rules.")
747

748 749
(defcalcmodevar calc-gnuplot-default-device "default"
  "The default device name for GNUPLOT plotting.")
750

751 752
(defcalcmodevar calc-gnuplot-default-output "STDOUT"
  "The default output file for GNUPLOT plotting.")
753

754 755
(defcalcmodevar calc-gnuplot-print-device "postscript"
  "The default device name for GNUPLOT printing.")
756

757 758
(defcalcmodevar calc-gnuplot-print-output "auto"
  "The default output for GNUPLOT printing.")
759

760 761
(defcalcmodevar calc-gnuplot-geometry nil
  "The default geometry for the GNUPLOT window.")
762

763 764
(defcalcmodevar calc-graph-default-resolution 15
  "The default number of data points when plotting curves.")
765

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

769 770 771
(defcalcmodevar calc-invocation-macro nil
  "A user defined macro for starting Calc.
Used by `calc-user-invocation'.")
Jay Belanger's avatar
Jay Belanger committed
772 773 774

(defcalcmodevar calc-show-banner t
  "*If non-nil, show a friendly greeting above the stack.")
Eli Zaretskii's avatar
Eli Zaretskii committed
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 823 824 825 826 827 828 829 830

(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))

831 832 833 834 835 836 837 838 839 840 841 842 843 844
(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
845

846 847 848 849 850 851
(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.")

852 853 854 855 856 857 858 859 860
(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.")

861 862
;; Set up the autoloading linkage.
(let ((name (and (fboundp 'calc-dispatch)
863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888
                 (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
889

890 891 892
;; The following modes use specially-formatted data.
(put 'calc-mode 'mode-class 'special)
(put 'calc-trail-mode 'mode-class 'special)
893

894 895 896
;; 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)")
897

898 899 900 901 902
;; 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")
903

Jay Belanger's avatar
Jay Belanger committed
904
(defconst calc-version "2.1")
905 906 907 908 909 910 911 912 913 914 915 916 917 918
(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.")
(defvar calc-trail-buffer nil
  "A pointer to Calc Trail buffer.")
(defvar calc-why nil
  "Explanations of most recent errors.")
919
(defvar calc-next-why nil)
920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935
(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.")
936 937 938 939
(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.")
940 941
(defvar calc-lang-allow-percentsigns nil
  "A list of languages which allow percent signs in variable names.")
942 943 944 945 946 947
(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.")
948

949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972
(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.")
973 974
(defvar calc-prepared-composition nil)
(defvar calc-selection-cache-default-entry nil)
975 976 977 978 979 980 981 982
(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.")
983 984
(defvar math-eval-rules-cache-tag t)
(defvar math-radix-explicit-format t)
985 986 987 988
(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.")
989 990 991 992 993 994 995 996 997 998
(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)))

999 1000
(mapc (lambda (v) (or (boundp v) (set v nil)))
      calc-local-var-list)
Eli Zaretskii's avatar
Eli Zaretskii committed
1001

1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035
(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)
      
    (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"
1036 1037 1038 1039
                  ":\\|!()[]<>{},;=~`\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)
1040 1041 1042
    (mapc (lambda (x) (define-key map (char-to-string x) 'calcDigit-start))
          "_0123456789.#@")
    map)
1043 1044 1045
  "The key map for Calc.")


1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072

(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
1073

1074 1075 1076 1077 1078 1079 1080
(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)
1081
		      (if (featurep 'xemacs)
1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093
			  (if (= (length x) 1)
			      (vector (if (consp (aref x 0))
					  (cons 'meta (aref x 0))
					(list 'meta (aref x 0))))
			    "\e\C-d")
			(vconcat "\e" x))
		    (concat "\e" x))
		'calc-pop-above))
	  (error nil)))
      (if calc-scan-for-dels
	  (append (where-is-internal 'delete-backward-char global-map)
		  (where-is-internal 'backward-delete-char global-map)
1094
		  (where-is-internal 'backward-delete-char-untabify global-map)
1095 1096
		  '("\C-d"))
	'("\177" "\C-d")))
Eli Zaretskii's avatar
Eli Zaretskii committed
1097

1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145
(defvar calc-dispatch-map
  (let ((map (make-keymap)))
    (mapc (lambda (x)
            (define-key map (char-to-string (car x)) (cdr x))
            (when (string-match "abcdefhijklnopqrstuwxyz"
                                (char-to-string (car x)))
              (define-key map (char-to-string (- (car x) ?a -1)) (cdr x)))
            (define-key map (format "\e%c" (car x)) (cdr x)))
          '( ( ?a . calc-embedded-activate )
             ( ?b . calc-big-or-small )
             ( ?c . calc )
             ( ?d . calc-embedded-duplicate )
             ( ?e . calc-embedded )
             ( ?f . calc-embedded-new-formula )
             ( ?g . calc-grab-region )
             ( ?h . calc-dispatch-help )
             ( ?i . calc-info )
             ( ?j . calc-embedded-select )
             ( ?k . calc-keypad )
             ( ?l . calc-load-everything )
             ( ?m . read-kbd-macro )
             ( ?n . calc-embedded-next )
             ( ?o . calc-other-window )
             ( ?p . calc-embedded-previous )
             ( ?q . quick-calc )
             ( ?r . calc-grab-rectangle )
             ( ?s . calc-info-summary )
             ( ?t . calc-tutorial )
             ( ?u . calc-embedded-update-formula )
             ( ?w . calc-embedded-word )
             ( ?x . calc-quit )
             ( ?y . calc-copy-to-buffer )
             ( ?z . calc-user-invocation )
             ( ?\' . calc-embedded-new-formula )
             ( ?\` . calc-embedded-edit )
             ( ?: . calc-grab-sum-down )
             ( ?_ . calc-grab-sum-across )
             ( ?0 . calc-reset )
             ( ?? . calc-dispatch-help )
             ( ?# . calc-same-interface )
             ( ?& . calc-same-interface )
             ( ?\\ . calc-same-interface )
             ( ?= . calc-same-interface )
             ( ?* . calc-same-interface )
             ( ?/ . calc-same-interface )
             ( ?+ . calc-same-interface )
             ( ?- . calc-same-interface ) ))
    map)
1146 1147
  "The key map for starting Calc.")

Eli Zaretskii's avatar
Eli Zaretskii committed
1148 1149

;;;; (Autoloads here)
1150
(load "calc-loaddefs.el" nil t)
Eli Zaretskii's avatar
Eli Zaretskii committed
1151

1152
;;;###autoload (define-key ctl-x-map "*" 'calc-dispatch)
Eli Zaretskii's avatar
Eli Zaretskii committed
1153 1154 1155

;;;###autoload
(defun calc-dispatch (&optional arg)
1156
  "Invoke the GNU Emacs Calculator.  See `calc-dispatch-help' for details."
Eli Zaretskii's avatar
Eli Zaretskii committed
1157
  (interactive "P")