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?

ebpa
  • 7,319
  • 26
  • 53
  • 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 Apr 01 '16 at 02: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 Apr 01 '16 at 02:35

2 Answers2

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.)

Nova
  • 1,059
  • 9
  • 21
Dan
  • 32,584
  • 6
  • 98
  • 168
  • 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 Apr 01 '16 at 02: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.) – Harald Hanche-Olsen Apr 01 '16 at 07:17
  • @HaraldHanche-Olsen: thanks for the note! I've edited the answer to reflect it. – Dan Apr 01 '16 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)
Iqbal Ansari
  • 7,468
  • 1
  • 28
  • 31