1;;; calc-mode.el --- calculator modes for Calc
2
3;; Copyright (C) 1990, 1991, 1992, 1993, 2001, 2002, 2003, 2004,
4;;   2005, 2006, 2007 Free Software Foundation, Inc.
5
6;; Author: David Gillespie <daveg@synaptics.com>
7;; Maintainer: Jay Belanger <jay.p.belanger@gmail.com>
8
9;; This file is part of GNU Emacs.
10
11;; GNU Emacs is free software; you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by
13;; the Free Software Foundation; either version 2, or (at your option)
14;; any later version.
15
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
22;; along with GNU Emacs; see the file COPYING.  If not, write to the
23;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24;; Boston, MA 02110-1301, USA.
25
26;;; Commentary:
27
28;;; Code:
29
30;; This file is autoloaded from calc-ext.el.
31
32(require 'calc-ext)
33(require 'calc-macs)
34
35(defun calc-line-numbering (n)
36  (interactive "P")
37  (calc-wrapper
38   (message (if (calc-change-mode 'calc-line-numbering n t t)
39		"Displaying stack level numbers"
40	      "Hiding stack level numbers"))))
41
42(defun calc-line-breaking (n)
43  (interactive "P")
44  (calc-wrapper
45   (setq n (if n
46	       (and (> (setq n (prefix-numeric-value n)) 0)
47		    (or (< n 5)
48			n))
49	     (not calc-line-breaking)))
50   (if (calc-change-mode 'calc-line-breaking n t)
51       (if (integerp calc-line-breaking)
52	   (message "Breaking lines longer than %d characters" n)
53	 (message "Breaking long lines in Stack display"))
54     (message "Not breaking long lines in Stack display"))))
55
56
57(defun calc-left-justify (n)
58  (interactive "P")
59  (calc-wrapper
60   (and n (setq n (prefix-numeric-value n)))
61   (calc-change-mode '(calc-display-just calc-display-origin)
62		     (list nil n) t)
63   (if n
64       (message "Displaying stack entries indented by %d" n)
65     (message "Displaying stack entries left-justified"))))
66
67(defun calc-center-justify (n)
68  (interactive "P")
69  (calc-wrapper
70   (and n (setq n (prefix-numeric-value n)))
71   (calc-change-mode '(calc-display-just calc-display-origin)
72		     (list 'center n) t)
73   (if n
74       (message "Displaying stack entries centered on column %d" n)
75     (message "Displaying stack entries centered in window"))))
76
77(defun calc-right-justify (n)
78  (interactive "P")
79  (calc-wrapper
80   (and n (setq n (prefix-numeric-value n)))
81   (calc-change-mode '(calc-display-just calc-display-origin)
82		     (list 'right n) t)
83   (if n
84       (message "Displaying stack entries right-justified to column %d" n)
85     (message "Displaying stack entries right-justified in window"))))
86
87(defun calc-left-label (s)
88  (interactive "sLefthand label: ")
89  (calc-wrapper
90   (or (equal s "")
91       (setq s (concat s " ")))
92   (calc-change-mode 'calc-left-label s t)))
93
94(defun calc-right-label (s)
95  (interactive "sRighthand label: ")
96  (calc-wrapper
97   (or (equal s "")
98       (setq s (concat " " s)))
99   (calc-change-mode 'calc-right-label s t)))
100
101(defun calc-auto-why (n)
102  (interactive "P")
103  (calc-wrapper
104   (if n
105       (progn
106	 (setq n (prefix-numeric-value n))
107	 (if (<= n 0) (setq n nil)
108	   (if (> n 1) (setq n t))))
109     (setq n (and (not (eq calc-auto-why t)) (if calc-auto-why t 1))))
110   (calc-change-mode 'calc-auto-why n nil)
111   (cond ((null n)
112	  (message "User must press `w' to explain unsimplified results"))
113	 ((eq n t)
114	  (message "Automatically doing `w' to explain unsimplified results"))
115	 (t
116	  (message "Automatically doing `w' only for unusual messages")))))
117
118(defun calc-group-digits (n)
119  (interactive "P")
120  (calc-wrapper
121   (if n
122       (progn
123	 (setq n (prefix-numeric-value n))
124	 (cond ((or (> n 0) (< n -1)))
125	       ((= n -1)
126		(setq n nil))
127	       (t
128		(setq n calc-group-digits))))
129     (setq n (not calc-group-digits)))
130   (calc-change-mode 'calc-group-digits n t)
131   (cond ((null n)
132	  (message "Grouping is off"))
133	 ((integerp n)
134	  (message "Grouping every %d digits" (math-abs n)))
135	 (t
136	  (message "Grouping is on")))))
137
138(defun calc-group-char (ch)
139  (interactive "cGrouping character: ")
140  (calc-wrapper
141   (or (>= ch 32)
142       (error "Control characters not allowed for grouping"))
143   (if (= ch ?\\)
144       (setq ch "\\,")
145     (setq ch (char-to-string ch)))
146   (calc-change-mode 'calc-group-char ch calc-group-digits)
147   (message "Digit grouping character is \"%s\"" ch)))
148
149(defun calc-point-char (ch)
150  (interactive "cCharacter to use as decimal point: ")
151  (calc-wrapper
152   (or (>= ch 32)
153       (error "Control characters not allowed as decimal point"))
154   (calc-change-mode 'calc-point-char (char-to-string ch) t)
155   (message "Decimal point character is \"%c\"" ch)))
156
157(defun calc-normal-notation (n)
158  (interactive "P")
159  (calc-wrapper
160   (calc-change-mode 'calc-float-format
161		     (let* ((val (if n (prefix-numeric-value n) 0))
162			    (mode (/ (+ val 5000) 10000)))
163		       (if (or (< val -5000) (> mode 3))
164			   (error "Prefix out of range"))
165		       (setq n (list (aref [float sci eng fix] mode)
166				     (- (% (+ val 5000) 10000) 5000))))
167		     t)
168   (if (eq (nth 1 n) 0)
169       (message "Displaying floating-point numbers normally")
170     (if (> (nth 1 n) 0)
171	 (message
172	  "Displaying floating-point numbers with %d significant digits"
173	  (nth 1 n))
174       (message "Displaying floating-point numbers with (precision%d)"
175		(nth 1 n))))))
176
177(defun calc-fix-notation (n)
178  (interactive "NDigits after decimal point: ")
179  (calc-wrapper
180   (calc-change-mode 'calc-float-format
181		     (setq n (list 'fix (if n (prefix-numeric-value n) 0)))
182		     t)
183   (message "Displaying floats with %d digits after decimal"
184	    (math-abs (nth 1 n)))))
185
186(defun calc-sci-notation (n)
187  (interactive "P")
188  (calc-wrapper
189   (calc-change-mode 'calc-float-format
190		     (setq n (list 'sci (if n (prefix-numeric-value n) 0)))
191		     t)
192   (if (eq (nth 1 n) 0)
193       (message "Displaying floats in scientific notation")
194     (if (> (nth 1 n) 0)
195	 (message "Displaying scientific notation with %d significant digits"
196		  (nth 1 n))
197       (message "Displaying scientific notation with (precision%d)"
198		(nth 1 n))))))
199
200(defun calc-eng-notation (n)
201  (interactive "P")
202  (calc-wrapper
203   (calc-change-mode 'calc-float-format
204		     (setq n (list 'eng (if n (prefix-numeric-value n) 0)))
205		     t)
206   (if (eq (nth 1 n) 0)
207       (message "Displaying floats in engineering notation")
208     (if (> (nth 1 n) 0)
209	 (message "Displaying engineering notation with %d significant digits"
210		  (nth 1 n))
211       (message "Displaying engineering notation with (precision%d)"
212		(nth 1 n))))))
213
214
215(defun calc-truncate-stack (n &optional rel)
216  (interactive "P")
217  (calc-wrapper
218   (let ((oldtop calc-stack-top)
219	 (newtop calc-stack-top))
220     (calc-record-undo (list 'set 'saved-stack-top calc-stack-top))
221     (let ((calc-stack-top 0)
222	   (nn (prefix-numeric-value n)))
223       (setq newtop
224	     (if n
225		 (progn
226		   (if rel
227		       (setq nn (+ oldtop nn))
228		     (if (< nn 0)
229			 (setq nn (+ nn (calc-stack-size)))
230		       (setq nn (1+ nn))))
231		   (if (< nn 1)
232		       1
233		     (if (> nn (calc-stack-size))
234			 (calc-stack-size)
235		       nn)))
236	       (max 1 (calc-locate-cursor-element (point)))))
237       (if (= newtop oldtop)
238	   ()
239	 (calc-pop-stack 1 oldtop t)
240	 (calc-push-list '(top-of-stack) newtop)
241	 (if calc-line-numbering
242	     (calc-refresh))))
243     (calc-record-undo (list 'set 'saved-stack-top 0))
244     (setq calc-stack-top newtop))))
245
246(defun calc-truncate-up (n)
247  (interactive "p")
248  (calc-truncate-stack n t))
249
250(defun calc-truncate-down (n)
251  (interactive "p")
252  (calc-truncate-stack (- n) t))
253
254(defun calc-display-raw (arg)
255  (interactive "P")
256  (calc-wrapper
257   (setq calc-display-raw (if calc-display-raw nil (if arg 0 t)))
258   (calc-do-refresh)
259   (if calc-display-raw
260       (message "Press d ' again to cancel \"raw\" display mode"))))
261
262
263
264
265;;; Mode commands.
266
267(defun calc-save-modes ()
268  (interactive)
269  (calc-wrapper
270   (let (pos
271	 (vals (mapcar (function (lambda (v) (symbol-value (car v))))
272		       calc-mode-var-list)))
273     (unless calc-settings-file
274       (error "No `calc-settings-file' specified"))
275     (set-buffer (find-file-noselect (substitute-in-file-name
276				      calc-settings-file)))
277     (goto-char (point-min))
278     (if (and (search-forward ";;; Mode settings stored by Calc" nil t)
279	      (progn
280		(beginning-of-line)
281		(setq pos (point))
282		(search-forward "\n;;; End of mode settings" nil t)))
283	 (progn
284	   (beginning-of-line)
285	   (forward-line 1)
286	   (delete-region pos (point)))
287       (goto-char (point-max))
288       (insert "\n\n")
289       (forward-char -1))
290     (insert ";;; Mode settings stored by Calc on " (current-time-string) "\n")
291     (let ((list calc-mode-var-list))
292       (while list
293	 (let* ((v (car (car list)))
294		(def (nth 1 (car list)))
295		(val (car vals)))
296	   (or (equal val def)
297	       (progn
298		 (insert "(setq " (symbol-name v) " ")
299		 (if (and (or (listp val)
300			      (symbolp val))
301			  (not (memq val '(nil t))))
302		     (insert "'"))
303		 (insert (prin1-to-string val) ")\n"))))
304	 (setq list (cdr list)
305	       vals (cdr vals))))
306     (run-hooks 'calc-mode-save-hook)
307     (insert ";;; End of mode settings\n")
308     (save-buffer)
309     (if calc-embedded-info
310         (calc-embedded-save-original-modes)))))
311
312(defun calc-settings-file-name (name &optional arg)
313  (interactive
314   (list (read-file-name (format "Settings file name (normally %s): "
315				 (abbreviate-file-name calc-settings-file)))
316	 current-prefix-arg))
317  (calc-wrapper
318   (setq arg (if arg (prefix-numeric-value arg) 0))
319   (if (string-equal (file-name-nondirectory name) "")
320       (message "Calc settings file is \"%s\"" calc-settings-file)
321     (if (< (math-abs arg) 2)
322	 (let ((list calc-mode-var-list))
323	   (while list
324	     (set (car (car list)) (nth 1 (car list)))
325	     (setq list (cdr list)))))
326     (setq calc-settings-file name)
327     (or (and
328	  calc-settings-file
329          (equal user-init-file calc-settings-file)
330          (> arg 0))
331	 (< arg 0)
332	 (load name t)
333	 (message "New file")))))
334
335(defun math-get-modes-vec ()
336  (list 'vec
337	calc-internal-prec
338	calc-word-size
339	(calc-stack-size)
340	calc-number-radix
341	(+ (if (<= (nth 1 calc-float-format) 0)
342	       (+ calc-internal-prec (nth 1 calc-float-format))
343	     (nth 1 calc-float-format))
344	   (cdr (assq (car calc-float-format)
345		      '((float . 0) (sci . 10000)
346			(eng . 20000) (fix . 30000)))))
347	(cond ((eq calc-angle-mode 'rad) 2)
348	      ((eq calc-angle-mode 'hms) 3)
349	      (t 1))
350	(if calc-symbolic-mode 1 0)
351	(if calc-prefer-frac 1 0)
352	(if (eq calc-complex-mode 'polar) 1 0)
353	(cond ((eq calc-matrix-mode 'scalar) 0)
354	      ((eq calc-matrix-mode 'matrix) -2)
355	      ((eq calc-matrix-mode 'sqmatrix) -3)
356	      (calc-matrix-mode)
357	      (t -1))
358	(cond ((eq calc-simplify-mode 'none) -1)
359	      ((eq calc-simplify-mode 'num) 0)
360	      ((eq calc-simplify-mode 'binary) 2)
361	      ((eq calc-simplify-mode 'alg) 3)
362	      ((eq calc-simplify-mode 'ext) 4)
363	      ((eq calc-simplify-mode 'units) 5)
364	      (t 1))
365	(cond ((eq calc-infinite-mode 1) 0)
366	      (calc-infinite-mode 1)
367	      (t -1))))
368
369(defun calc-get-modes (n)
370  (interactive "P")
371  (calc-wrapper
372   (let ((modes (math-get-modes-vec)))
373     (calc-enter-result 0 "mode"
374			(if n
375			    (if (and (>= (setq n (prefix-numeric-value n)) 1)
376				     (< n (length modes)))
377				(nth n modes)
378			      (error "Prefix out of range"))
379			  modes)))))
380
381(defun calc-shift-prefix (arg)
382  (interactive "P")
383  (calc-wrapper
384   (setq calc-shift-prefix (if arg
385			       (> (prefix-numeric-value arg) 0)
386			     (not calc-shift-prefix)))
387   (calc-init-prefixes)
388   (message (if calc-shift-prefix
389		"Prefix keys are now case-insensitive"
390	      "Prefix keys must be unshifted (except V, Z)"))))
391
392(defun calc-mode-record-mode (n)
393  (interactive "P")
394  (calc-wrapper
395   (calc-change-mode 'calc-mode-save-mode
396		     (cond ((null n)
397			    (cond ((not calc-embedded-info)
398				   (if (eq calc-mode-save-mode 'save)
399				       'local 'save))
400				  ((eq calc-mode-save-mode 'local)  'edit)
401				  ((eq calc-mode-save-mode 'edit)   'perm)
402				  ((eq calc-mode-save-mode 'perm)   'global)
403				  ((eq calc-mode-save-mode 'global) 'save)
404				  ((eq calc-mode-save-mode 'save)   nil)
405				  ((eq calc-mode-save-mode nil)     'local)))
406			   ((= (setq n (prefix-numeric-value n)) 0) nil)
407			   ((= n 2) 'edit)
408			   ((= n 3) 'perm)
409			   ((= n 4) 'global)
410			   ((= n 5) 'save)
411			   (t 'local)))
412   (message "%s"
413	    (cond ((and (eq calc-mode-save-mode 'local) calc-embedded-info)
414		   "Recording mode changes with [calc-mode: ...]")
415		  ((eq calc-mode-save-mode 'edit)
416		   "Recording mode changes with [calc-edit-mode: ...]")
417		  ((eq calc-mode-save-mode 'perm)
418		   "Recording mode changes with [calc-perm-mode: ...]")
419		  ((eq calc-mode-save-mode 'global)
420		   "Recording mode changes with [calc-global-mode: ...]")
421		  ((eq calc-mode-save-mode 'save)
422		   (format "Recording mode changes in \"%s\""
423			   calc-settings-file))
424		  (t
425		   "Not recording mode changes permanently")))))
426
427(defun calc-total-algebraic-mode (flag)
428  (interactive "P")
429  (calc-wrapper
430   (if (eq calc-algebraic-mode 'total)
431       (calc-algebraic-mode nil)
432     (calc-change-mode '(calc-algebraic-mode calc-incomplete-algebraic-mode)
433		       '(total nil))
434     (use-local-map calc-alg-map)
435     (message
436      "All keys begin algebraic entry; use Meta (ESC) for Calc keys"))))
437
438(defun calc-algebraic-mode (flag)
439  (interactive "P")
440  (calc-wrapper
441   (if flag
442       (calc-change-mode '(calc-algebraic-mode
443			   calc-incomplete-algebraic-mode)
444			 (list nil (not calc-incomplete-algebraic-mode)))
445     (calc-change-mode '(calc-algebraic-mode calc-incomplete-algebraic-mode)
446		       (list (not calc-algebraic-mode) nil)))
447   (use-local-map calc-mode-map)
448   (message (if calc-algebraic-mode
449		"Numeric keys and ( and [ begin algebraic entry"
450	      (if calc-incomplete-algebraic-mode
451		  "Only ( and [ begin algebraic entry"
452		"No keys except ' and $ begin algebraic entry")))))
453
454(defun calc-symbolic-mode (n)
455  (interactive "P")
456  (calc-wrapper
457
458   (message (if (calc-change-mode 'calc-symbolic-mode n nil t)
459		"Inexact computations like sqrt(2) are deferred"
460	      "Numerical computations are always done immediately"))))
461
462(defun calc-infinite-mode (n)
463  (interactive "P")
464  (calc-wrapper
465   (if (eq n 0)
466       (progn
467	 (calc-change-mode 'calc-infinite-mode 1)
468	 (message "Computations like 1 / 0 produce \"inf\""))
469     (message (if (calc-change-mode 'calc-infinite-mode n nil t)
470		  "Computations like 1 / 0 produce \"uinf\""
471		"Computations like 1 / 0 are left unsimplified")))))
472
473(defun calc-matrix-mode (arg)
474  (interactive "P")
475  (calc-wrapper
476   (calc-change-mode 'calc-matrix-mode
477		     (cond ((eq arg 0) 'scalar)
478			   ((< (prefix-numeric-value arg) 1)
479			    (and (< (prefix-numeric-value arg) -1) 'matrix))
480			   (arg
481                            (if (consp arg) 'sqmatrix
482                              (prefix-numeric-value arg)))
483			   ((eq calc-matrix-mode 'matrix) 'scalar)
484			   ((eq calc-matrix-mode 'scalar) nil)
485			   (t 'matrix)))
486   (if (integerp calc-matrix-mode)
487       (message "Variables are assumed to be %dx%d matrices"
488		calc-matrix-mode calc-matrix-mode)
489     (message (if (eq calc-matrix-mode 'matrix)
490		  "Variables are assumed to be matrices"
491                (if (eq calc-matrix-mode 'sqmatrix)
492                    "Variables are assumed to be square matrices"
493                  (if calc-matrix-mode
494                      "Variables are assumed to be scalars (non-matrices)"
495                    "Variables are not assumed to be matrix or scalar")))))))
496
497(defun calc-set-simplify-mode (mode arg msg)
498  (calc-change-mode 'calc-simplify-mode
499		    (if arg
500			(and (> (prefix-numeric-value arg) 0)
501			     mode)
502		      (and (not (eq calc-simplify-mode mode))
503			   mode)))
504  (message (if (eq calc-simplify-mode mode)
505	       msg
506	     "Default simplifications enabled")))
507
508(defun calc-no-simplify-mode (arg)
509  (interactive "P")
510  (calc-wrapper
511   (calc-set-simplify-mode 'none arg
512			   "All default simplifications are disabled")))
513
514(defun calc-num-simplify-mode (arg)
515  (interactive "P")
516  (calc-wrapper
517   (calc-set-simplify-mode 'num arg
518			   "Default simplifications apply only if arguments are numeric")))
519
520(defun calc-default-simplify-mode (arg)
521  (interactive "p")
522  (cond ((= arg 1)
523	 (calc-wrapper
524	  (calc-set-simplify-mode
525	   nil nil "Usual default simplifications are enabled")))
526	((= arg 0) (calc-num-simplify-mode 1))
527	((< arg 0) (calc-no-simplify-mode 1))
528	((= arg 2) (calc-bin-simplify-mode 1))
529	((= arg 3) (calc-alg-simplify-mode 1))
530	((= arg 4) (calc-ext-simplify-mode 1))
531	((= arg 5) (calc-units-simplify-mode 1))
532	(t (error "Prefix argument out of range"))))
533
534(defun calc-bin-simplify-mode (arg)
535  (interactive "P")
536  (calc-wrapper
537   (calc-set-simplify-mode 'binary arg
538			   (format "Binary simplification occurs by default (word size=%d)"
539				   calc-word-size))))
540
541(defun calc-alg-simplify-mode (arg)
542  (interactive "P")
543  (calc-wrapper
544   (calc-set-simplify-mode 'alg arg
545			   "Algebraic simplification occurs by default")))
546
547(defun calc-ext-simplify-mode (arg)
548  (interactive "P")
549  (calc-wrapper
550   (calc-set-simplify-mode 'ext arg
551			   "Extended algebraic simplification occurs by default")))
552
553(defun calc-units-simplify-mode (arg)
554  (interactive "P")
555  (calc-wrapper
556   (calc-set-simplify-mode 'units arg
557			   "Units simplification occurs by default")))
558
559(defun calc-auto-recompute (arg)
560  (interactive "P")
561  (calc-wrapper
562   (calc-change-mode 'calc-auto-recompute arg nil t)
563   (calc-refresh-evaltos)
564   (message (if calc-auto-recompute
565		"Automatically recomputing `=>' forms when necessary"
566	      "Not recomputing `=>' forms automatically"))))
567
568(defun calc-working (n)
569  (interactive "P")
570  (calc-wrapper
571   (cond ((consp n)
572	  (calc-pop-push-record 0 "work"
573				(cond ((eq calc-display-working-message t) 1)
574				      (calc-display-working-message 2)
575				      (t 0))))
576	 ((eq n 2) (calc-change-mode 'calc-display-working-message 'lots))
577	 ((eq n 0) (calc-change-mode 'calc-display-working-message nil))
578	 ((eq n 1) (calc-change-mode 'calc-display-working-message t)))
579   (cond ((eq calc-display-working-message t)
580	  (message "\"Working...\" messages enabled"))
581	 (calc-display-working-message
582	  (message "Detailed \"Working...\" messages enabled"))
583	 (t
584	  (message "\"Working...\" messages disabled")))))
585
586(defun calc-always-load-extensions ()
587  (interactive)
588  (calc-wrapper
589   (if (setq calc-always-load-extensions (not calc-always-load-extensions))
590       (message "Always loading extensions package")
591     (message "Loading extensions package on demand only"))))
592
593
594(defun calc-matrix-left-justify ()
595  (interactive)
596  (calc-wrapper
597   (calc-change-mode 'calc-matrix-just nil t)
598   (message "Matrix elements will be left-justified in columns")))
599
600(defun calc-matrix-center-justify ()
601  (interactive)
602  (calc-wrapper
603   (calc-change-mode 'calc-matrix-just 'center t)
604   (message "Matrix elements will be centered in columns")))
605
606(defun calc-matrix-right-justify ()
607  (interactive)
608  (calc-wrapper
609   (calc-change-mode 'calc-matrix-just 'right t)
610   (message "Matrix elements will be right-justified in columns")))
611
612(defun calc-full-vectors (n)
613  (interactive "P")
614  (calc-wrapper
615   (message (if (calc-change-mode 'calc-full-vectors n t t)
616		"Displaying long vectors in full"
617	      "Displaying long vectors in [a, b, c, ..., z] notation"))))
618
619(defun calc-full-trail-vectors (n)
620  (interactive "P")
621  (calc-wrapper
622   (message (if (calc-change-mode 'calc-full-trail-vectors n nil t)
623		"Recording long vectors in full"
624	      "Recording long vectors in [a, b, c, ..., z] notation"))))
625
626(defun calc-break-vectors (n)
627  (interactive "P")
628  (calc-wrapper
629   (message (if (calc-change-mode 'calc-break-vectors n t t)
630		"Displaying vector elements one-per-line"
631	      "Displaying vector elements all on one line"))))
632
633(defun calc-vector-commas ()
634  (interactive)
635  (calc-wrapper
636   (if (calc-change-mode 'calc-vector-commas (if calc-vector-commas nil ",") t)
637       (message "Separating vector elements with \",\"")
638     (message "Separating vector elements with spaces"))))
639
640(defun calc-vector-brackets ()
641  (interactive)
642  (calc-wrapper
643   (if (calc-change-mode 'calc-vector-brackets
644			 (if (equal calc-vector-brackets "[]") nil "[]") t)
645       (message "Surrounding vectors with \"[]\"")
646     (message "Not surrounding vectors with brackets"))))
647
648(defun calc-vector-braces ()
649  (interactive)
650  (calc-wrapper
651   (if (calc-change-mode 'calc-vector-brackets
652			 (if (equal calc-vector-brackets "{}") nil "{}") t)
653       (message "Surrounding vectors with \"{}\"")
654     (message "Not surrounding vectors with brackets"))))
655
656(defun calc-vector-parens ()
657  (interactive)
658  (calc-wrapper
659   (if (calc-change-mode 'calc-vector-brackets
660			 (if (equal calc-vector-brackets "()") nil "()") t)
661       (message "Surrounding vectors with \"()\"")
662     (message "Not surrounding vectors with brackets"))))
663
664(defun calc-matrix-brackets (arg)
665  (interactive "sCode letters (R, O, C, P): ")
666  (calc-wrapper
667   (let ((code (append (and (string-match "[rR]" arg) '(R))
668		       (and (string-match "[oO]" arg) '(O))
669		       (and (string-match "[cC]" arg) '(C))
670		       (and (string-match "[pP]" arg) '(P))))
671	 (bad (string-match "[^rRoOcCpP ]" arg)))
672     (if bad
673	 (error "Unrecognized character: %c" (aref arg bad)))
674     (calc-change-mode 'calc-matrix-brackets code t))))
675
676(provide 'calc-mode)
677
678;;; arch-tag: ecc70eea-c712-43f2-9085-4205e58d6ddf
679;;; calc-mode.el ends here
680