Function: ses-update-cells

ses-update-cells is a byte-compiled function defined in ses.el.gz.

Signature

(ses-update-cells LIST &optional FORCE)

Documentation

Recalculate cells in LIST, checking for dependency loops.

Print progress messages every second. Dependent cells are not recalculated if the cell's value is unchanged and FORCE is nil.

Source Code

;; Defined in /usr/src/emacs/lisp/ses.el.gz
(defun ses-update-cells (list &optional force)
  "Recalculate cells in LIST, checking for dependency loops.
Print progress messages every second.  Dependent cells are not
recalculated if the cell's value is unchanged and FORCE is nil."
  (let ((ses--deferred-recalc list)
	(nextlist             list)
	(pos		      (point))
	curlist prevlist this-sym this-rowcol formula)
    (with-temp-message " "
      (while ses--deferred-recalc
	;; In each loop, recalculate cells that refer only to other cells that
	;; have already been recalculated or aren't in the recalculation region.
	;; Repeat until all cells have been processed or until the set of cells
	;; being worked on stops changing.
	(if prevlist
	    (message "Recalculating... (%d cells left)"
		     (length ses--deferred-recalc)))
	(setq curlist              ses--deferred-recalc
	      ses--deferred-recalc nil
	      prevlist             nextlist)
	(while curlist
	  ;; this-sym has to be popped from curlist *BEFORE* the check, and not
	  ;; after because of the case of cells referring to themselves.
	  (setq this-sym   (pop curlist)
		this-rowcol (ses-sym-rowcol this-sym)
		formula     (ses-cell-formula (car this-rowcol)
					      (cdr this-rowcol)))
	  (or (catch 'ref
		(dolist (ref (ses-formula-references formula))
		  (if (and ses-self-reference-early-detection (eq ref this-sym))
		      (error "Cycle found: cell %S is self-referring" this-sym)
		    (when (or (memq ref curlist)
			      (memq ref ses--deferred-recalc))
		      ;; This cell refers to another that isn't done yet
		      (cl-pushnew this-sym ses--deferred-recalc :test #'equal)
		      (throw 'ref t)))))
	      ;; ses-update-cells is called from post-command-hook, so
	      ;; inhibit-quit is implicitly bound to t.
	      (when quit-flag
		;; Abort the recalculation.  User will probably undo now.
		(error "Quit"))
	      (ses-calculate-cell (car this-rowcol) (cdr this-rowcol) force)))
	(dolist (ref ses--deferred-recalc)
          (cl-pushnew ref nextlist :test #'equal)))
      (when ses--deferred-recalc
	;; Just couldn't finish these.
	(dolist (x ses--deferred-recalc)
	  (let ((this-rowcol (ses-sym-rowcol x)))
	    (ses-set-cell (car this-rowcol) (cdr this-rowcol) 'value '*error*)
	    (1value (ses-print-cell (car this-rowcol) (cdr this-rowcol)))))
	(error "Circular references: %s" ses--deferred-recalc))
      (message " "))
    ;; Can't use save-excursion here: if the cell under point is updated,
    ;; save-excursion's marker will move past the cell.
    (goto-char pos)))