9

Folding gets in the way when merging two org files using ediff, so I'm trying to disable all folding in org-mode buffers created by ediff. Non-ediff folding behavior should remain unaffected.

Naively I think that something akin to the following should work:

  (add-hook 'ediff-mode-hook
        (lambda ()
          (set (make-local-variable 'org-inhibit-startup-visibility-stuff) t)))

I'm fairly certain that this is the org variable to modify (rather than org-startup-folded or org-agenda-inhibit-startup).

I've tried various hooks to no avail (mainly ediff-mode-hook, ediff-before-setup-hook, ediff-meta-mode-hook, and ediff-prepare-buffer-hook- which is probably too late) hoping that the interned variable will be inherited.

It's quite possible that I'm using make-local-variable incorrectly; the pattern is just borrowed from what I've widely seen.

Only setting the value globally has been effective (but that's not what I'm shooting for). Should I be (ab)using the advice mechanism?

2
  • Not sure which hook to use, but why not just a function call to show-all instead? (org-mode is built on top of outline-mode, and it sounds like you always want it to show everything.)
    – Dan
    Commented Apr 1, 2016 at 2:29
  • (add-hook 'ediff-prepare-buffer-hook 'show-all) does the trick! Add that as an answer, @Dan? I'm still curious about local variables for ediff, but I think show-all is the best solution to my problem.
    – ebpa
    Commented Apr 1, 2016 at 2:35

2 Answers 2

11

It sounds like your goal is to have org-mode files always show everything when in ediff. The simplest solution is probably to avoid the local variables approach and just put show-all in the relevant hook, ediff-prepare-buffer-hook which is run after buffers A, B, & C are set up:

 (with-eval-after-load 'outline
   (add-hook 'ediff-prepare-buffer-hook #'org-show-all))

Despite the name, org-show-all also works in outline-mode which org-mode is built on top of. Unlike outline-show-all, it shows property drawers and blocks like #+begin_src ... #+end_src.

org-show-all has been added in Org 9.1.6. In earlier versions you can use outline-show-all or show-all.

(Note, according to a comment, that show-all is marked obsolete in Emacs 25.1 in favor of outline-show-all. The latter symbol is not bound in 24.5.)

3
  • It looks like show-all is defined sanely, so that it doesn't need any defensive conditions in the hook and can be safely called within non-org / non-outline modes.
    – ebpa
    Commented Apr 1, 2016 at 2:52
  • 3
    Great answer. But show-all is marked obsolete since 25.1. Better to use outline-show-all, I think. (The former is just an alias for the latter.) Commented Apr 1, 2016 at 7:17
  • @HaraldHanche-Olsen: thanks for the note! I've edited the answer to reflect it.
    – Dan
    Commented Apr 1, 2016 at 12:35
4

Another option can be found on the worg page. The basic idea is to use ediff-select-hook to unfold an element whenever given region is selected in ediff and folding them back in the ediff-unselect-hook. I am posting the code here for completeness

;; Check for org mode and existence of buffer
(defun f-ediff-org-showhide (buf command &rest cmdargs)
  "If buffer exists and is orgmode then execute command"
  (when buf
    (when (eq (buffer-local-value 'major-mode (get-buffer buf)) 'org-mode)
      (save-excursion (set-buffer buf) (apply command cmdargs)))))

(defun f-ediff-org-unfold-tree-element ()
  "Unfold tree at diff location"
  (f-ediff-org-showhide ediff-buffer-A 'org-reveal)  
  (f-ediff-org-showhide ediff-buffer-B 'org-reveal)  
  (f-ediff-org-showhide ediff-buffer-C 'org-reveal))

(defun f-ediff-org-fold-tree ()
  "Fold tree back to top level"
  (f-ediff-org-showhide ediff-buffer-A 'hide-sublevels 1)  
  (f-ediff-org-showhide ediff-buffer-B 'hide-sublevels 1)  
  (f-ediff-org-showhide ediff-buffer-C 'hide-sublevels 1))

(add-hook 'ediff-select-hook 'f-ediff-org-unfold-tree-element)
(add-hook 'ediff-unselect-hook 'f-ediff-org-fold-tree)
1
  • This works really well for me, thank you!
    – mbafford
    Commented Aug 24, 2021 at 12:54

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.