Evaluate all in document?

Is it possible to evaluate all fields in a document like how is possible in Mathematica and Jupyter notebooks? Using the evaluate all from the toolbar only evaluates connected fields.

1 Like

Hi and welcome to the forum!
As far as I know, an evaluation command to evaluate all fields in a document does not exist, I agree that it would be useful.
I found that “Evaluate all” executes session-evaluate-all, defined with this code:

(tm-define (session-evaluate-all)
  (session-forall
    (lambda (t)
      (when (not (tree-empty? (tree-ref t 1)))
	(field-process-input t)))))

My feeling is that it is possible to extend this by iterating over all of the trees that represent the same session. Give me a little time, maybe I am able to write code that does that.
Other relevant functions are

(define (session-forall-sub fun t)
  (for (u (tree-children t))
    (when (field-context? u)
      (fun u))
    (when (and (tm-func? u 'unfolded-subsession)
	       (tm-func? (tree-ref u 1) 'document))
      (session-forall-sub fun (tree-ref u 1)))))

(define (session-forall fun)
  (with-innermost t subsession-document-context?
    (session-forall-sub fun t)))

(I found all of them in progs/dynamic/session-edit.scm)

1 Like

It’s a bit tricky, as the functions in session-edit.scm rely on (get-env "prog-session") to send input to the right session. But the environment variable is only set to the right value if the cursor is in the session. I tried

(map
  (lambda (ses) (begin (tree-go-to ses 1 1 0) (session-evaluate-all)))
  (tree-search (buffer-tree) subsession-document-context?))

to move the cursor to the session and then evaluate, but it doesn’t work.

1 Like

Nice work :slight_smile:

I found out that with for-each it works:

(define (ev-all) (for-each
	    (lambda (ses) (begin (tree-go-to ses 1 1 0) (session-evaluate-all)))
	    (tree-search (buffer-tree) subsession-document-context?)))

(kbd-map
  ("A-e" (ev-all)))

I have a faint hint of why that may be the case (executing the statements in order? it does not seem a sufficient explanation).
Edit: the shortcut A-e in regular text starts an enumeration environment in the emacs look and feel. But perhaps it is ok as it is written, as it works inside a session. One should (again, perhaps) adapt the shortcut to the look and feel.

2 Likes

@konfou Putting everything in your my-init-texmacs should provide you the command for evaluating all fields; maybe a refinement is still helpful as this evaluates all fields in all sessions in your document, and you might want to evaluate all fields in a given session (even if they are disconnected).

You can also extend the context menu using

(tm-menu (texmacs-popup-menu)
  (:require (inside? 'session))
  (former)
  ---
  ("Evaluate all fields in document" (ev-all)))

(also to add in my-init-texmacs.scm)

3 Likes

Thanks, works great! Just an addition, in the older TeXmacs version I’m using, tree-search isn’t in global namespace and it has to be imported using

(use-modules
 ((link link-extract)
  #:select (tree-search)))
2 Likes

I’ve got one more suggestion: in the previous incarnation, the cursor went to the second element of the session (1 1 0), the first element usually being the banner. However, if you have a session without banner and just one field, this may break. I think this should work better (note the (tree-go-to ses :last 1 0)):

(define (ev-all)
  (for-each (lambda (ses) (begin (tree-go-to ses :last 1 0) (session-evaluate-all)))
    (tree-search (buffer-tree) subsession-document-context?)))
1 Like