This lets <recalc> recalculate org tables in any buffer with the button in a different (or the same) window.
<recalc>
Here's a table. Click in it and then shift-middle-click recalc, above. "aaa12" should change to "12" and your cursor should stay in the same place.
| a | aaa12 |
| a | 5 |
| | 17 |
#+TBLFM: @1$2=3*4::@2$2=2+3::@3$2=vsum(@1..@2)
Here's my current definition for recalc
(defvar bill/hyp-state nil)
(defun bill/hyp-save-state (&rest args)
(setq bill/hyp-state
(list (selected-window) (point-marker) (and (use-region-p) (copy-marker (mark-marker))))))
(cl-defun bill/hyp-load-state (&optional (state bill/hyp-state))
(let ((window (car state))
(point (cadr state))
(mark (caddr state)))
(when window
(select-window window)
(set-buffer (marker-buffer point))
(and mark (set-mark (marker-position mark)))
(goto-char point))))
(defun bill/hyp-restore ()
(let ((state bill/hyp-state))
(run-at-time 0 nil (lambda () (bill/hyp-load-state state)))))
(advice-add 'action-key-depress :before 'bill/hyp-save-state)
;; evaluate this to remove the advice
;;(advice-remove 'action-key-depress 'bill/hyp-save-state)
(defun bill/recalc (end)
(let ((act-point action-key-depress-prev-point))
(bill/hyp-load-state)
(when (org-at-table-p)
(org-table-analyze)
(org-table-maybe-eval-formula)
(call-interactively 'org-table-recalculate)
(org-table-align)))
(bill/hyp-restore))
(defib recalc ()
"recalculate the table at point"
(save-excursion
(let* ((pos (point))
(eol (progn (re-search-forward "\n") (point)))
(bol (progn (re-search-backward "\n" nil t 2) (1+ (point))))
(start (progn (goto-char pos) (re-search-backward "<" bol t)))
(end (progn (goto-char pos) (re-search-forward ">" eol t))))
(and start end (string-match "<recalc[> ].*" (buffer-substring start end))
(hact 'bill/recalc end)))))