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)

2 Likes

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

Is it possible to also get evaluate all code blocks above and all code blocks below like Jupyter ?

There is a command for evaluating the input cells below or above the current one in a session, but it evaluated only connected fields.

I think it is possible to evaluate all fields above, but it may take a bit of coding. The way that I see is, once you have extracted subtrees with tree-search, you have to order them using their path (or make sure that tree-search always returns them ordered). You also need to figure out the subtree you are currently in (maybe you do it with tree-search-upwards, like in the thread Inserting picture one looks for the image at the current position of the cursor), then you will apply the avaluation command only to the code snippets above or below.

Also, one might take inspiration from the code that executes when the menu commands Evaluate above or Evaluate below are issued (I did not search for that code in the TeXmacs sources).

1 Like