Org-mode is a fantastic way to organise information in simple text files. I often use internal links to other sections in a document for navigation, but I’ve found that there is not a great mechanism to quickly insert an internal link. I wanted an interface that would provide me a list of headlines in the document that I could use to select a link target, so I put together the functions below.
These simple functions leverage the fantastic ivy and worf packages, so install them first. Then put the code below into your emacs config file. Then, invoking
M-x bjm/worf-insert-internal-link provides an
ivy completion interface for the list of headlines in the document. Once you select the headline you want as the link target, the link is inserted for you.
;; use ivy to insert a link to a heading in the current document
;; based on `worf-goto`
(defun bjm/worf-insert-internal-link ()
"Use ivy to insert a link to a heading in the current `org-mode' document. Code is based on `worf-goto'."
(let ((cands (worf--goto-candidates)))
(ivy-read "Heading: " cands
(defun bjm/worf-insert-internal-link-action (x)
"Insert link for `bjm/worf-insert-internal-link'"
;; go to heading
(goto-char (cdr x))
;; store link
;; return to original point and insert link
;; org-insert-last-stored-link adds a newline so delete this
Org mode is wonderful for managing todo lists. Usually to add a task, I would run
org-capture using the default
C-c c and then select my todo template by hitting
t. I do this so often that I wanted a shorter shortcut, so I defined a function to call
org-capture with the specific template I wanted and bound this to a simple shortcut (I used
C-9 after removing numeric prefixes):
;; function to capture a todo
(defun bjm/org-capture-todo ()
"Capture a TODO item"
(org-capture nil "t"))
(define-key global-map (kbd "C-9") 'bjm/org-capture-todo)
C-9 takes me straight to my todo capture template.
I was recently managing a set of interviews and I had my notes on all of the candidates in a single org file, with each candidate under their own top-level headline:
* J Kepler
- Nice work on orbits
* I Newton
- Hard to work with
* C Sagan
- Good communication skills
However, I wanted to generate a separate pdf file for each candidate that I could circulate to interviewers (since each interviewer was only interviewing a subset of applicants).
I came across this stackexchange answer that demonstrated how to build a function to export top level headlines to separate files. There are a few variations on that page, and I put together the slightly tweaked version below. All of the credit goes to stackexchange user
itsjeyd for a very detailed answer. In my version I hard code it to export to pdf, save the file first, and apply the export options from the parent file to each of the new files that are created. The new files have a name taken from the headline, with spaces replaced by underscores, unless the
:EXPORT_FILE_NAME: property is set for a headline.
;; export headlines to separate files
(defun org-export-headlines-to-pdf ()
"Export all subtrees that are *not* tagged with :noexport: to
Subtrees that do not have the :EXPORT_FILE_NAME: property set
are exported to a filename derived from the headline text."
(let ((modifiedp (buffer-modified-p)))
(goto-char (re-search-forward "^*"))
(let ((export-file (org-entry-get (point) "EXPORT_FILE_NAME")))
(replace-regexp-in-string " " "_" (nth 4 (org-heading-components)))))
(org-latex-export-to-pdf nil t)
(unless export-file (org-delete-property "EXPORT_FILE_NAME"))
To add or remove a tag from multiple headlines in an org-mode file, select a region containing multiple headlines and then run
M-x org-change-tag-in-region. You’ll be prompted for a tag and asked if you want to add or remove it from the selected headlines.
As I have mentioned before in my tutorial about todo lists and scheduled tasks in org-mode, my preferred way to view my agenda is to use
C-c a n to view a list of my scheduled tasks with unscheduled tasks below that.
I wanted to make a shorter keybinding for this view and I found this advice on how to achieve this. We just need to define a simple helper function like so
;;keybinding for favourite agenda view
(defun org-agenda-show-agenda-and-todo (&optional arg)
(org-agenda arg "n"))
I then add this to my personal key map
(define-key bjm-map (kbd "a") 'org-agenda-show-agenda-and-todo)
and I can pull up my agenda with
C-1 a. You might not want to use the same keybinding as me, but maybe you’ll find the idea helpful.
You can quickly sort tables in
org-mode by using
C-c ^ with the point inside a table. You’ll be prompted for a sorting type, where you can choose e.g.
a for alphabetic or
n for numeric. You can use capital letter versions of these options to reverse the sort.
The table is sorted based on the column that the point is in, and from the documentation:
The range of lines is the range between the nearest horizontal separator lines, or the entire table of no such lines exist.
I love the way that org-mode allows you to add simple clean structures to your text, with lists and tables. You can get some of that functionality in other modes by using
orgtbl-mode, which are part of
Enable these minor modes in any major mode for one-off use with
M-x orgstruct++-mode or
M-x orgtbl-mode and you can use the normal
org-mode commands to create lists and tables. I find this especially useful in emails, so I use this code in my emacs config file to automatically enable these for
;; use org structures and tables in message mode
(add-hook 'message-mode-hook 'turn-on-orgtbl)
(add-hook 'message-mode-hook 'turn-on-orgstruct++)
I recently needed to transpose a table in org-mode and spent a few minutes trying to come up with a keyboard macro to do it before it occurred to me that there might be a command to do this already. And of course there was:
M-x org-table-transpose-table-at-point. Here it is in action:
It’s great when there’s a command that does exactly what you want!
I (all too) often find myself failing to complete all the tasks I schedule for a particular day and so need to reschedule them in my org agenda. To do this (and other operations) on multiple items, mark the items in your agenda view using
m then hit
B to bring up the bulk action list and then
s to reschedule. This will set the new scheduled date to all marked items.
This trick is in the org-mode manual but it’s worth a quick mention in its own right. If you want to start a numbered list in org-mode from a number other than 1, then put
[@N] at the start of the first item, where
N is the number you want to start with. So for example,
1) item 1
2) item 2
This text would interrupt the list and the next item would be 1) on a
3) [@3] This will be item 3 thanks to [@3]
4) and this will be item 4