14

There are plenty of ways to fold code in Emacs and I've settled in on using the outline minor mode... it works great!

However, I really want my folding to be persisted when I close and re-open files. It is quite frustrating to have folding set up in a file the way I like it, only to have that lost when I restart Emacs.

Has anyone found a way to keep the folding state of a file persistent?

HaskellElephant
  • 9,819
  • 4
  • 38
  • 67
Chris Holtz
  • 141
  • 3
  • 2
    Not an exact answer, but you can use org-mode with [orgfold.el](http://www.emacswiki.org/emacs/orgfold.el) or [orgfold-separate-file.el](http://www.emacswiki.org/emacs/orgfold-separate-file.el)-- though it would be nice if the latter worked with just one global state-storage file (like in [saveplace.el](http://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/saveplace.el)). – Mark Mar 04 '13 at 16:07

2 Answers2

6

Edit: Now that I understand the question...

How about something like the following nippet of code. It seems to work for me, though I haven't figured out how to avoid being prompted for the file local variable every time.

(defvar omm-state nil
  "file local variable storing outline overlays")
(defun omm-state-mode (&optional arg)
  "poor man's minor mode to re-apply the outline overlays "
  (interactive)
  (omm-re-enable-outline-state)
  (add-hook 'before-save-hook 'omm-state-save))
(defun omm-get-all-overlays ()
  "return a list of outline information for all the current buffer"
  (save-excursion
    (let ((all-overlays (overlays-in (point-min) (point-max))))
      (mapcar (lambda (o)
                (list (overlay-start o) (overlay-end o) (overlay-get o 'invisible)))
              (reverse all-overlays)))))
(defun omm-re-enable-outline-state (&optional arg)
  "turn on outline-minor-mode and re-apply the outline information"
  (outline-minor-mode 1)
  (when (listp omm-state)
    (mapcar (lambda (p)
              (apply 'outline-flag-region p))
            omm-state)))
(defun omm-state-save ()
  "save the outline state in a file local variable
Note: this just replaces the existing value, you need to start
it off by adding something like this to your file:

# Local Variables:
# omm-state:()
# mode:omm-state
# End:            
"
  (ignore-errors
    (save-excursion
      (goto-char (point-max))
      (when (search-backward "omm-state:" nil t)
        (goto-char (match-end 0))
        (kill-sexp)
        (princ (omm-get-all-overlays) (current-buffer)))))
  nil)

This solution requires you "seeding" your file with something like:

# Local Variables:
# omm-state:()
# mode:omm-state
# End:            
Trey Jackson
  • 73,529
  • 11
  • 197
  • 229
  • Thanks for the feedback Trey. To be clear - I am able to enable outline minor mode for any file type I like with a hook. What I'm looking for is to fold an entry of code, close the buffer and then later when I re-open the file, I want that entry to still be folded. – Chris Holtz Mar 19 '10 at 19:55
  • 1
    @Chris I understand now... don't know that this is possible. – Trey Jackson Mar 19 '10 at 20:13
  • Where would this persistence be stored? In the file itself? Bad idea; some other file? possible, I suppose, but there are no such hooks to do this, yet. And I'd remain suspicious of dropping those files all over the place. If collected in one folder.. sheesh, that'd be huge. – Michael Paulukonis Mar 19 '10 at 20:18
  • @OtherMichael How about storing it in the current file itself... I've got a solution that seems to work above. – Trey Jackson Mar 19 '10 at 21:11
  • Trey, this is great. Now I need to figure out how to make this work with hs-minor-mode :) – Leo Alekseyev Mar 19 '10 at 21:17
  • Storing it in the local file presumes the persistance mechanism will be ignored by the files interpreter; or, it has to be stripped out prior to interpretation/compilation. Those hashes, f'r instance, would be fine for Perl, but cause some issues in a JavaScript or XML file. Plaintext rocks, but plaintext also sucks. – Michael Paulukonis Mar 20 '10 at 15:44
  • @OtherMichael Right, you can change the # to be whatever comment character you want to use. You can even use C-style comments /* ... */. I presume you can use HTML/XML comments too. – Trey Jackson Mar 20 '10 at 15:53
4

I realize this is an old post but FWIW I created a minor mode that complements hs-minor-mode, outline-mode etc. I also "really want my folding to be persisted when I close and re-open files". :)

The package is in MELPA as of today and called persistent-overlays.

It is also available directly on github: https://github.com/mneilly/Emacs-Persistent-Overlays

Mike N.
  • 1,662
  • 1
  • 13
  • 19