Style cleanup; don't put closing parens on their
[bpt/emacs.git] / lisp / calc / calc-sel.el
CommitLineData
136211a9 1;; Calculator for GNU Emacs, part II [calc-sel.el]
8f66f479 2;; Copyright (C) 1990, 1991, 1992, 1993, 2001 Free Software Foundation, Inc.
136211a9
EZ
3;; Written by Dave Gillespie, daveg@synaptics.com.
4
5;; This file is part of GNU Emacs.
6
7;; GNU Emacs is distributed in the hope that it will be useful,
8;; but WITHOUT ANY WARRANTY. No author or distributor
9;; accepts responsibility to anyone for the consequences of using it
10;; or for whether it serves any particular purpose or works at all,
11;; unless he says so in writing. Refer to the GNU Emacs General Public
12;; License for full details.
13
14;; Everyone is granted permission to copy, modify and redistribute
15;; GNU Emacs, but only under the conditions described in the
16;; GNU Emacs General Public License. A copy of this license is
17;; supposed to have been given to you along with GNU Emacs so you
18;; can know your rights and responsibilities. It should be in a
19;; file named COPYING. Among other things, the copyright notice
20;; and this notice must be preserved on all copies.
21
22
23
24;; This file is autoloaded from calc-ext.el.
25(require 'calc-ext)
26
27(require 'calc-macs)
28
29(defun calc-Need-calc-sel () nil)
30
31
32;;; Selection commands.
33
34(defun calc-select-here (num &optional once keep)
35 (interactive "P")
36 (calc-wrapper
37 (calc-prepare-selection)
38 (let ((found (calc-find-selected-part))
39 (entry calc-selection-cache-entry))
40 (or (and keep (nth 2 entry))
41 (progn
42 (if once (progn
43 (setq calc-keep-selection nil)
44 (message "(Selection will apply to next command only)")))
45 (calc-change-current-selection
46 (if found
47 (if (and num (> (setq num (prefix-numeric-value num)) 0))
48 (progn
49 (while (and (>= (setq num (1- num)) 0)
50 (not (eq found (car entry))))
51 (setq found (calc-find-assoc-parent-formula
52 (car entry) found)))
53 found)
54 (calc-grow-assoc-formula (car entry) found))
bf77c646 55 (car entry))))))))
136211a9
EZ
56
57(defun calc-select-once (num)
58 (interactive "P")
bf77c646 59 (calc-select-here num t))
136211a9
EZ
60
61(defun calc-select-here-maybe (num)
62 (interactive "P")
bf77c646 63 (calc-select-here num nil t))
136211a9
EZ
64
65(defun calc-select-once-maybe (num)
66 (interactive "P")
bf77c646 67 (calc-select-here num t t))
136211a9
EZ
68
69(defun calc-select-additional ()
70 (interactive)
71 (calc-wrapper
72 (let (calc-keep-selection)
73 (calc-prepare-selection))
74 (let ((found (calc-find-selected-part))
75 (entry calc-selection-cache-entry))
76 (calc-change-current-selection
77 (if found
78 (let ((sel (nth 2 entry)))
79 (if sel
80 (progn
81 (while (not (or (eq sel (car entry))
82 (calc-find-sub-formula sel found)))
83 (setq sel (calc-find-assoc-parent-formula
84 (car entry) sel)))
85 sel)
86 (calc-grow-assoc-formula (car entry) found)))
bf77c646 87 (car entry))))))
136211a9
EZ
88
89(defun calc-select-more (num)
90 (interactive "P")
91 (calc-wrapper
92 (calc-prepare-selection)
93 (let ((entry calc-selection-cache-entry))
94 (if (nth 2 entry)
95 (let ((sel (nth 2 entry)))
96 (while (and (not (eq sel (car entry)))
97 (>= (setq num (1- (prefix-numeric-value num))) 0))
98 (setq sel (calc-find-assoc-parent-formula (car entry) sel)))
99 (calc-change-current-selection sel))
bf77c646 100 (calc-select-here num)))))
136211a9
EZ
101
102(defun calc-select-less (num)
103 (interactive "p")
104 (calc-wrapper
105 (calc-prepare-selection)
106 (let ((found (calc-find-selected-part))
107 (entry calc-selection-cache-entry))
108 (calc-change-current-selection
109 (and found
110 (let ((sel (nth 2 entry))
111 old index op)
112 (while (and sel
113 (not (eq sel found))
114 (>= (setq num (1- num)) 0))
115 (setq old sel
116 index (calc-find-sub-formula sel found))
117 (and (setq sel (and index (nth index old)))
118 calc-assoc-selections
119 (setq op (assq (car-safe sel) calc-assoc-ops))
120 (memq (car old) (nth index op))
121 (setq num (1+ num))))
bf77c646 122 sel))))))
136211a9
EZ
123
124(defun calc-select-part (num)
125 (interactive "P")
126 (or num (setq num (- last-command-char ?0)))
127 (calc-wrapper
128 (calc-prepare-selection)
129 (let ((sel (calc-find-nth-part (or (nth 2 calc-selection-cache-entry)
130 (car calc-selection-cache-entry))
131 num)))
132 (if sel
133 (calc-change-current-selection sel)
bf77c646 134 (error "%d is not a valid sub-formula index" num)))))
136211a9
EZ
135
136(defun calc-find-nth-part (expr num)
137 (if (and calc-assoc-selections
138 (assq (car-safe expr) calc-assoc-ops))
139 (let (op)
140 (calc-find-nth-part-rec expr))
141 (if (eq (car-safe expr) 'intv)
142 (and (>= num 1) (<= num 2) (nth (1+ num) expr))
143 (and (not (Math-primp expr)) (>= num 1) (< num (length expr))
bf77c646 144 (nth num expr)))))
136211a9
EZ
145
146(defun calc-find-nth-part-rec (expr) ; uses num, op
147 (or (if (and (setq op (assq (car-safe (nth 1 expr)) calc-assoc-ops))
148 (memq (car expr) (nth 1 op)))
149 (calc-find-nth-part-rec (nth 1 expr))
150 (and (= (setq num (1- num)) 0)
151 (nth 1 expr)))
152 (if (and (setq op (assq (car-safe (nth 2 expr)) calc-assoc-ops))
153 (memq (car expr) (nth 2 op)))
154 (calc-find-nth-part-rec (nth 2 expr))
155 (and (= (setq num (1- num)) 0)
bf77c646 156 (nth 2 expr)))))
136211a9
EZ
157
158(defun calc-select-next (num)
159 (interactive "p")
160 (if (< num 0)
161 (calc-select-previous (- num))
162 (calc-wrapper
163 (calc-prepare-selection)
164 (let* ((entry calc-selection-cache-entry)
165 (sel (nth 2 entry)))
166 (if sel
167 (progn
168 (while (>= (setq num (1- num)) 0)
169 (let* ((parent (calc-find-parent-formula (car entry) sel))
170 (p parent)
171 op)
172 (and (eq p t) (setq p nil))
173 (while (and (setq p (cdr p))
174 (not (eq (car p) sel))))
175 (if (cdr p)
176 (setq sel (or (and calc-assoc-selections
177 (setq op (assq (car-safe (nth 1 p))
178 calc-assoc-ops))
179 (memq (car parent) (nth 2 op))
180 (nth 1 (nth 1 p)))
181 (nth 1 p)))
182 (if (and calc-assoc-selections
183 (setq op (assq (car-safe parent) calc-assoc-ops))
184 (consp (setq p (calc-find-parent-formula
185 (car entry) parent)))
186 (eq (nth 1 p) parent)
187 (memq (car p) (nth 1 op)))
188 (setq sel (nth 2 p))
189 (error "No \"next\" sub-formula")))))
190 (calc-change-current-selection sel))
191 (if (Math-primp (car entry))
192 (calc-change-current-selection (car entry))
bf77c646 193 (calc-select-part num)))))))
136211a9
EZ
194
195(defun calc-select-previous (num)
196 (interactive "p")
197 (if (< num 0)
198 (calc-select-next (- num))
199 (calc-wrapper
200 (calc-prepare-selection)
201 (let* ((entry calc-selection-cache-entry)
202 (sel (nth 2 entry)))
203 (if sel
204 (progn
205 (while (>= (setq num (1- num)) 0)
206 (let* ((parent (calc-find-parent-formula (car entry) sel))
207 (p (cdr-safe parent))
208 (prev nil)
209 op)
210 (if (eq (car-safe parent) 'intv) (setq p (cdr p)))
211 (while (and (not (eq (car p) sel))
212 (setq prev (car p)
213 p (cdr p))))
214 (if prev
215 (setq sel (or (and calc-assoc-selections
216 (setq op (assq (car-safe prev)
217 calc-assoc-ops))
218 (memq (car parent) (nth 1 op))
219 (nth 2 prev))
220 prev))
221 (if (and calc-assoc-selections
222 (setq op (assq (car-safe parent) calc-assoc-ops))
223 (consp (setq p (calc-find-parent-formula
224 (car entry) parent)))
225 (eq (nth 2 p) parent)
226 (memq (car p) (nth 2 op)))
227 (setq sel (nth 1 p))
228 (error "No \"previous\" sub-formula")))))
229 (calc-change-current-selection sel))
230 (if (Math-primp (car entry))
231 (calc-change-current-selection (car entry))
232 (let ((len (if (and calc-assoc-selections
233 (assq (car (car entry)) calc-assoc-ops))
234 (let (op (num 0))
235 (calc-find-nth-part-rec (car entry))
236 (- 1 num))
237 (length (car entry)))))
bf77c646 238 (calc-select-part (- len num)))))))))
136211a9
EZ
239
240(defun calc-find-parent-formula (expr part)
241 (cond ((eq expr part) t)
242 ((Math-primp expr) nil)
243 (t
244 (let ((p expr) res)
245 (while (and (setq p (cdr p))
246 (not (setq res (calc-find-parent-formula
247 (car p) part)))))
248 (and p
bf77c646 249 (if (eq res t) expr res))))))
136211a9
EZ
250
251
252(defun calc-find-assoc-parent-formula (expr part)
bf77c646 253 (calc-grow-assoc-formula expr (calc-find-parent-formula expr part)))
136211a9
EZ
254
255(defun calc-grow-assoc-formula (expr part)
256 (if calc-assoc-selections
257 (let ((op (assq (car-safe part) calc-assoc-ops)))
258 (if op
259 (let (new)
260 (while (and (consp (setq new (calc-find-parent-formula
261 expr part)))
262 (memq (car new)
263 (nth (calc-find-sub-formula new part) op)))
264 (setq part new))))
265 part)
bf77c646 266 part))
136211a9
EZ
267
268(defun calc-find-sub-formula (expr part)
269 (cond ((eq expr part) t)
270 ((Math-primp expr) nil)
271 (t
272 (let ((num 1))
273 (while (and (setq expr (cdr expr))
274 (not (calc-find-sub-formula (car expr) part)))
275 (setq num (1+ num)))
bf77c646 276 (and expr num)))))
136211a9
EZ
277
278(defun calc-unselect (num)
279 (interactive "P")
280 (calc-wrapper
281 (calc-prepare-selection num)
bf77c646 282 (calc-change-current-selection nil)))
136211a9
EZ
283
284(defun calc-clear-selections ()
285 (interactive)
286 (calc-wrapper
287 (let ((limit (calc-stack-size))
288 (n 1))
289 (while (<= n limit)
290 (if (calc-top n 'sel)
291 (progn
292 (calc-prepare-selection n)
293 (calc-change-current-selection nil)))
294 (setq n (1+ n))))
bf77c646 295 (calc-clear-command-flag 'position-point)))
136211a9
EZ
296
297(defun calc-show-selections (arg)
298 (interactive "P")
299 (calc-wrapper
300 (calc-preserve-point)
301 (setq calc-show-selections (if arg
302 (> (prefix-numeric-value arg) 0)
303 (not calc-show-selections)))
304 (let ((p calc-stack))
305 (while (and p
306 (or (null (nth 2 (car p)))
307 (equal (car p) calc-selection-cache-entry)))
308 (setq p (cdr p)))
309 (or (and p
310 (let ((calc-selection-cache-default-entry
311 calc-selection-cache-entry))
312 (calc-do-refresh)))
313 (and calc-selection-cache-entry
314 (let ((sel (nth 2 calc-selection-cache-entry)))
315 (setcar (nthcdr 2 calc-selection-cache-entry) nil)
316 (calc-change-current-selection sel)))))
317 (message (if calc-show-selections
318 "Displaying only selected part of formulas"
bf77c646 319 "Displaying all but selected part of formulas"))))
136211a9
EZ
320
321(defun calc-preserve-point ()
322 (or (looking-at "\\.\n+\\'")
323 (progn
324 (setq calc-final-point-line (+ (count-lines (point-min) (point))
325 (if (bolp) 1 0))
326 calc-final-point-column (current-column))
bf77c646 327 (calc-set-command-flag 'position-point))))
136211a9
EZ
328
329(defun calc-enable-selections (arg)
330 (interactive "P")
331 (calc-wrapper
332 (calc-preserve-point)
333 (setq calc-use-selections (if arg
334 (> (prefix-numeric-value arg) 0)
335 (not calc-use-selections)))
336 (calc-set-command-flag 'renum-stack)
337 (message (if calc-use-selections
338 "Commands operate only on selected sub-formulas"
bf77c646 339 "Selections of sub-formulas have no effect"))))
136211a9
EZ
340
341(defun calc-break-selections (arg)
342 (interactive "P")
343 (calc-wrapper
344 (calc-preserve-point)
345 (setq calc-assoc-selections (if arg
346 (<= (prefix-numeric-value arg) 0)
347 (not calc-assoc-selections)))
348 (message (if calc-assoc-selections
349 "Selection treats a+b+c as a sum of three terms"
bf77c646 350 "Selection treats a+b+c as (a+b)+c"))))
136211a9
EZ
351
352(defun calc-prepare-selection (&optional num)
353 (or num (setq num (calc-locate-cursor-element (point))))
354 (setq calc-selection-true-num num
355 calc-keep-selection t)
356 (or (> num 0) (setq num 1))
357 ;; (if (or (< num 1) (> num (calc-stack-size)))
358 ;; (error "Cursor must be positioned on a stack element"))
359 (let* ((entry (calc-top num 'entry))
360 ww w)
361 (or (equal entry calc-selection-cache-entry)
362 (progn
363 (setcar entry (calc-encase-atoms (car entry)))
364 (setq calc-selection-cache-entry entry
365 calc-selection-cache-num num
366 calc-selection-cache-comp
367 (let ((math-comp-tagged t))
368 (math-compose-expr (car entry) 0))
369 calc-selection-cache-offset
370 (+ (car (math-stack-value-offset calc-selection-cache-comp))
371 (length calc-left-label)
372 (if calc-line-numbering 4 0))))))
bf77c646 373 (calc-preserve-point))
136211a9
EZ
374(setq calc-selection-cache-entry nil)
375
376;;; The following ensures that no two subformulas will be "eq" to each other!
377(defun calc-encase-atoms (x)
378 (if (or (not (consp x))
379 (equal x '(float 0 0)))
380 (list 'cplx x 0)
381 (calc-encase-atoms-rec x)
bf77c646 382 x))
136211a9
EZ
383
384(defun calc-encase-atoms-rec (x)
385 (or (Math-primp x)
386 (progn
387 (if (eq (car x) 'intv)
388 (setq x (cdr x)))
389 (while (setq x (cdr x))
390 (if (or (not (consp (car x)))
391 (equal (car x) '(float 0 0)))
392 (setcar x (list 'cplx (car x) 0))
bf77c646 393 (calc-encase-atoms-rec (car x)))))))
136211a9
EZ
394
395(defun calc-find-selected-part ()
396 (let* ((math-comp-sel-hpos (- (current-column) calc-selection-cache-offset))
397 toppt
398 (lcount 0)
399 (spaces 0)
400 (math-comp-sel-vpos (save-excursion
401 (beginning-of-line)
402 (let ((line (point)))
403 (calc-cursor-stack-index
404 calc-selection-cache-num)
405 (setq toppt (point))
406 (while (< (point) line)
407 (forward-line 1)
408 (setq spaces (+ spaces
409 (current-indentation))
410 lcount (1+ lcount)))
411 (- lcount (math-comp-ascent
412 calc-selection-cache-comp) -1))))
413 (math-comp-sel-cpos (- (point) toppt calc-selection-cache-offset
414 spaces lcount))
415 (math-comp-sel-tag nil))
416 (and (>= math-comp-sel-hpos 0)
417 (> calc-selection-true-num 0)
418 (math-composition-to-string calc-selection-cache-comp 1000000))
bf77c646 419 (nth 1 math-comp-sel-tag)))
136211a9
EZ
420
421(defun calc-change-current-selection (sub-expr)
422 (or (eq sub-expr (nth 2 calc-selection-cache-entry))
423 (let ((calc-prepared-composition calc-selection-cache-comp)
424 (buffer-read-only nil)
425 top)
426 (calc-set-command-flag 'renum-stack)
427 (setcar (nthcdr 2 calc-selection-cache-entry) sub-expr)
428 (calc-cursor-stack-index calc-selection-cache-num)
429 (setq top (point))
430 (calc-cursor-stack-index (1- calc-selection-cache-num))
431 (delete-region top (point))
432 (let ((calc-selection-cache-default-entry calc-selection-cache-entry))
433 (insert (math-format-stack-value calc-selection-cache-entry)
bf77c646 434 "\n")))))
136211a9
EZ
435
436(defun calc-top-selected (&optional n m)
437 (and calc-any-selections
438 calc-use-selections
439 (progn
440 (or n (setq n 1))
441 (or m (setq m 1))
442 (calc-check-stack (+ n m -1))
443 (let ((top (nthcdr (+ m calc-stack-top -1) calc-stack))
444 (sel nil))
445 (while (>= (setq n (1- n)) 0)
446 (if (nth 2 (car top))
447 (setq sel (if sel t (nth 2 (car top)))))
448 (setq top (cdr top)))
bf77c646 449 sel))))
136211a9
EZ
450
451(defun calc-replace-sub-formula (expr old new)
452 (setq new (calc-encase-atoms new))
bf77c646 453 (calc-replace-sub-formula-rec expr))
136211a9
EZ
454
455(defun calc-replace-sub-formula-rec (expr)
456 (cond ((eq expr old) new)
457 ((Math-primp expr) expr)
458 (t
459 (cons (car expr)
bf77c646 460 (mapcar 'calc-replace-sub-formula-rec (cdr expr))))))
136211a9
EZ
461
462(defun calc-sel-error ()
bf77c646 463 (error "Illegal operation on sub-formulas"))
136211a9
EZ
464
465(defun calc-replace-selections (n vals m)
466 (if (calc-top-selected n m)
467 (let ((num (length vals)))
468 (calc-preserve-point)
469 (cond
470 ((= n num)
471 (let* ((old (calc-top-list n m 'entry))
472 (new nil)
473 (sel nil)
474 val)
475 (while old
476 (if (nth 2 (car old))
477 (setq val (calc-encase-atoms (car vals))
478 new (cons (calc-replace-sub-formula (car (car old))
479 (nth 2 (car old))
480 val)
481 new)
482 sel (cons val sel))
483 (setq new (cons (car vals) new)
484 sel (cons nil sel)))
485 (setq vals (cdr vals)
486 old (cdr old)))
487 (calc-pop-stack n m t)
488 (calc-push-list (nreverse new)
489 m (and calc-keep-selection (nreverse sel)))))
490 ((= num 1)
491 (let* ((old (calc-top-list n m 'entry))
492 more)
493 (while (and old (not (nth 2 (car old))))
494 (setq old (cdr old)))
495 (setq more old)
496 (while (and (setq more (cdr more)) (not (nth 2 (car more)))))
497 (and more
498 (calc-sel-error))
499 (calc-pop-stack n m t)
500 (if old
501 (let ((val (calc-encase-atoms (car vals))))
502 (calc-push-list (list (calc-replace-sub-formula
503 (car (car old))
504 (nth 2 (car old))
505 val))
506 m (and calc-keep-selection (list val))))
507 (calc-push-list vals))))
508 (t (calc-sel-error))))
509 (calc-pop-stack n m t)
bf77c646 510 (calc-push-list vals m)))
136211a9
EZ
511(setq calc-keep-selection t)
512
513(defun calc-delete-selection (n)
514 (let ((entry (calc-top n 'entry)))
515 (if (nth 2 entry)
516 (if (eq (nth 2 entry) (car entry))
517 (progn
518 (calc-pop-stack 1 n t)
519 (calc-push-list '(0) n))
520 (let ((parent (calc-find-parent-formula (car entry) (nth 2 entry)))
521 (repl nil))
522 (calc-preserve-point)
523 (calc-pop-stack 1 n t)
524 (cond ((or (memq (car parent) '(* / %))
525 (and (eq (car parent) '^)
526 (eq (nth 2 parent) (nth 2 entry))))
527 (setq repl 1))
528 ((memq (car parent) '(vec calcFunc-min calcFunc-max)))
529 ((and (assq (car parent) calc-tweak-eqn-table)
530 (= (length parent) 3))
531 (setq repl 'del))
532 (t
533 (setq repl 0)))
534 (cond
535 ((eq repl 'del)
536 (calc-push-list (list
537 (calc-normalize
538 (calc-replace-sub-formula
539 (car entry)
540 parent
541 (if (eq (nth 2 entry) (nth 1 parent))
542 (nth 2 parent)
543 (nth 1 parent)))))
544 n))
545 (repl
546 (calc-push-list (list
547 (calc-normalize
548 (calc-replace-sub-formula (car entry)
549 (nth 2 entry)
550 repl)))
551 n))
552 (t
553 (calc-push-list (list
554 (calc-normalize
555 (calc-replace-sub-formula (car entry)
556 parent
557 (delq (nth 2 entry)
558 (copy-sequence
559 parent)))))
560 n)))))
bf77c646 561 (calc-pop-stack 1 n t))))
136211a9
EZ
562
563(defun calc-roll-down-with-selections (n m)
564 (let ((vals (append (calc-top-list m 1)
565 (calc-top-list (- n m) (1+ m))))
566 (sels (append (calc-top-list m 1 'sel)
567 (calc-top-list (- n m) (1+ m) 'sel))))
bf77c646 568 (calc-pop-push-list n vals 1 sels)))
136211a9
EZ
569
570(defun calc-roll-up-with-selections (n m)
571 (let ((vals (append (calc-top-list (- n m) 1)
572 (calc-top-list m (- n m -1))))
573 (sels (append (calc-top-list (- n m) 1 'sel)
574 (calc-top-list m (- n m -1) 'sel))))
bf77c646 575 (calc-pop-push-list n vals 1 sels)))
136211a9
EZ
576
577(defun calc-auto-selection (entry)
578 (or (nth 2 entry)
579 (progn
580 (and (boundp 'reselect) (setq reselect nil))
581 (calc-prepare-selection)
bf77c646 582 (calc-grow-assoc-formula (car entry) (calc-find-selected-part)))))
136211a9
EZ
583
584(defun calc-copy-selection ()
585 (interactive)
586 (calc-wrapper
587 (calc-preserve-point)
588 (let* ((num (max 1 (calc-locate-cursor-element (point))))
589 (entry (calc-top num 'entry)))
bf77c646 590 (calc-push (or (calc-auto-selection entry) (car entry))))))
136211a9
EZ
591
592(defun calc-del-selection ()
593 (interactive)
594 (calc-wrapper
595 (calc-preserve-point)
596 (let* ((num (max 1 (calc-locate-cursor-element (point))))
597 (entry (calc-top num 'entry))
598 (sel (calc-auto-selection entry)))
599 (setcar (nthcdr 2 entry) (and (not (eq sel (car entry))) sel))
bf77c646 600 (calc-delete-selection num))))
136211a9
EZ
601
602(defun calc-enter-selection ()
603 (interactive)
604 (calc-wrapper
605 (calc-preserve-point)
606 (let* ((num (max 1 (calc-locate-cursor-element (point))))
607 (reselect calc-keep-selection)
608 (entry (calc-top num 'entry))
609 (expr (car entry))
610 (sel (or (calc-auto-selection entry) expr))
611 alg)
612 (let ((calc-dollar-values (list sel))
613 (calc-dollar-used 0))
614 (setq alg (calc-do-alg-entry "" "Replace selection with: "))
615 (and alg
616 (progn
617 (setq alg (calc-encase-atoms (car alg)))
618 (calc-pop-push-record-list 1 "repl"
619 (list (calc-replace-sub-formula
620 expr sel alg))
621 num
622 (list (and reselect alg))))))
bf77c646 623 (calc-handle-whys))))
136211a9
EZ
624
625(defun calc-edit-selection ()
626 (interactive)
627 (calc-wrapper
628 (calc-preserve-point)
629 (let* ((num (max 1 (calc-locate-cursor-element (point))))
630 (reselect calc-keep-selection)
631 (entry (calc-top num 'entry))
632 (expr (car entry))
633 (sel (or (calc-auto-selection entry) expr))
634 alg)
635 (let ((str (math-showing-full-precision
8f66f479 636 (math-format-nice-expr sel (frame-width)))))
136211a9
EZ
637 (calc-edit-mode (list 'calc-finish-selection-edit
638 num (list 'quote sel) reselect))
639 (insert str "\n"))))
bf77c646 640 (calc-show-edit-buffer))
136211a9
EZ
641
642(defun calc-finish-selection-edit (num sel reselect)
643 (let ((buf (current-buffer))
644 (str (buffer-substring (point) (point-max)))
645 (start (point)))
646 (switch-to-buffer calc-original-buffer)
647 (let ((val (math-read-expr str)))
648 (if (eq (car-safe val) 'error)
649 (progn
650 (switch-to-buffer buf)
651 (goto-char (+ start (nth 1 val)))
652 (error (nth 2 val))))
653 (calc-wrapper
654 (calc-preserve-point)
655 (if disp-trail
656 (calc-trail-display 1 t))
657 (setq val (calc-encase-atoms (calc-normalize val)))
658 (let ((expr (calc-top num 'full)))
659 (if (calc-find-sub-formula expr sel)
660 (calc-pop-push-record-list 1 "edit"
661 (list (calc-replace-sub-formula
662 expr sel val))
663 num
664 (list (and reselect val)))
665 (calc-push val)
bf77c646 666 (error "Original selection has been lost")))))))
136211a9
EZ
667
668(defun calc-sel-evaluate (arg)
669 (interactive "p")
670 (calc-slow-wrapper
671 (calc-preserve-point)
672 (let* ((num (max 1 (calc-locate-cursor-element (point))))
673 (reselect calc-keep-selection)
674 (entry (calc-top num 'entry))
675 (sel (or (calc-auto-selection entry) (car entry))))
676 (calc-with-default-simplification
677 (let ((math-simplify-only nil))
678 (calc-modify-simplify-mode arg)
679 (let ((val (calc-encase-atoms (calc-normalize sel))))
680 (calc-pop-push-record-list 1 "jsmp"
681 (list (calc-replace-sub-formula
682 (car entry) sel val))
683 num
684 (list (and reselect val))))))
bf77c646 685 (calc-handle-whys))))
136211a9
EZ
686
687(defun calc-sel-expand-formula (arg)
688 (interactive "p")
689 (calc-slow-wrapper
690 (calc-preserve-point)
691 (let* ((num (max 1 (calc-locate-cursor-element (point))))
692 (reselect calc-keep-selection)
693 (entry (calc-top num 'entry))
694 (sel (or (calc-auto-selection entry) (car entry))))
695 (calc-with-default-simplification
696 (let ((math-simplify-only nil))
697 (calc-modify-simplify-mode arg)
698 (let* ((math-expand-formulas (> arg 0))
699 (val (calc-normalize sel))
700 top)
701 (and (<= arg 0)
702 (setq top (math-expand-formula val))
703 (setq val (calc-normalize top)))
704 (setq val (calc-encase-atoms val))
705 (calc-pop-push-record-list 1 "jexf"
706 (list (calc-replace-sub-formula
707 (car entry) sel val))
708 num
709 (list (and reselect val))))))
bf77c646 710 (calc-handle-whys))))
136211a9
EZ
711
712(defun calc-sel-mult-both-sides (no-simp &optional divide)
713 (interactive "P")
714 (calc-wrapper
715 (calc-preserve-point)
716 (let* ((num (max 1 (calc-locate-cursor-element (point))))
717 (reselect calc-keep-selection)
718 (entry (calc-top num 'entry))
719 (expr (car entry))
720 (sel (or (calc-auto-selection entry) expr))
721 (func (car-safe sel))
722 alg lhs rhs)
723 (setq alg (calc-with-default-simplification
724 (car (calc-do-alg-entry ""
725 (if divide
726 "Divide both sides by: "
727 "Multiply both sides by: ")))))
728 (and alg
729 (progn
730 (if (and (or (eq func '/)
731 (assq func calc-tweak-eqn-table))
732 (= (length sel) 3))
733 (progn
734 (or (memq func '(/ calcFunc-eq calcFunc-neq))
735 (if (math-known-nonposp alg)
736 (progn
737 (setq func (nth 1 (assq func
738 calc-tweak-eqn-table)))
739 (or (math-known-negp alg)
740 (message "Assuming this factor is nonzero")))
741 (or (math-known-posp alg)
742 (if (math-known-nonnegp alg)
743 (message "Assuming this factor is nonzero")
744 (message "Assuming this factor is positive")))))
745 (setq lhs (list (if divide '/ '*) (nth 1 sel) alg)
746 rhs (list (if divide '/ '*) (nth 2 sel) alg))
747 (or no-simp
748 (progn
749 (setq lhs (math-simplify lhs)
750 rhs (math-simplify rhs))
751 (and (eq func '/)
752 (or (Math-equal (nth 1 sel) 1)
753 (Math-equal (nth 1 sel) -1)
754 (and (memq (car-safe (nth 2 sel)) '(+ -))
755 (memq (car-safe alg) '(+ -))))
756 (setq rhs (math-expand-term rhs)))))
757 (setq alg (calc-encase-atoms
758 (calc-normalize (list func lhs rhs)))))
759 (setq rhs (list (if divide '* '/) sel alg))
760 (or no-simp
761 (setq rhs (math-simplify rhs)))
762 (setq alg (calc-encase-atoms
763 (calc-normalize (if divide
764 (list '/ rhs alg)
765 (list '* alg rhs))))))
766 (calc-pop-push-record-list 1 (if divide "div" "mult")
767 (list (calc-replace-sub-formula
768 expr sel alg))
769 num
770 (list (and reselect alg)))))
bf77c646 771 (calc-handle-whys))))
136211a9
EZ
772
773(defun calc-sel-div-both-sides (no-simp)
774 (interactive "P")
bf77c646 775 (calc-sel-mult-both-sides no-simp t))
136211a9
EZ
776
777(defun calc-sel-add-both-sides (no-simp &optional subtract)
778 (interactive "P")
779 (calc-wrapper
780 (calc-preserve-point)
781 (let* ((num (max 1 (calc-locate-cursor-element (point))))
782 (reselect calc-keep-selection)
783 (entry (calc-top num 'entry))
784 (expr (car entry))
785 (sel (or (calc-auto-selection entry) expr))
786 (func (car-safe sel))
787 alg lhs rhs)
788 (setq alg (calc-with-default-simplification
789 (car (calc-do-alg-entry ""
790 (if subtract
791 "Subtract from both sides: "
792 "Add to both sides: ")))))
793 (and alg
794 (progn
795 (if (and (assq func calc-tweak-eqn-table)
796 (= (length sel) 3))
797 (progn
798 (setq lhs (list (if subtract '- '+) (nth 1 sel) alg)
799 rhs (list (if subtract '- '+) (nth 2 sel) alg))
800 (or no-simp
801 (setq lhs (math-simplify lhs)
802 rhs (math-simplify rhs)))
803 (setq alg (calc-encase-atoms
804 (calc-normalize (list func lhs rhs)))))
805 (setq rhs (list (if subtract '+ '-) sel alg))
806 (or no-simp
807 (setq rhs (math-simplify rhs)))
808 (setq alg (calc-encase-atoms
809 (calc-normalize (list (if subtract '- '+) alg rhs)))))
810 (calc-pop-push-record-list 1 (if subtract "sub" "add")
811 (list (calc-replace-sub-formula
812 expr sel alg))
813 num
814 (list (and reselect alg)))))
bf77c646 815 (calc-handle-whys))))
136211a9
EZ
816
817(defun calc-sel-sub-both-sides (no-simp)
818 (interactive "P")
bf77c646 819 (calc-sel-add-both-sides no-simp t))
136211a9 820
bf77c646 821;;; calc-sel.el ends here