I realize that this question has been asked before, many times, (How to save expansion state of org-file?, as well as org-mode: go back from sparse tree to previous visibility), but, it does seem to be that, with the changes introduced in 9.6 (by yantar92), the glue for doing this is back in place, or newly in place.

Specifically, it seemed that using org-fold-core-save-visibility (which ostensibly saves and/or restores folding state) within a hook, and then freezing that state to a file might do the trick.

Unfortunately, my abilities as a lisp programmer are laughable. Does this seem like a valid approach to bang my head over?

  • I don't think that org-fold-core-save-visibility will help with saving state to disk but the functions that it uses to accomplish what it does might be able to help. Do C-h f on org-fold-core-get-regions and org-fold-core-regions for more information.
    – NickD
    Nov 30, 2023 at 5:05

1 Answer 1


As org 9.6 already provides functions for storing and restoring the org folding state (as, already mentioned by @NickD, we find from inspecting the code of org-fold-core-save-visibility), and I already had been working last year on fixing https://www.emacswiki.org/emacs/orgfold-separate-file.el, creating a version for org-versions >= 9.6 was quick and easy.

The new version can be found here. Just load the file and auto store/restore should work.

Note the initial comment in the file!

For completeness, as it is short anyway, I'll add the complete code here:

;;; org-fold-restore.el --- Auto restore folding state of org buffers  -*- lexical-binding: t; -*-

;; NOTE only stores state if buffer has been modified and saved

(defun org-fold-store-state ()
  (let ((state (org-fold-get-regions)))
    (with-temp-file (concat buffer-file-name ".fold")
      (prin1 state (current-buffer)))))

(defun org-fold-restore-state ()
  (let* ((file-base buffer-file-name)
         (state (with-temp-buffer
                  (concat file-base ".fold"))
                 (read (current-buffer)))))
    (org-fold-regions state)
    (goto-char (point-min))))

(add-hook 'org-mode-hook 'org-fold-activate)

(defun org-fold-activate ()
  ;; call the restore function
  (when (file-exists-p (concat buffer-file-name ".fold"))
  ;; and add a local hook, to save the foldstates
  ;; (only is buffer was saved, see `orgfold-kill-buffer')
  (add-hook 'kill-buffer-hook 'org-fold-kill-buffer nil t))

(defun org-fold-kill-buffer ()
  ;; don't save folding info for unsaved buffers
  (unless (buffer-modified-p)
  • This looks great...
    – B2Pi
    Nov 30, 2023 at 17:11
  • 1
    It seems to me that the folding state should be saved when the buffer is saved: it may be that I change the folding state, save the buffer, then change the folding state again and then kill the buffer without saving. That's going to (correctly) not save the final folding state, but it is going to miss the intermediate folding state. That is, IIUC - which is doubtful.
    – NickD
    Nov 30, 2023 at 18:44
  • Right. You're asking for a hook on a after-save-hook, that ought be the same as the code for org-fold-kill-buffer (in fact, I'm not sure that the kill-buffer-hook is needed if you hook after-save-hook)
    – B2Pi
    Nov 30, 2023 at 19:24
  • 1
    @NickD I understand your perspective, but the current version simply stores the final coding state (except when killing without saving). If a user wants to store on save, then it should not be too difficult to replace the kill-buffer-hook with the hook of his/her preference. Alternatively, the user could remove the condition in the org-fold-kill-buffer function (I don't remember why I preferred it there). Nov 30, 2023 at 22:51
  • 1
    Yes, the important thing is how to save and restore the folding state. When it should be stored is perhaps a matter of opinion. You might want to include the code in your answer, so that it's more than a link (which can disappear). Thanks for writing that code BTW!
    – NickD
    Dec 1, 2023 at 0:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.