(define (subsession-document-context-lan? lan)
  (lambda (t)
    (or (and (tree-is? t 'document)
	     (tree-is? (tree-ref t :up) 'session)
	     (== (tree-ref t :up 0) (tree lan)))
        (and (tree-is? t 'document)
	     (tree-is? (tree-ref t :up) 'unfolded-subsession)
             (== (tree-ref t :up 0) (tree lan))
	     (== (tree-index t) 1)))))

(define (map-session-code-string f lan)
  (let ((io-handler (lambda (io)
                      (f (texmacs->code (tree-ref io 1) "SourceCode"))
                      (f "\n\n")))
        (is-io? (lambda (t) (tm-in? t '(input unfolded-io folded-io)))))
    (for-each
        (lambda (ses)
          (for-each io-handler (tree-search ses is-io?)))
      (tree-search (buffer-tree) (subsession-document-context-lan? lan)))))

(define (guess-saved-buffer suffix)
  (let* ((name (propose-name-buffer))
         (name1 (if (string-ends? name ".tm") name
                    (string-append name (basename (url->string (url-temp))) ".tm")))
         (suffix1 (if (string-starts? suffix ".") suffix
                      (string-append "." suffix))))
    (string-append (string-drop-right name1 3) suffix1)))

;; Shell io is currently buggy, save to a file
(tm-define (save-lan-to-file lan file suffix)
  (:argument lan "Language to save")
  (:argument file "Save to")
  (:argument suffix "Filename ext (default to lan)")
  (let* ((lan1 (if (string? lan) lan ""))
         (suffix1 (if (string? suffix) suffix lan1))
         (file1 (if (and (string? file) (not (string-null? file)))
                    file (guess-saved-buffer suffix1)))
         (port (open-output-file file1)))
    (map-session-code-string (lambda (t) (display t port)) lan1)
    (close-port port)))
