emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Request: ses.el Turn accessors into defsubst


From: T.V. Raman
Subject: Request: ses.el Turn accessors into defsubst
Date: Thu, 2 Aug 2012 08:32:46 -0700

An additional "nice to have"  would be to make sure that all
functionality available through the mouse is also available
through the keyboard.  When i first looked at ses.el a couple of
years ago, this was definitely not true; looking at the code and
info pages now, it looks like a lot of those previous issues are
gone. But it's hard for me to tell if I am missing functionality
as a non-mouse-waving human.
-- 

-- 


On 8/1/12, Stefan Monnier <address@hidden> wrote:
>> At present, ses.el defines its all its internal accessors as
>> macros -- could we please have them changed to use defsubst?
>
> Fine by me.
>
> I have some local changes which do that and a few more things, but
> I haven't cleaned it up and some of the changes are probably not
> appropriate.  It might be a good starting point for someone to
> extract the defstruct part.
>
>
>         Stefan
>
>
> Using submit branch file:///home/monnier/src/emacs/bzr/trunk/
> === modified file 'lisp/ses.el'
> --- lisp/ses.el       2012-07-22 21:14:12 +0000
> +++ lisp/ses.el       2012-07-24 23:57:58 +0000
> @@ -25,8 +25,18 @@
>
>  ;;; To-do list:
>
> +;; * M-w should deactivate the mark.
> +;; * offer some way to use absolute cell addressing.
> +;; * Maybe some way to copy a reference to a cell's formula rather than
> the
> +;;   formula itself.
>  ;; * split (catch 'cycle ...) call back into one or more functions
>  ;; * Use $ or … for truncated fields
> +;; * M-t to transpose 2 columns.
> +;; * M-d should kill the cell under point.
> +;; * C-t to transpose 2 rows.
> +;; * C-k and M-k should be ses-kill-row and ses-kill-column.
> +;; * C-o should insert the row below point rather than above.
> +;; * rows inserted with C-o should inherit formulas from surrounding rows.
>  ;; * 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
> @@ -345,22 +355,30 @@
>
>  (defmacro ses-get-cell (row col)
>    "Return the cell structure that stores information about cell
> (ROW,COL)."
> +  (declare (debug t))
>    `(aref (aref ses--cells ,row) ,col))
>
> -;; We might want to use defstruct here, but cells are explicitly used as
> -;; arrays in ses-set-cell, so we'd need to fix this first.  --Stef
> -(defsubst ses-make-cell (&optional symbol formula printer references
> -                                property-list)
> -  (vector symbol formula printer references property-list))
> +(cl-defstruct (ses-cell
> +            (:constructor nil)
> +            (:constructor ses-make-cell
> +             (&optional symbol formula printer references))
> +            (:copier nil)
> +            ;; This is treated as an 4-elem array in various places.
> +            ;; Mostly in ses-set-cell.
> +            (:type vector)           ;Not named.
> +            (:conc-name ses-cell--))
> +  symbol formula printer references)
>
>  (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."
> -  `(aref ,(if col `(ses-get-cell ,row ,col) row) 0))
> +  (declare (debug t))
> +  `(ses-cell--symbol ,(if col `(ses-get-cell ,row ,col) row)))
>  (put 'ses-cell-symbol 'safe-function t)
>
>  (defmacro ses-cell-formula (row &optional col)
>    "From a CELL or a pair (ROW,COL), get the function that computes its
> value."
> -  `(aref ,(if col `(ses-get-cell ,row ,col) row) 1))
> +  (declare (debug t))
> +  `(ses-cell--formula ,(if col `(ses-get-cell ,row ,col) row)))
>
>  (defmacro ses-cell-formula-aset (cell formula)
>    "From a CELL set the function that computes its value."
> @@ -368,12 +386,14 @@
>
>  (defmacro ses-cell-printer (row &optional col)
>    "From a CELL or a pair (ROW,COL), get the function that prints its
> value."
> -  `(aref ,(if col `(ses-get-cell ,row ,col) row) 2))
> +  (declare (debug t))
> +  `(ses-cell--printer ,(if col `(ses-get-cell ,row ,col) row)))
>
>  (defmacro ses-cell-references (row &optional col)
>    "From a CELL or a pair (ROW,COL), get the list of symbols for cells
> whose
>  functions refer to its value."
> -  `(aref ,(if col `(ses-get-cell ,row ,col) row) 3))
> +  (declare (debug t))
> +  `(ses-cell--references ,(if col `(ses-get-cell ,row ,col) row)))
>
>  (defmacro ses-cell-references-aset (cell references)
>    "From a CELL set the list REFERENCES of symbols for cells the
> @@ -500,19 +520,23 @@
>
>  (defmacro ses-cell-value (row &optional col)
>    "From a CELL or a pair (ROW,COL), get the current value for that cell."
> +  (declare (debug t))
>    `(symbol-value (ses-cell-symbol ,row ,col)))
>
>  (defmacro ses-col-width (col)
>    "Return the width for column COL."
> +  (declare (debug t))
>    `(aref ses--col-widths ,col))
>
>  (defmacro ses-col-printer (col)
>    "Return the default printer for column COL."
> +  (declare (debug t))
>    `(aref ses--col-printers ,col))
>
>  (defmacro ses-sym-rowcol (sym)
>    "From a cell-symbol SYM, gets the cons (row . col).  A1 => (0 . 0).
>  Result is nil if SYM is not a symbol that names a cell."
> +  (declare (debug t))
>    `(and (symbolp ,sym) (get ,sym 'ses-cell)))
>
>  (defmacro ses-cell (sym value formula printer references)
> @@ -536,6 +560,28 @@
>    (set sym value)
>    sym)
>
> +(defmacro ses-c (sym formula &optional references value printer)
> +  "Load a cell SYM from the spreadsheet file.  Does not recompute VALUE
> from
> +FORMULA, does not reprint using PRINTER, does not check REFERENCES.  This
> is a
> +macro to prevent propagate-on-load viruses.  Safety-checking for FORMULA
> and
> +PRINTER are deferred until first use."
> +  (unless value (setq value formula))
> +  (let ((rowcol (ses-sym-rowcol sym)))
> +    (ses-formula-record formula)
> +    (ses-printer-record printer)
> +    (or (atom formula)
> +     (eq safe-functions t)
> +     (setq formula `(ses-safe-formula ,formula)))
> +    (or (not printer)
> +     (stringp printer)
> +     (eq safe-functions t)
> +     (setq printer `(ses-safe-printer ,printer)))
> +    (aset (aref ses--cells (car rowcol))
> +       (cdr rowcol)
> +       (ses-make-cell sym formula printer references)))
> +  (set sym value)
> +  sym)
> +
>  (defmacro ses-column-widths (widths)
>    "Load the vector of column widths from the spreadsheet file.  This is a
>  macro to prevent propagate-on-load viruses."
> @@ -604,9 +650,11 @@
>  (defmacro 1value (form)
>    "For code-coverage testing, indicate that FORM is expected to always
> have
>  the same value."
> +  (declare (debug t))
>    form)
>  (defmacro noreturn (form)
>    "For code-coverage testing, indicate that FORM will always signal an
> error."
> +  (declare (debug t))
>    form)
>
>
> @@ -745,21 +793,23 @@
>  ;; The cells
> ;;----------------------------------------------------------------------------
>
> -(defun ses-set-cell (row col field val)
> -  "Install VAL as the contents for field FIELD (named by a quoted symbol)
> of
> -cell (ROW,COL).  This is undoable.  The cell's data will be updated
> through
> -`post-command-hook'."
> -  (let ((cell (ses-get-cell row col))
> -     (elt  (plist-get '(value t symbol 0 formula 1 printer 2 references 3)
> -                      field))
> -     change)
> +(defmacro ses-set-cell (row col field val)
> +  "Install VAL as the contents for field FIELD of cell (ROW,COL).
> +FIELD is a quoted symbol.  This is undoable.
> +The cell's data will be updated through `post-command-hook'."
> +  (declare (debug t))
> +  (let ((elt  (plist-get '(value t symbol 0 formula 1 printer 2 references
> 3)
> +                      (eval field))))
>      (or elt (signal 'args-out-of-range nil))
> -    (setq change (if (eq elt t)
> -                  (ses-set-with-undo (ses-cell-symbol cell) val)
> -                (ses-aset-with-undo cell elt val)))
> +    `(let* ((row ,row)
> +         (col ,col)
> +         (val ,val)
> +         (cell (ses-get-cell row col))
> +         (change ,(if (eq elt t)
> +                     `(ses-set-with-undo (ses-cell-symbol cell) val)
> +                    `(ses-aset-with-undo cell ,elt val))))
>      (if change
> -     (add-to-list 'ses--deferred-write (cons row col))))
> -  nil) ; Make coverage-tester happy.
> +        (add-to-list 'ses--deferred-write (cons row col))))))
>
>  (defun ses-cell-set-formula (row col formula)
>    "Store a new formula for (ROW . COL) and enqueue the cell for
> @@ -1124,7 +1174,8 @@
>        ((< len width)
>         ;; Fill field to length with spaces.
>         (setq len  (make-string (- width len) ?\s)
> -             text (if (eq ses-call-printer-return t)
> +             text (if (or (stringp value)
> +                          (eq ses-call-printer-return t))
>                        (concat text len)
>                      (concat len text))))
>        ((> len width)
> @@ -1331,8 +1382,9 @@
>    "Write cells in `ses--deferred-write' from local variables to data area.
>  Newlines in the data are escaped."
>    (let* ((inhibit-read-only t)
> +      (standard-output (current-buffer))
>        (print-escape-newlines t)
> -      rowcol row col cell sym formula printer text)
> +      rowcol row col cell sym formula printer)
>      (setq ses-start-time (float-time))
>      (with-temp-message " "
>        (save-excursion
> @@ -1350,27 +1402,26 @@
>             (setq formula (cadr formula)))
>         (if (eq (car-safe printer) 'ses-safe-printer)
>             (setq printer (cadr printer)))
> -       ;; This is noticeably faster than (format "%S %S %S %S %S")
> -       (setq text    (concat "(ses-cell "
> -                             (symbol-name sym)
> -                             " "
> -                             (prin1-to-string (symbol-value sym))
> -                             " "
> -                             (prin1-to-string formula)
> -                             " "
> -                             (prin1-to-string printer)
> -                             " "
> -                             (if (atom (ses-cell-references cell))
> -                                 "nil"
> -                               (concat "("
> -                                       (mapconcat 'symbol-name
> -                                                  (ses-cell-references cell)
> -                                                  " ")
> -                                       ")"))
> -                             ")"))
>         (ses-goto-data row col)
>         (delete-region (point) (line-end-position))
> -       (insert text)))
> +       ;; This is noticably faster than (format "%S %S %S %S %S")
> +       (insert "(ses-c ")
> +       (prin1 sym)
> +       (insert " ")
> +       (prin1 formula)
> +       (let ((refs (ses-cell-references cell))
> +             (val (symbol-value sym)))
> +         (if (eq val formula) (setq val nil))
> +         (when (or refs val printer)
> +           (insert " ")
> +           (prin1 refs)
> +           (when (or val printer)
> +             (insert " ")
> +             (prin1 val)
> +             (when printer
> +               (insert " ")
> +               (prin1 printer)))))
> +       (insert ")")))
>        (message " "))))
>
>
> @@ -1405,6 +1456,8 @@
>        ))
>      result-so-far)
>
> +(defalias 'ses-absolute 'identity)
> +
>  (defsubst ses-relocate-symbol (sym rowcol startrow startcol rowincr
> colincr)
>    "Relocate one symbol SYM, which corresponds to ROWCOL (a cons of ROW and
>  COL).  Cells starting at (STARTROW,STARTCOL) are being shifted
> @@ -1457,7 +1510,7 @@
>         (setq cur (ses-relocate-range cur startrow startcol rowincr colincr))
>         (if cur
>             (push cur result)))
> -      ((or (atom cur) (eq (car cur) 'quote))
> +      ((or (atom cur) (eq (car cur) 'quote) (eq (car cur) 'ses-absolute))
>         ;; Constants pass through unchanged.
>         (push cur result))
>        (t
> @@ -1677,6 +1730,7 @@
>  (defun ses-aset-with-undo (array idx newval)
>    "Like `aset', but undoable.
>  Result is t if element has changed."
> +  ;; BEWARE: This is also used on ses-cell elements, assuming they're
> arrays.
>    (unless (equal (aref array idx) newval)
>      (push `(apply ses-aset-with-undo ,array ,idx
>                 ,(aref array idx)) buffer-undo-list)
> @@ -1737,7 +1791,7 @@
>        (let* ((x      (read (current-buffer)))
>            (sym  (car-safe (cdr-safe x))))
>       (or (and (looking-at "\n")
> -              (eq (car-safe x) 'ses-cell)
> +              (memq (car-safe x) '(ses-cell ses-c))
>                (ses-create-cell-variable sym row col))
>           (error "Cell-def error"))
>       (eval x)))
> @@ -1874,7 +1928,8 @@
>         ;; calculation).
>         indent-tabs-mode       nil)
>      (1value (add-hook 'change-major-mode-hook 'ses-cleanup nil t))
> -    (1value (add-hook 'before-revert-hook 'ses-cleanup nil t))
> +    ;; This makes revert impossible if the buffer is read-only.
> +    ;; (1value (add-hook 'before-revert-hook 'ses-cleanup nil t))
>      (setq header-line-format   '(:eval (progn
>                                        (when (/= (window-hscroll)
>                                                  ses--header-hscroll)
> @@ -2258,16 +2313,23 @@
>       (barf-if-buffer-read-only)
>       (list (car rowcol)
>          (cdr rowcol)
> +           (if (equal initial "\"")
> +               (progn
> +                 (if (not (stringp curval)) (setq curval nil))
> +                 (read-string (if curval
> +                                  (format "String Cell %s (default %s): "
> +                                          ses--curcell curval)
> +                                (format "String Cell %s: " ses--curcell))
> +                              nil 'ses-read-string-history curval))
>             (read-from-minibuffer
>              (format "Cell %s: " ses--curcell)
> -            (cons (if (equal initial "\"") "\"\""
> -                    (if (equal initial "(") "()" initial)) 2)
> +              (cons (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))))))
> +                                 curval)))))))
>    (when (ses-edit-cell row col newval)
>      (ses-command-hook) ; Update cell widths before movement.
>      (dolist (x ses-after-entry-functions)
> @@ -2891,9 +2953,9 @@
>        ;; Invalid sexp --- leave it as a string.
>        (setq val (substring text from to)))
>       ((and (car val) (symbolp (car val)))
> -      (if (consp arg)
> -       (setq val (list 'quote (car val)))  ; Keep symbol.
> -     (setq val (substring text from to)))) ; Treat symbol as text.
> +      (setq val (if (consp arg)
> +                 (list 'quote (car val))   ; Keep symbol.
> +               (substring text from to)))) ; Treat symbol as text.
>       (t
>        (setq val (car val))))
>      (let ((row (car rowcol))
> @@ -3437,7 +3499,7 @@
>    "Return ARGS reversed, with the blank elements (nil and *skip*)
> removed."
>    (let (result)
>      (dolist (cur args)
> -      (unless (memq cur '(nil *skip*))
> +      (unless (memq cur '(nil *skip* *error*))
>       (push cur result)))
>      result))
>
> @@ -3470,7 +3532,7 @@
>
>  ;;All standard formulas are safe
>  (dolist (x '(ses-cell-value ses-range ses-delete-blanks ses+ ses-average
> -          ses-select))
> +          ses-select ses-absolute))
>    (put x 'side-effect-free t))
>
>
>
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]