12

If I'm in an org file, I want a command that narrows a candidate list, in ivy/helm style, comprised of all org headlines in the file and lets me choose the headline, through fuzzy searching, to which I want to jump to. Is there a way to do that?

10

The Org Manual node on Motion gives a somewhat laconic description of the built-in command org-goto (default binding: C-c C-j), whose behaviour can easily be customised to achieve the desired effect:

  1. Inspect the documentation of the customisable variable listed at the end of this manual node: C-h v org-goto-interface RET
  2. If you are happy to forgo the default org-goto behaviour of incrementally searching through the buffer's outline, you can switch to picking a headline via completion:

    (setq org-goto-interface 'outline-path-completion)
    
  3. Users of completion packages like ido/ivy/helm will probably want to change the following setting in order to see the whole target path at once:

    (setq org-outline-path-complete-in-steps nil)
    

    See here for more discussion.

This approach has the added benefit (over using, say, helm-specific functionality) of working with all completion frameworks that plug into the default completing-read, including, as I can personally confirm, ivy.

ADDENDUM:

When using the outline-path-completion interface to the org-goto command as described in this answer, the customisable variable org-goto-max-level determines the maximum depth of headlines to offer.

EDIT:

I found an older, relevant question with useful answers: https://stackoverflow.com/q/15011703/3084001

CLARIFICATION (as prompted by Att Righ's comment):

Setting org-goto-interface to one of the two recognised values does not mean sacrificing the alternative interface. Calling org-goto with a prefix argument (i.e. C-u C-c C-j or C-u M-x org-goto RET) automatically selects the alternative interface for the current completion. This way, you can set org-goto-interface to the interface you are likely to use most often and use the prefix argument when you wish to temporarily switch behaviour. If even this does not suit your needs, you can always write your own wrapper around org-goto, as per Att Righ's example.

  • > forgo the default org-goto behaviour, you can work around this by using a let binding around the functional call (defun my-org-goto () (let ((org-goto-interface 'outline-path-completion)) (org-goto))) – Att Righ May 7 '17 at 1:07
  • outline-path-completion does not play nicely with helm on my box (it can't complete past one level - achieved by pressing <TAB> if helm is disabled: see helm-completing-read-handlers-alist) – Att Righ May 7 '17 at 1:28
  • @AttRigh Sure, let-expressions can be used for any sort of temporary binding; this question is more about relevant settings/functionality/packages. A more general way to achieve a temporary switch of interface is to call org-goto with a prefix argument. I'll add a note to this answer. – Basil May 7 '17 at 2:19
  • @AttRigh I remember seeing something similar with ivy, but only when refiling and with an incorrect depth setting in org-refile-targets, as org-goto temporarily adapts refile-relevant settings to suit its needs. Unfortunately I'm not in a position to explore the helm functionality at the moment, perhaps another user can chime in? – Basil May 7 '17 at 2:24
  • 1
    thanks @Basil for the detaild answer. Unfortunately, the completion in this approach does not work as well as worf or counsel-imenu. – ninrod May 8 '17 at 1:48
8

I use the package worf, but I bind only one of its functions:

 (use-package worf
    :diminish worf-mode
    :bind (:map org-mode-map ("C-c h" . worf-goto)))

worf-goto gives you a list of the headings in the buffer in the mini buffer, which you can then filter.

The package is made by the author of ivy, so if you like ivy, you might like worf.

Some relevant snippets from worf.el:

;;  - "g" (`worf-goto'): select an outline in the current buffer, with
;;    completion.  It's very good when you want to search/navigate to
;;    a heading by word or level. See https://github.com/abo-abo/lispy
;;    for a package that uses this method to navigate Lisp code.

(defun worf-goto-action (x)
  (with-ivy-window
    (goto-char (cdr x))
    (outline-show-children 1000)
    (worf-more)))

(defun worf-goto ()
  "Jump to a heading with completion."
  (interactive)
  (let ((cands (worf--goto-candidates)))
    (cond ((eq worf-completion-method 'helm)
           (require 'helm-multi-match)
           (let (helm-update-blacklist-regexps
                 helm-candidate-number-limit)
             (helm :sources
                   `((name . "Headings")
                     (candidates . ,cands)
                     (action . worf-goto-action)
                     (pattern-transformer . worf--pattern-transformer)))))
          ((eq worf-completion-method 'ivy)
           (ivy-read "Heading: " cands
                     :action 'worf-goto-action)))))
  • 1
    thanks @tirocinium. counsel-imenu completion works better than worf but can't search through level1 org headlines. worfs searches all levels, so I think this what I'm looking for. – ninrod May 8 '17 at 1:50
  • @ninrod Have you tried setting org-imenu-depth to something greater than the default of 2? – Sam Jun 11 at 22:04
5

I find helm-org-rifle particularly nice. Also anything that takes imenu source will be able to display headers (e. g. Helm with imenu).

  • It should be noted that helm-org-rifle searches the content of org entries in addition to their titles. I found no way to alter this behaviour. helm-org-rifle references org-search-goto which does search all headlines but doesn't really support fuzzy searching. – Att Righ May 7 '17 at 1:02
  • Att Righ is right, helm-org-rifle does not search only headings. It could be expanded to do this, but there's little reason to do so, since helm-org-in-buffer-headings, etc. exist in Helm itself. – blujay May 8 '17 at 23:09
4

imenu is built into Emacs and can be paired with helm/ivy to provide the fuzzy search required. I'd recommend helm-org-rifle if you use helm, however.

4

The swiper library has a new feature in 0.9.0, which is completion for headlines of files in your org-agenda-files.

counsel-org-agenda-headlines

Just need to setup your agenda files list in org init.

(setq org-agenda-files (list "~/org/work.org"
                             "~/org/school.org" 
                             "~/org/home.org"))

In relation to @tirocinium's answer, this provides the same but for many agenda files.

3

I use counsel-imenu; it will list the different heads, you can type some letters to narrow your selection and then just press <return>.

  • hi @gnuvince. this does not allow me to jump to level 1 org files right? – ninrod May 6 '17 at 20:02
3

Flagrant self-promotion, but you might like to try out orgnav. Which is my kind of alpha (but actively used by me) project for this purpose.

orgnav searches headlines rather than content, can vary the depth of search, search subtrees rather than the entire file (though this can also be achieved with narrowing).

Here's a video of some features: https://asciinema.org/a/1r0fp33xgwh48lfgsh7mllw4u

You should probably also be aware of helm-org package which is part of helm which was the inspiration for this package (or rather whose limitations were the inspiration for this package), as well as helm-org-rifle discussed in other posts.

(Courtesy of answers here: https://www.reddit.com/r/emacs/comments/69mc6l/how_to_jump_directly_to_an_orgheadline/ ) Also potentially of interest is the worf-goto function as part of worf (an org navigation mode that applies a different set of keybindings over "*" before headlines). This seems very much analogous to helm-org.

2

I recommend helm-org-in-buffer-headings. It's built-in to Helm, and it respects narrowed buffers, which is important if you use indirect buffers to edit subtrees independently. There's also helm-org-parent-headings for navigating up a tree, and helm-org-agenda-files-headings for navigating across all agenda files.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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