1 ;;; org-jump.el --- navigate over the structure of an org file
3 ;; Author: Christoph Lange <math.semantic.web@gmail.com>
5 ;; Copyright (C) 2016 by Christoph Lange
7 ;; This file is NOT part of GNU Emacs.
9 ;; This program is free software: you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation, either version 3 of the License, or
12 ;; (at your option) any later version.
14 ;; This program is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
22 (defun org-jump-to-child ()
23 "Interactively prompts for the title of a child node of the current heading and jumps to the last child node having that title. This function will not work if the first child node is not exactly one level below the current heading."
25 (let* ((child-position
27 ;; Go to the heading of the current node
29 (let* ((ref-level (org-reduced-level (org-outline-level))))
30 (outline-next-heading)
31 ;; If the next visible heading is one level lower, then ...
32 (if (= (- (org-reduced-level (org-outline-level)) ref-level
) 1)
36 (let* ((old-point (point)))
37 ;; ... continue adding its headline text and the point to a list
38 (add-to-list 'children
40 ;; remove any markup such as links (copied from org-clock-in)
41 (replace-regexp-in-string
42 "\\[\\[.*?\\]\\[\\(.*?\\)\\]\\]" "\\1"
43 (substring-no-properties (nth 4 (org-heading-components))))
45 ;; ... and go to the next sibling.
46 (org-forward-heading-same-level 1 t
)
47 (setq continue
(/= (point) old-point
))))
48 ;; Prompt for a child headline text, ...
49 (let* ((child (org-icompleting-read "Headline text: " (mapcar 'car children
))))
50 ;; ... and return its location (point).
51 (cdr (assoc child children
))))
52 ;; Otherwise return -1.
54 ;; Go to the desired heading and make it visible, or otherwise output an error message.
55 (if (> child-position -
1)
57 (goto-char child-position
)
59 (message "No children."))))
61 (define-key org-mode-map
(kbd "\C-coc") 'org-jump-to-child
)
63 (defun org-jump-to-id ()
64 "Interactively prompts for an identifier and searches for the first node in the current file that has this identifier as a CUSTOM_ID property."
66 (let* ((property "CUSTOM_ID")
67 (custom-id (org-icompleting-read "CUSTOM_ID of entry: "
68 (mapcar 'list
(org-property-values property
)))))
69 ;; What will happen if there is more than one node with this CUSTOM_ID?
70 ;; Alternative implementation:
71 ;; (org-jump-to-first-node-with-property-value property custom-id)
72 (org-link-search (concat "#" custom-id
))))
74 (define-key org-mode-map
(kbd "\C-coj") 'org-jump-to-id
)
76 (defun org-jump-to-first-node-with-property-value (property value
)
82 (org-make-tags-matcher (format "%s=\"%s\"" property value
))))))
85 ;; further idea: org-find-text-property-in-string