(w32-system-shells): Add TCC (new name for 4NT.)
[bpt/emacs.git] / lisp / ses.el
index 85f6f8d..ced4994 100644 (file)
@@ -1,6 +1,6 @@
 ;;; ses.el -- Simple Emacs Spreadsheet  -*- coding: utf-8 -*-
 
-;; Copyright (C) 2002, 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+;; Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
 
 ;; Author: Jonathan Yavner <jyavner@member.fsf.org>
 ;; Maintainer: Jonathan Yavner <jyavner@member.fsf.org>
@@ -10,7 +10,7 @@
 
 ;; 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 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
 ;; any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
@@ -172,8 +172,10 @@ Each function is called with ARG=1."
                "\""      ses-read-cell
                "'"       ses-read-symbol
                "="       ses-edit-cell
+               "c"       ses-recalculate-cell
                "j"       ses-jump
                "p"       ses-read-cell-printer
+               "t"       ses-truncate-cell
                "w"       ses-set-column-width
                "x"       ses-export-keymap
                "\M-p"    ses-read-column-printer))
@@ -271,6 +273,9 @@ default printer and then modify its output.")
     (make-local-variable x)
     (set x nil)))
 
+;;;This variable is documented as being permitted in file-locals:
+(put 'ses--symbolic-formulas 'safe-local-variable 'consp)
+
 (defconst ses-paramlines-plist
   '(ses--col-widths  -5 ses--col-printers -4 ses--default-printer -3
     ses--header-row  -2 ses--file-format   1 ses--numrows          2
@@ -297,7 +302,7 @@ need to be recalculated.")
 (defvar ses-call-printer-return nil
   "Set to t if last cell printer invoked by `ses-call-printer' requested
 left-justification of the result.  Set to error-signal if ses-call-printer
-encountered an error during printing.  Nil otherwise.")
+encountered an error during printing.  Otherwise nil.")
 
 (defvar ses-start-time nil
   "Time when current operation started.  Used by `ses-time-check' to decide
@@ -507,10 +512,12 @@ for this spreadsheet."
                 (list (symbol-name (cadr formula))))))
 
 (defun ses-column-letter (col)
-  "Converts a column number to A..Z or AA..ZZ"
-  (if (< col 26)
-      (char-to-string (+ ?A col))
-    (string (+ ?@ (/ col 26)) (+ ?A (% col 26)))))
+  "Return the alphabetic name of column number COL.
+0-25 become A-Z; 26-701 become AA-ZZ, and so on."
+  (let ((units (char-to-string (+ ?A (% col 26)))))
+    (if (< col 26)
+        units
+      (concat (ses-column-letter (1- (/ col 26))) units))))
 
 (defun ses-create-cell-symbol (row col)
   "Produce a symbol that names the cell (ROW,COL).  (0,0) => 'A1."
@@ -628,8 +635,9 @@ the old and FORCE is nil."
     (let ((oldval  (ses-cell-value   cell))
          (formula (ses-cell-formula cell))
          newval)
-      (if (eq (car-safe formula) 'ses-safe-formula)
-         (ses-set-cell row col 'formula (ses-safe-formula (cadr formula))))
+      (when (eq (car-safe formula) 'ses-safe-formula)
+       (setq formula (ses-safe-formula (cadr formula)))
+       (ses-set-cell row col 'formula formula))
       (condition-case sig
          (setq newval (eval formula))
        (error
@@ -737,6 +745,9 @@ region, or nil if cursor is not at a cell."
     ;;Range
     (let ((bcell (get-text-property (region-beginning) 'intangible))
          (ecell (get-text-property (1- (region-end))  'intangible)))
+      (when (= (region-end) ses--data-marker)
+       ;;Correct for overflow
+       (setq ecell (get-text-property (- (region-end) 2)  'intangible)))
       (setq ses--curcell (if (and bcell ecell)
                             (cons bcell ecell)
                           nil))))
@@ -878,9 +889,9 @@ preceding cell has spilled over."
 
 (defun ses-call-printer (printer &optional value)
   "Invokes PRINTER (a string or parenthesized string or function-symbol or
-lambda of one argument) on VALUE.  Result is the the printed cell as a
-string.  The variable `ses-call-printer-return' is set to t if the printer
-used parenthesis to request left-justification, or the error-signal if the
+lambda of one argument) on VALUE.  Result is the printed cell as a string.
+The variable `ses-call-printer-return' is set to t if the printer used
+parenthesis to request left-justification, or the error-signal if the
 printer signaled one (and \"%s\" is used as the default printer), else nil."
   (setq ses-call-printer-return nil)
   (unless value
@@ -1470,22 +1481,27 @@ Narrows the buffer to show only the print area.  Gives it `read-only' and
   (overlay-put ses--curcell-overlay 'face 'underline))
 
 (defun ses-cleanup ()
-  "Cleanup when changing a buffer from SES mode to something else.  Delete
-overlay, remove special text properties."
+  "Cleanup when changing a buffer from SES mode to something else.
+Delete overlays, remove special text properties."
   (widen)
   (let ((inhibit-read-only t)
+        ;; When reverting, hide the buffer name, otherwise Emacs will ask
+        ;; the user "the file is modified, do you really want to make
+        ;; modifications to this buffer", where the "modifications" refer to
+        ;; the irrelevant set-text-properties below.
+        (buffer-file-name nil)
        (was-modified      (buffer-modified-p)))
     ;;Delete read-only, keymap, and intangible properties
     (set-text-properties (point-min) (point-max) nil)
     ;;Delete overlay
     (mapc 'delete-overlay (overlays-in (point-min) (point-max)))
     (unless was-modified
-      (set-buffer-modified-p nil))))
+      (restore-buffer-modified-p nil))))
 
 ;;;###autoload
 (defun ses-mode ()
   "Major mode for Simple Emacs Spreadsheet.
-See \"ses-example.ses\" (in the etc data directory) for more info.
+See \"ses-example.ses\" (in `data-directory') for more info.
 
 Key definitions:
 \\{ses-mode-map}
@@ -2322,6 +2338,9 @@ hard to override how mouse-1 works."
 (defun ses-copy-region (beg end)
   "Treat the region as rectangular.  Convert the intangible attributes to
 SES attributes recording the contents of the cell as of the time of copying."
+  (when (= end ses--data-marker)
+    ;;Avoid overflow situation
+    (setq end (1- ses--data-marker)))
   (let* ((inhibit-point-motion-hooks t)
         (x (mapconcat 'ses-copy-region-helper
                       (extract-rectangle beg (1- end)) "\n")))
@@ -2902,7 +2921,7 @@ TEST is evaluated."
 ;;----------------------------------------------------------------------------
 
 ;;These functions use the variables 'row' and 'col' that are
-;;dynamically bound by ses-print-cell.  We define these varables at
+;;dynamically bound by ses-print-cell.  We define these variables at
 ;;compile-time to make the compiler happy.
 (eval-when-compile
   (dolist (x '(row col))
@@ -2961,6 +2980,19 @@ current column and continues until the next nonblank column."
 (dolist (x (cons 'ses-unsafe ses-standard-printer-functions))
   (put x 'side-effect-free t))
 
+(defun ses-unload-function ()
+  "Unload the Simple Emacs Spreadsheet."
+  (dolist (fun '(copy-region-as-kill yank))
+    (ad-remove-advice fun 'around (intern (concat "ses-" (symbol-name fun))))
+    (ad-update fun))
+  (save-current-buffer
+    (dolist (buf (buffer-list))
+      (set-buffer buf)
+      (when (eq major-mode 'ses-mode)
+       (funcall (or default-major-mode 'fundamental-mode)))))
+  ;; continue standard unloading
+  nil)
+
 (provide 'ses)
 
 ;; arch-tag: 88c1ccf0-4293-4824-8c5d-0757b52217f3