I have hundreds of org files in a single directory that I use as a personal knowledge base and use deft to quickly find and open them. Each file is automatically named based on the current time (yyyy-mm-dd-hhmm.org) but Deft displays the org file's title instead, which is identified at the beginning of the file with the syntax #+TITLE: <title>.

When using ivy's switch-to-buffer minibuffer, only the filename is displayed for other org file buffers. I would like it to instead display the title listed as <title> above (and potentially display in a different color as well). I'm very new to elisp and can't quite figure out how to do this.

2 Answers 2


The following code renames the buffer to the value of #+TITLE: when you open the Org file. This is the most simple version. It does not update the buffer name when you add or change the title. But in that case you can call org+-buffer-name-to-title directly if you really need it.

(defun org+-buffer-name-to-title ()
  "Rename buffer to value of #+TITLE:."
    (goto-char (point-min))
    (when (re-search-forward "^[[:space:]]*#\\+TITLE:[[:space:]]*\\(.*?\\)[[:space:]]*$" nil t)
      (rename-buffer (match-string 1)))))

(add-hook 'org-mode-hook #'org+-buffer-name-to-title)

An enhanced version that exploits font lock to update the buffer name as you input the value of #+TITLE::

(defun org+-buffer-name-to-title (&optional end)
  "Rename buffer to value of #+TITLE:.
If END is non-nil search for #+TITLE: at `point' and
delimit it to END.
Start an unlimited search at `point-min' otherwise."
  (let ((beg (or (and end (point))
      (when end
    (goto-char end)
    (setq end (line-end-position)))
      (goto-char beg)
      (when (re-search-forward "^[[:space:]]*#\\+TITLE:[[:space:]]*\\(.*?\\)[[:space:]]*$" end t)
    (rename-buffer (match-string 1)))))

(defun org+-buffer-name-to-title-config ()
  "Configure Org to rename buffer to value of #+TITLE:."
  (font-lock-add-keywords nil '(org+-buffer-name-to-title)))

(add-hook 'org-mode-hook #'org+-buffer-name-to-title-config)
  • Thanks so much! I'll have to study your solution to figure out how it works. +1
    – Ryan West
    Jan 11, 2020 at 21:21

Here's another solution that uses the function org-get-title:

(defun org-title-to-buffer-name ()
  (let ((title (org-get-title)))
    (when title
        (rename-buffer title))))

(add-hook 'org-mode-hook 'org-title-to-buffer-name)

I use this since it's not case-sensitive. I don't need the buffer title to be synced directly with the #+TITLE property, so it doesn't use font-lock. It simply makes it more convenient for buffer management.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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