PageRenderTime 70ms CodeModel.GetById 42ms RepoModel.GetById 1ms app.codeStats 0ms

/lisp/calc/calcsel2.el

https://github.com/T-force/emacs
Emacs Lisp | 302 lines | 254 code | 25 blank | 23 comment | 0 complexity | d0450cbf4ccf4b2985ed97cacaddab27 MD5 | raw file
  1. ;;; calcsel2.el --- selection functions for Calc
  2. ;; Copyright (C) 1990-1993, 2001-2011 Free Software Foundation, Inc.
  3. ;; Author: David Gillespie <daveg@synaptics.com>
  4. ;; Maintainer: Jay Belanger <jay.p.belanger@gmail.com>
  5. ;; This file is part of GNU Emacs.
  6. ;; GNU Emacs is free software: you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation, either version 3 of the License, or
  9. ;; (at your option) any later version.
  10. ;; GNU Emacs is distributed in the hope that it will be useful,
  11. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ;; GNU General Public License for more details.
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  16. ;;; Commentary:
  17. ;;; Code:
  18. ;; This file is autoloaded from calc-ext.el.
  19. (require 'calc-ext)
  20. (require 'calc-macs)
  21. ;; The variable calc-keep-selection is declared and set in calc-sel.el.
  22. (defvar calc-keep-selection)
  23. ;; The variable calc-sel-reselect is local to the methods below,
  24. ;; but is used by some functions in calc-sel.el which are called
  25. ;; by the functions below.
  26. (defun calc-commute-left (arg)
  27. (interactive "p")
  28. (if (< arg 0)
  29. (calc-commute-right (- arg))
  30. (calc-wrapper
  31. (calc-preserve-point)
  32. (let ((num (max 1 (calc-locate-cursor-element (point))))
  33. (calc-sel-reselect calc-keep-selection))
  34. (if (= arg 0) (setq arg nil))
  35. (while (or (null arg) (>= (setq arg (1- arg)) 0))
  36. (let* ((entry (calc-top num 'entry))
  37. (expr (car entry))
  38. (sel (calc-auto-selection entry))
  39. parent new)
  40. (or (and sel
  41. (consp (setq parent (calc-find-assoc-parent-formula
  42. expr sel))))
  43. (error "No term is selected"))
  44. (if (and calc-assoc-selections
  45. (assq (car parent) calc-assoc-ops))
  46. (let ((outer (calc-find-parent-formula parent sel)))
  47. (if (eq sel (nth 2 outer))
  48. (setq new (calc-replace-sub-formula
  49. parent outer
  50. (cond
  51. ((memq (car outer)
  52. (nth 1 (assq (car-safe (nth 1 outer))
  53. calc-assoc-ops)))
  54. (let* ((other (nth 2 (nth 1 outer)))
  55. (new (calc-build-assoc-term
  56. (car (nth 1 outer))
  57. (calc-build-assoc-term
  58. (car outer)
  59. (nth 1 (nth 1 outer))
  60. sel)
  61. other)))
  62. (setq sel (nth 2 (nth 1 new)))
  63. new))
  64. ((eq (car outer) '-)
  65. (calc-build-assoc-term
  66. '+
  67. (setq sel (math-neg sel))
  68. (nth 1 outer)))
  69. ((eq (car outer) '/)
  70. (calc-build-assoc-term
  71. '*
  72. (setq sel (calcFunc-div 1 sel))
  73. (nth 1 outer)))
  74. (t (calc-build-assoc-term
  75. (car outer) sel (nth 1 outer))))))
  76. (let ((next (calc-find-parent-formula parent outer)))
  77. (if (not (and (consp next)
  78. (eq outer (nth 2 next))
  79. (eq (car next) (car outer))))
  80. (setq new nil)
  81. (setq new (calc-build-assoc-term
  82. (car next)
  83. sel
  84. (calc-build-assoc-term
  85. (car next) (nth 1 next) (nth 2 outer)))
  86. sel (nth 1 new)
  87. new (calc-replace-sub-formula
  88. parent next new))))))
  89. (if (eq (nth 1 parent) sel)
  90. (setq new nil)
  91. (let ((p (nthcdr (1- (calc-find-sub-formula parent sel))
  92. (setq new (copy-sequence parent)))))
  93. (setcar (cdr p) (car p))
  94. (setcar p sel))))
  95. (if (null new)
  96. (if arg
  97. (error "Term is already leftmost")
  98. (or calc-sel-reselect
  99. (calc-pop-push-list 1 (list expr) num '(nil)))
  100. (setq arg 0))
  101. (calc-pop-push-record-list
  102. 1 "left"
  103. (list (calc-replace-sub-formula expr parent new))
  104. num
  105. (list (and (or (not (eq arg 0)) calc-sel-reselect)
  106. sel))))))))))
  107. (defun calc-commute-right (arg)
  108. (interactive "p")
  109. (if (< arg 0)
  110. (calc-commute-left (- arg))
  111. (calc-wrapper
  112. (calc-preserve-point)
  113. (let ((num (max 1 (calc-locate-cursor-element (point))))
  114. (calc-sel-reselect calc-keep-selection))
  115. (if (= arg 0) (setq arg nil))
  116. (while (or (null arg) (>= (setq arg (1- arg)) 0))
  117. (let* ((entry (calc-top num 'entry))
  118. (expr (car entry))
  119. (sel (calc-auto-selection entry))
  120. parent new)
  121. (or (and sel
  122. (consp (setq parent (calc-find-assoc-parent-formula
  123. expr sel))))
  124. (error "No term is selected"))
  125. (if (and calc-assoc-selections
  126. (assq (car parent) calc-assoc-ops))
  127. (let ((outer (calc-find-parent-formula parent sel)))
  128. (if (eq sel (nth 1 outer))
  129. (setq new (calc-replace-sub-formula
  130. parent outer
  131. (if (memq (car outer)
  132. (nth 2 (assq (car-safe (nth 2 outer))
  133. calc-assoc-ops)))
  134. (let ((other (nth 1 (nth 2 outer))))
  135. (calc-build-assoc-term
  136. (car outer)
  137. other
  138. (calc-build-assoc-term
  139. (car (nth 2 outer))
  140. sel
  141. (nth 2 (nth 2 outer)))))
  142. (let ((new (cond
  143. ((eq (car outer) '-)
  144. (calc-build-assoc-term
  145. '+
  146. (math-neg (nth 2 outer))
  147. sel))
  148. ((eq (car outer) '/)
  149. (calc-build-assoc-term
  150. '*
  151. (calcFunc-div 1 (nth 2 outer))
  152. sel))
  153. (t (calc-build-assoc-term
  154. (car outer)
  155. (nth 2 outer)
  156. sel)))))
  157. (setq sel (nth 2 new))
  158. new))))
  159. (let ((next (calc-find-parent-formula parent outer)))
  160. (if (not (and (consp next)
  161. (eq outer (nth 1 next))))
  162. (setq new nil)
  163. (setq new (calc-build-assoc-term
  164. (car outer)
  165. (calc-build-assoc-term
  166. (car next) (nth 1 outer) (nth 2 next))
  167. sel)
  168. sel (nth 2 new)
  169. new (calc-replace-sub-formula
  170. parent next new))))))
  171. (if (eq (nth (1- (length parent)) parent) sel)
  172. (setq new nil)
  173. (let ((p (nthcdr (calc-find-sub-formula parent sel)
  174. (setq new (copy-sequence parent)))))
  175. (setcar p (nth 1 p))
  176. (setcar (cdr p) sel))))
  177. (if (null new)
  178. (if arg
  179. (error "Term is already rightmost")
  180. (or calc-sel-reselect
  181. (calc-pop-push-list 1 (list expr) num '(nil)))
  182. (setq arg 0))
  183. (calc-pop-push-record-list
  184. 1 "rght"
  185. (list (calc-replace-sub-formula expr parent new))
  186. num
  187. (list (and (or (not (eq arg 0)) calc-sel-reselect)
  188. sel))))))))))
  189. (defun calc-build-assoc-term (op lhs rhs)
  190. (cond ((and (eq op '+) (or (math-looks-negp rhs)
  191. (and (eq (car-safe rhs) 'cplx)
  192. (math-negp (nth 1 rhs))
  193. (eq (nth 2 rhs) 0))))
  194. (list '- lhs (math-neg rhs)))
  195. ((and (eq op '-) (or (math-looks-negp rhs)
  196. (and (eq (car-safe rhs) 'cplx)
  197. (math-negp (nth 1 rhs))
  198. (eq (nth 2 rhs) 0))))
  199. (list '+ lhs (math-neg rhs)))
  200. ((and (eq op '*) (and (eq (car-safe rhs) '/)
  201. (or (math-equal-int (nth 1 rhs) 1)
  202. (equal (nth 1 rhs) '(cplx 1 0)))))
  203. (list '/ lhs (nth 2 rhs)))
  204. ((and (eq op '/) (and (eq (car-safe rhs) '/)
  205. (or (math-equal-int (nth 1 rhs) 1)
  206. (equal (nth 1 rhs) '(cplx 1 0)))))
  207. (list '/ lhs (nth 2 rhs)))
  208. (t (list op lhs rhs))))
  209. (defun calc-sel-unpack ()
  210. (interactive)
  211. (calc-wrapper
  212. (calc-preserve-point)
  213. (let* ((num (max 1 (calc-locate-cursor-element (point))))
  214. (calc-sel-reselect calc-keep-selection)
  215. (entry (calc-top num 'entry))
  216. (expr (car entry))
  217. (sel (or (calc-auto-selection entry) expr)))
  218. (or (and (not (math-primp sel))
  219. (= (length sel) 2))
  220. (error "Selection must be a function of one argument"))
  221. (calc-pop-push-record-list 1 "unpk"
  222. (list (calc-replace-sub-formula
  223. expr sel (nth 1 sel)))
  224. num
  225. (list (and calc-sel-reselect (nth 1 sel)))))))
  226. (defun calc-sel-isolate ()
  227. (interactive)
  228. (calc-slow-wrapper
  229. (calc-preserve-point)
  230. (let* ((num (max 1 (calc-locate-cursor-element (point))))
  231. (calc-sel-reselect calc-keep-selection)
  232. (entry (calc-top num 'entry))
  233. (expr (car entry))
  234. (sel (or (calc-auto-selection entry) (error "No selection")))
  235. (eqn sel)
  236. soln)
  237. (while (and (or (consp (setq eqn (calc-find-parent-formula expr eqn)))
  238. (error "Selection must be a member of an equation"))
  239. (not (assq (car eqn) calc-tweak-eqn-table))))
  240. (setq soln (math-solve-eqn eqn sel calc-hyperbolic-flag))
  241. (or soln
  242. (error "No solution found"))
  243. (setq soln (calc-encase-atoms
  244. (if (eq (not (calc-find-sub-formula (nth 2 eqn) sel))
  245. (eq (nth 1 soln) sel))
  246. soln
  247. (list (nth 1 (assq (car soln) calc-tweak-eqn-table))
  248. (nth 2 soln)
  249. (nth 1 soln)))))
  250. (calc-pop-push-record-list 1 "isol"
  251. (list (calc-replace-sub-formula
  252. expr eqn soln))
  253. num
  254. (list (and calc-sel-reselect sel)))
  255. (calc-handle-whys))))
  256. (defun calc-sel-commute (many)
  257. (interactive "P")
  258. (let ((calc-assoc-selections nil))
  259. (calc-rewrite-selection "CommuteRules" many "cmut"))
  260. (calc-set-mode-line))
  261. (defun calc-sel-jump-equals (many)
  262. (interactive "P")
  263. (calc-rewrite-selection "JumpRules" many "jump"))
  264. (defun calc-sel-distribute (many)
  265. (interactive "P")
  266. (calc-rewrite-selection "DistribRules" many "dist"))
  267. (defun calc-sel-merge (many)
  268. (interactive "P")
  269. (calc-rewrite-selection "MergeRules" many "merg"))
  270. (defun calc-sel-negate (many)
  271. (interactive "P")
  272. (calc-rewrite-selection "NegateRules" many "jneg"))
  273. (defun calc-sel-invert (many)
  274. (interactive "P")
  275. (calc-rewrite-selection "InvertRules" many "jinv"))
  276. (provide 'calcsel2)
  277. ;;; calcsel2.el ends here