comparison lisp/ses.el @ 58409:924fa48ab4bf

Add coding cookie. Fix up docstrings, follow new commenting conventions. (ses-header-line-menu): Fix missing variable rename for header-row. (ses-cell-size): Remove. (ses-make-cell): New function. (ses-cell, ses-insert-row, ses-insert-column): Use it. (ses-calculate-cell): Remove unused var `symbol'. (ses-narrowed-p): New function. (ses-goto-data, undo-more, ses-reconstruct-all): Use it. (ses-initial-file-trailer): Change ;;; to ;; for local vars. (ses-load, ses-reconstruct-all): Adjust string search accordingly. (ses-setup): Use restore-buffer-modified-p. (ses-cleanup): Remove unused var `end'. (ses-header-string-left-offset): Remove. (ses-create-header-string): Adjust to new behavior of `align-to'. Truncate excessively large fields to preserve alignment. (ses-reconstruct-all): Remove unused var `refs'. (ses-read-cell-printer): Remove unused var `prompt'. (ses-delete-row): Remove unused var `pos'. (ses-delete-column): Remove unused var `new'.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Mon, 22 Nov 2004 01:21:07 +0000
parents 6956afbe5459
children c8adcd0d5e2e f2ebccfa87d4
comparison
equal deleted inserted replaced
58408:6b5846d74ff0 58409:924fa48ab4bf
1 ;;; ses.el -- Simple Emacs Spreadsheet 1 ;;; ses.el -- Simple Emacs Spreadsheet -*- coding: utf-8 -*-
2 2
3 ;; Copyright (C) 2002,03,04 Free Software Foundation, Inc. 3 ;; Copyright (C) 2002,03,04 Free Software Foundation, Inc.
4 4
5 ;; Author: Jonathan Yavner <jyavner@member.fsf.org> 5 ;; Author: Jonathan Yavner <jyavner@member.fsf.org>
6 ;; Maintainer: Jonathan Yavner <jyavner@member.fsf.org> 6 ;; Maintainer: Jonathan Yavner <jyavner@member.fsf.org>
21 ;; You should have received a copy of the GNU General Public License 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 22 ;; along with GNU Emacs; see the file COPYING. If not, write to the
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, 23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA. 24 ;; Boston, MA 02111-1307, USA.
25 25
26 ;;; Commentary:
27
26 ;;; To-do list: 28 ;;; To-do list:
29
27 ;; * Use $ or … for truncated fields 30 ;; * Use $ or … for truncated fields
28 ;; * Add command to make a range of columns be temporarily invisible. 31 ;; * Add command to make a range of columns be temporarily invisible.
29 ;; * Allow paste of one cell to a range of cells -- copy formula to each. 32 ;; * Allow paste of one cell to a range of cells -- copy formula to each.
30 ;; * Do something about control characters & octal codes in cell print 33 ;; * Do something about control characters & octal codes in cell print
31 ;; areas. Use string-width? 34 ;; areas. Use string-width?
33 ;; * Faces (colors & styles) in print cells. 36 ;; * Faces (colors & styles) in print cells.
34 ;; * Move a column by dragging its letter in the header line. 37 ;; * Move a column by dragging its letter in the header line.
35 ;; * Left-margin column for row number. 38 ;; * Left-margin column for row number.
36 ;; * Move a row by dragging its number in the left-margin. 39 ;; * Move a row by dragging its number in the left-margin.
37 40
41
42 ;;; Code:
43
38 (require 'unsafep) 44 (require 'unsafep)
39 45
40 46
41 ;;;---------------------------------------------------------------------------- 47 ;;----------------------------------------------------------------------------
42 ;;;; User-customizable variables 48 ;; User-customizable variables
43 ;;;---------------------------------------------------------------------------- 49 ;;----------------------------------------------------------------------------
44 50
45 (defgroup ses nil 51 (defgroup ses nil
46 "Simple Emacs Spreadsheet" 52 "Simple Emacs Spreadsheet"
47 :group 'applications 53 :group 'applications
48 :prefix "ses-" 54 :prefix "ses-"
64 :type '(choice string 70 :type '(choice string
65 (list :tag "Parenthesized string" string) 71 (list :tag "Parenthesized string" string)
66 function)) 72 function))
67 73
68 (defcustom ses-after-entry-functions '(forward-char) 74 (defcustom ses-after-entry-functions '(forward-char)
69 "Things to do after entering a value into a cell. An abnormal hook that 75 "Things to do after entering a value into a cell.
70 usually runs a cursor-movement function. Each function is called with ARG=1." 76 An abnormal hook that usually runs a cursor-movement function.
77 Each function is called with ARG=1."
71 :group 'ses 78 :group 'ses
72 :type 'hook 79 :type 'hook
73 :options '(forward-char backward-char next-line previous-line)) 80 :options '(forward-char backward-char next-line previous-line))
74 81
75 (defcustom ses-mode-hook nil 82 (defcustom ses-mode-hook nil
76 "Hook functions to be run upon entering SES mode." 83 "Hook functions to be run upon entering SES mode."
77 :group 'ses 84 :group 'ses
78 :type 'hook) 85 :type 'hook)
79 86
80 87
81 ;;;---------------------------------------------------------------------------- 88 ;;----------------------------------------------------------------------------
82 ;;;; Global variables and constants 89 ;; Global variables and constants
83 ;;;---------------------------------------------------------------------------- 90 ;;----------------------------------------------------------------------------
84 91
85 (defvar ses-read-cell-history nil 92 (defvar ses-read-cell-history nil
86 "List of formulas that have been typed in.") 93 "List of formulas that have been typed in.")
87 94
88 (defvar ses-read-printer-history nil 95 (defvar ses-read-printer-history nil
90 97
91 (easy-menu-define ses-header-line-menu nil 98 (easy-menu-define ses-header-line-menu nil
92 "Context menu when mouse-3 is used on the header-line in an SES buffer." 99 "Context menu when mouse-3 is used on the header-line in an SES buffer."
93 '("SES header row" 100 '("SES header row"
94 ["Set current row" ses-set-header-row t] 101 ["Set current row" ses-set-header-row t]
95 ["Unset row" ses-unset-header-row (> header-row 0)])) 102 ["Unset row" ses-unset-header-row (> ses--header-row 0)]))
96 103
97 (defconst ses-mode-map 104 (defconst ses-mode-map
98 (let ((keys `("\C-c\M-\C-l" ses-reconstruct-all 105 (let ((keys `("\C-c\M-\C-l" ses-reconstruct-all
99 "\C-c\C-l" ses-recalculate-all 106 "\C-c\C-l" ses-recalculate-all
100 "\C-c\C-n" ses-renarrow-buffer 107 "\C-c\C-n" ses-renarrow-buffer
206 (define-key map "T" (cons " tab-formulas" 'ses-export-tsf)) 213 (define-key map "T" (cons " tab-formulas" 'ses-export-tsf))
207 (define-key map "t" (cons " tab-values" 'ses-export-tsv)) 214 (define-key map "t" (cons " tab-values" 'ses-export-tsv))
208 map)) 215 map))
209 216
210 (defconst ses-print-data-boundary "\n\014\n" 217 (defconst ses-print-data-boundary "\n\014\n"
211 "Marker string denoting the boundary between print area and data area") 218 "Marker string denoting the boundary between print area and data area.")
212 219
213 (defconst ses-initial-global-parameters 220 (defconst ses-initial-global-parameters
214 "\n( ;Global parameters (these are read first)\n 2 ;SES file-format\n 1 ;numrows\n 1 ;numcols\n)\n\n" 221 "\n( ;Global parameters (these are read first)\n 2 ;SES file-format\n 1 ;numrows\n 1 ;numcols\n)\n\n"
215 "Initial contents for the three-element list at the bottom of the data area") 222 "Initial contents for the three-element list at the bottom of the data area.")
216 223
217 (defconst ses-initial-file-trailer 224 (defconst ses-initial-file-trailer
218 ";;; Local Variables:\n;;; mode: ses\n;;; End:\n" 225 ";; Local Variables:\n;; mode: ses\n;; End:\n"
219 "Initial contents for the file-trailer area at the bottom of the file.") 226 "Initial contents for the file-trailer area at the bottom of the file.")
220 227
221 (defconst ses-initial-file-contents 228 (defconst ses-initial-file-contents
222 (concat " \n" ;One blank cell in print area 229 (concat " \n" ;One blank cell in print area
223 ses-print-data-boundary 230 ses-print-data-boundary
229 "(ses-header-row 0)\n" 236 "(ses-header-row 0)\n"
230 ses-initial-global-parameters 237 ses-initial-global-parameters
231 ses-initial-file-trailer) 238 ses-initial-file-trailer)
232 "The initial contents of an empty spreadsheet.") 239 "The initial contents of an empty spreadsheet.")
233 240
234 (defconst ses-cell-size 4
235 "A cell consists of a SYMBOL, a FORMULA, a PRINTER-function, and a list of
236 REFERENCES.")
237
238 (defconst ses-paramlines-plist 241 (defconst ses-paramlines-plist
239 '(ses--col-widths 2 ses--col-printers 3 ses--default-printer 4 242 '(ses--col-widths 2 ses--col-printers 3 ses--default-printer 4
240 ses--header-row 5 ses--file-format 8 ses--numrows 9 243 ses--header-row 5 ses--file-format 8 ses--numrows 9
241 ses--numcols 10) 244 ses--numcols 10)
242 "Offsets from last cell line to various parameter lines in the data area 245 "Offsets from last cell line to various parameter lines in the data area
269 (dolist (x ses-localvars) 272 (dolist (x ses-localvars)
270 (make-local-variable x) 273 (make-local-variable x)
271 (set x nil))) 274 (set x nil)))
272 275
273 276
274 ;;; 277 ;;
275 ;;; "Side-effect variables". They are set in one function, altered in 278 ;; "Side-effect variables". They are set in one function, altered in
276 ;;; another as a side effect, then read back by the first, as a way of 279 ;; another as a side effect, then read back by the first, as a way of
277 ;;; passing back more than one value. These declarations are just to make 280 ;; passing back more than one value. These declarations are just to make
278 ;;; the compiler happy, and to conform to standard Emacs-Lisp practice (I 281 ;; the compiler happy, and to conform to standard Emacs-Lisp practice (I
279 ;;; think the make-local-variable trick above is cleaner). 282 ;; think the make-local-variable trick above is cleaner).
280 ;;; 283 ;;
281 284
282 (defvar ses-relocate-return nil 285 (defvar ses-relocate-return nil
283 "Set by `ses-relocate-formula' and `ses-relocate-range', read by 286 "Set by `ses-relocate-formula' and `ses-relocate-range', read by
284 `ses-relocate-all'. Set to 'delete if a cell-reference was deleted from a 287 `ses-relocate-all'. Set to 'delete if a cell-reference was deleted from a
285 formula--so the formula needs recalculation. Set to 'range if the size of a 288 formula--so the formula needs recalculation. Set to 'range if the size of a
294 (defvar ses-start-time nil 297 (defvar ses-start-time nil
295 "Time when current operation started. Used by `ses-time-check' to decide 298 "Time when current operation started. Used by `ses-time-check' to decide
296 when to emit a progress message.") 299 when to emit a progress message.")
297 300
298 301
299 ;;;---------------------------------------------------------------------------- 302 ;;----------------------------------------------------------------------------
300 ;;;; Macros 303 ;; Macros
301 ;;;---------------------------------------------------------------------------- 304 ;;----------------------------------------------------------------------------
302 305
303 (defmacro ses-get-cell (row col) 306 (defmacro ses-get-cell (row col)
304 "Return the cell structure that stores information about cell (ROW,COL)." 307 "Return the cell structure that stores information about cell (ROW,COL)."
305 `(aref (aref ses--cells ,row) ,col)) 308 `(aref (aref ses--cells ,row) ,col))
309
310 ;; We might want to use defstruct here, but cells are explicitly used as
311 ;; arrays in ses-set-cell, so we'd need to fix this first. --Stef
312 (defsubst ses-make-cell (&optional symbol formula printer references)
313 (vector symbol formula printer references))
306 314
307 (defmacro ses-cell-symbol (row &optional col) 315 (defmacro ses-cell-symbol (row &optional col)
308 "From a CELL or a pair (ROW,COL), get the symbol that names the local-variable holding its value. (0,0) => A1." 316 "From a CELL or a pair (ROW,COL), get the symbol that names the local-variable holding its value. (0,0) => A1."
309 `(aref ,(if col `(ses-get-cell ,row ,col) row) 0)) 317 `(aref ,(if col `(ses-get-cell ,row ,col) row) 0))
310 318
353 (stringp printer) 361 (stringp printer)
354 (eq safe-functions t) 362 (eq safe-functions t)
355 (setq printer `(ses-safe-printer ,printer))) 363 (setq printer `(ses-safe-printer ,printer)))
356 (aset (aref ses--cells (car rowcol)) 364 (aset (aref ses--cells (car rowcol))
357 (cdr rowcol) 365 (cdr rowcol)
358 (vector sym formula printer references))) 366 (ses-make-cell sym formula printer references)))
359 (set sym value) 367 (set sym value)
360 sym) 368 sym)
361 369
362 (defmacro ses-column-widths (widths) 370 (defmacro ses-column-widths (widths)
363 "Load the vector of column widths from the spreadsheet file. This is a 371 "Load the vector of column widths from the spreadsheet file. This is a
453 (defmacro noreturn (form) 461 (defmacro noreturn (form)
454 "For code-coverage testing, indicate that FORM will always signal an error." 462 "For code-coverage testing, indicate that FORM will always signal an error."
455 form) 463 form)
456 464
457 465
458 ;;;---------------------------------------------------------------------------- 466 ;;----------------------------------------------------------------------------
459 ;;;; Utility functions 467 ;; Utility functions
460 ;;;---------------------------------------------------------------------------- 468 ;;----------------------------------------------------------------------------
461 469
462 (defun ses-vector-insert (array idx new) 470 (defun ses-vector-insert (array idx new)
463 "Create a new vector which is one larger than ARRAY and has NEW inserted 471 "Create a new vector which is one larger than ARRAY and has NEW inserted
464 before element IDX." 472 before element IDX."
465 (let* ((len (length array)) 473 (let* ((len (length array))
536 xcol (+ col mincol) 544 xcol (+ col mincol)
537 sym (ses-create-cell-symbol xrow xcol)) 545 sym (ses-create-cell-symbol xrow xcol))
538 (put sym 'ses-cell (cons xrow xcol)) 546 (put sym 'ses-cell (cons xrow xcol))
539 (make-local-variable sym))))) 547 (make-local-variable sym)))))
540 548
541 ;;;We do not delete the ses-cell properties for the cell-variables, in case a 549 ;;We do not delete the ses-cell properties for the cell-variables, in case a
542 ;;;formula that refers to this cell is in the kill-ring and is later pasted 550 ;;formula that refers to this cell is in the kill-ring and is later pasted
543 ;;;back in. 551 ;;back in.
544 (defun ses-destroy-cell-variable-range (minrow maxrow mincol maxcol) 552 (defun ses-destroy-cell-variable-range (minrow maxrow mincol maxcol)
545 "Destroy buffer-local variables for cells. This is undoable." 553 "Destroy buffer-local variables for cells. This is undoable."
546 (let (sym) 554 (let (sym)
547 (dotimes (row (1+ (- maxrow minrow))) 555 (dotimes (row (1+ (- maxrow minrow)))
548 (dotimes (col (1+ (- maxcol mincol))) 556 (dotimes (col (1+ (- maxcol mincol)))
568 (message format (eval arg)) 576 (message format (eval arg))
569 (setq ses-start-time (float-time))) 577 (setq ses-start-time (float-time)))
570 nil) 578 nil)
571 579
572 580
573 ;;;---------------------------------------------------------------------------- 581 ;;----------------------------------------------------------------------------
574 ;;;; The cells 582 ;; The cells
575 ;;;---------------------------------------------------------------------------- 583 ;;----------------------------------------------------------------------------
576 584
577 (defun ses-set-cell (row col field val) 585 (defun ses-set-cell (row col field val)
578 "Install VAL as the contents for field FIELD (named by a quoted symbol) of 586 "Install VAL as the contents for field FIELD (named by a quoted symbol) of
579 cell (ROW,COL). This is undoable. The cell's data will be updated through 587 cell (ROW,COL). This is undoable. The cell's data will be updated through
580 `post-command-hook'." 588 `post-command-hook'."
632 Any cells that depend on this cell are queued for update after the end of 640 Any cells that depend on this cell are queued for update after the end of
633 processing for the current keystroke, unless the new value is the same as 641 processing for the current keystroke, unless the new value is the same as
634 the old and FORCE is nil." 642 the old and FORCE is nil."
635 (let ((cell (ses-get-cell row col)) 643 (let ((cell (ses-get-cell row col))
636 formula-error printer-error) 644 formula-error printer-error)
637 (let ((symbol (ses-cell-symbol cell)) 645 (let ((oldval (ses-cell-value cell))
638 (oldval (ses-cell-value cell))
639 (formula (ses-cell-formula cell)) 646 (formula (ses-cell-formula cell))
640 newval) 647 newval)
641 (if (eq (car-safe formula) 'ses-safe-formula) 648 (if (eq (car-safe formula) 'ses-safe-formula)
642 (ses-set-cell row col 'formula (ses-safe-formula (cadr formula)))) 649 (ses-set-cell row col 'formula (ses-safe-formula (cadr formula))))
643 (condition-case sig 650 (condition-case sig
715 ;;Can't use save-excursion here: if the cell under point is 722 ;;Can't use save-excursion here: if the cell under point is
716 ;;updated, save-excusion's marker will move past the cell. 723 ;;updated, save-excusion's marker will move past the cell.
717 (goto-char pos))) 724 (goto-char pos)))
718 725
719 726
720 ;;;---------------------------------------------------------------------------- 727 ;;----------------------------------------------------------------------------
721 ;;;; The print area 728 ;; The print area
722 ;;;---------------------------------------------------------------------------- 729 ;;----------------------------------------------------------------------------
723 730
724 (defun ses-in-print-area () 731 (defun ses-in-print-area ()
725 "Returns t if point is in print area of spreadsheet." 732 "Returns t if point is in print area of spreadsheet."
726 (eq (get-text-property (point) 'keymap) 'ses-mode-print-map)) 733 (eq (get-text-property (point) 'keymap) 'ses-mode-print-map))
727 734
728 ;;;We turn off point-motion-hooks and explicitly position the cursor, in case 735 ;;We turn off point-motion-hooks and explicitly position the cursor, in case
729 ;;;the intangible properties have gotten screwed up (e.g., when 736 ;;the intangible properties have gotten screwed up (e.g., when
730 ;;;ses-goto-print is called during a recursive ses-print-cell). 737 ;;ses-goto-print is called during a recursive ses-print-cell).
731 (defun ses-goto-print (row col) 738 (defun ses-goto-print (row col)
732 "Move point to print area for cell (ROW,COL)." 739 "Move point to print area for cell (ROW,COL)."
733 (let ((inhibit-point-motion-hooks t)) 740 (let ((inhibit-point-motion-hooks t))
734 (goto-char (point-min)) 741 (goto-char (point-min))
735 (forward-line row) 742 (forward-line row)
770 (error "Can't use a range"))) 777 (error "Can't use a range")))
771 ((memq 'needrange args) 778 ((memq 'needrange args)
772 (error "Need a range")))) 779 (error "Need a range"))))
773 780
774 (defun ses-print-cell (row col) 781 (defun ses-print-cell (row col)
775 "Format and print the value of cell (ROW,COL) to the print area, using the 782 "Format and print the value of cell (ROW,COL) to the print area.
776 cell's printer function. If the cell's new print form is too wide, it will 783 Use the cell's printer function. If the cell's new print form is too wide,
777 spill over into the following cell, but will not run off the end of the row 784 it will spill over into the following cell, but will not run off the end of the
778 or overwrite the next non-nil field. Result is nil for normal operation, or 785 row or overwrite the next non-nil field. Result is nil for normal operation,
779 the error signal if the printer function failed and the cell was formatted 786 or the error signal if the printer function failed and the cell was formatted
780 with \"%s\". If the cell's value is *skip*, nothing is printed because the 787 with \"%s\". If the cell's value is *skip*, nothing is printed because the
781 preceding cell has spilled over." 788 preceding cell has spilled over."
782 (catch 'ses-print-cell 789 (catch 'ses-print-cell
783 (let* ((cell (ses-get-cell row col)) 790 (let* ((cell (ses-get-cell row col))
784 (value (ses-cell-value cell)) 791 (value (ses-cell-value cell))
946 (backward-char 1) 953 (backward-char 1)
947 (let ((rowcol (ses-sym-rowcol (get-text-property (point) 'intangible)))) 954 (let ((rowcol (ses-sym-rowcol (get-text-property (point) 'intangible))))
948 (ses-print-cell (car rowcol) (cdr rowcol))))) 955 (ses-print-cell (car rowcol) (cdr rowcol)))))
949 956
950 957
951 ;;;---------------------------------------------------------------------------- 958 ;;----------------------------------------------------------------------------
952 ;;;; The data area 959 ;; The data area
953 ;;;---------------------------------------------------------------------------- 960 ;;----------------------------------------------------------------------------
961
962 (defun ses-narrowed-p () (/= (- (point-max) (point-min)) (buffer-size)))
954 963
955 (defun ses-goto-data (def &optional col) 964 (defun ses-goto-data (def &optional col)
956 "Move point to data area for (DEF,COL). If DEF is a row 965 "Move point to data area for (DEF,COL). If DEF is a row
957 number, COL is the column number for a data cell -- otherwise DEF 966 number, COL is the column number for a data cell -- otherwise DEF
958 is one of the symbols ses--col-widths, ses--col-printers, 967 is one of the symbols ses--col-widths, ses--col-printers,
959 ses--default-printer, ses--numrows, or ses--numcols." 968 ses--default-printer, ses--numrows, or ses--numcols."
960 (if (< (point-max) (buffer-size)) 969 (if (ses-narrowed-p)
961 (setq ses--deferred-narrow t)) 970 (setq ses--deferred-narrow t))
962 (widen) 971 (widen)
963 (let ((inhibit-point-motion-hooks t)) ;In case intangible attrs are wrong 972 (let ((inhibit-point-motion-hooks t)) ;In case intangible attrs are wrong
964 (goto-char (point-min)) 973 (goto-char (point-min))
965 (if col 974 (if col
969 (setq def (plist-get ses-paramlines-plist def)) 978 (setq def (plist-get ses-paramlines-plist def))
970 (or def (signal 'args-out-of-range nil)) 979 (or def (signal 'args-out-of-range nil))
971 (forward-line (+ (* ses--numrows (+ ses--numcols 2)) def))))) 980 (forward-line (+ (* ses--numrows (+ ses--numcols 2)) def)))))
972 981
973 (defun ses-set-parameter (def value &optional elem) 982 (defun ses-set-parameter (def value &optional elem)
974 "Sets parameter DEF to VALUE (with undo) and writes the value to the data 983 "Set parameter DEF to VALUE (with undo) and write the value to the data area.
975 area. See `ses-goto-data' for meaning of DEF. Newlines in the data 984 See `ses-goto-data' for meaning of DEF. Newlines in the data are escaped.
976 are escaped. If ELEM is specified, it is the array subscript within DEF to 985 If ELEM is specified, it is the array subscript within DEF to be set to VALUE."
977 be set to VALUE."
978 (save-excursion 986 (save-excursion
979 ;;We call ses-goto-data early, using the old values of numrows and 987 ;;We call ses-goto-data early, using the old values of numrows and
980 ;;numcols in case one of them is being changed. 988 ;;numcols in case one of them is being changed.
981 (ses-goto-data def) 989 (ses-goto-data def)
982 (if elem 990 (if elem
993 def))) 1001 def)))
994 (delete-region (point) (line-end-position)) 1002 (delete-region (point) (line-end-position))
995 (insert (format fmt (symbol-value def)))))) 1003 (insert (format fmt (symbol-value def))))))
996 1004
997 (defun ses-write-cells () 1005 (defun ses-write-cells ()
998 "`ses--deferred-write' is a list of (ROW,COL) for cells to be written from 1006 "Write cells in `ses--deferred-write' from local variables to data area.
999 buffer-local variables to data area. Newlines in the data are escaped." 1007 Newlines in the data are escaped."
1000 (let* ((inhibit-read-only t) 1008 (let* ((inhibit-read-only t)
1001 (print-escape-newlines t) 1009 (print-escape-newlines t)
1002 rowcol row col cell sym formula printer text) 1010 rowcol row col cell sym formula printer text)
1003 (setq ses-start-time (float-time)) 1011 (setq ses-start-time (float-time))
1004 (with-temp-message " " 1012 (with-temp-message " "
1039 (delete-region (point) (line-end-position)) 1047 (delete-region (point) (line-end-position))
1040 (insert text))) 1048 (insert text)))
1041 (message " ")))) 1049 (message " "))))
1042 1050
1043 1051
1044 ;;;---------------------------------------------------------------------------- 1052 ;;----------------------------------------------------------------------------
1045 ;;;; Formula relocation 1053 ;; Formula relocation
1046 ;;;---------------------------------------------------------------------------- 1054 ;;----------------------------------------------------------------------------
1047 1055
1048 (defun ses-formula-references (formula &optional result-so-far) 1056 (defun ses-formula-references (formula &optional result-so-far)
1049 "Produce a list of symbols for cells that this formula's value 1057 "Produce a list of symbols for cells that this formula's value
1050 refers to. For recursive calls, RESULT-SO-FAR is the list being constructed, 1058 refers to. For recursive calls, RESULT-SO-FAR is the list being constructed,
1051 or t to get a wrong-type-argument error when the first reference is found." 1059 or t to get a wrong-type-argument error when the first reference is found."
1282 reform (cdr reform)) 1290 reform (cdr reform))
1283 (ses-cell-set-formula row col (ses-cell-formula row col)))) 1291 (ses-cell-set-formula row col (ses-cell-formula row col))))
1284 (message nil)))) 1292 (message nil))))
1285 1293
1286 1294
1287 ;;;---------------------------------------------------------------------------- 1295 ;;----------------------------------------------------------------------------
1288 ;;;; Undo control 1296 ;; Undo control
1289 ;;;---------------------------------------------------------------------------- 1297 ;;----------------------------------------------------------------------------
1290 1298
1291 (defadvice undo-more (around ses-undo-more activate preactivate) 1299 (defadvice undo-more (around ses-undo-more activate preactivate)
1292 "Define a meaning for conses in buffer-undo-list whose car is a symbol 1300 "Define a meaning for conses in buffer-undo-list whose car is a symbol
1293 other than t or nil. To undo these, apply the car--a function--to the 1301 other than t or nil. To undo these, apply the car--a function--to the
1294 cdr--its arglist." 1302 cdr--its arglist."
1306 (apply (car ses-x) (cdr ses-x))))) 1314 (apply (car ses-x) (cdr ses-x)))))
1307 (if (not (eq major-mode 'ses-mode)) 1315 (if (not (eq major-mode 'ses-mode))
1308 ad-do-it 1316 ad-do-it
1309 ;;Here is some extra code for SES mode. 1317 ;;Here is some extra code for SES mode.
1310 (setq ses--deferred-narrow 1318 (setq ses--deferred-narrow
1311 (or ses--deferred-narrow (< (point-max) (buffer-size)))) 1319 (or ses--deferred-narrow (ses-narrowed-p)))
1312 (widen) 1320 (widen)
1313 (condition-case x 1321 (condition-case x
1314 ad-do-it 1322 ad-do-it
1315 (error 1323 (error
1316 ;;Restore narrow if appropriate 1324 ;;Restore narrow if appropriate
1351 (push `(ses-aset-with-undo ,array ,idx ,(aref array idx)) buffer-undo-list) 1359 (push `(ses-aset-with-undo ,array ,idx ,(aref array idx)) buffer-undo-list)
1352 (aset array idx newval) 1360 (aset array idx newval)
1353 t)) 1361 t))
1354 1362
1355 1363
1356 ;;;---------------------------------------------------------------------------- 1364 ;;----------------------------------------------------------------------------
1357 ;;;; Startup for major mode 1365 ;; Startup for major mode
1358 ;;;---------------------------------------------------------------------------- 1366 ;;----------------------------------------------------------------------------
1359 1367
1360 (defun ses-load () 1368 (defun ses-load ()
1361 "Parse the current buffer and sets up buffer-local variables. Does not 1369 "Parse the current buffer and sets up buffer-local variables. Does not
1362 execute cell formulas or print functions." 1370 execute cell formulas or print functions."
1363 (widen) 1371 (widen)
1364 ;;Read our global parameters, which should be a 3-element list 1372 ;;Read our global parameters, which should be a 3-element list
1365 (goto-char (point-max)) 1373 (goto-char (point-max))
1366 (search-backward ";;; Local Variables:\n" nil t) 1374 (search-backward ";; Local Variables:\n" nil t)
1367 (backward-list 1) 1375 (backward-list 1)
1368 (let ((params (condition-case nil (read (current-buffer)) (error nil))) 1376 (let ((params (condition-case nil (read (current-buffer)) (error nil))))
1369 sym)
1370 (or (and (= (safe-length params) 3) 1377 (or (and (= (safe-length params) 3)
1371 (numberp (car params)) 1378 (numberp (car params))
1372 (numberp (cadr params)) 1379 (numberp (cadr params))
1373 (> (cadr params) 0) 1380 (> (cadr params) 0)
1374 (numberp (nth 2 params)) 1381 (numberp (nth 2 params))
1479 col (1+ col))) 1486 col (1+ col)))
1480 (setq end (+ end (ses-col-width col) 1)) 1487 (setq end (+ end (ses-col-width col) 1))
1481 (put-text-property pos end 'intangible sym))) 1488 (put-text-property pos end 'intangible sym)))
1482 ;;Adding these properties did not actually alter the text 1489 ;;Adding these properties did not actually alter the text
1483 (unless was-modified 1490 (unless was-modified
1484 (set-buffer-modified-p nil) 1491 (restore-buffer-modified-p nil)
1485 (buffer-disable-undo) 1492 (buffer-disable-undo)
1486 (buffer-enable-undo))) 1493 (buffer-enable-undo)))
1487 ;;Create the underlining overlay. It's impossible for (point) to be 2, 1494 ;;Create the underlining overlay. It's impossible for (point) to be 2,
1488 ;;because column A must be at least 1 column wide. 1495 ;;because column A must be at least 1 column wide.
1489 (setq ses--curcell-overlay (make-overlay (1+ (point-min)) (1+ (point-min)))) 1496 (setq ses--curcell-overlay (make-overlay (1+ (point-min)) (1+ (point-min))))
1492 (defun ses-cleanup () 1499 (defun ses-cleanup ()
1493 "Cleanup when changing a buffer from SES mode to something else. Delete 1500 "Cleanup when changing a buffer from SES mode to something else. Delete
1494 overlay, remove special text properties." 1501 overlay, remove special text properties."
1495 (widen) 1502 (widen)
1496 (let ((inhibit-read-only t) 1503 (let ((inhibit-read-only t)
1497 (was-modified (buffer-modified-p)) 1504 (was-modified (buffer-modified-p)))
1498 end)
1499 ;;Delete read-only, keymap, and intangible properties 1505 ;;Delete read-only, keymap, and intangible properties
1500 (set-text-properties (point-min) (point-max) nil) 1506 (set-text-properties (point-min) (point-max) nil)
1501 ;;Delete overlay 1507 ;;Delete overlay
1502 (mapc 'delete-overlay (overlays-in (point-min) (point-max))) 1508 (mapc 'delete-overlay (overlays-in (point-min) (point-max)))
1503 (unless was-modified 1509 (unless was-modified
1637 (unless executing-kbd-macro 1643 (unless executing-kbd-macro
1638 (ding)) 1644 (ding))
1639 (message (error-message-string err)))) 1645 (message (error-message-string err))))
1640 nil) ;Make coverage-tester happy 1646 nil) ;Make coverage-tester happy
1641 1647
1642 (defun ses-header-string-left-offset ()
1643 "Number of characters in left fringe and left scrollbar (if any)."
1644 (let ((left-fringe (round (or (frame-parameter nil 'left-fringe) 0)
1645 (frame-char-width)))
1646 (left-scrollbar (if (not (eq (frame-parameter nil
1647 'vertical-scroll-bars)
1648 'left))
1649 0
1650 (let ((x (frame-parameter nil 'scroll-bar-width)))
1651 ;;Non-toolkil bar is always 14 pixels?
1652 (unless x (setq x 14))
1653 ;;Always round up
1654 (ceiling x (frame-char-width))))))
1655 (+ left-fringe left-scrollbar)))
1656
1657 (defun ses-create-header-string () 1648 (defun ses-create-header-string ()
1658 "Sets up `ses--header-string' as the buffer's header line, based on the 1649 "Set up `ses--header-string' as the buffer's header line.
1659 current set of columns and window-scroll position." 1650 Based on the current set of columns and `window-hscroll' position."
1660 (let* ((left-offset (ses-header-string-left-offset)) 1651 (let ((totwidth (- (window-hscroll)))
1661 (totwidth (- left-offset (window-hscroll))) 1652 result width x)
1662 result width result x)
1663 ;;Leave room for the left-side fringe and scrollbar 1653 ;;Leave room for the left-side fringe and scrollbar
1664 (push (make-string left-offset ? ) result) 1654 (push (propertize " " 'display '((space :align-to 0))) result)
1665 (dotimes (col ses--numcols) 1655 (dotimes (col ses--numcols)
1666 (setq width (ses-col-width col) 1656 (setq width (ses-col-width col)
1667 totwidth (+ totwidth width 1)) 1657 totwidth (+ totwidth width 1))
1668 (if (= totwidth (+ left-offset 1)) 1658 (if (= totwidth 1)
1669 ;;Scrolled so intercolumn space is leftmost 1659 ;;Scrolled so intercolumn space is leftmost
1670 (push " " result)) 1660 (push " " result))
1671 (when (> totwidth (+ left-offset 1)) 1661 (when (> totwidth 1)
1672 (if (> ses--header-row 0) 1662 (if (> ses--header-row 0)
1673 (save-excursion 1663 (save-excursion
1674 (ses-goto-print (1- ses--header-row) col) 1664 (ses-goto-print (1- ses--header-row) col)
1675 (setq x (buffer-substring-no-properties (point) 1665 (setq x (buffer-substring-no-properties (point)
1676 (+ (point) width))) 1666 (+ (point) width)))
1677 (if (>= width (- totwidth left-offset)) 1667 ;; Strip trailing space.
1678 (setq x (substring x (- width totwidth left-offset -1)))) 1668 (if (string-match "[ \t]+\\'" x)
1679 (push (propertize x 'face ses-box-prop) result)) 1669 (setq x (substring x 0 (match-beginning 0))))
1680 (setq x (ses-column-letter col)) 1670 ;; Cut off excess text.
1671 (if (>= (length x) totwidth)
1672 (setq x (substring x 0 (- totwidth -1)))))
1673 (setq x (ses-column-letter col)))
1681 (push (propertize x 'face ses-box-prop) result) 1674 (push (propertize x 'face ses-box-prop) result)
1682 (push (propertize (make-string (- width (length x)) ?.) 1675 (push (propertize "."
1683 'display `((space :align-to ,(1- totwidth))) 1676 'display `((space :align-to ,(1- totwidth)))
1684 'face ses-box-prop) 1677 'face ses-box-prop)
1685 result)) 1678 result)
1686 ;;Allow the following space to be squished to make room for the 3-D box 1679 ;;Allow the following space to be squished to make room for the 3-D box
1687 ;;Coverage test ignores properties, thinks this is always a space! 1680 ;;Coverage test ignores properties, thinks this is always a space!
1688 (push (1value (propertize " " 'display `((space :align-to ,totwidth)))) 1681 (push (1value (propertize " " 'display `((space :align-to ,totwidth))))
1689 result))) 1682 result)))
1690 (if (> ses--header-row 0) 1683 (if (> ses--header-row 0)
1692 'display '((height (- 1)))) 1685 'display '((height (- 1))))
1693 result)) 1686 result))
1694 (setq ses--header-string (apply 'concat (nreverse result))))) 1687 (setq ses--header-string (apply 'concat (nreverse result)))))
1695 1688
1696 1689
1697 ;;;---------------------------------------------------------------------------- 1690 ;;----------------------------------------------------------------------------
1698 ;;;; Redisplay and recalculation 1691 ;; Redisplay and recalculation
1699 ;;;---------------------------------------------------------------------------- 1692 ;;----------------------------------------------------------------------------
1700 1693
1701 (defun ses-jump (sym) 1694 (defun ses-jump (sym)
1702 "Move point to cell SYM." 1695 "Move point to cell SYM."
1703 (interactive "SJump to cell: ") 1696 (interactive "SJump to cell: ")
1704 (let ((rowcol (ses-sym-rowcol sym))) 1697 (let ((rowcol (ses-sym-rowcol sym)))
1812 (defun ses-reconstruct-all () 1805 (defun ses-reconstruct-all ()
1813 "Reconstruct buffer based on cell data stored in Emacs variables." 1806 "Reconstruct buffer based on cell data stored in Emacs variables."
1814 (interactive "*") 1807 (interactive "*")
1815 (ses-begin-change) 1808 (ses-begin-change)
1816 ;;Reconstruct reference lists. 1809 ;;Reconstruct reference lists.
1817 (let (refs x yrow ycol) 1810 (let (x yrow ycol)
1818 ;;Delete old reference lists 1811 ;;Delete old reference lists
1819 (ses-dotimes-msg (row ses--numrows) "Deleting references..." 1812 (ses-dotimes-msg (row ses--numrows) "Deleting references..."
1820 (dotimes (col ses--numcols) 1813 (dotimes (col ses--numcols)
1821 (ses-set-cell row col 'references nil))) 1814 (ses-set-cell row col 'references nil)))
1822 ;;Create new reference lists 1815 ;;Create new reference lists
1828 ycol (cdr x)) 1821 ycol (cdr x))
1829 (ses-set-cell yrow ycol 'references 1822 (ses-set-cell yrow ycol 'references
1830 (cons (ses-cell-symbol row col) 1823 (cons (ses-cell-symbol row col)
1831 (ses-cell-references yrow ycol))))))) 1824 (ses-cell-references yrow ycol)))))))
1832 ;;Delete everything and reconstruct basic data area 1825 ;;Delete everything and reconstruct basic data area
1833 (if (< (point-max) (buffer-size)) 1826 (if (ses-narrowed-p)
1834 (setq ses--deferred-narrow t)) 1827 (setq ses--deferred-narrow t))
1835 (widen) 1828 (widen)
1836 (let ((inhibit-read-only t)) 1829 (let ((inhibit-read-only t))
1837 (goto-char (point-max)) 1830 (goto-char (point-max))
1838 (if (search-backward ";;; Local Variables:\n" nil t) 1831 (if (search-backward ";; Local Variables:\n" nil t)
1839 (delete-region (point-min) (point)) 1832 (delete-region (point-min) (point))
1840 ;;Buffer is quite screwed up - can't even save the user-specified locals 1833 ;;Buffer is quite screwed up - can't even save the user-specified locals
1841 (delete-region (point-min) (point-max)) 1834 (delete-region (point-min) (point-max))
1842 (insert ses-initial-file-trailer) 1835 (insert ses-initial-file-trailer)
1843 (goto-char (point-min))) 1836 (goto-char (point-min)))
1860 (ses-setup) 1853 (ses-setup)
1861 (ses-recalculate-all) 1854 (ses-recalculate-all)
1862 (goto-char (point-min))) 1855 (goto-char (point-min)))
1863 1856
1864 1857
1865 ;;;---------------------------------------------------------------------------- 1858 ;;----------------------------------------------------------------------------
1866 ;;;; Input of cell formulas 1859 ;; Input of cell formulas
1867 ;;;---------------------------------------------------------------------------- 1860 ;;----------------------------------------------------------------------------
1868 1861
1869 (defun ses-edit-cell (row col newval) 1862 (defun ses-edit-cell (row col newval)
1870 "Display current cell contents in minibuffer, for editing. Returns nil if 1863 "Display current cell contents in minibuffer, for editing. Returns nil if
1871 cell formula was unsafe and user declined confirmation." 1864 cell formula was unsafe and user declined confirmation."
1872 (interactive 1865 (interactive
1966 (ses-set-curcell) 1959 (ses-set-curcell)
1967 (let ((rowcol (ses-sym-rowcol ses--curcell))) 1960 (let ((rowcol (ses-sym-rowcol ses--curcell)))
1968 (ses-clear-cell (car rowcol) (cdr rowcol)))))) 1961 (ses-clear-cell (car rowcol) (cdr rowcol))))))
1969 1962
1970 1963
1971 ;;;---------------------------------------------------------------------------- 1964 ;;----------------------------------------------------------------------------
1972 ;;;; Input of cell-printer functions 1965 ;; Input of cell-printer functions
1973 ;;;---------------------------------------------------------------------------- 1966 ;;----------------------------------------------------------------------------
1974 1967
1975 (defun ses-read-printer (prompt default) 1968 (defun ses-read-printer (prompt default)
1976 "Common code for `ses-read-cell-printer', `ses-read-column-printer', and `ses-read-default-printer'. 1969 "Common code for `ses-read-cell-printer', `ses-read-column-printer', and `ses-read-default-printer'.
1977 PROMPT should end with \": \". Result is t if operation was cancelled." 1970 PROMPT should end with \": \". Result is t if operation was cancelled."
1978 (barf-if-buffer-read-only) 1971 (barf-if-buffer-read-only)
2007 one argument, or a symbol that names a function of one argument. In the 2000 one argument, or a symbol that names a function of one argument. In the
2008 latter two cases, the function's result should be either a string (will be 2001 latter two cases, the function's result should be either a string (will be
2009 right-justified) or a list of one string (will be left-justified)." 2002 right-justified) or a list of one string (will be left-justified)."
2010 (interactive 2003 (interactive
2011 (let ((default t) 2004 (let ((default t)
2012 prompt x) 2005 x)
2013 (ses-check-curcell 'range) 2006 (ses-check-curcell 'range)
2014 ;;Default is none if not all cells in range have same printer 2007 ;;Default is none if not all cells in range have same printer
2015 (catch 'ses-read-cell-printer 2008 (catch 'ses-read-cell-printer
2016 (ses-dorange ses--curcell 2009 (ses-dorange ses--curcell
2017 (setq x (ses-cell-printer row col)) 2010 (setq x (ses-cell-printer row col))
2057 (ses-begin-change) 2050 (ses-begin-change)
2058 (ses-set-parameter 'ses--default-printer newval) 2051 (ses-set-parameter 'ses--default-printer newval)
2059 (ses-reprint-all t))) 2052 (ses-reprint-all t)))
2060 2053
2061 2054
2062 ;;;---------------------------------------------------------------------------- 2055 ;;----------------------------------------------------------------------------
2063 ;;;; Spreadsheet size adjustments 2056 ;; Spreadsheet size adjustments
2064 ;;;---------------------------------------------------------------------------- 2057 ;;----------------------------------------------------------------------------
2065 2058
2066 (defun ses-insert-row (count) 2059 (defun ses-insert-row (count)
2067 "Insert a new row before the current one. With prefix, insert COUNT rows 2060 "Insert a new row before the current one. With prefix, insert COUNT rows
2068 before current one." 2061 before current one."
2069 (interactive "*p") 2062 (interactive "*p")
2083 (ses-dotimes-msg (x count) "Inserting row..." 2076 (ses-dotimes-msg (x count) "Inserting row..."
2084 ;;Create a row of empty cells. The `symbol' fields will be set by 2077 ;;Create a row of empty cells. The `symbol' fields will be set by
2085 ;;the call to ses-relocate-all. 2078 ;;the call to ses-relocate-all.
2086 (setq newrow (make-vector ses--numcols nil)) 2079 (setq newrow (make-vector ses--numcols nil))
2087 (dotimes (col ses--numcols) 2080 (dotimes (col ses--numcols)
2088 (aset newrow col (make-vector ses-cell-size nil))) 2081 (aset newrow col (ses-make-cell)))
2089 (setq ses--cells (ses-vector-insert ses--cells row newrow)) 2082 (setq ses--cells (ses-vector-insert ses--cells row newrow))
2090 (push `(ses-vector-delete ses--cells ,row 1) buffer-undo-list) 2083 (push `(ses-vector-delete ses--cells ,row 1) buffer-undo-list)
2091 (insert ses--blank-line)) 2084 (insert ses--blank-line))
2092 ;;Insert empty lines in cell data area (will be replaced by 2085 ;;Insert empty lines in cell data area (will be replaced by
2093 ;;ses-relocate-all) 2086 ;;ses-relocate-all)
2120 (interactive "*p") 2113 (interactive "*p")
2121 (ses-check-curcell) 2114 (ses-check-curcell)
2122 (or (> count 0) (signal 'args-out-of-range nil)) 2115 (or (> count 0) (signal 'args-out-of-range nil))
2123 (let ((inhibit-quit t) 2116 (let ((inhibit-quit t)
2124 (inhibit-read-only t) 2117 (inhibit-read-only t)
2125 (row (car (ses-sym-rowcol ses--curcell))) 2118 (row (car (ses-sym-rowcol ses--curcell))))
2126 pos)
2127 (setq count (min count (- ses--numrows row))) 2119 (setq count (min count (- ses--numrows row)))
2128 (ses-begin-change) 2120 (ses-begin-change)
2129 (ses-set-parameter 'ses--numrows (- ses--numrows count)) 2121 (ses-set-parameter 'ses--numrows (- ses--numrows count))
2130 ;;Delete lines from print area 2122 ;;Delete lines from print area
2131 (ses-goto-print row 0) 2123 (ses-goto-print row 0)
2147 ;;Reconstruct attributes 2139 ;;Reconstruct attributes
2148 (ses-setup) 2140 (ses-setup)
2149 (ses-jump-safe ses--curcell)) 2141 (ses-jump-safe ses--curcell))
2150 2142
2151 (defun ses-insert-column (count &optional col width printer) 2143 (defun ses-insert-column (count &optional col width printer)
2152 "Insert a new column before COL (default is the current one). With prefix, 2144 "Insert a new column before COL (default is the current one).
2153 insert COUNT columns before current one. If COL is specified, the new 2145 With prefix, insert COUNT columns before current one.
2154 column(s) get the specified WIDTH and PRINTER (otherwise they're taken from 2146 If COL is specified, the new column(s) get the specified WIDTH and PRINTER
2155 the current column)." 2147 \(otherwise they're taken from the current column)."
2156 (interactive "*p") 2148 (interactive "*p")
2157 (ses-check-curcell) 2149 (ses-check-curcell)
2158 (or (> count 0) (signal 'args-out-of-range nil)) 2150 (or (> count 0) (signal 'args-out-of-range nil))
2159 (or col 2151 (or col
2160 (setq col (cdr (ses-sym-rowcol ses--curcell)) 2152 (setq col (cdr (ses-sym-rowcol ses--curcell))
2179 (and (< (1+ col) ses--numcols) (eq (ses-cell-value row col) '*skip*) 2171 (and (< (1+ col) ses--numcols) (eq (ses-cell-value row col) '*skip*)
2180 ;;Inserting in the middle of a spill-over 2172 ;;Inserting in the middle of a spill-over
2181 (setq has-skip t)) 2173 (setq has-skip t))
2182 (ses-aset-with-undo ses--cells row 2174 (ses-aset-with-undo ses--cells row
2183 (ses-vector-insert (aref ses--cells row) 2175 (ses-vector-insert (aref ses--cells row)
2184 col 2176 col (ses-make-cell)))
2185 (make-vector ses-cell-size nil)))
2186 ;;Insert empty lines in cell data area (will be replaced by 2177 ;;Insert empty lines in cell data area (will be replaced by
2187 ;;ses-relocate-all) 2178 ;;ses-relocate-all)
2188 (ses-goto-data row col) 2179 (ses-goto-data row col)
2189 (insert ?\n)) 2180 (insert ?\n))
2190 ;;Insert column width and printer 2181 ;;Insert column width and printer
2215 (or (> count 0) (signal 'args-out-of-range nil)) 2206 (or (> count 0) (signal 'args-out-of-range nil))
2216 (let ((inhibit-quit t) 2207 (let ((inhibit-quit t)
2217 (inhibit-read-only t) 2208 (inhibit-read-only t)
2218 (rowcol (ses-sym-rowcol ses--curcell)) 2209 (rowcol (ses-sym-rowcol ses--curcell))
2219 (width 0) 2210 (width 0)
2220 new col origrow has-skip) 2211 col origrow has-skip)
2221 (setq origrow (car rowcol) 2212 (setq origrow (car rowcol)
2222 col (cdr rowcol) 2213 col (cdr rowcol)
2223 count (min count (- ses--numcols col))) 2214 count (min count (- ses--numcols col)))
2224 (if (= count ses--numcols) 2215 (if (= count ses--numcols)
2225 (error "Can't delete all columns!")) 2216 (error "Can't delete all columns!"))
2318 (ses-set-parameter 'ses--col-widths newwidth col)) 2309 (ses-set-parameter 'ses--col-widths newwidth col))
2319 (dotimes (row ses--numrows) 2310 (dotimes (row ses--numrows)
2320 (ses-print-cell-new-width row col)))) 2311 (ses-print-cell-new-width row col))))
2321 2312
2322 2313
2323 ;;;---------------------------------------------------------------------------- 2314 ;;----------------------------------------------------------------------------
2324 ;;;; Cut and paste, import and export 2315 ;; Cut and paste, import and export
2325 ;;;---------------------------------------------------------------------------- 2316 ;;----------------------------------------------------------------------------
2326 2317
2327 (defadvice copy-region-as-kill (around ses-copy-region-as-kill 2318 (defadvice copy-region-as-kill (around ses-copy-region-as-kill
2328 activate preactivate) 2319 activate preactivate)
2329 "It doesn't make sense to copy read-only or intangible attributes into the 2320 "It doesn't make sense to copy read-only or intangible attributes into the
2330 kill ring. It probably doesn't make sense to copy keymap properties. 2321 kill ring. It probably doesn't make sense to copy keymap properties.
2652 (push "\n" result)))) 2643 (push "\n" result))))
2653 (setq result (apply 'concat (nreverse result))) 2644 (setq result (apply 'concat (nreverse result)))
2654 (kill-new result))) 2645 (kill-new result)))
2655 2646
2656 2647
2657 ;;;---------------------------------------------------------------------------- 2648 ;;----------------------------------------------------------------------------
2658 ;;;; Other user commands 2649 ;; Other user commands
2659 ;;;---------------------------------------------------------------------------- 2650 ;;----------------------------------------------------------------------------
2660 2651
2661 (defun ses-unset-header-row () 2652 (defun ses-unset-header-row ()
2662 "Select the default header row." 2653 "Select the default header row."
2663 (interactive) 2654 (interactive)
2664 (ses-set-header-row 0)) 2655 (ses-set-header-row 0))
2827 (interactive "*e") 2818 (interactive "*e")
2828 (mouse-set-point event) 2819 (mouse-set-point event)
2829 (ses-insert-ses-range)) 2820 (ses-insert-ses-range))
2830 2821
2831 2822
2832 ;;;---------------------------------------------------------------------------- 2823 ;;----------------------------------------------------------------------------
2833 ;;;; Checking formulas for safety 2824 ;; Checking formulas for safety
2834 ;;;---------------------------------------------------------------------------- 2825 ;;----------------------------------------------------------------------------
2835 2826
2836 (defun ses-safe-printer (printer) 2827 (defun ses-safe-printer (printer)
2837 "Returns PRINTER if safe, or the substitute printer `ses-unsafe' otherwise." 2828 "Returns PRINTER if safe, or the substitute printer `ses-unsafe' otherwise."
2838 (if (or (stringp printer) 2829 (if (or (stringp printer)
2839 (stringp (car-safe printer)) 2830 (stringp (car-safe printer))
2860 t 2851 t
2861 (y-or-n-p (format "Formula %S\nmight be unsafe %S. Process it? " 2852 (y-or-n-p (format "Formula %S\nmight be unsafe %S. Process it? "
2862 formula checker))))) 2853 formula checker)))))
2863 2854
2864 2855
2865 ;;;---------------------------------------------------------------------------- 2856 ;;----------------------------------------------------------------------------
2866 ;;;; Standard formulas 2857 ;; Standard formulas
2867 ;;;---------------------------------------------------------------------------- 2858 ;;----------------------------------------------------------------------------
2868 2859
2869 (defmacro ses-range (from to) 2860 (defmacro ses-range (from to)
2870 "Expands to a list of cell-symbols for the range. The range automatically 2861 "Expands to a list of cell-symbols for the range. The range automatically
2871 expands to include any new row or column inserted into its middle. The SES 2862 expands to include any new row or column inserted into its middle. The SES
2872 library code specifically looks for the symbol `ses-range', so don't create an 2863 library code specifically looks for the symbol `ses-range', so don't create an
2878 2869
2879 (defun ses-delete-blanks (&rest args) 2870 (defun ses-delete-blanks (&rest args)
2880 "Return ARGS reversed, with the blank elements (nil and *skip*) removed." 2871 "Return ARGS reversed, with the blank elements (nil and *skip*) removed."
2881 (let (result) 2872 (let (result)
2882 (dolist (cur args) 2873 (dolist (cur args)
2883 (and cur (not (eq cur '*skip*)) 2874 (unless (memq cur '(nil *skip*))
2884 (push cur result))) 2875 (push cur result)))
2885 result)) 2876 result))
2886 2877
2887 (defun ses+ (&rest args) 2878 (defun ses+ (&rest args)
2888 "Compute the sum of the arguments, ignoring blanks." 2879 "Compute the sum of the arguments, ignoring blanks."
2889 (apply '+ (apply 'ses-delete-blanks args))) 2880 (apply '+ (apply 'ses-delete-blanks args)))
2914 ;;All standard formulas are safe 2905 ;;All standard formulas are safe
2915 (dolist (x '(ses-range ses-delete-blanks ses+ ses-average ses-select)) 2906 (dolist (x '(ses-range ses-delete-blanks ses+ ses-average ses-select))
2916 (put x 'side-effect-free t)) 2907 (put x 'side-effect-free t))
2917 2908
2918 2909
2919 ;;;---------------------------------------------------------------------------- 2910 ;;----------------------------------------------------------------------------
2920 ;;;; Standard print functions 2911 ;; Standard print functions
2921 ;;;---------------------------------------------------------------------------- 2912 ;;----------------------------------------------------------------------------
2922 2913
2923 ;;These functions use the variables 'row' and 'col' that are 2914 ;;These functions use the variables 'row' and 'col' that are
2924 ;;dynamically bound by ses-print-cell. We define these varables at 2915 ;;dynamically bound by ses-print-cell. We define these varables at
2925 ;;compile-time to make the compiler happy. 2916 ;;compile-time to make the compiler happy.
2926 (eval-when-compile 2917 (eval-when-compile
2980 (dolist (x (cons 'ses-unsafe ses-standard-printer-functions)) 2971 (dolist (x (cons 'ses-unsafe ses-standard-printer-functions))
2981 (put x 'side-effect-free t)) 2972 (put x 'side-effect-free t))
2982 2973
2983 (provide 'ses) 2974 (provide 'ses)
2984 2975
2985 ;;; arch-tag: 88c1ccf0-4293-4824-8c5d-0757b52217f3 2976 ;; arch-tag: 88c1ccf0-4293-4824-8c5d-0757b52217f3
2986 ;; ses.el ends here. 2977 ;;; ses.el ends here