;;; calc-embed.el --- embed Calc in a buffer
-;; Copyright (C) 1990, 1991, 1992, 1993, 2001, 2005 Free Software Foundation, Inc.
+;; Copyright (C) 1990-1993, 2001-2012 Free Software Foundation, Inc.
;; Author: David Gillespie <daveg@synaptics.com>
-;; Maintainer: Jay Belanger <belanger@truman.edu>
+;; Maintainer: Jay Belanger <jay.p.belanger@gmail.com>
;; This file is part of GNU Emacs.
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY. No author or distributor
-;; accepts responsibility to anyone for the consequences of using it
-;; or for whether it serves any particular purpose or works at all,
-;; unless he says so in writing. Refer to the GNU Emacs General Public
-;; License for full details.
-
-;; Everyone is granted permission to copy, modify and redistribute
-;; GNU Emacs, but only under the conditions described in the
-;; GNU Emacs General Public License. A copy of this license is
-;; supposed to have been given to you along with GNU Emacs so you
-;; can know your rights and responsibilities. It should be in a
-;; file named COPYING. Among other things, the copyright notice
-;; and this notice must be preserved on all copies.
+;; 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
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
(require 'calc-ext)
(require 'calc-macs)
+;; Declare functions which are defined elsewhere.
+(declare-function thing-at-point-looking-at "thingatpt" (regexp))
+
+
(defun calc-show-plain (n)
(interactive "P")
(calc-wrapper
(defvar calc-embedded-announce-formula)
(defvar calc-embedded-open-formula)
(defvar calc-embedded-close-formula)
-(defvar calc-embedded-open-word)
-(defvar calc-embedded-close-word)
(defvar calc-embedded-open-plain)
(defvar calc-embedded-close-plain)
(defvar calc-embedded-open-new-formula)
(defvar calc-embedded-close-new-formula)
(defvar calc-embedded-open-mode)
(defvar calc-embedded-close-mode)
+(defvar calc-embedded-word-regexp)
-(defconst calc-embedded-mode-vars '(("precision" . calc-internal-prec)
+(defconst calc-embedded-mode-vars '(("twos-complement" . calc-twos-complement-mode)
+ ("precision" . calc-internal-prec)
("word-size" . calc-word-size)
("angles" . calc-angle-mode)
("symbolic" . calc-symbolic-mode)
))
-;;; Format of calc-embedded-info vector:
-;;; 0 Editing buffer.
-;;; 1 Calculator buffer.
-;;; 2 Top of current formula (marker).
-;;; 3 Bottom of current formula (marker).
-;;; 4 Top of current formula's delimiters (marker).
-;;; 5 Bottom of current formula's delimiters (marker).
-;;; 6 String representation of current formula.
-;;; 7 Non-nil if formula is embedded within a single line.
-;;; 8 Internal representation of current formula.
-;;; 9 Variable assigned by this formula, or nil.
-;;; 10 List of variables upon which this formula depends.
-;;; 11 Evaluated value of the formula, or nil.
-;;; 12 Mode settings for current formula.
-;;; 13 Local mode settings for current formula.
-;;; 14 Permanent mode settings for current formula.
-;;; 15 Global mode settings for editing buffer.
-
-
-;;; calc-embedded-active is an a-list keyed on buffers; each cdr is a
-;;; sorted list of calc-embedded-infos in that buffer. We do this
-;;; rather than using buffer-local variables because the latter are
-;;; thrown away when a buffer changes major modes.
+;; Format of calc-embedded-info vector:
+;; 0 Editing buffer.
+;; 1 Calculator buffer.
+;; 2 Top of current formula (marker).
+;; 3 Bottom of current formula (marker).
+;; 4 Top of current formula's delimiters (marker).
+;; 5 Bottom of current formula's delimiters (marker).
+;; 6 String representation of current formula.
+;; 7 Non-nil if formula is embedded within a single line.
+;; 8 Internal representation of current formula.
+;; 9 Variable assigned by this formula, or nil.
+;; 10 List of variables upon which this formula depends.
+;; 11 Evaluated value of the formula, or nil.
+;; 12 Mode settings for current formula.
+;; 13 Local mode settings for current formula.
+;; 14 Permanent mode settings for current formula.
+;; 15 Global mode settings for editing buffer.
+
+
+;; calc-embedded-active is an a-list keyed on buffers; each cdr is a
+;; sorted list of calc-embedded-infos in that buffer. We do this
+;; rather than using buffer-local variables because the latter are
+;; thrown away when a buffer changes major modes.
(defvar calc-embedded-original-modes nil
"The mode settings for Calc buffer when put in embedded mode.")
(defun calc-embedded-save-original-modes ()
- "Save the current Calc modes when entereding embedded mode."
+ "Save the current Calc modes when entering embedded mode."
(let ((calcbuf (save-excursion
(calc-create-buffer)
(current-buffer)))
(let ((var (cdr (car v))))
(unless (memq var '(the-language the-display-just))
(setq modes
- (cons (cons var (symbol-value var))
+ (cons (cons var (symbol-value var))
modes))))
(setq v (cdr v))))
(setq calc-embedded-original-modes (cons lang modes)))
(message "Current modes will be preserved when leaving embedded mode."))
(message "Not in embedded mode.")))
-(defun calc-embedded-restore-original-modes ()
+(defun calc-embedded-restore-original-modes (calcbuf)
"Restore the original Calc modes when leaving embedded mode."
- (let ((calcbuf (get-buffer "*Calculator*"))
- (changed nil)
+ (let ((changed nil)
(lang (car calc-embedded-original-modes))
(modes (cdr calc-embedded-original-modes)))
(if (and calcbuf calc-embedded-original-modes)
(calc-set-mode-line))))
(setq calc-embedded-original-modes nil)))
-;; The variables calc-embed-outer-top, calc-embed-outer-bot,
+;; The variables calc-embed-outer-top, calc-embed-outer-bot,
;; calc-embed-top and calc-embed-bot are
;; local to calc-do-embedded, calc-embedded-mark-formula,
;; calc-embedded-duplicate, calc-embedded-new-formula and
;; The variable calc-embed-arg is local to calc-do-embedded,
;; calc-embedded-update-formula, calc-embedded-edit and
-;; calc-do-embedded-activate, but is used by
+;; calc-do-embedded-activate, but is used by
;; calc-embedded-make-info, which is called by the above
;; functions.
(defvar calc-embed-arg)
(defvar calc-embedded-quiet nil)
+
+(defvar calc-embedded-firsttime)
+(defvar calc-embedded-firsttime-buf)
+(defvar calc-embedded-firsttime-formula)
+
+;; The following is to take care of any minor modes which override
+;; a Calc command.
+(defvar calc-override-minor-modes-map
+ (make-sparse-keymap)
+ "A list of keybindings that might be overwritten by minor modes.")
+
+;; Add any keys that might be overwritten here.
+(define-key calc-override-minor-modes-map "`" 'calc-edit)
+
+(defvar calc-override-minor-modes
+ (cons t calc-override-minor-modes-map))
+
(defun calc-do-embedded (calc-embed-arg end obeg oend)
(if calc-embedded-info
((eq (current-buffer) (aref calc-embedded-info 0))
(let* ((info calc-embedded-info)
- (mode calc-embedded-modes))
- (save-excursion
- (set-buffer (aref info 1))
+ (mode calc-embedded-modes)
+ (calcbuf (aref calc-embedded-info 1)))
+ (with-current-buffer (aref info 1)
(if (and (> (calc-stack-size) 0)
(equal (calc-top 1 'full) (aref info 8)))
(let ((calc-no-refresh-evaltos t))
truncate-lines (nth 2 mode)
buffer-read-only nil)
(use-local-map (nth 1 mode))
+ (setq minor-mode-overriding-map-alist
+ (remq calc-override-minor-modes minor-mode-overriding-map-alist))
(set-buffer-modified-p (buffer-modified-p))
- (calc-embedded-restore-original-modes)
+ (calc-embedded-restore-original-modes calcbuf)
(or calc-embedded-quiet
- (message "Back to %s mode" mode-name))))
+ (message "Back to %s mode" (format-mode-line mode-name)))))
(t
(if (buffer-name (aref calc-embedded-info 0))
- (save-excursion
- (set-buffer (aref calc-embedded-info 0))
+ (with-current-buffer (aref calc-embedded-info 0)
(or (y-or-n-p (format "Cancel Calc Embedded mode in buffer %s? "
(buffer-name)))
(keyboard-quit))
(let ((modes (list mode-line-buffer-identification
(current-local-map)
truncate-lines))
+ (calc-embedded-firsttime (not calc-embedded-active))
+ (calc-embedded-firsttime-buf nil)
+ (calc-embedded-firsttime-formula nil)
calc-embed-top calc-embed-bot calc-embed-outer-top calc-embed-outer-bot
info chg ident)
(barf-if-buffer-read-only)
(calc-embedded-save-original-modes)
(or calc-embedded-globals
(calc-find-globals))
- (setq info
+ (setq info
(calc-embedded-make-info (point) nil t calc-embed-arg end obeg oend))
(if (eq (car-safe (aref info 8)) 'error)
(progn
buffer-read-only t)
(set-buffer-modified-p (buffer-modified-p))
(use-local-map calc-mode-map)
+ (setq minor-mode-overriding-map-alist
+ (cons calc-override-minor-modes
+ minor-mode-overriding-map-alist))
(setq calc-no-refresh-evaltos nil)
(and chg calc-any-evaltos (calc-wrapper (calc-refresh-evaltos)))
(let (str)
(unless (equal str mode-line-buffer-identification)
(setq mode-line-buffer-identification str)
(set-buffer-modified-p (buffer-modified-p))))
+ (if calc-embedded-firsttime
+ (run-hooks 'calc-embedded-mode-hook))
+ (if calc-embedded-firsttime-buf
+ (run-hooks 'calc-embedded-new-buffer-hook))
+ (if calc-embedded-firsttime-formula
+ (run-hooks 'calc-embedded-new-formula-hook))
(or (eq calc-embedded-quiet t)
(message "Embedded Calc mode enabled; %s to return to normal"
(if calc-embedded-quiet
- "Type `M-# x'"
+ "Type `C-x * x'"
"Give this command again")))))
(scroll-down 0)) ; fix a bug which occurs when truncate-lines is changed.
(start (point))
pos)
(switch-to-buffer calc-original-buffer)
- (let ((val (save-excursion
- (set-buffer (aref info 1))
+ (let ((val (with-current-buffer (aref info 1)
(let ((calc-language nil)
- (math-expr-opers math-standard-opers))
+ (math-expr-opers (math-standard-ops)))
(math-read-expr str)))))
(if (eq (car-safe val) 'error)
(progn
(aset info 8 val)
(calc-embedded-update info 14 t t))))
+;;;###autoload
(defun calc-do-embedded-activate (calc-embed-arg cbuf)
(calc-plain-buffer-only)
(if calc-embed-arg
(goto-char calc-embed-outer-bot)
(insert "\n")
(setq new-top (point))
- (insert-buffer-substring (current-buffer)
+ (insert-buffer-substring (current-buffer)
calc-embed-outer-top calc-embed-outer-bot)
(goto-char (+ new-top (- calc-embed-top calc-embed-outer-top)))
(let ((calc-embedded-quiet (if already t 'x)))
(equal (symbol-value (car (car v))) value))
(progn
(setq changed t)
- (if temp (setq calc-embed-prev-modes
+ (if temp (setq calc-embed-prev-modes
(cons (cons (car (car v))
(symbol-value (car (car v))))
calc-embed-prev-modes)))
(list modes emodes pmodes)))
;; The variable calc-embed-vars-used is local to calc-embedded-make-info,
-;; calc-embedded-evaluate-expr and calc-embedded-update, but is
+;; calc-embedded-evaluate-expr and calc-embedded-update, but is
;; used by calc-embedded-find-vars, which is called by the above functions.
(defvar calc-embed-vars-used)
(defun calc-embedded-make-info (point cbuf fresh &optional
- calc-embed-top calc-embed-bot
+ calc-embed-top calc-embed-bot
calc-embed-outer-top calc-embed-outer-bot)
(let* ((bufentry (assq (current-buffer) calc-embedded-active))
(found bufentry)
- (force (and fresh calc-embed-top))
+ (force (and fresh calc-embed-top (null (equal calc-embed-top '(t)))))
(fixed calc-embed-top)
(new-info nil)
info str)
(or found
- (setq found (list (current-buffer))
- calc-embedded-active (cons found calc-embedded-active)))
+ (and
+ (setq found (list (current-buffer))
+ calc-embedded-active (cons found calc-embedded-active)
+ calc-embedded-firsttime-buf t)
+ (let ((newann (assoc major-mode calc-embedded-announce-formula-alist))
+ (newform (assoc major-mode calc-embedded-open-close-formula-alist))
+ (newword (assoc major-mode calc-embedded-word-regexp-alist))
+ (newplain (assoc major-mode calc-embedded-open-close-plain-alist))
+ (newnewform
+ (assoc major-mode calc-embedded-open-close-new-formula-alist))
+ (newmode (assoc major-mode calc-embedded-open-close-mode-alist)))
+ (when newann
+ (make-local-variable 'calc-embedded-announce-formula)
+ (setq calc-embedded-announce-formula (cdr newann)))
+ (when newform
+ (make-local-variable 'calc-embedded-open-formula)
+ (make-local-variable 'calc-embedded-close-formula)
+ (setq calc-embedded-open-formula (nth 0 (cdr newform)))
+ (setq calc-embedded-close-formula (nth 1 (cdr newform))))
+ (when newword
+ (make-local-variable 'calc-embedded-word-regexp)
+ (setq calc-embedded-word-regexp (nth 1 newword)))
+ (when newplain
+ (make-local-variable 'calc-embedded-open-plain)
+ (make-local-variable 'calc-embedded-close-plain)
+ (setq calc-embedded-open-plain (nth 0 (cdr newplain)))
+ (setq calc-embedded-close-plain (nth 1 (cdr newplain))))
+ (when newnewform
+ (make-local-variable 'calc-embedded-open-new-formula)
+ (make-local-variable 'calc-embedded-close-new-formula)
+ (setq calc-embedded-open-new-formula (nth 0 (cdr newnewform)))
+ (setq calc-embedded-close-new-formula (nth 1 (cdr newnewform))))
+ (when newmode
+ (make-local-variable 'calc-embedded-open-mode)
+ (make-local-variable 'calc-embedded-close-mode)
+ (setq calc-embedded-open-mode (nth 0 (cdr newmode)))
+ (setq calc-embedded-close-mode (nth 1 (cdr newmode)))))))
(while (and (cdr found)
(> point (aref (car (cdr found)) 3)))
(setq found (cdr found)))
(if (and (cdr found)
(>= point (aref (nth 1 found) 2)))
- (setq info (nth 1 found))
+ (setq info (nth 1 found))
+ (setq calc-embedded-firsttime-formula t)
(setq info (make-vector 16 nil)
new-info t
fresh t)
(aset info 1 (or cbuf (save-excursion
(calc-create-buffer)
(current-buffer)))))
- (if (and
+ (if (and
(or (integerp calc-embed-top) (equal calc-embed-top '(4)))
- (not calc-embed-bot))
+ (not calc-embed-bot))
; started with a user-supplied argument
(progn
(if (equal calc-embed-top '(4))
(setq calc-embed-top (aref info 2)
fixed calc-embed-top)
(if (consp calc-embed-top)
- (let ((calc-embedded-open-formula calc-embedded-open-word)
- (calc-embedded-close-formula calc-embedded-close-word))
- (calc-embedded-find-bounds 'plain))
+ (progn
+ (require 'thingatpt)
+ (if (thing-at-point-looking-at calc-embedded-word-regexp)
+ (progn
+ (setq calc-embed-top (copy-marker (match-beginning 0)))
+ (setq calc-embed-bot (copy-marker (match-end 0)))
+ (setq calc-embed-outer-top calc-embed-top)
+ (setq calc-embed-outer-bot calc-embed-bot))
+ (setq calc-embed-top (point-marker))
+ (setq calc-embed-bot (point-marker))
+ (setq calc-embed-outer-top calc-embed-top)
+ (setq calc-embed-outer-bot calc-embed-bot)))
(or calc-embed-top
(calc-embedded-find-bounds 'plain)))
(aset info 2 (copy-marker (min calc-embed-top calc-embed-bot)))
(pref-len (length open-plain))
(calc-embed-vars-used nil)
suff-pos val temp)
- (save-excursion
- (set-buffer (aref info 1))
+ (with-current-buffer (aref info 1)
(calc-embedded-set-modes (aref info 15)
(aref info 12) (aref info 14))
(if (and (> (length str) pref-len)
(substring str pref-len suff-pos)))
(if (string-match "[^ \t\n]" str)
(setq pref-len 0
- val (math-read-big-expr str))
+ val (condition-case nil
+ (math-read-big-expr str)
+ (error (math-read-expr str))))
(setq val nil))))
(if (eq (car-safe val) 'error)
(setq val (list 'error
(if need-display
(calc-embedded-set-justify (cdr (car calc-embed-prev-modes)))))
(t
- (set (car (car calc-embed-prev-modes))
+ (set (car (car calc-embed-prev-modes))
(cdr (car calc-embed-prev-modes)))))
(setq calc-embed-prev-modes (cdr calc-embed-prev-modes))))))
(defun calc-embedded-finish-command ()
(let ((buf (current-buffer))
horiz vert)
- (save-excursion
- (set-buffer (aref calc-embedded-info 1))
+ (with-current-buffer (aref calc-embedded-info 1)
(if (> (calc-stack-size) 0)
(let ((pt (point))
(col (current-column))
(defun calc-embedded-stack-change ()
(or calc-executing-macro
- (save-excursion
- (set-buffer (aref calc-embedded-info 1))
+ (with-current-buffer (aref calc-embedded-info 1)
(let* ((info calc-embedded-info)
(extra-line (if (eq calc-language 'big) 1 0))
(the-point (point))
(provide 'calc-embed)
-;;; arch-tag: 1b8f311e-fba1-40d3-b8c3-1d6f68fd26fc
+;; Local variables:
+;; generated-autoload-file: "calc-loaddefs.el"
+;; End:
+
;;; calc-embed.el ends here