Commit 94be2532 authored by Jonathan Yavner's avatar Jonathan Yavner
Browse files

Delete function ses-build-load-map and distribute its functions to

defconst's for the three maps.  Add menus.  Use "ses--" prefixes for
buffer-local variables.  Use (point-min) instead of 1, even when we know the
buffer is unnarrowed.  New function ses-read-number duplicates some code
from interactive "N" spec.
parent 84456793
;;;; ses.el -- Simple Emacs Spreadsheet ;;; ses.el -- Simple Emacs Spreadsheet
;; Copyright (C) 2002,03,04 Free Software Foundation, Inc. ;; Copyright (C) 2002,03,04 Free Software Foundation, Inc.
...@@ -24,11 +24,12 @@ ...@@ -24,11 +24,12 @@
;; Boston, MA 02111-1307, USA. ;; Boston, MA 02111-1307, USA.
;;; To-do list: ;;; To-do list:
;; * Use $ or … for truncated fields
;; * Add command to make a range of columns be temporarily invisible.
;; * Allow paste of one cell to a range of cells -- copy formula to each.
;; * Do something about control characters & octal codes in cell print ;; * Do something about control characters & octal codes in cell print
;; areas. Currently they distort the columnar appearance, but fixing them ;; areas. Use string-width?
;; seems like too much work? Use text-char-description?
;; * Input validation functions. How specified? ;; * Input validation functions. How specified?
;; * Menubar and popup menus.
;; * Faces (colors & styles) in print cells. ;; * Faces (colors & styles) in print cells.
;; * Move a column by dragging its letter in the header line. ;; * Move a column by dragging its letter in the header line.
;; * Left-margin column for row number. ;; * Left-margin column for row number.
...@@ -87,16 +88,119 @@ usually runs a cursor-movement function. Each function is called with ARG=1." ...@@ -87,16 +88,119 @@ usually runs a cursor-movement function. Each function is called with ARG=1."
(defvar ses-read-printer-history nil (defvar ses-read-printer-history nil
"List of printer functions that have been typed in.") "List of printer functions that have been typed in.")
(defvar ses-mode-map nil (easy-menu-define ses-header-line-menu nil
"Local keymap for Simple Emacs Spreadsheet.") "Context menu when mouse-3 is used on the header-line in an SES buffer."
'("SES header row"
["Set current row" ses-set-header-row t]
["Unset row" ses-unset-header-row (> header-row 0)]))
(defvar ses-mode-print-map nil (defconst ses-mode-map
"Local keymap for SES print area.") (let ((keys `("\C-c\M-\C-l" ses-reconstruct-all
"\C-c\C-l" ses-recalculate-all
"\C-c\C-n" ses-renarrow-buffer
"\C-c\C-c" ses-recalculate-cell
"\C-c\M-\C-s" ses-sort-column
"\C-c\M-\C-h" ses-set-header-row
"\C-c\C-t" ses-truncate-cell
"\C-c\C-j" ses-jump
"\C-c\C-p" ses-read-default-printer
"\M-\C-l" ses-reprint-all
[?\S-\C-l] ses-reprint-all
[header-line down-mouse-3] ,ses-header-line-menu
[header-line mouse-2] ses-sort-column-click))
(newmap (make-sparse-keymap)))
(while keys
(define-key (1value newmap) (car keys) (cadr keys))
(setq keys (cddr keys)))
newmap)
"Local keymap for Simple Emacs Spreadsheet.")
(defvar ses-mode-edit-map nil (easy-menu-define ses-menu ses-mode-map
"Menu bar menu for SES."
'("SES"
["Insert row" ses-insert-row (ses-in-print-area)]
["Delete row" ses-delete-row (ses-in-print-area)]
["Insert column" ses-insert-column (ses-in-print-area)]
["Delete column" ses-delete-column (ses-in-print-area)]
["Set column printer" ses-read-column-printer t]
["Set column width" ses-set-column-width t]
["Set default printer" ses-read-default-printer t]
["Jump to cell" ses-jump t]
["Set cell printer" ses-read-cell-printer t]
["Recalculate cell" ses-recalculate-cell t]
["Truncate cell display" ses-truncate-cell t]
["Export values" ses-export-tsv t]
["Export formulas" ses-export-tsf t]))
(defconst ses-mode-edit-map
(let ((keys '("\C-c\C-r" ses-insert-range
"\C-c\C-s" ses-insert-ses-range
[S-mouse-3] ses-insert-range-click
[C-S-mouse-3] ses-insert-ses-range-click
"\M-\C-i" lisp-complete-symbol))
(newmap (make-sparse-keymap)))
(set-keymap-parent newmap minibuffer-local-map)
(while keys
(define-key newmap (car keys) (cadr keys))
(setq keys (cddr keys)))
newmap)
"Local keymap for SES minibuffer cell-editing.") "Local keymap for SES minibuffer cell-editing.")
;Key map used for 'x' key. ;Local keymap for SES print area
(defalias 'ses-mode-print-map
(let ((keys '([backtab] backward-char
[tab] ses-forward-or-insert
"\C-i" ses-forward-or-insert ;Needed for ses-coverage.el?
"\M-o" ses-insert-column
"\C-o" ses-insert-row
"\C-m" ses-edit-cell
"\M-k" ses-delete-column
"\M-y" ses-yank-pop
"\C-k" ses-delete-row
"\C-j" ses-append-row-jump-first-column
"\M-h" ses-mark-row
"\M-H" ses-mark-column
"\C-d" ses-clear-cell-forward
"\C-?" ses-clear-cell-backward
"(" ses-read-cell
"\"" ses-read-cell
"'" ses-read-symbol
"=" ses-edit-cell
"j" ses-jump
"p" ses-read-cell-printer
"w" ses-set-column-width
"x" ses-export-keymap
"\M-p" ses-read-column-printer))
(repl '(;;We'll replace these wherever they appear in the keymap
clipboard-kill-region ses-kill-override
end-of-line ses-end-of-line
kill-line ses-delete-row
kill-region ses-kill-override
open-line ses-insert-row))
(numeric "0123456789.-")
(newmap (make-keymap)))
;;Get rid of printables
(suppress-keymap newmap t)
;;These keys insert themselves as the beginning of a numeric value
(dotimes (x (length numeric))
(define-key newmap (substring numeric x (1+ x)) 'ses-read-cell))
;;Override these global functions wherever they're bound
(while repl
(substitute-key-definition (car repl) (cadr repl) newmap
(current-global-map))
(setq repl (cddr repl)))
;;Apparently substitute-key-definition doesn't catch this?
(define-key newmap [(menu-bar) edit cut] 'ses-kill-override)
;;Define our other local keys
(while keys
(define-key newmap (car keys) (cadr keys))
(setq keys (cddr keys)))
newmap))
;;Helptext for ses-mode wants keymap as variable, not function
(defconst ses-mode-print-map (symbol-function 'ses-mode-print-map))
;;Key map used for 'x' key.
(defalias 'ses-export-keymap (defalias 'ses-export-keymap
(let ((map (make-sparse-keymap "SES export"))) (let ((map (make-sparse-keymap "SES export")))
(define-key map "T" (cons " tab-formulas" 'ses-export-tsf)) (define-key map "T" (cons " tab-formulas" 'ses-export-tsf))
...@@ -132,8 +236,9 @@ usually runs a cursor-movement function. Each function is called with ARG=1." ...@@ -132,8 +236,9 @@ usually runs a cursor-movement function. Each function is called with ARG=1."
REFERENCES.") REFERENCES.")
(defconst ses-paramlines-plist (defconst ses-paramlines-plist
'(column-widths 2 col-printers 3 default-printer 4 header-row 5 '(ses--col-widths 2 ses--col-printers 3 ses--default-printer 4
file-format 8 numrows 9 numcols 10) ses--header-row 5 ses--file-format 8 ses--numrows 9
ses--numcols 10)
"Offsets from last cell line to various parameter lines in the data area "Offsets from last cell line to various parameter lines in the data area
of a spreadsheet.") of a spreadsheet.")
...@@ -150,11 +255,13 @@ default printer and then modify its output.") ...@@ -150,11 +255,13 @@ default printer and then modify its output.")
(eval-and-compile (eval-and-compile
(defconst ses-localvars (defconst ses-localvars
'(blank-line cells col-printers column-widths curcell curcell-overlay '(ses--blank-line ses--cells ses--col-printers ses--col-widths ses--curcell
default-printer deferred-narrow deferred-recalc deferred-write ses--curcell-overlay ses--default-printer ses--deferred-narrow
file-format header-hscroll header-row header-string linewidth ses--deferred-recalc ses--deferred-write ses--file-format
mode-line-process next-line-add-newlines numcols numrows ses--header-hscroll ses--header-row ses--header-string ses--linewidth
symbolic-formulas transient-mark-mode) ses--numcols ses--numrows ses--symbolic-formulas
;;Global variables that we override
mode-line-process next-line-add-newlines transient-mark-mode)
"Buffer-local variables used by SES.")) "Buffer-local variables used by SES."))
;;When compiling, create all the buffer locals and give them values ;;When compiling, create all the buffer locals and give them values
...@@ -195,7 +302,7 @@ when to emit a progress message.") ...@@ -195,7 +302,7 @@ when to emit a progress message.")
(defmacro ses-get-cell (row col) (defmacro ses-get-cell (row col)
"Return the cell structure that stores information about cell (ROW,COL)." "Return the cell structure that stores information about cell (ROW,COL)."
`(aref (aref cells ,row) ,col)) `(aref (aref ses--cells ,row) ,col))
(defmacro ses-cell-symbol (row &optional col) (defmacro ses-cell-symbol (row &optional col)
"From a CELL or a pair (ROW,COL), get the symbol that names the local-variable holding its value. (0,0) => A1." "From a CELL or a pair (ROW,COL), get the symbol that names the local-variable holding its value. (0,0) => A1."
...@@ -220,11 +327,11 @@ functions refer to its value." ...@@ -220,11 +327,11 @@ functions refer to its value."
(defmacro ses-col-width (col) (defmacro ses-col-width (col)
"Return the width for column COL." "Return the width for column COL."
`(aref column-widths ,col)) `(aref ses--col-widths ,col))
(defmacro ses-col-printer (col) (defmacro ses-col-printer (col)
"Return the default printer for column COL." "Return the default printer for column COL."
`(aref col-printers ,col)) `(aref ses--col-printers ,col))
(defmacro ses-sym-rowcol (sym) (defmacro ses-sym-rowcol (sym)
"From a cell-symbol SYM, gets the cons (row . col). A1 => (0 . 0). Result "From a cell-symbol SYM, gets the cons (row . col). A1 => (0 . 0). Result
...@@ -246,7 +353,7 @@ PRINTER are deferred until first use." ...@@ -246,7 +353,7 @@ PRINTER are deferred until first use."
(stringp printer) (stringp printer)
(eq safe-functions t) (eq safe-functions t)
(setq printer `(ses-safe-printer ,printer))) (setq printer `(ses-safe-printer ,printer)))
(aset (aref cells (car rowcol)) (aset (aref ses--cells (car rowcol))
(cdr rowcol) (cdr rowcol)
(vector sym formula printer references))) (vector sym formula printer references)))
(set sym value) (set sym value)
...@@ -255,39 +362,39 @@ PRINTER are deferred until first use." ...@@ -255,39 +362,39 @@ PRINTER are deferred until first use."
(defmacro ses-column-widths (widths) (defmacro ses-column-widths (widths)
"Load the vector of column widths from the spreadsheet file. This is a "Load the vector of column widths from the spreadsheet file. This is a
macro to prevent propagate-on-load viruses." macro to prevent propagate-on-load viruses."
(or (and (vectorp widths) (= (length widths) numcols)) (or (and (vectorp widths) (= (length widths) ses--numcols))
(error "Bad column-width vector")) (error "Bad column-width vector"))
;;To save time later, we also calculate the total width of each line in the ;;To save time later, we also calculate the total width of each line in the
;;print area (excluding the terminating newline) ;;print area (excluding the terminating newline)
(setq column-widths widths (setq ses--col-widths widths
linewidth (apply '+ -1 (mapcar '1+ widths)) ses--linewidth (apply '+ -1 (mapcar '1+ widths))
blank-line (concat (make-string linewidth ? ) "\n")) ses--blank-line (concat (make-string ses--linewidth ? ) "\n"))
t) t)
(defmacro ses-column-printers (printers) (defmacro ses-column-printers (printers)
"Load the vector of column printers from the spreadsheet file and checks "Load the vector of column printers from the spreadsheet file and checks
them for safety. This is a macro to prevent propagate-on-load viruses." them for safety. This is a macro to prevent propagate-on-load viruses."
(or (and (vectorp printers) (= (length printers) numcols)) (or (and (vectorp printers) (= (length printers) ses--numcols))
(error "Bad column-printers vector")) (error "Bad column-printers vector"))
(dotimes (x numcols) (dotimes (x ses--numcols)
(aset printers x (ses-safe-printer (aref printers x)))) (aset printers x (ses-safe-printer (aref printers x))))
(setq col-printers printers) (setq ses--col-printers printers)
(mapc 'ses-printer-record printers) (mapc 'ses-printer-record printers)
t) t)
(defmacro ses-default-printer (def) (defmacro ses-default-printer (def)
"Load the global default printer from the spreadsheet file and checks it "Load the global default printer from the spreadsheet file and checks it
for safety. This is a macro to prevent propagate-on-load viruses." for safety. This is a macro to prevent propagate-on-load viruses."
(setq default-printer (ses-safe-printer def)) (setq ses--default-printer (ses-safe-printer def))
(ses-printer-record def) (ses-printer-record def)
t) t)
(defmacro ses-header-row (row) (defmacro ses-header-row (row)
"Load the header row from the spreadsheet file and checks it "Load the header row from the spreadsheet file and checks it
for safety. This is a macro to prevent propagate-on-load viruses." for safety. This is a macro to prevent propagate-on-load viruses."
(or (and (wholenump row) (< row numrows)) (or (and (wholenump row) (< row ses--numrows))
(error "Bad header-row")) (error "Bad header-row"))
(setq header-row row) (setq ses--header-row row)
t) t)
(defmacro ses-dotimes-msg (spec msg &rest body) (defmacro ses-dotimes-msg (spec msg &rest body)
...@@ -405,7 +512,7 @@ checking that it is a valid printer function." ...@@ -405,7 +512,7 @@ checking that it is a valid printer function."
for this spreadsheet." for this spreadsheet."
(when (and (eq (car-safe formula) 'quote) (when (and (eq (car-safe formula) 'quote)
(symbolp (cadr formula))) (symbolp (cadr formula)))
(add-to-list 'symbolic-formulas (add-to-list 'ses--symbolic-formulas
(list (symbol-name (cadr formula)))))) (list (symbol-name (cadr formula))))))
(defun ses-column-letter (col) (defun ses-column-letter (col)
...@@ -451,7 +558,7 @@ for this spreadsheet." ...@@ -451,7 +558,7 @@ for this spreadsheet."
"Flags the header string for update. Upon undo, the header string will be "Flags the header string for update. Upon undo, the header string will be
updated again." updated again."
(push '(ses-reset-header-string) buffer-undo-list) (push '(ses-reset-header-string) buffer-undo-list)
(setq header-hscroll -1)) (setq ses--header-hscroll -1))
;;Split this code off into a function to avoid coverage-testing difficulties ;;Split this code off into a function to avoid coverage-testing difficulties
(defun ses-time-check (format arg) (defun ses-time-check (format arg)
...@@ -480,7 +587,7 @@ cell (ROW,COL). This is undoable. The cell's data will be updated through ...@@ -480,7 +587,7 @@ cell (ROW,COL). This is undoable. The cell's data will be updated through
(ses-set-with-undo (ses-cell-symbol cell) val) (ses-set-with-undo (ses-cell-symbol cell) val)
(ses-aset-with-undo cell elt val))) (ses-aset-with-undo cell elt val)))
(if change (if change
(add-to-list 'deferred-write (cons row col)))) (add-to-list 'ses--deferred-write (cons row col))))
nil) ;Make coverage-tester happy nil) ;Make coverage-tester happy
(defun ses-cell-set-formula (row col formula) (defun ses-cell-set-formula (row col formula)
...@@ -496,7 +603,7 @@ means Emacs will crash if FORMULA contains a circular list." ...@@ -496,7 +603,7 @@ means Emacs will crash if FORMULA contains a circular list."
(newref (ses-formula-references formula)) (newref (ses-formula-references formula))
(inhibit-quit t) (inhibit-quit t)
x xrow xcol) x xrow xcol)
(add-to-list 'deferred-recalc sym) (add-to-list 'ses--deferred-recalc sym)
;;Delete old references from this cell. Skip the ones that are also ;;Delete old references from this cell. Skip the ones that are also
;;in the new list. ;;in the new list.
(dolist (ref oldref) (dolist (ref oldref)
...@@ -542,10 +649,10 @@ the old and FORCE is nil." ...@@ -542,10 +649,10 @@ the old and FORCE is nil."
;;Don't lose the *skip* - previous field spans this one ;;Don't lose the *skip* - previous field spans this one
(setq newval '*skip*)) (setq newval '*skip*))
(when (or force (not (eq newval oldval))) (when (or force (not (eq newval oldval)))
(add-to-list 'deferred-write (cons row col)) ;In case force=t (add-to-list 'ses--deferred-write (cons row col)) ;In case force=t
(ses-set-cell row col 'value newval) (ses-set-cell row col 'value newval)
(dolist (ref (ses-cell-references cell)) (dolist (ref (ses-cell-references cell))
(add-to-list 'deferred-recalc ref)))) (add-to-list 'ses--deferred-recalc ref))))
(setq printer-error (ses-print-cell row col)) (setq printer-error (ses-print-cell row col))
(or formula-error printer-error))) (or formula-error printer-error)))
...@@ -558,21 +665,21 @@ the old and FORCE is nil." ...@@ -558,21 +665,21 @@ the old and FORCE is nil."
"Recalculate cells in LIST, checking for dependency loops. Prints "Recalculate cells in LIST, checking for dependency loops. Prints
progress messages every second. Dependent cells are not recalculated progress messages every second. Dependent cells are not recalculated
if the cell's value is unchanged if FORCE is nil." if the cell's value is unchanged if FORCE is nil."
(let ((deferred-recalc list) (let ((ses--deferred-recalc list)
(nextlist list) (nextlist list)
(pos (point)) (pos (point))
curlist prevlist rowcol formula) curlist prevlist rowcol formula)
(with-temp-message " " (with-temp-message " "
(while (and deferred-recalc (not (equal nextlist prevlist))) (while (and ses--deferred-recalc (not (equal nextlist prevlist)))
;;In each loop, recalculate cells that refer only to other cells that ;;In each loop, recalculate cells that refer only to other cells that
;;have already been recalculated or aren't in the recalculation ;;have already been recalculated or aren't in the recalculation
;;region. Repeat until all cells have been processed or until the ;;region. Repeat until all cells have been processed or until the
;;set of cells being worked on stops changing. ;;set of cells being worked on stops changing.
(if prevlist (if prevlist
(message "Recalculating... (%d cells left)" (message "Recalculating... (%d cells left)"
(length deferred-recalc))) (length ses--deferred-recalc)))
(setq curlist deferred-recalc (setq curlist ses--deferred-recalc
deferred-recalc nil ses--deferred-recalc nil
prevlist nextlist) prevlist nextlist)
(while curlist (while curlist
(setq rowcol (ses-sym-rowcol (car curlist)) (setq rowcol (ses-sym-rowcol (car curlist))
...@@ -580,9 +687,9 @@ if the cell's value is unchanged if FORCE is nil." ...@@ -580,9 +687,9 @@ if the cell's value is unchanged if FORCE is nil."
(or (catch 'ref (or (catch 'ref
(dolist (ref (ses-formula-references formula)) (dolist (ref (ses-formula-references formula))
(when (or (memq ref curlist) (when (or (memq ref curlist)
(memq ref deferred-recalc)) (memq ref ses--deferred-recalc))
;;This cell refers to another that isn't done yet ;;This cell refers to another that isn't done yet
(add-to-list 'deferred-recalc (car curlist)) (add-to-list 'ses--deferred-recalc (car curlist))
(throw 'ref t)))) (throw 'ref t))))
;;ses-update-cells is called from post-command-hook, so ;;ses-update-cells is called from post-command-hook, so
;;inhibit-quit is implicitly bound to t. ;;inhibit-quit is implicitly bound to t.
...@@ -591,19 +698,19 @@ if the cell's value is unchanged if FORCE is nil." ...@@ -591,19 +698,19 @@ if the cell's value is unchanged if FORCE is nil."
(error "Quit")) (error "Quit"))
(ses-calculate-cell (car rowcol) (cdr rowcol) force)) (ses-calculate-cell (car rowcol) (cdr rowcol) force))
(setq curlist (cdr curlist))) (setq curlist (cdr curlist)))
(dolist (ref deferred-recalc) (dolist (ref ses--deferred-recalc)
(add-to-list 'nextlist ref)) (add-to-list 'nextlist ref))
(setq nextlist (sort (copy-sequence nextlist) 'string<)) (setq nextlist (sort (copy-sequence nextlist) 'string<))
(if (equal nextlist prevlist) (if (equal nextlist prevlist)
;;We'll go around the loop one more time. ;;We'll go around the loop one more time.
(add-to-list 'nextlist t))) (add-to-list 'nextlist t)))
(when deferred-recalc (when ses--deferred-recalc
;;Just couldn't finish these ;;Just couldn't finish these
(dolist (x deferred-recalc) (dolist (x ses--deferred-recalc)
(let ((rowcol (ses-sym-rowcol x))) (let ((rowcol (ses-sym-rowcol x)))
(ses-set-cell (car rowcol) (cdr rowcol) 'value '*error*) (ses-set-cell (car rowcol) (cdr rowcol) 'value '*error*)
(1value (ses-print-cell (car rowcol) (cdr rowcol))))) (1value (ses-print-cell (car rowcol) (cdr rowcol)))))
(error "Circular references: %s" deferred-recalc)) (error "Circular references: %s" ses--deferred-recalc))
(message " ")) (message " "))
;;Can't use save-excursion here: if the cell under point is ;;Can't use save-excursion here: if the cell under point is
;;updated, save-excusion's marker will move past the cell. ;;updated, save-excusion's marker will move past the cell.
...@@ -614,46 +721,50 @@ if the cell's value is unchanged if FORCE is nil." ...@@ -614,46 +721,50 @@ if the cell's value is unchanged if FORCE is nil."
;;;; The print area ;;;; The print area
;;;---------------------------------------------------------------------------- ;;;----------------------------------------------------------------------------
(defun ses-in-print-area ()
"Returns t if point is in print area of spreadsheet."
(eq (get-text-property (point) 'keymap) 'ses-mode-print-map))
;;;We turn off point-motion-hooks and explicitly position the cursor, in case ;;;We turn off point-motion-hooks and explicitly position the cursor, in case
;;;the intangible properties have gotten screwed up (e.g., when ;;;the intangible properties have gotten screwed up (e.g., when
;;;ses-goto-print is called during a recursive ses-print-cell). ;;;ses-goto-print is called during a recursive ses-print-cell).
(defun ses-goto-print (row col) (defun ses-goto-print (row col)
"Move point to print area for cell (ROW,COL)." "Move point to print area for cell (ROW,COL)."
(let ((inhibit-point-motion-hooks t)) (let ((inhibit-point-motion-hooks t))
(goto-char 1) (goto-char (point-min))
(forward-line row) (forward-line row)
(dotimes (c col) (dotimes (c col)
(forward-char (1+ (ses-col-width c)))))) (forward-char (1+ (ses-col-width c))))))
(defun ses-set-curcell () (defun ses-set-curcell ()
"Sets `curcell' to the current cell symbol, or a cons (BEG,END) for a "Sets `ses--curcell' to the current cell symbol, or a cons (BEG,END) for a
region, or nil if cursor is not at a cell." region, or nil if cursor is not at a cell."
(if (or (not mark-active) (if (or (not mark-active)
deactivate-mark deactivate-mark
(= (region-beginning) (region-end))) (= (region-beginning) (region-end)))
;;Single cell ;;Single cell
(setq curcell (get-text-property (point) 'intangible)) (setq ses--curcell (get-text-property (point) 'intangible))
;;Range ;;Range
(let ((bcell (get-text-property (region-beginning) 'intangible)) (let ((bcell (get-text-property (region-beginning) 'intangible))
(ecell (get-text-property (1- (region-end)) 'intangible))) (ecell (get-text-property (1- (region-end)) 'intangible)))
(setq curcell (if (and bcell ecell) (setq ses--curcell (if (and bcell ecell)
(cons bcell ecell) (cons bcell ecell)
nil)))) nil))))
nil) nil)
(defun ses-check-curcell (&rest args) (defun ses-check-curcell (&rest args)
"Signal an error if curcell is inappropriate. The end marker is "Signal an error if ses--curcell is inappropriate. The end marker is
appropriate if some argument is 'end. A range is appropriate if some appropriate if some argument is 'end. A range is appropriate if some
argument is 'range. A single cell is appropriate unless some argument is argument is 'range. A single cell is appropriate unless some argument is
'needrange." 'needrange."
(if (eq curcell t) (if (eq ses--curcell t)
;;curcell recalculation was postponed, but user typed ahead ;;curcell recalculation was postponed, but user typed ahead
(ses-set-curcell)) (ses-set-curcell))
(cond (cond
((not curcell) ((not ses--curcell)
(or (memq 'end args) (or (memq 'end args)
(error "Not at cell"))) (error "Not at cell")))
((consp curcell) ((consp ses--curcell)
(or (memq 'range args) (or (memq 'range args)
(memq 'needrange args) (memq 'needrange args)
(error "Can't use a range"))) (error "Can't use a range")))
...@@ -689,7 +800,7 @@ preceding cell has spilled over." ...@@ -689,7 +800,7 @@ preceding cell has spilled over."
;;Print the value ;;Print the value
(setq text (ses-call-printer (or printer (setq text (ses-call-printer (or printer
(ses-col-printer col) (ses-col-printer col)
default-printer) ses--default-printer)
value)) value))
(if (consp ses-call-printer-return) (if (consp ses-call-printer-return)
;;Printer returned an error ;;Printer returned an error
...@@ -708,7 +819,7 @@ preceding cell has spilled over." ...@@ -708,7 +819,7 @@ preceding cell has spilled over."
;;Spill over into following cells, if possible ;;Spill over into following cells, if possible
(let ((maxwidth width)) (let ((maxwidth width))
(while (and (> len maxwidth) (while (and (> len maxwidth)
(< maxcol numcols) (< maxcol ses--numcols)
(or (not (setq x (ses-cell-value row maxcol))) (or (not (setq x (ses-cell-value row maxcol)))
(eq x '*skip*))) (eq x '*skip*)))
(unless x (unless x
...@@ -748,7 +859,7 @@ preceding cell has spilled over." ...@@ -748,7 +859,7 @@ preceding cell has spilled over."
(delete-char (1+ (length text))) (delete-char (1+ (length text)))
;;We use concat instead of inserting separate strings in order to ;;We use concat instead of inserting separate strings in order to
;;reduce the number of cells in the undo list. ;;reduce the number of cells in the undo list.
(setq x (concat text (if (< maxcol numcols) " " "\n"))) (setq x (concat text (if (< maxcol ses--numcols) " " "\n")))
;;We use set-text-properties to prevent a wacky print function ;;We use set-text-properties to prevent a wacky print function
;;from inserting rogue properties, and to ensure that the keymap ;;from inserting rogue properties, and to ensure that the keymap
;;property is inherited (is it a bug that only unpropertied strings ;;property is inherited (is it a bug that only unpropertied strings
...@@ -759,15 +870,16 @@ preceding cell has spilled over." ...@@ -759,15 +870,16 @@ preceding cell has spilled over."
(ses-cell-symbol cell)) (ses-cell-symbol cell))
(when (and (zerop row) (zerop col)) (when (and (zerop row) (zerop col))
;;Reconstruct special beginning-of-buffer attributes ;;Reconstruct special beginning-of-buffer attributes
(put-text-property 1 (point) 'keymap 'ses-mode-print-map) (put-text-property (point-min) (point) 'keymap 'ses-mode-print-map)
(put-text-property 1 (point) 'read-only 'ses) (put-text-property (point-min) (point) 'read-only 'ses)
(put-text-property 1 2 'front-sticky t))) (put-text-property (point-min) (1+ (point-min)) 'front-sticky t)))
(if (= row (1- header-row)) (if (= row (1- ses--header-row))
;;This line is part of the header - force recalc ;;This line is part of the header - force recalc
(ses-reset-header-string)) (ses-reset-header-string))
;;If this cell (or a preceding one on the line) previously spilled over ;;If this cell (or a preceding one on the line) previously spilled over
;;and has gotten shorter, redraw following cells on line recursively. ;;and has gotten shorter, redraw following cells on line recursively.
(when (and (< maxcol numcols) (eq (ses-cell-value row maxcol) '*skip*)) (when (and (< maxcol ses--numcols)
(eq (ses-cell-value row maxcol) '*skip*))