I would like all org-roam buffers to automatically go into a persp-mode.el perspective.

org-roam-mode is a global minor mode, so I can't use that as a way to detect whether a new buffer is for org-roam.

I tried this:

(defun my/roam-buffer (_buffer state)
  (let ((name (buffer-file-name)))
    (when (and name (s-contains-p "/org-roam/" name))
      (if (null state)

(with-eval-after-load 'org-roam
  (setq org-roam-db-location (expand-file-name "~/.org-roam.sqlite"))
  (persp-def-auto-persp "org-roam"
                        :parameters '((dont-save-to-file . t))
                        :predicate 'my/roam-buffer
                        :dyn-env '(after-switch-to-buffer-functions ;; prevent recursion
                                    (persp-add-buffer-on-find-file nil)
                        :hooks '(after-switch-to-buffer-functions)
                        :switch 'frame))

However, (buffer-file-name) in my/roam-buffer is nil. I'm guessing that's because initially when the buffer is created (again I'm guessing persp is hooking into that), it's not linked to a file yet?

How can I achieve what I want?


It appears as though org-roam has a hook specifically for this: org-roam-file-setup-hook. It's not well documented, but from reading the code it looks like it's called whenever an org-roam file is opened.

From my testing, that means when it's done through the normal find-file means, from org-roam-find-file, and probably just about everything else that opens files. This includes creating new files.

Here's the code I used to test, which you can adjust for your needs:

  (defun bjc/test-roam-hook ()
    (message "org roam buffer opened in %S for file %S"
             (current-buffer) (buffer-file-name)))

  (add-hook 'org-roam-file-setup-hook 'bjc/test-roam-hook)
  • Ah, I'd actually forgotten I'd even specified a hook in my persp config code! I'm sure I copied that part... Feb 26 at 18:08
  • Just switching my code to use that hook instead of after-switch-to-buffer-functions seems to have done the trick Feb 26 at 18:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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