Created
March 9, 2017 21:52
-
-
Save mm--/60e0790bcbf8447160cc87a66dc949ab to your computer and use it in GitHub Desktop.
Hydra for quickly refiling Org mode entries
This file contains 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
;; Adapted from https://emacs.stackexchange.com/questions/8045/org-refile-to-a-known-fixed-location | |
(defun my/refile (file headline &optional arg) | |
"Refile to a specific location. | |
With a 'C-u' ARG argument, we jump to that location (see | |
`org-refile'). | |
Use `org-agenda-refile' in `org-agenda' mode." | |
(let* ((pos (with-current-buffer (or (get-buffer file) ;Is the file open in a buffer already? | |
(find-file-noselect file)) ;Otherwise, try to find the file by name (Note, default-directory matters here if it isn't absolute) | |
(or (org-find-exact-headline-in-buffer headline) | |
(error "Can't find headline `%s'" headline)))) | |
(filepath (buffer-file-name (marker-buffer pos)));If we're given a relative name, find absolute path | |
(rfloc (list headline filepath nil pos))) | |
(if (and (eq major-mode 'org-agenda-mode) (not (and arg (listp arg)))) ;Don't use org-agenda-refile if we're just jumping | |
(org-agenda-refile nil rfloc) | |
(org-refile arg nil rfloc)))) | |
(defun josh/refile (file headline &optional arg) | |
"Refile to HEADLINE in FILE. Clean up org-capture if it's activated. | |
With a `C-u` ARG, just jump to the headline." | |
(interactive "P") | |
(let ((is-capturing (and (boundp 'org-capture-mode) org-capture-mode))) | |
(cond | |
((and arg (listp arg)) ;Are we jumping? | |
(my/refile file headline arg)) | |
;; Are we in org-capture-mode? | |
(is-capturing ;Minor mode variable that's defined when capturing | |
(josh/org-capture-refile-but-with-args file headline arg)) | |
(t | |
(my/refile file headline arg))) | |
(when (or arg is-capturing) | |
(setq hydra-deactivate t)))) | |
(defun josh/org-capture-refile-but-with-args (file headline &optional arg) | |
"Copied from `org-capture-refile' since it doesn't allow passing arguments. This does." | |
(unless (eq (org-capture-get :type 'local) 'entry) | |
(error | |
"Refiling from a capture buffer makes only sense for `entry'-type templates")) | |
(let ((pos (point)) | |
(base (buffer-base-buffer (current-buffer))) | |
(org-capture-is-refiling t) | |
(kill-buffer (org-capture-get :kill-buffer 'local))) | |
(org-capture-put :kill-buffer nil) | |
(org-capture-finalize) | |
(save-window-excursion | |
(with-current-buffer (or base (current-buffer)) | |
(org-with-wide-buffer | |
(goto-char pos) | |
(my/refile file headline arg)))) | |
(when kill-buffer (kill-buffer base)))) | |
(defmacro josh/make-org-refile-hydra (hydraname file keyandheadline) | |
"Make a hydra named HYDRANAME with refile targets to FILE. | |
KEYANDHEADLINE should be a list of cons cells of the form (\"key\" . \"headline\")" | |
`(defhydra ,hydraname (:color blue :after-exit (unless (or hydra-deactivate | |
current-prefix-arg) ;If we're just jumping to a location, quit the hydra | |
(josh/org-refile-hydra/body))) | |
,file | |
,@(cl-loop for kv in keyandheadline | |
collect (list (car kv) (list 'josh/refile file (cdr kv) 'current-prefix-arg) (cdr kv))) | |
("q" nil "cancel"))) | |
;;;;;;;;;; | |
;; Here we'll define our refile headlines | |
;;;;;;;;;; | |
(josh/make-org-refile-hydra josh/org-refile-hydra-file-a | |
"file-a.org" | |
(("1" . "Headline 1") | |
("2" . "Headline 2"))) | |
(josh/make-org-refile-hydra josh/org-refile-hydra-file-b | |
"file-b.org" | |
(("1" . "One") | |
("2" . "Two"))) | |
(josh/make-org-refile-hydra josh/org-refile-hydra-file-c | |
"file-c.org" | |
(("1" . "1") | |
("2" . "2"))) | |
(defhydra josh/org-refile-hydra (:foreign-keys run) | |
"Refile" | |
("a" josh/org-refile-hydra-file-a/body "File A" :exit t) | |
("b" josh/org-refile-hydra-file-b/body "File B" :exit t) | |
("c" josh/org-refile-hydra-file-c/body "File C" :exit t) | |
("j" org-refile-goto-last-stored "Jump to last refile" :exit t) | |
("q" nil "cancel")) | |
(global-set-key (kbd "<f9> r") 'josh/org-refile-hydra/body) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment