aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Belaïche2017-06-23 11:16:37 +0200
committerVincent Belaïche2017-06-23 11:16:37 +0200
commiteebb9783e1674732b7c63d50211b524ff0fea7bd (patch)
treebed257f0db158f3086066c6d12c35b63a0cddcc7
parentd533f5f2a783e4c6448f841e709f4528f498b7ea (diff)
downloademacs-eebb9783e1674732b7c63d50211b524ff0fea7bd.tar.gz
emacs-eebb9783e1674732b7c63d50211b524ff0fea7bd.zip
Fix symbol relocation when the relocated cell is renamed.
* lisp/ses.el (ses-sym-rowcol): Check that the renamed cell hashmap has been instantiated before getting data from it. When editing several spreadsheets, and you have spreadsheet #1 with a cell named `foo', and no renamed cell in spreadsheet #2, then if you make a formula with `foo' in spreadsheet #2, not doing this check will make an error. (ses-cell-set-formula): Robustify versus incorrect cell references given in the user provided formula. An explicit error message is provided after the action when the user gives an incorrect cell reference, but the formula edition is not changed. This means that if the incorrect reference is to a cell that is created someday, then this new cell will not have the edited cell in its reference list. Fixing this can still be done by editing again the first cell formula. (ses-relocate-symbol): Do not create symbol of referred-to cell when this is a renamed cell.
-rw-r--r--lisp/ses.el46
1 files changed, 32 insertions, 14 deletions
diff --git a/lisp/ses.el b/lisp/ses.el
index b3686076358..97bade380ec 100644
--- a/lisp/ses.el
+++ b/lisp/ses.el
@@ -437,7 +437,7 @@ is nil if SYM is not a symbol that names a cell."
437 (declare (debug t)) 437 (declare (debug t))
438 `(let ((rc (and (symbolp ,sym) (get ,sym 'ses-cell)))) 438 `(let ((rc (and (symbolp ,sym) (get ,sym 'ses-cell))))
439 (if (eq rc :ses-named) 439 (if (eq rc :ses-named)
440 (gethash ,sym ses--named-cell-hashmap) 440 (and ses--named-cell-hashmap (gethash ,sym ses--named-cell-hashmap))
441 rc))) 441 rc)))
442 442
443(defun ses-cell-p (cell) 443(defun ses-cell-p (cell)
@@ -868,27 +868,39 @@ means Emacs will crash if FORMULA contains a circular list."
868 (oldref (ses-formula-references old)) 868 (oldref (ses-formula-references old))
869 (newref (ses-formula-references formula)) 869 (newref (ses-formula-references formula))
870 (inhibit-quit t) 870 (inhibit-quit t)
871 not-a-cell-ref-list
871 x xrow xcol) 872 x xrow xcol)
872 (cl-pushnew sym ses--deferred-recalc) 873 (cl-pushnew sym ses--deferred-recalc)
873 ;;Delete old references from this cell. Skip the ones that are also 874 ;;Delete old references from this cell. Skip the ones that are also
874 ;;in the new list. 875 ;;in the new list.
875 (dolist (ref oldref) 876 (dolist (ref oldref)
876 (unless (memq ref newref) 877 (unless (memq ref newref)
877 (setq x (ses-sym-rowcol ref) 878 ;; because we do not cancel edit when the user provides a
878 xrow (car x) 879 ;; false reference in it, then we need to check that ref
879 xcol (cdr x)) 880 ;; points to a cell that is within the spreadsheet.
880 (ses-set-cell xrow xcol 'references 881 (setq x (ses-sym-rowcol ref))
881 (delq sym (ses-cell-references xrow xcol))))) 882 (and x
883 (< (setq xrow (car x)) ses--numrows)
884 (< (setq xcol (cdr x)) ses--numcols)
885 (ses-set-cell xrow xcol 'references
886 (delq sym (ses-cell-references xrow xcol))))))
882 ;;Add new ones. Skip ones left over from old list 887 ;;Add new ones. Skip ones left over from old list
883 (dolist (ref newref) 888 (dolist (ref newref)
884 (setq x (ses-sym-rowcol ref) 889 (setq x (ses-sym-rowcol ref))
885 xrow (car x) 890 ;;Do not trust the user, the reference may be outside the spreadsheet
886 xcol (cdr x) 891 (if (and
887 x (ses-cell-references xrow xcol)) 892 x
888 (or (memq sym x) 893 (< (setq xrow (car x)) ses--numrows)
889 (ses-set-cell xrow xcol 'references (cons sym x)))) 894 (< (setq xcol (cdr x)) ses--numcols))
895 (progn
896 (setq x (ses-cell-references xrow xcol))
897 (or (memq sym x)
898 (ses-set-cell xrow xcol 'references (cons sym x))))
899 (cl-pushnew ref not-a-cell-ref-list)))
890 (ses-formula-record formula) 900 (ses-formula-record formula)
891 (ses-set-cell row col 'formula formula)))) 901 (ses-set-cell row col 'formula formula)
902 (and not-a-cell-ref-list
903 (error "Found in formula cells not in spreadsheet: %S" not-a-cell-ref-list)))))
892 904
893 905
894(defun ses-repair-cell-reference-all () 906(defun ses-repair-cell-reference-all ()
@@ -1529,7 +1541,13 @@ by (ROWINCR,COLINCR)."
1529 ;;Relocate this variable, unless it is a named cell 1541 ;;Relocate this variable, unless it is a named cell
1530 (if (eq (get sym 'ses-cell) :ses-named) 1542 (if (eq (get sym 'ses-cell) :ses-named)
1531 sym 1543 sym
1532 (ses-create-cell-symbol row col)) 1544 ;; otherwise, we create the relocated cell symbol because
1545 ;; ses-cell-symbol gives the old symbols, however since
1546 ;; renamed cell are not relocated we keep the relocated
1547 ;; cell old symbol in this case.
1548 (if (eq (get (setq sym (ses-cell-symbol row col)) 'ses-cell) :ses-named)
1549 sym
1550 (ses-create-cell-symbol row col)))
1533 ;;Delete reference to a deleted cell 1551 ;;Delete reference to a deleted cell
1534 nil)))) 1552 nil))))
1535 1553