6

I'd like to find a way to jump to a location in an org-mode file while automatically unfolding only the heading at the location I'm jumping to and all its parent headings (but not any sibling headings).

For example, if I have this org-mode file:

* A
** AA
*** AAA
** AB
*** ABA
* B
** BA
*** BAA
** BB
*** BBA
* C
** CA
*** CAA
** CB
*** CBA

and I use evil-set-marker to mark the location at BBA, and then fold up all the headings, the file will now be displayed in org-mode as:

* A...
* B...
* C...

and if I now evil-goto-mark with the intention of going back to BBA, emacs will only place point on B without unfolding any of the headings, so the way the file is displayed remains unchanged.

Instead, I'd like emacs to unfold just BBA and all of its parent headings (but no sibling headings) like so:

* A...
* B
** BA...
** BB
*** BBA
* C...

and place point on the exact location I marked at BBA.

4
  • 3
    C-c C-r is org-reveal which shows the hierachy above with out siblings. C-u C-c C-r includes siblings too. More control is availably via org-show-context Commented Sep 24, 2017 at 10:15
  • Unfortunately, org-reveal does not seem to solve my issue, or at least I can't figure out how to apply it to my problem. Please see my comments in reply to Heikki's answer below.
    – izkon
    Commented Sep 24, 2017 at 20:23
  • Your last display is exactly what C-u C-c C-r gives in this situation. Commented Sep 25, 2017 at 7:50
  • Unfortunately, it does absolutely nothing for me. I've described the exact steps I tried in my replies to Heikki's answer below. For a moment I suspect that maybe this was because I had an older version of evil installed, but I just installed the newest version from git and it still doesn't work. (I'm using emacs 25.3.1 on Gentoo amd64)
    – izkon
    Commented Sep 25, 2017 at 17:45

3 Answers 3

1

You could define a custom function :

(defun evil-goto-and-unfold ()
  (interactive)
  (progn
    (evil-goto-mark)
    (show-subtree)))

It is untested as-is as I do not use evil-mode myself, but might work as I bumped on the same limitations/weirdnesses of org-reveal as you, and I solved it with show-subtree.

0

This does what you want -- except it does not show the sister heading BA.

Function Signature
(org-reveal &optional SIBLINGS)

Documentation
Show current entry, hierarchy above it, and the following headline.

This can be used to show a consistent set of context around
locations exposed with org-show-context.

With optional argument SIBLINGS, on each level of the hierarchy all
siblings are shown.  This repairs the tree structure to what it would
look like when opened with hierarchical calls to org-cycle.

With a C-u C-u prefix, go to the parent and show the entire tree.

Key Bindings
org-mode-map <menu-bar> <Org> <Show/Hide> <Reveal Context>
org-mode-map C-c C-r
9
  • I'm having trouble getting org-reveal to do anything when the headings are all folded and point is on * B ... (where evil-goto-mark places it). Could you give an example of exactly how when I could use this command?
    – izkon
    Commented Sep 24, 2017 at 7:27
  • Put cursor on the BBA line in your sample text, press Shift-Tab until the mini-buffer says OVERVIEW. The press C-c C-r to reveal the cursor line and its parents.
    – Heikki
    Commented Sep 24, 2017 at 19:22
  • I see what you mean, and that does work in the case when point is actually on the BBA line and org-shift-tab is used to fold up the outline. But the situation I described in my question is quite different: I've not only folded up the outline but also moved point away from BBA. I need to both jump back to the BBA line and then unfold properly. I don't see how I can do that. If I do an evil-set-marker at BBA, fold up the outline, move point away, and then evil-goto-marker, emacs takes me back to just the folded * B... line where org-reveal does nothing.
    – izkon
    Commented Sep 24, 2017 at 20:22
  • Try this: Put cursor on BBA, press C-Space (set-mark-command) twice and and move the cursor away. When you want to return, press C-u C-Space to return to the mark. You can then fold the org hierarchy the way you want using Shift-tab or org-reveal. The only caveat is that before you return, you might run a command that automatically sets the mark in a new position.
    – Heikki
    Commented Sep 26, 2017 at 8:14
  • Thank you for staying with me for this. Unfortunately, after I put my cursor on BBA and press C-Space twice and move the cursors away, C-u C-Space does not return to the mark for me. If I had pressed C-Space only once instead of twice, then C-u C-Space does return to the mark for me. But even then, returning to the mark only works if I haven't in the meantime folded up the outline. I want to be able to first fold up the outline before returning to the mark, and have the outline automatically unfolded as I have described in my original question when I return to mark.
    – izkon
    Commented Sep 26, 2017 at 20:08
-1

Lisp function org-show-context works. This is the command used by me to open file at point.


(defun my-find-file-at-point-with-line ()
  "Opens the file at point and goes to line-number."
  (interactive)
  ;; TODO: support file like "d:\\asbc\\dd.txt"
  (if (eq major-mode 'org-mode)
    (org-open-at-point)
    (let ((fname (ffap-file-at-point)))
      (if fname
        (let ((line
               (save-excursion
                 (goto-char (cadr ffap-string-at-point-region))
                 (and (re-search-backward ":\\([0-9]+\\)"
                                          (line-beginning-position) t)
                      (string-to-number (match-string 1))))))
          ;;(message "file:%s,line:%s" fname line)
          (when (and (tramp-tramp-file-p default-directory)
                     (= ?/ (aref fname 0)))
            ;; if fname is an absolute path in remote machine, it will not return a tramp path,fix it here.
            (let ((pos (position ?: default-directory)))
              (if (not pos) (error "failed find first tramp indentifier ':'"))
              (setf pos (position ?: default-directory :start (1+ pos)))
              (if (not pos) (error "failed find second tramp indentifier ':'"))
              (setf fname (concat (substring default-directory 0 (1+ pos)) fname))))
          (find-file-existing fname)
          (when line (goto-line line))
          ;; make sure context in point is visible.
          (when (and buffer-file-name (string-match "\\.org$" buffer-file-name))
            (org-show-context)))
        (warn "File does not exist.")))))
2
  • 2
    Welcome to Emacs.SE! Please expand your answer to show how OP can use this function.
    – Dan
    Commented Nov 29, 2018 at 14:15
  • 1
    What @Dan said. Define "works"; show how it works.
    – Drew
    Commented Nov 29, 2018 at 17:31

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.