X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/d0f6a32f46d1cd035ce6cbaf5cf44fe1e4e964f1..05db920d6f6a99f0ae84a35d3cf09b2a4f1ce264:/lisp/ses.el diff --git a/lisp/ses.el b/lisp/ses.el index 09f7809752..62067471b6 100644 --- a/lisp/ses.el +++ b/lisp/ses.el @@ -1,6 +1,6 @@ ;;; ses.el -- Simple Emacs Spreadsheet -*- coding: utf-8 -*- -;; Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +;; Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. ;; Author: Jonathan Yavner ;; Maintainer: Jonathan Yavner @@ -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, @@ -20,8 +20,8 @@ ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. ;;; Commentary: @@ -49,7 +49,7 @@ ;;---------------------------------------------------------------------------- (defgroup ses nil - "Simple Emacs Spreadsheet" + "Simple Emacs Spreadsheet." :group 'applications :prefix "ses-" :version "21.1") @@ -148,8 +148,7 @@ Each function is called with ARG=1." (newmap (make-sparse-keymap))) (set-keymap-parent newmap minibuffer-local-map) (while keys - (define-key newmap (car keys) (cadr keys)) - (setq keys (cddr keys))) + (define-key newmap (pop keys) (pop keys))) newmap) "Local keymap for SES minibuffer cell-editing.") @@ -173,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)) @@ -238,13 +239,6 @@ Each function is called with ARG=1." ses-initial-file-trailer) "The initial contents of an empty spreadsheet.") -(defconst ses-paramlines-plist - '(ses--col-widths 2 ses--col-printers 3 ses--default-printer 4 - 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 -of a spreadsheet.") - (defconst ses-box-prop '(:box (:line-width 2 :style released-button)) "Display properties to create a raised box for cells in the header line.") @@ -256,13 +250,19 @@ functions. None of these standard-printer functions is suitable for use as a column printer or a global-default printer because they invoke the column or default printer and then modify its output.") + +;;---------------------------------------------------------------------------- +;; Local variables and constants +;;---------------------------------------------------------------------------- + (eval-and-compile (defconst ses-localvars '(ses--blank-line ses--cells ses--col-printers ses--col-widths ses--curcell ses--curcell-overlay ses--default-printer ses--deferred-narrow ses--deferred-recalc ses--deferred-write ses--file-format ses--header-hscroll ses--header-row ses--header-string ses--linewidth - ses--numcols ses--numrows ses--symbolic-formulas + ses--numcols ses--numrows ses--symbolic-formulas ses--data-marker + ses--params-marker ;;Global variables that we override mode-line-process next-line-add-newlines transient-mark-mode) "Buffer-local variables used by SES.")) @@ -273,6 +273,16 @@ 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 + ses--numcols 3) + "Offsets from 'Global parameters' line to various parameter lines in the +data area of a spreadsheet.") + ;; ;; "Side-effect variables". They are set in one function, altered in @@ -292,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 @@ -376,7 +386,7 @@ macro to prevent propagate-on-load viruses." ;;print area (excluding the terminating newline) (setq ses--col-widths widths ses--linewidth (apply '+ -1 (mapcar '1+ widths)) - ses--blank-line (concat (make-string ses--linewidth ? ) "\n")) + ses--blank-line (concat (make-string ses--linewidth ?\s) "\n")) t) (defmacro ses-column-printers (printers) @@ -400,7 +410,7 @@ for safety. This is a macro to prevent propagate-on-load viruses." (defmacro ses-header-row (row) "Load the header row from the spreadsheet file and checks it for safety. This is a macro to prevent propagate-on-load viruses." - (or (and (wholenump row) (< row ses--numrows)) + (or (and (wholenump row) (or (zerop ses--numrows) (< row ses--numrows))) (error "Bad header-row")) (setq ses--header-row row) t) @@ -409,6 +419,7 @@ for safety. This is a macro to prevent propagate-on-load viruses." "Execute BODY repeatedly, with the variables `row' and `col' set to each cell in the range specified by CURCELL. The range is available in the variables `minrow', `maxrow', `mincol', and `maxcol'." + (declare (indent defun) (debug (form body))) (let ((cur (make-symbol "cur")) (min (make-symbol "min")) (max (make-symbol "max")) @@ -430,9 +441,6 @@ variables `minrow', `maxrow', `mincol', and `maxcol'." (setq col (+ ,c mincol)) ,@body)))))) -(put 'ses-dorange 'lisp-indent-function 'defun) -(def-edebug-spec ses-dorange (form body)) - ;;Support for coverage testing. (defmacro 1value (form) "For code-coverage testing, indicate that FORM is expected to always have @@ -504,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." @@ -625,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 @@ -651,7 +662,7 @@ the old and FORCE is nil." (defun ses-update-cells (list &optional force) "Recalculate cells in LIST, checking for dependency loops. Prints 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 and FORCE is nil." (let ((ses--deferred-recalc list) (nextlist list) (pos (point)) @@ -710,7 +721,7 @@ if the cell's value is unchanged if FORCE is nil." (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)) + (<= (point) ses--data-marker)) ;;We turn off point-motion-hooks and explicitly position the cursor, in case ;;the intangible properties have gotten screwed up (e.g., when @@ -734,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)))) @@ -798,7 +812,7 @@ preceding cell has spilled over." (cond ((< len width) ;;Fill field to length with spaces - (setq len (make-string (- width len) ? ) + (setq len (make-string (- width len) ?\s) text (if (eq ses-call-printer-return t) (concat text len) (concat len text)))) @@ -816,7 +830,7 @@ preceding cell has spilled over." maxcol (1+ maxcol))) (if (<= len maxwidth) ;;Fill to complete width of all the fields spanned - (setq text (concat text (make-string (- maxwidth len) ? ))) + (setq text (concat text (make-string (- maxwidth len) ?\s))) ;;Not enough room to end of line or next non-nil field. Truncate ;;if string or decimal; otherwise fill with error indicator (setq sig `(error "Too wide" ,text)) @@ -875,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 @@ -906,12 +920,12 @@ printer signaled one (and \"%s\" is used as the default printer), else nil." COL=NUMCOLS. Deletes characters if CHANGE < 0. Caller should bind inhibit-quit to t." (let ((inhibit-read-only t) - (blank (if (> change 0) (make-string change ? ))) + (blank (if (> change 0) (make-string change ?\s))) (at-end (= col ses--numcols))) (ses-set-with-undo 'ses--linewidth (+ ses--linewidth change)) ;;ses-set-with-undo always returns t for strings. (1value (ses-set-with-undo 'ses--blank-line - (concat (make-string ses--linewidth ? ) "\n"))) + (concat (make-string ses--linewidth ?\s) "\n"))) (dotimes (row ses--numrows) (ses-goto-print row col) (when at-end @@ -941,23 +955,29 @@ cell (ROW,COL) has changed." (defun ses-narrowed-p () (/= (- (point-max) (point-min)) (buffer-size))) +(defun ses-widen () + "Turn off narrowing, to be reenabled at end of command loop." + (if (ses-narrowed-p) + (setq ses--deferred-narrow t)) + (widen)) + (defun ses-goto-data (def &optional col) "Move point to data area for (DEF,COL). If DEF is a row number, COL is the column number for a data cell -- otherwise DEF is one of the symbols ses--col-widths, ses--col-printers, ses--default-printer, ses--numrows, or ses--numcols." - (if (ses-narrowed-p) - (setq ses--deferred-narrow t)) - (widen) + (ses-widen) (let ((inhibit-point-motion-hooks t)) ;In case intangible attrs are wrong - (goto-char (point-min)) (if col - ;;It's a cell - (forward-line (+ ses--numrows 2 (* def (1+ ses--numcols)) col)) - ;;Convert def-symbol to offset - (setq def (plist-get ses-paramlines-plist def)) - (or def (signal 'args-out-of-range nil)) - (forward-line (+ (* ses--numrows (+ ses--numcols 2)) def))))) + ;;It's a cell + (progn + (goto-char ses--data-marker) + (forward-line (+ 1 (* def (1+ ses--numcols)) col))) + ;;Convert def-symbol to offset + (setq def (plist-get ses-paramlines-plist def)) + (or def (signal 'args-out-of-range nil)) + (goto-char ses--params-marker) + (forward-line def)))) (defun ses-set-parameter (def value &optional elem) "Set parameter DEF to VALUE (with undo) and write the value to the data area. @@ -967,9 +987,6 @@ If ELEM is specified, it is the array subscript within DEF to be set to VALUE." ;;We call ses-goto-data early, using the old values of numrows and ;;numcols in case one of them is being changed. (ses-goto-data def) - (if elem - (ses-aset-with-undo (symbol-value def) elem value) - (ses-set-with-undo def value)) (let ((inhibit-read-only t) (fmt (plist-get '(ses--col-widths "(ses-column-widths %S)" ses--col-printers "(ses-column-printers %S)" @@ -978,9 +995,20 @@ If ELEM is specified, it is the array subscript within DEF to be set to VALUE." ses--file-format " %S ;SES file-format" ses--numrows " %S ;numrows" ses--numcols " %S ;numcols") - def))) - (delete-region (point) (line-end-position)) - (insert (format fmt (symbol-value def)))))) + def)) + oldval) + (if elem + (progn + (setq oldval (aref (symbol-value def) elem)) + (aset (symbol-value def) elem value)) + (setq oldval (symbol-value def)) + (set def value)) + ;;Special undo since it's outside the narrowed buffer + (let (buffer-undo-list) + (delete-region (point) (line-end-position)) + (insert (format fmt (symbol-value def)))) + (push `(apply ses-set-parameter ,def ,oldval ,elem) buffer-undo-list)))) + (defun ses-write-cells () "Write cells in `ses--deferred-write' from local variables to data area. @@ -1059,6 +1087,23 @@ or t to get a wrong-type-argument error when the first reference is found." )))) result-so-far) +(defsubst ses-relocate-symbol (sym rowcol startrow startcol rowincr colincr) + "Relocate one symbol SYM, whichs corresponds to ROWCOL (a cons of ROW and +COL). Cells starting at (STARTROW,STARTCOL) are being shifted +by (ROWINCR,COLINCR)." + (let ((row (car rowcol)) + (col (cdr rowcol))) + (if (or (< row startrow) (< col startcol)) + sym + (setq row (+ row rowincr) + col (+ col colincr)) + (if (and (>= row startrow) (>= col startcol) + (< row ses--numrows) (< col ses--numcols)) + ;;Relocate this variable + (ses-create-cell-symbol row col) + ;;Delete reference to a deleted cell + nil)))) + (defun ses-relocate-formula (formula startrow startcol rowincr colincr) "Produce a copy of FORMULA where all symbols that refer to cells in row STARTROW or above and col STARTCOL or above are altered by adding ROWINCR @@ -1103,23 +1148,6 @@ Sets `ses-relocate-return' to 'delete if cell-references were removed." result)))) (nreverse result)))) -(defun ses-relocate-symbol (sym rowcol startrow startcol rowincr colincr) - "Relocate one symbol SYM, whichs corresponds to ROWCOL (a cons of ROW and -COL). Cells starting at (STARTROW,STARTCOL) are being shifted -by (ROWINCR,COLINCR)." - (let ((row (car rowcol)) - (col (cdr rowcol))) - (if (or (< row startrow) (< col startcol)) - sym - (setq row (+ row rowincr) - col (+ col colincr)) - (if (and (>= row startrow) (>= col startcol) - (< row ses--numrows) (< col ses--numcols)) - ;;Relocate this variable - (ses-create-cell-symbol row col) - ;;Delete reference to a deleted cell - nil)))) - (defun ses-relocate-range (range startrow startcol rowincr colincr) "Relocate one RANGE, of the form '(ses-range min max). Cells starting at (STARTROW,STARTCOL) are being shifted by (ROWINCR,COLINCR). Result is the @@ -1279,23 +1307,6 @@ to each symbol." ;; Undo control ;;---------------------------------------------------------------------------- -;; This should be unnecessary, because the feature is now built in. - -(defadvice undo-more (around ses-undo-more activate preactivate) - "For SES mode, allow undo outside of narrowed buffer range." - (if (not (eq major-mode 'ses-mode)) - ad-do-it - ;;Here is some extra code for SES mode. - (setq ses--deferred-narrow - (or ses--deferred-narrow (ses-narrowed-p))) - (widen) - (condition-case x - ad-do-it - (error - ;;Restore narrow if appropriate - (ses-command-hook) - (signal (car x) (cdr x)))))) - (defun ses-begin-change () "For undo, remember point before we start changing hidden stuff." (let ((inhibit-read-only t)) @@ -1304,7 +1315,7 @@ to each symbol." (defun ses-set-with-undo (sym newval) "Like set, but undoable. Result is t if value has changed." - ;;We avoid adding redundant entries to the undo list, but this is + ;;We try to avoid adding redundant entries to the undo list, but this is ;;unavoidable for strings because equal ignores text properties and there's ;;no easy way to get the whole property list to see if it's different! (unless (and (boundp sym) @@ -1343,11 +1354,12 @@ execute cell formulas or print functions." (goto-char (point-max)) (search-backward ";; Local Variables:\n" nil t) (backward-list 1) + (setq ses--params-marker (point-marker)) (let ((params (condition-case nil (read (current-buffer)) (error nil)))) (or (and (= (safe-length params) 3) (numberp (car params)) (numberp (cadr params)) - (> (cadr params) 0) + (>= (cadr params) 0) (numberp (nth 2 params)) (> (nth 2 params) 0)) (error "Invalid SES file")) @@ -1372,7 +1384,9 @@ execute cell formulas or print functions." (forward-line ses--numrows) (or (looking-at ses-print-data-boundary) (error "Missing marker between print and data areas")) - (forward-char (length ses-print-data-boundary)) + (forward-char 1) + (setq ses--data-marker (point-marker)) + (forward-char (1- (length ses-print-data-boundary))) ;;Initialize printer and symbol lists (mapc 'ses-printer-record ses-standard-printer-functions) (setq ses--symbolic-formulas nil) @@ -1467,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} @@ -1569,19 +1588,17 @@ narrows the buffer now." (let ((old ses--deferred-recalc)) (setq ses--deferred-recalc nil) (ses-update-cells old))) - (if ses--deferred-write - ;;We don't reset the deferred list before starting -- the most - ;;likely error is keyboard-quit, and we do want to keep trying - ;;these writes after a quit. - (ses-write-cells)) + (when ses--deferred-write + ;;We don't reset the deferred list before starting -- the most + ;;likely error is keyboard-quit, and we do want to keep trying + ;;these writes after a quit. + (ses-write-cells) + (push '(apply ses-widen) buffer-undo-list)) (when ses--deferred-narrow ;;We're not allowed to narrow the buffer until after-find-file has ;;read the local variables at the end of the file. Now it's safe to ;;do the narrowing. - (save-excursion - (goto-char (point-min)) - (forward-line ses--numrows) - (narrow-to-region (point-min) (point))) + (narrow-to-region (point-min) ses--data-marker) (setq ses--deferred-narrow nil)) ;;Update the modeline (let ((oldcell ses--curcell)) @@ -1612,7 +1629,7 @@ narrows the buffer now." (error (unless executing-kbd-macro (ding)) - (message (error-message-string err)))) + (message "%s" (error-message-string err)))) nil) ;Make coverage-tester happy (defun ses-create-header-string () @@ -1739,7 +1756,7 @@ to are recalculated first." (error (setq sig hold)))) (cond (sig - (message (error-message-string sig))) + (message "%s" (error-message-string sig))) ((consp ses--curcell) (message " ")) (t @@ -1795,9 +1812,7 @@ cells." (cons (ses-cell-symbol row col) (ses-cell-references yrow ycol))))))) ;;Delete everything and reconstruct basic data area - (if (ses-narrowed-p) - (setq ses--deferred-narrow t)) - (widen) + (ses-widen) (let ((inhibit-read-only t)) (goto-char (point-max)) (if (search-backward ";; Local Variables:\n" nil t) @@ -1810,11 +1825,17 @@ cells." (dotimes (row ses--numrows) (insert ses--blank-line)) (insert ses-print-data-boundary) + (backward-char (1- (length ses-print-data-boundary))) + (setq ses--data-marker (point-marker)) + (forward-char (1- (length ses-print-data-boundary))) ;;Placeholders for cell data (insert (make-string (* ses--numrows (1+ ses--numcols)) ?\n)) ;;Placeholders for col-widths, col-printers, default-printer, header-row (insert "\n\n\n\n") - (insert ses-initial-global-parameters)) + (insert ses-initial-global-parameters) + (backward-char (1- (length ses-initial-global-parameters))) + (setq ses--params-marker (point-marker)) + (forward-char (1- (length ses-initial-global-parameters)))) (ses-set-parameter 'ses--col-widths ses--col-widths) (ses-set-parameter 'ses--col-printers ses--col-printers) (ses-set-parameter 'ses--default-printer ses--default-printer) @@ -1865,20 +1886,22 @@ cell formula was unsafe and user declined confirmation." (defun ses-read-cell (row col newval) "Self-insert for initial character of cell function." (interactive - (let ((initial (this-command-keys)) - (rowcol (progn (ses-check-curcell) (ses-sym-rowcol ses--curcell)))) + (let* ((initial (this-command-keys)) + (rowcol (progn (ses-check-curcell) (ses-sym-rowcol ses--curcell))) + (curval (ses-cell-formula (car rowcol) (cdr rowcol)))) (barf-if-buffer-read-only) - (if (string= initial "\"") - (setq initial "\"\"") ;Enter a string - (if (string= initial "(") - (setq initial "()"))) ;Enter a formula list (list (car rowcol) (cdr rowcol) - (read-from-minibuffer (format "Cell %s: " ses--curcell) - (cons initial 2) - ses-mode-edit-map - t ;Convert to Lisp object - 'ses-read-cell-history)))) + (read-from-minibuffer + (format "Cell %s: " ses--curcell) + (cons (if (equal initial "\"") "\"\"" + (if (equal initial "(") "()" initial)) 2) + ses-mode-edit-map + t ;Convert to Lisp object + 'ses-read-cell-history + (prin1-to-string (if (eq (car-safe curval) 'ses-safe-formula) + (cadr curval) + curval)))))) (when (ses-edit-cell row col newval) (ses-command-hook) ;Update cell widths before movement (dolist (x ses-after-entry-functions) @@ -2074,6 +2097,8 @@ before current one." (ses-reset-header-string))) ;;Reconstruct text attributes (ses-setup) + ;;Prepare for undo + (push '(apply ses-widen) buffer-undo-list) ;;Return to current cell (if ses--curcell (ses-jump-safe ses--curcell) @@ -2110,6 +2135,8 @@ current one." (ses-reset-header-string))) ;;Reconstruct attributes (ses-setup) + ;;Prepare for undo + (push '(apply ses-widen) buffer-undo-list) (ses-jump-safe ses--curcell)) (defun ses-insert-column (count &optional col width printer) @@ -2311,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"))) @@ -2560,7 +2590,7 @@ spot, or error signal if user requests cancel." colbool (> needcols 0)) (when (or rowbool colbool) ;;Need to insert. Get confirm - (or (y-or-n-p (format "Yank will insert %s%s%s. Continue " + (or (y-or-n-p (format "Yank will insert %s%s%s. Continue? " (if rowbool (format "%d rows" needrows) "") (if (and rowbool colbool) " and " "") (if colbool (format "%d columns" needcols) ""))) @@ -2644,7 +2674,10 @@ The top row is row 1. Selecting row 0 displays the default header row." (if (or (< row 0) (> row ses--numrows)) (error "Invalid header-row")) (ses-begin-change) - (ses-set-parameter 'ses--header-row row) + (let ((oldval ses--header-row)) + (let (buffer-undo-list) + (ses-set-parameter 'ses--header-row row)) + (push `(apply ses-set-header-row ,oldval) buffer-undo-list)) (ses-reset-header-string)) (defun ses-mark-row () @@ -2878,7 +2911,8 @@ TEST is evaluated." (cons 'list result))) ;;All standard formulas are safe -(dolist (x '(ses-range ses-delete-blanks ses+ ses-average ses-select)) +(dolist (x '(ses-cell-value ses-range ses-delete-blanks ses+ ses-average + ses-select)) (put x 'side-effect-free t)) @@ -2901,7 +2935,7 @@ columns to include in width (default = 0)." (let ((printer (or (ses-col-printer col) ses--default-printer)) (width (ses-col-width col)) half) - (or fill (setq fill ? )) + (or fill (setq fill ?\s)) (or span (setq span 0)) (setq value (ses-call-printer printer value)) (dotimes (x span)