Instantly share code, notes, and snippets.
Created
April 22, 2020 12:33
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save mskorzhinskiy/7e7d8c39f7b7e4dc73a3c8eb6b2422e1 to your computer and use it in GitHub Desktop.
Customized navigation for org-mode
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; New navigation/edition | |
(defmacro org-user/save-state (&rest body) | |
"Helper for executing BODY with macroses." | |
(declare (debug (body))) | |
`(save-excursion | |
(save-restriction | |
(org-save-outline-visibility nil | |
,@body)))) | |
(defun org-user/current-headline-level () | |
"Get current headline level." | |
(let ((element (org-element-at-point))) | |
(when element | |
(getf (getf element 'headline) :level)))) | |
(defun org-user/narrow-to-content () | |
"Narrow to content." | |
(interactive) | |
(let ((end)) | |
(save-excursion | |
(save-restriction | |
(org-narrow-to-element) | |
(outline-next-heading) | |
(setq end (point)))) | |
(narrow-to-region (point) end))) | |
(defun org-user/fold-all-items () | |
"Fold all items in item list." | |
(interactive) | |
(let ((eos (save-excursion (org-end-of-subtree t t) | |
(when (bolp) (backward-char)) (point)))) | |
(save-excursion | |
(org-back-to-heading) | |
(while (org-list-search-forward (org-item-beginning-re) eos t) | |
(beginning-of-line 1) | |
(let* ((struct (org-list-struct)) | |
(prevs (org-list-prevs-alist struct)) | |
(end (org-list-get-bottom-point struct))) | |
(dolist (e (org-list-get-all-items (point) struct prevs)) | |
(org-list-set-item-visibility e struct 'folded)) | |
(goto-char (if (< end eos) end eos))))))) | |
(defun org-user/item-list-find-in-content () | |
"Goto down to next item list." | |
(catch 'found | |
(org-user/save-state | |
(org-user/narrow-to-content) | |
(org-show-all) | |
(while (not (eobp)) | |
(when (org-at-item-p) | |
(throw 'found (point))) | |
(forward-line) | |
(beginning-of-line))))) | |
(defun org-user/jump-to-item-list () | |
"Jump to nearest item list." | |
(let ((found (org-user/item-list-find-in-content))) | |
(when found | |
(goto-char found) | |
(org-show-set-visibility 'minimal) | |
(org-user/fold-all-items)) | |
found)) | |
(defun org-user/jump-to-child () | |
"Jump to nearest child item." | |
(let ((level (org-user/current-headline-level)) | |
should-go) | |
(save-excursion | |
(outline-next-heading) | |
(setq should-go (< level (org-user/current-headline-level)))) | |
(when should-go | |
(org-show-children) | |
(outline-next-heading)))) | |
(defun org-user/show-item () | |
"Default function for showing item." | |
(outline-hide-subtree) | |
(outline-show-entry) | |
(outline-show-children) | |
(org-user/fold-all-items) | |
(when (org-at-item-p) | |
(org-list-set-item-visibility | |
(point-at-bol) (org-list-struct) 'children))) | |
(defun org-user/up () | |
"Goto to upper item." | |
(interactive) | |
(cond | |
((org-at-item-p) (org-previous-visible-heading 1)) | |
((org-at-heading-p) (org-up-heading-safe)) | |
(t (outline-previous-heading))) | |
(org-user/show-item)) | |
(defun org-user/down () | |
"Goto down hierarhy." | |
(interactive) | |
(cond ((org-at-heading-p) | |
(unless (org-user/jump-to-item-list) | |
(unless (org-user/jump-to-child) | |
(org-forward-paragraph) | |
(org-indent-line))) | |
(org-user/show-item)))) | |
(defun org-user/next () | |
"Go to next thing." | |
(interactive) | |
(cond | |
;; Item | |
((org-at-item-p) | |
(let ((struct (org-list-struct))) | |
(org-list-set-item-visibility | |
(point-at-bol) struct 'folded) | |
(org-next-item) | |
(org-list-set-item-visibility | |
(point-at-bol) struct 'children))) | |
;; Heading | |
((org-at-heading-p) | |
(outline-hide-subtree) | |
(outline-forward-same-level 1) | |
(org-user/show-item)) | |
;; Content \ out of hierarchy | |
(t (forward-line 1)))) | |
(defun org-user/prev () | |
"Go to next thing." | |
(interactive) | |
(cond | |
;; Item | |
((org-at-item-p) | |
(let ((struct (org-list-struct))) | |
(org-list-set-item-visibility | |
(point-at-bol) struct 'folded) | |
(org-previous-item) | |
(org-list-set-item-visibility | |
(point-at-bol) struct 'children))) | |
;; Heading | |
((org-at-heading-p) | |
(outline-hide-subtree) | |
(outline-backward-same-level 1) | |
(org-user/show-item)) | |
;; Content \ out of hierarhy | |
(t (forward-line -1)))) | |
;; Each keybinding folds item under the point and unfolds next item, but only | |
;; 1-level deep. Item can be anything: headline or item list. | |
(define-key org-mode-map (kbd "C-c C-n") #'org-user/next) | |
(define-key org-mode-map (kbd "C-c C-p") #'org-user/prev) | |
;; Up acts as universal "up". With headline or item under the point will jump to | |
;; the parent. But will jump to the current headline if pointer is on the | |
;; headline contents. | |
(define-key org-mode-map (kbd "C-c C-b") #'org-user/up) | |
;; Down will jump to the nearest "child" thing. In that order: | |
;; 1. If there are item lists in current headline, it will jump to the head of the item list; | |
;; 2. If there are children headlines, it will jump to the first child headline; | |
;; 3. If there are nothing, it will jump to the contents; | |
(define-key org-mode-map (kbd "C-c C-f") #'org-user/down) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment