mirror of
https://github.com/org-roam/org-roam
synced 2025-08-01 12:17:21 -05:00
1563 lines
56 KiB
Org Mode
1563 lines
56 KiB
Org Mode
#+title: Org-roam User Manual
|
||
#+author: Jethro Kuan
|
||
#+email: jethrokuan95@gmail.com
|
||
#+date: 2020-2021
|
||
#+language: en
|
||
|
||
#+texinfo_deffn: t
|
||
#+texinfo_dir_category: Emacs
|
||
#+texinfo_dir_title: Org-roam: (org-roam).
|
||
#+texinfo_dir_desc: Roam Research for Emacs.
|
||
#+subtitle: for version 2.0.0
|
||
|
||
#+options: H:4 num:3 toc:nil creator:t ':t
|
||
#+property: header-args :eval never
|
||
#+texinfo: @noindent
|
||
|
||
This manual is for Org-roam version 2.0.0.
|
||
|
||
#+BEGIN_QUOTE
|
||
Copyright (C) 2020-2021 Jethro Kuan <jethrokuan95@gmail.com>
|
||
|
||
You can redistribute this document and/or modify it under the terms of the GNU
|
||
General Public License as published by the Free Software Foundation, either
|
||
version 3 of the License, or (at your option) any later version.
|
||
|
||
This document is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
General Public License for more details.
|
||
#+END_QUOTE
|
||
|
||
* Introduction
|
||
|
||
Org-roam is a tool for networked thought. It reproduces some of [[https://roamresearch.com/][Roam
|
||
Research's]] [fn:roam] key features within [[https://orgmode.org/][Org-mode]].
|
||
|
||
Org-roam allows for effortless non-hierarchical note-taking: with Org-roam,
|
||
notes flow naturally, making note-taking fun and easy. Org-roam augments the
|
||
Org-mode syntax, and will work for anyone already using Org-mode for their
|
||
personal wiki.
|
||
|
||
Org-roam leverages the mature ecosystem around Org-mode. For example, it has
|
||
first-class support for [[https://github.com/jkitchin/org-ref][org-ref]] for citation management, and is able to
|
||
piggyback off Org's excellent LaTeX and source-block evaluation capabilities.
|
||
|
||
Org-roam provides these benefits over other tooling:
|
||
|
||
- *Privacy and Security:* Your personal wiki belongs only to you, entirely
|
||
offline and in your control. Encrypt your notes with GPG.
|
||
- *Longevity of Plain Text:* Unlike web solutions like Roam Research, the notes
|
||
are first and foremost plain Org-mode files -- Org-roam simply builds an
|
||
auxiliary database to give the personal wiki superpowers. Having your notes
|
||
in plain-text is crucial for the longevity of your wiki. Never have to worry
|
||
about proprietary web solutions being taken down. The notes are still
|
||
functional even if Org-roam ceases to exist.
|
||
- *Free and Open Source:* Org-roam is free and open-source, which means that if
|
||
you feel unhappy with any part of Org-roam, you may choose to extend Org-roam,
|
||
or open a pull request.
|
||
- *Leverage the Org-mode ecosystem:* Over the decades, Emacs and Org-mode has
|
||
developed into a mature system for plain-text organization. Building upon
|
||
Org-mode already puts Org-roam light-years ahead of many other solutions.
|
||
- *Built on Emacs:* Emacs is also a fantastic interface for editing text, and
|
||
Org-roam inherits many of the powerful text-navigation and editing packages
|
||
available to Emacs.
|
||
|
||
* Target Audience
|
||
|
||
Org-roam is a tool that will appear unfriendly to anyone unfamiliar with Emacs
|
||
and Org-mode, but it is also extremely powerful to those willing to put effort
|
||
inn mastering the intricacies. Org-roam stands on the shoulders on giants. Emacs
|
||
was first created in 1976, and remains the tool of choice for many for editing
|
||
text and designing textual interfaces. The malleability of Emacs allowed the
|
||
creation of Org-mode, an all-purpose plain-text system for maintaining TODO
|
||
lists, planning projects, and authoring documents. Both of these tools are
|
||
incredibly vast and require significant time investment to master.
|
||
|
||
Org-roam assumes only basic familiarity with these tools. It is not difficult to
|
||
get up and running with basic text-editing functionality, but one will only
|
||
fully appreciate the power of building Roam functionality into Emacs and
|
||
Org-mode when the usage of these tools become more advanced.
|
||
|
||
One key advantage to Org-roam is that building on top of Emacs gives it
|
||
malleability. This is especially important for note-taking workflows. It is our
|
||
belief that note-taking workflows are extremely personal, and there is no one
|
||
tool that's perfect for you. Org-mode and Org-roam allows you to discover what
|
||
works for you, and build that perfect tool for yourself.
|
||
|
||
If you are new to the software, and choose to take this leap of faith, I hope
|
||
you find yourself equally entranced as Neal Stephenson was.
|
||
|
||
#+BEGIN_QUOTE
|
||
Emacs outshines all other editing software in approximately the same way that
|
||
the noonday sun does the stars. It is not just bigger and brighter; it simply
|
||
makes everything else vanish. – Neal Stephenson, In the Beginning was the
|
||
Command Line (1998)
|
||
#+END_QUOTE
|
||
|
||
* A Brief Introduction to the Zettelkasten Method
|
||
|
||
Org-roam provides utilities for maintaining a digital slip-box. This section
|
||
aims to provide a brief introduction to the "slip-box", or "Zettelkasten"
|
||
method. By providing some background on the method, we hope that the design
|
||
decisions of Org-roam will become clear, and that will aid in using Org-roam
|
||
appropriately. In this section we will introduce terms commonly used within the
|
||
Zettelkasten community and the Org-roam forums.
|
||
|
||
The Zettelkasten is a personal tool for thinking and writing. It places heavy
|
||
emphasis on connecting ideas, building up a web of thought. Hence, it is well
|
||
suited for knowledge workers and intellectual tasks, such as conducting
|
||
research. The Zettelkasten can act as a research partner, where conversations
|
||
with it may produce new and surprising lines of thought.
|
||
|
||
This method is attributed to German sociologist Niklas Luhmann, who using the
|
||
method had produced volumes of written works. Luhmann's slip-box was simply a
|
||
box of cards. These cards are small -- often only large enough to fit a single
|
||
concept. The size limitation encourages ideas to be broken down into individual
|
||
concepts. These ideas are explicitly linked together. The breakdown of ideas
|
||
encourages tangential exploration of ideas, increasing the surface for thought.
|
||
Making linking explicit between notes also encourages one to think about the
|
||
connections between concepts.
|
||
|
||
At the corner of each note, Luhmann ascribed each note with an ordered ID,
|
||
allowing him to link and jump between notes. In Org-roam, we simply use
|
||
hyperlinks.
|
||
|
||
Org-roam is the slip-box, digitalized in Org-mode. Every zettel (card) is a
|
||
plain-text, Org-mode file. In the same way one would maintain a paper slip-box,
|
||
Org-roam makes it easy to create new zettels, pre-filling boilerplate content
|
||
using a powerful templating system.
|
||
|
||
** Fleeting notes
|
||
|
||
A slip-box requires a method for quickly capturing ideas. These are called
|
||
*fleeting notes*: they are simple reminders of information or ideas that will
|
||
need to be processed later on, or trashed. This is typically accomplished using
|
||
~org-capture~ (see info:org#Capture), or using Org-roam's daily notes
|
||
functionality (see [[*Daily-notes][Daily-notes]]). This provides a central inbox for collecting
|
||
thoughts, to be processed later into permanent notes.
|
||
|
||
** Permanent notes
|
||
|
||
Permanent notes are further split into two categories: *literature notes* and
|
||
*concept notes*. Literature notes can be brief annotations on a particular
|
||
source (e.g. book, website or paper), that you'd like to access later on.
|
||
Concept notes require much more care in authoring: they need to be
|
||
self-explanatory and detailed. Org-roam's templating system supports the
|
||
addition of different templates to facilitate the creation of these notes.
|
||
|
||
* Installation
|
||
|
||
Org-roam can be installed using Emacs' package manager or manually from its
|
||
development repository.
|
||
|
||
** Installing from MELPA
|
||
|
||
Org-roam is available from Melpa and Melpa-Stable. If you haven't used Emacs'
|
||
package manager before, you may familiarize yourself with it by reading the
|
||
documentation in the Emacs manual, see info:emacs#Packages. Then, add one of the
|
||
archives to =package-archives=:
|
||
|
||
- To use Melpa:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(require 'package)
|
||
(add-to-list 'package-archives
|
||
'("melpa" . "http://melpa.org/packages/") t)
|
||
#+END_SRC
|
||
|
||
- To use Melpa-Stable:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(require 'package)
|
||
(add-to-list 'package-archives
|
||
'("melpa-stable" . "http://stable.melpa.org/packages/") t)
|
||
#+END_SRC
|
||
|
||
Org-roam also depends on a recent version of Org, which can be obtained in Org's
|
||
package repository (see info:org#Installation). To use Org's ELPA archive:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-to-list 'package-archives '("org" . "https://orgmode.org/elpa/") t)
|
||
#+END_SRC
|
||
|
||
Once you have added your preferred archive, you need to update the
|
||
local package list using:
|
||
|
||
#+BEGIN_EXAMPLE
|
||
M-x package-refresh-contents RET
|
||
#+END_EXAMPLE
|
||
|
||
Once you have done that, you can install Org-roam and its dependencies
|
||
using:
|
||
|
||
#+BEGIN_EXAMPLE
|
||
M-x package-install RET org-roam RET
|
||
#+END_EXAMPLE
|
||
|
||
Now see [[*Post-Installation Tasks][Post-Installation Tasks]].
|
||
|
||
** Installing from Apt
|
||
|
||
Users of Debian 11 or later or Ubuntu 20.10 or later can simply install Org-roam
|
||
using Apt:
|
||
|
||
#+BEGIN_SRC bash
|
||
apt-get install elpa-org-roam
|
||
#+END_SRC
|
||
|
||
Org-roam will then be autoloaded into Emacs.
|
||
|
||
** Installing from the Git Repository
|
||
|
||
You may install Org-roam directly from the repository on [[https://github.com/org-roam/org-roam][GitHub]] if you like.
|
||
This will give you access to the latest version hours or days before it appears
|
||
on MELPA, and months (or more) before it is added to the Debian or Ubuntu
|
||
repositories. This will also give you access to various developmental branches
|
||
that may be available.
|
||
|
||
Note, however, that development version, and especially any feature branches,
|
||
may not always be in working order. You'll need to be prepared to do some
|
||
debugging, or to manually roll-back to working versions, if you install from
|
||
GitHub.
|
||
|
||
Installing from GitHub requires that you clone the repository:
|
||
|
||
#+begin_src bash
|
||
git clone https://github.com/org-roam/org-roam.git /path/to/org/roam
|
||
#+end_src
|
||
|
||
where ~./path/to/org/roam~ is the location you will store your copy of the code.
|
||
|
||
Next, you need to add this location to your load path, and ~require~ the
|
||
Org-roam library. Add the following code to your ~.emacs~:
|
||
|
||
#+begin_src elisp
|
||
(add-to-list 'load-path "/path/to/org/roam")
|
||
(require 'org-roam)
|
||
#+end_src
|
||
|
||
You now have Org-roam installed. However, you don't necessarily have the
|
||
dependencies that it requires. These include:
|
||
|
||
- dash
|
||
- f
|
||
- s
|
||
- org
|
||
- emacsql
|
||
- emacsql-sqlite3
|
||
|
||
You can install this manually as well, or get the latest version from MELPA. You
|
||
may wish to use [[https://github.com/jwiegley/use-package][use-package]], [[https://github.com/raxod502/straight.el][straight.el]] to help manage this.
|
||
|
||
If you would like to install the manual for access from Emacs' built-in Info
|
||
system, you'll need to compile the .texi source file, and install it in an
|
||
appropriate location.
|
||
|
||
To compile the .texi source file, from a terminal navigate to the ~/doc~
|
||
subdirectory of the Org-roam repository, and run the following:
|
||
|
||
#+begin_src bash
|
||
make infodir=/path/to/my/info/files install-info
|
||
#+end_src
|
||
|
||
Where ~/path/to/my/info/files~ is the location where you keep info files. This
|
||
target directory needs to be stored in the variable
|
||
`Info-default-directory-list`. If you aren't using one of the default info
|
||
locations, you can configure this with the following in your ~.emacs~ file:
|
||
|
||
#+begin_src elisp
|
||
(require 'info)
|
||
(add-to-list 'Info-default-directory-list
|
||
"/path/to/my/info/files")
|
||
#+end_src
|
||
|
||
You can also use one of the default locations, such as:
|
||
|
||
- /usr/local/share/info/
|
||
- /usr/share/info/
|
||
- /usr/local/share/info/
|
||
|
||
If you do this, you'll need to make sure you have write-access to that location,
|
||
or run the above ~make~ command as root.
|
||
|
||
Now that the info file is ready, you need to add it to the corresponding ~dir~
|
||
file:
|
||
|
||
#+begin_src bash
|
||
install-info /path/to/my/info/files/org-roam.info /path/to/my/info/files/dir
|
||
#+end_src
|
||
|
||
** Post-Installation Tasks
|
||
|
||
Org-roam requires ~sqlite3~ to be located on ~exec-path~. Please ensure that
|
||
~sqlite3~ is installed appropriately on your operating system. You can verify
|
||
that this is the case by executing:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(executable-find "sqlite3")
|
||
#+END_SRC
|
||
|
||
If you have ~sqlite3~ installed, and ~executable-find~ still reports ~nil~, then
|
||
it is likely that the path to the executable is not a member of the Emacs
|
||
variable ~exec-path~. You may rectify this by manually adding the path within
|
||
your Emacs configuration:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-to-list 'exec-path "path/to/sqlite3")
|
||
#+END_SRC
|
||
|
||
* Getting Started
|
||
|
||
** The Org-roam Node
|
||
|
||
We first begin with some terminology we'll use throughout the manual. We term
|
||
the basic denomination in Org-roam a node. We define a node as follows:
|
||
|
||
#+begin_quote
|
||
A node is any headline or top level file with an ID.
|
||
#+end_quote
|
||
|
||
For example, with this example file content:
|
||
|
||
#+begin_src org
|
||
:PROPERTIES:
|
||
:ID: foo
|
||
:END:
|
||
,#+title: Foo
|
||
|
||
,* Bar
|
||
:PROPERTIES:
|
||
:ID: bar
|
||
:END:
|
||
#+end_src
|
||
|
||
We create two nodes:
|
||
|
||
1. A file node "Foo" with id ~foo~.
|
||
2. A headline node "Bar" with id ~bar~.
|
||
|
||
Headlines without IDs will not be considered Org-roam nodes. Org IDs can be
|
||
added to files or headlines via the interactive command ~M-x org-id-get-create~.
|
||
|
||
** Links between Nodes
|
||
|
||
We link between nodes using Org's standard ID link (e.g. ~id:foo~). While only
|
||
ID links will be considered during the computation of links between nodes,
|
||
Org-roam caches all other links in the documents for external use.
|
||
|
||
** Setting up Org-roam
|
||
|
||
Org-roam's primary capability comes from its aggressive caching: it crawls all
|
||
files within ~org-roam-directory~, keeping a cache of all its links and nodes,
|
||
and making sure that the cache is consistent.
|
||
|
||
To first start using Org-roam, one needs to pick a location to store the
|
||
Org-roam files. The directory that will contain your notes is specified by the
|
||
variable ~org-roam-directory~. Org-roam searches recursively within
|
||
~org-roam-directory~ for notes. This variable needs to be set before any calls
|
||
to Org-roam functions. For this tutorial, create an empty directory, and set
|
||
~org-roam-directory~:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(make-directory "~/org-roam")
|
||
(setq org-roam-directory "~/org-roam")
|
||
#+END_SRC
|
||
|
||
Next, we need to setup Org-roam to maintain cache consistency. This is achieved
|
||
by running ~M-x org-roam-setup~. To ensure that Org-roam is available on
|
||
startup, one can place this in their Emacs configuration:
|
||
|
||
#+begin_src emacs-lisp
|
||
(require 'org-roam)
|
||
(org-roam-setup)
|
||
#+end_src
|
||
|
||
To build the cache manually, one can run ~M-x org-roam-db-build-cache~. Cache
|
||
builds may take a while the first time, but is often instantaneous in subsequent
|
||
runs because it only reprocesses modified files.
|
||
|
||
** TODO Creating New Notes
|
||
|
||
Let us now create our first node. Call ~M-x org-roam-find-file~. This shows a
|
||
list of titles for nodes that reside in ~org-roam-directory~. It should show
|
||
nothing right now, since there are no notes in the directory. Entering the title
|
||
of the note you wish to create, and pressing ~RET~ should begin the note
|
||
creation process. This process uses ~org-capture~'s templating system, and can
|
||
be customized (see [[*The Templating System][The Templating System]]). Using the default template, pressing
|
||
~C-c C-c~ finishes the note capture.
|
||
|
||
For experienced ~org-capture~ users, the behavior of ~M-x org-roam-find-file~
|
||
may seem unfamiliar: after finishing a capture with ~C-c C-c~, you are returned
|
||
not to the original buffer from which you called ~M-x org-roam-find-file~, but
|
||
to a buffer pointing to the note you just created. For the usual ~org-capture~
|
||
behavior you can call ~M-x org-roam-capture~ instead of ~M-x org-roam-find-file~.
|
||
|
||
Org-roam makes it easy to create notes, and link them together. To link notes
|
||
together, we call ~M-x org-roam-insert~. This brings up a prompt with a list of
|
||
title for existing notes. Selecting an existing entry will create and insert a
|
||
link to the current file. Entering a non-existent title will create a new note
|
||
with that title. Good usage of Org-roam requires liberally linking files: this
|
||
facilitates building up a dense graph of inter-connected notes.
|
||
|
||
Org-roam provides an interface to view backlinks. It shows backlinks for the
|
||
currently active Org-roam note, along with some surrounding context. To toggle
|
||
the visibility of this buffer, call ~M-x org-roam~.
|
||
|
||
For a visual representation of the notes and their connections, Org-roam also
|
||
provides graphing capabilities, using Graphviz. It generates graphs with notes
|
||
as nodes, and links between them as edges. The generated graph can be used to
|
||
navigate to the files, but this requires some additional setup (see [[*Roam
|
||
Protocol][Roam Protocol]]).
|
||
|
||
* TODO Node Properties
|
||
** TODO Standard Org properties
|
||
** TODO Aliases
|
||
** TODO Refs
|
||
Refs are unique identifiers for files. For example, a note for a website may
|
||
contain a ref:
|
||
|
||
#+BEGIN_SRC org
|
||
#+title: Google
|
||
#+roam_key: https://www.google.com/
|
||
#+END_SRC
|
||
|
||
These keys allow references to the key to show up in the backlinks buffer. For
|
||
instance, with the example above, if another file then links to
|
||
https://www.google.com, that will show up as a “Ref Backlink”.
|
||
|
||
These keys also come in useful for when taking website notes, using the
|
||
~roam-ref~ protocol (see [[*Roam Protocol][Roam Protocol]]).
|
||
|
||
[[https://github.com/jkitchin/org-ref][org-ref]] citation keys can also be used as refs:
|
||
|
||
#+BEGIN_SRC org
|
||
#+title: Neural Ordinary Differential Equations
|
||
#+roam_key: cite:chen18_neural_ordin_differ_equat
|
||
#+END_SRC
|
||
|
||
#+CAPTION: org-ref-citelink
|
||
[[file:images/org-ref-citelink.png]]
|
||
|
||
You may assign multiple refs to a single file, for example when you want
|
||
multiple papers in a series to share the same note, or an article has a citation
|
||
key and a URL at the same time.
|
||
|
||
* TODO The Org-roam Buffer
|
||
* TODO Styling Org-roam
|
||
* TODO Completion
|
||
* TODO Encryption
|
||
* TODO Org-roam protocol
|
||
* TODO Diagnosing and Repair
|
||
* TODO Building Extensions
|
||
** TODO Public Interface
|
||
|
||
Database (for developers)
|
||
- querying: (org-roam-db-query)
|
||
- updating full database: (org-roam-db-sync)
|
||
- update current file: (org-roam-db-update-file)
|
||
- remove file from database: (org-roam-db-clear-file)
|
||
|
||
Nodes:
|
||
- List all nodes
|
||
- Read a node in from completion
|
||
- Get node at point
|
||
|
||
Links:
|
||
- Get backlinks for node
|
||
|
||
Tags:
|
||
- Add tag to node
|
||
- delete tag for node
|
||
- Get tags for node
|
||
|
||
Aliases:
|
||
- Add alias to node
|
||
- Delete alias for node
|
||
- Get aliases for node
|
||
|
||
Ref:
|
||
- Add ref to node
|
||
|
||
Capture:
|
||
|
||
Navigation:
|
||
- Find or create a node
|
||
-
|
||
|
||
|
||
* TODO The Org-mode Ecosystem
|
||
* TODO Frequently Asked Questions
|
||
* The Templating System
|
||
|
||
Rather than creating blank files on ~org-roam-insert~ and ~org-roam-find-file~,
|
||
it may be desirable to prefill the file with templated content. This may
|
||
include:
|
||
|
||
- Time of creation
|
||
- File it was created from
|
||
- Clipboard content
|
||
- Any other data you may want to input manually
|
||
|
||
This requires a complex template insertion system. Fortunately, Org ships with a
|
||
powerful one: ~org-capture~ (see info:org#capture). However, org-capture was not
|
||
designed for such use. Org-roam abuses ~org-capture~, extending its syntax and
|
||
capabilities. To first understand how org-roam's templating system works, it may
|
||
be useful to look into basic usage of ~org-capture~.
|
||
|
||
For these reasons, Org-roam capture templates are not compatible with regular
|
||
~org-capture~. Hence, Org-roam's templates can be customized by instead
|
||
modifying the variable ~org-roam-capture-templates~. Just like
|
||
~org-capture-templates~, ~org-roam-capture-templates~ can contain multiple
|
||
templates. If ~org-roam-capture-templates~ only contains one template, there
|
||
will be no prompt for template selection.
|
||
|
||
** Template Walkthrough
|
||
|
||
To demonstrate the additions made to org-capture templates. Here, we walkthrough
|
||
the default template, reproduced below.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
("d" "default" plain (function org-roam--capture-get-point)
|
||
"%?"
|
||
:file-name "%<%Y%m%d%H%M%S>-${slug}"
|
||
:head "#+title: ${title}\n"
|
||
:unnarrowed t)
|
||
#+END_SRC
|
||
|
||
1. The template has short key ~"d"~. If you have only one template, org-roam
|
||
automatically chooses this template for you.
|
||
2. The template is given a description of ~"default"~.
|
||
3. ~plain~ text is inserted. Other options include Org headings via
|
||
~entry~.
|
||
4. ~(function org-roam--capture-get-point)~ should not be changed.
|
||
5. ~"%?"~ is the template inserted on each call to ~org-roam-capture--capture~.
|
||
This template means don't insert any content, but place the cursor here.
|
||
6. ~:file-name~ is the file-name template for a new note, if it doesn't yet
|
||
exist. This creates a file at path that looks like
|
||
~/path/to/org-roam-directory/20200213032037-foo.org~. This template also
|
||
allows you to specify if you want the note to go into a subdirectory. For
|
||
example, the template ~private/${slug}~ will create notes in
|
||
~/path/to/org-roam-directory/private~.
|
||
7. ~:head~ contains the initial template to be inserted (once only), at
|
||
the beginning of the file. Here, the title global attribute is
|
||
inserted.
|
||
8. ~:unnarrowed t~ tells org-capture to show the contents for the whole
|
||
file, rather than narrowing to just the entry.
|
||
|
||
Other options you may want to learn about include ~:immediate-finish~.
|
||
|
||
** Org-roam Template Expansion
|
||
|
||
Org-roam's template definitions also extend org-capture's template syntax, to
|
||
allow prefilling of strings. We have seen a glimpse of this in [[*Template Walkthrough][Template
|
||
Walkthrough]].
|
||
|
||
In org-roam templates, the ~${var}~ syntax allows for the expansion of
|
||
variables, stored in ~org-roam-capture--info~. For example, during
|
||
~org-roam-insert~, the user is prompted for a title. Upon entering a
|
||
non-existent title, the ~title~ key in ~org-roam-capture--info~ is set to the
|
||
provided title. ~${title}~ is then expanded into the provided title during the
|
||
org-capture process. Any variables that do not contain strings, are prompted for
|
||
values using ~completing-read~.
|
||
|
||
After doing this expansion, the org-capture's template expansion system is used
|
||
to fill up the rest of the template. You may read up more on this on
|
||
[[https://orgmode.org/manual/Template-expansion.html#Template-expansion][org-capture's documentation page]].
|
||
|
||
To illustrate this dual expansion process, take for example the template string:
|
||
~"%<%Y%m%d%H%M%S>-${title}"~, with the title ~"Foo"~. The template is first
|
||
expanded into ~%<%Y%m%d%H%M%S>-Foo~. Then org-capture expands ~%<%Y%m%d%H%M%S>~
|
||
with timestamp: e.g. ~20200213032037-Foo~.
|
||
|
||
All of the flexibility afforded by Emacs and Org-mode are available. For
|
||
example, if you want to encode a UTC timestamp in the filename, you can take
|
||
advantage of org-mode's ~%(EXP)~ template expansion to call ~format-time-string~
|
||
directly to provide its third argument to specify UTC.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
("d" "default" plain (function org-roam--capture-get-point)
|
||
"%?"
|
||
:file-name "%(format-time-string \"%Y-%m-%d--%H-%M-%SZ--${slug}\" (current-time) t)"
|
||
:head "#+title: ${title}\n"
|
||
:unnarrowed t)
|
||
#+END_SRC
|
||
|
||
* Concepts and Configuration
|
||
The number of configuration options is deliberately kept small, to keep the
|
||
Org-roam codebase manageable. However, we attempt to accommodate as many usage
|
||
styles as possible.
|
||
|
||
All of Org-roam's customization options can be viewed via ~M-x customize-group
|
||
org-roam~.
|
||
|
||
** Directories and Files
|
||
|
||
This section concerns the placement and creation of files.
|
||
|
||
- Variable: org-roam-directory
|
||
|
||
This is the default path to Org-roam files. All Org files, at any level of
|
||
nesting, are considered part of the Org-roam.
|
||
|
||
- Variable: org-roam-db-location
|
||
|
||
Location of the Org-roam database. If this is non-nil, the Org-roam sqlite
|
||
database is saved here.
|
||
|
||
It is the user’s responsibility to set this correctly, especially when used
|
||
with multiple Org-roam instances.
|
||
|
||
- Variable: org-roam-file-exclude-regexp
|
||
|
||
Files matching this regular expression are excluded from the Org-roam.
|
||
|
||
** The Org-roam Buffer
|
||
|
||
The Org-roam buffer displays backlinks for the currently active Org-roam note.
|
||
|
||
- User Option: org-roam-buffer
|
||
|
||
The name of the org-roam buffer. Defaults to ~*org-roam*~.
|
||
|
||
- User Option: org-roam-buffer-position
|
||
|
||
The position of the Org-roam buffer side window. Valid values are ~'left~,
|
||
~'right~, ~'top~, ~'bottom~.
|
||
|
||
- User Option: org-roam-buffer-width
|
||
|
||
Width of ~org-roam-buffer~. Has an effect only if ~org-roam-buffer-position~ is
|
||
~'left~ or ~'right~.
|
||
|
||
- User Option: org-roam-buffer-height
|
||
|
||
Height of ~org-roam-buffer~. Has an effect only if ~org-roam-buffer-position~ is
|
||
~'top~ or ~'bottom~.
|
||
|
||
- User Option: org-roam-buffer-window-parameters
|
||
|
||
Additional window parameters for the org-roam-buffer side window.
|
||
|
||
For example one can prevent the window from being deleted when calling
|
||
~delete-other-windows~, by setting it with the following:
|
||
|
||
~(setq org-roam-buffer-window-parameters '((no-delete-other-windows . t)))~
|
||
|
||
** Org-roam Files
|
||
|
||
Org-roam files are created and prefilled using Org-roam's templating
|
||
system. The templating system is customizable (see [[*The Templating System][The Templating System]]).
|
||
|
||
** Org-roam Faces
|
||
|
||
Org-roam introduces several faces to distinguish links within the same buffer.
|
||
These faces are enabled by default in Org-roam notes.
|
||
|
||
- User Option: org-roam-link-use-custom-faces
|
||
|
||
When ~t~, use custom faces only inside Org-roam notes.
|
||
When ~everywhere~, the custom face is applied additionally to non Org-roam notes.
|
||
When ~nil~, do not use Org-roam's custom faces.
|
||
|
||
The ~org-roam-link~ face is the face applied to links to other Org-roam files.
|
||
This distinguishes internal links from external links (e.g. external web links).
|
||
|
||
The ~org-roam-link-current~ face corresponds to links to the same file it is in.
|
||
|
||
The ~org-roam-link-invalid~ face is applied to links that are broken. These are
|
||
links to files or IDs that cannot be found.
|
||
|
||
* Inserting Links
|
||
|
||
The preferred mode of linking is via ~file~ links to files, and ~id~ links for
|
||
headlines. This maintains the strongest compatibility with Org-mode, ensuring
|
||
that the links still function without Org-roam, and work well exporting to other
|
||
backends.
|
||
|
||
~file~ links can be inserted via ~org-roam-insert~. Links to headlines can be
|
||
inserted by navigating to the desired headline and calling ~org-store-link~.
|
||
This will create an ID for the headline if it does not already exist, and
|
||
populate the Org-roam database. The link can then be inserted via
|
||
~org-insert-link~.
|
||
|
||
An alternative mode of insertion is using Org-roam's ~roam~ links. Org-roam
|
||
registers this link type, and interprets the path as follows:
|
||
|
||
- ~[[roam:title]]~ :: links to an Org-roam file with title or alias "title"
|
||
- ~[[roam:*headline]]~ :: links to the headline "headline" in the current
|
||
Org-roam file
|
||
- ~[[roam:title*headline]]~ :: links to the headline "headline" in the Org-roam
|
||
file with title or alias "title"
|
||
|
||
- User Option: org-roam-link-title-format
|
||
|
||
To distinguish between org-roam links and regular links, one may choose to use
|
||
special indicators for Org-roam links. Defaults to ~"%s"~.
|
||
|
||
If your version of Org is at least ~9.2~, consider styling the link differently,
|
||
by customizing the ~org-roam-link~, and ~org-roam-link-current~ faces.
|
||
|
||
- User Option: org-roam-link-auto-replace
|
||
|
||
When non-nil, ~roam~ links will be replaced with ~file~ or ~id~ links when
|
||
they are navigated to, and on file save, when a match is found. This is
|
||
desirable to maintain compatibility with vanilla Org, but resolved links are
|
||
harder to edit. Defaults to ~t~.
|
||
|
||
* Completions
|
||
|
||
Completions for Org-roam are provided via ~completion-at-point~. Completion
|
||
suggestions are implemented as separate functions. Org-roam installs all
|
||
functions in ~org-roam-completion-functions~ to ~completion-at-point-functions~.
|
||
|
||
- Variable: org-roam-completion-functions
|
||
|
||
The list of functions to be used with ~completion-at-point~.
|
||
|
||
- User Option: org-roam-completion-ignore-case
|
||
|
||
When non-nil, the ~roam~ link completions are ignore case. For example,
|
||
calling ~completion-at-point~ within ~[[roam:fo]]~ will present a completion
|
||
for a file with title "Foo". Defaults to ~t~.
|
||
|
||
To use the completions from Org-roam with ~company-mode~, prepend ~company-capf~
|
||
to variable ~company-backends~.
|
||
|
||
** Link Completion
|
||
|
||
~roam~ links support auto-completion via ~completion-at-point~: simply call
|
||
~M-x completion-at-point~ within a roam link. That is, where the ~|~ character
|
||
represents the cursor:
|
||
|
||
- ~[[|]]~: completes for a file title
|
||
- ~[[roam:]]~: completes for a file title
|
||
- ~[[*|]]~: completes for a headline within this file
|
||
- ~[[foo*|]]~: completes a headline within the file with title "foo"
|
||
- ~[[roam:foo*|]]~ completes a headline within the file with title "foo"
|
||
|
||
Completions account for the current input. For example, for ~[[f|]]~, the
|
||
completions (by default) only show for files with titles that start with "f".
|
||
|
||
- Function: org-roam-link-complete-at-point
|
||
|
||
Do appropriate completion for the link at point.
|
||
|
||
*** Link Completions Everywhere
|
||
|
||
Org-roam is able to provide completions from the current word at point, enabling
|
||
as-you-type link completions. However, this is disabled by default: the author
|
||
believes that linking should be a deliberate action and linking should be
|
||
performed with great care.
|
||
|
||
Setting ~org-roam-completion-everywhere~ to ~t~ will enable word-at-point
|
||
completions.
|
||
|
||
- User Option: org-roam-completion-everywhere
|
||
|
||
If non-nil, provide completions from the current word at point. That is, in
|
||
the scenario ~this is a sent|~, calling ~completion-at-point~ will show
|
||
completions for titles that begin with "sent".
|
||
|
||
** Tag Completion
|
||
|
||
Org-roam facilitates the insertion of existing tags via ~completion-at-point~.
|
||
|
||
That is, suppose you have notes with tags "foo", and "bar". Now, in a note, if
|
||
you're on a line beginning with ~#+roam_tags:~, completions for these will
|
||
appear as-you-type if they match.
|
||
|
||
This functionality is implemented in ~org-roam-complete-tags-at-point~.
|
||
|
||
* Navigating Around
|
||
** Index File
|
||
|
||
As your collection grows, you might want to create an index where you keep links
|
||
to your main files.
|
||
|
||
In Org-roam, you can define the path to your index file by setting
|
||
~org-roam-index-file~.
|
||
|
||
- Variable: org-roam-index-file
|
||
|
||
Path to the Org-roam index file.
|
||
|
||
The path can be a string or a function. If it is a string, it should be the
|
||
path (absolute or relative to ~org-roam-directory~) to the index file. If it
|
||
is is a function, the function should return the path to the index file.
|
||
Otherwise, the index is assumed to be a note in ~org-roam-index~ whose
|
||
title is ~"Index"~.
|
||
|
||
- Function: org-roam-find-index
|
||
|
||
Opens the Index file in the current ~org-roam-directory~.
|
||
|
||
* Encryption
|
||
|
||
One may wish to keep private, encrypted files. Org-roam supports encryption (via
|
||
GPG), which can be enabled for all new files by setting ~org-roam-encrypt-files~
|
||
to ~t~. When enabled, new files are created with the ~.org.gpg~ extension and
|
||
decryption are handled automatically by EasyPG.
|
||
|
||
Note that Emacs will prompt for a password for encrypted files during cache
|
||
updates if it requires reading the encrypted file. To reduce the number of
|
||
password prompts, you may wish to cache the password.
|
||
|
||
- User Option: org-roam-encrypt-files
|
||
|
||
Whether to encrypt new files. If true, create files with .org.gpg extension.
|
||
|
||
* Graphing
|
||
|
||
Org-roam provides graphing capabilities to explore interconnections between
|
||
notes. This is done by performing SQL queries and generating images using
|
||
[[https://graphviz.org/][Graphviz]]. The graph can also be navigated: see [[*Roam Protocol][Roam Protocol]].
|
||
|
||
The entry point to graph creation is ~org-roam-graph~.
|
||
|
||
- Function: org-roam-graph & optional arg file node-query
|
||
|
||
Build and possibly display a graph for FILE from NODE-QUERY.
|
||
If FILE is nil, default to current buffer’s file name.
|
||
ARG may be any of the following values:
|
||
|
||
- ~nil~ show the graph.
|
||
- ~C-u~ show the graph for FILE.
|
||
- ~C-u N~ show the graph for FILE limiting nodes to N steps.
|
||
- ~C-u C-u~ build the graph.
|
||
- ~C-u -~ build the graph for FILE.
|
||
- ~C-u -N~ build the graph for FILE limiting nodes to N steps.
|
||
|
||
- User Option: org-roam-graph-executable
|
||
|
||
Path to the graphing executable (in this case, Graphviz). Set this if Org-roam
|
||
is unable to find the Graphviz executable on your system.
|
||
|
||
You may also choose to use ~neato~ in place of ~dot~, which generates a more
|
||
compact graph layout.
|
||
|
||
- User Option: org-roam-graph-viewer
|
||
|
||
Org-roam defaults to using Firefox (located on PATH) to view the SVG, but you
|
||
may choose to set it to:
|
||
|
||
1. A string, which is a path to the program used
|
||
2. a function accepting a single argument: the graph file path.
|
||
|
||
~nil~ uses ~view-file~ to view the graph.
|
||
|
||
If you are using WSL2 and would like to open the graph in Windows, you can use
|
||
the second option to set the browser and network file path:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq org-roam-graph-viewer
|
||
(lambda (file)
|
||
(let ((org-roam-graph-viewer "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"))
|
||
(org-roam-graph--open (concat "file://///wsl$/Ubuntu" file)))))
|
||
#+END_SRC
|
||
|
||
** Graph Options
|
||
|
||
Graphviz provides many options for customizing the graph output, and Org-roam
|
||
supports some of them. See https://graphviz.gitlab.io/_pages/doc/info/attrs.html
|
||
for customizable options.
|
||
|
||
- User Option: org-roam-graph-extra-config
|
||
|
||
Extra options passed to graphviz for the digraph (The "G" attributes).
|
||
Example: ~'~(("rankdir" . "LR"))~
|
||
|
||
- User Option: org-roam-graph-node-extra-config
|
||
|
||
Extra options for nodes in the graphviz output (The "N" attributes).
|
||
Example: ~'(("color" . "skyblue"))~
|
||
|
||
- User Option: org-roam-graph-edge-extra-config
|
||
|
||
Extra options for edges in the graphviz output (The "E" attributes).
|
||
Example: ~'(("dir" . "back"))~
|
||
|
||
- User Option: org-roam-graph-edge-cites-extra-config
|
||
|
||
Extra options for citation edges in the graphviz output.
|
||
Example: ~'(("color" . "red"))~
|
||
|
||
** Excluding Nodes and Edges
|
||
|
||
One may want to exclude certain files to declutter the graph.
|
||
|
||
- User Option: org-roam-graph-exclude-matcher
|
||
|
||
Matcher for excluding nodes from the generated graph. Any nodes and links for
|
||
file paths matching this string is excluded from the graph.
|
||
|
||
If value is a string, the string is the only matcher.
|
||
|
||
If value is a list, all file paths matching any of the strings
|
||
are excluded.
|
||
|
||
#+BEGIN_EXAMPLE
|
||
(setq org-roam-graph-exclude-matcher '("private" "dailies"))
|
||
#+END_EXAMPLE
|
||
|
||
This setting excludes all files whose path contain "private" or "dailies".
|
||
|
||
* Minibuffer Completion
|
||
|
||
Org-roam allows customization of which minibuffer completion system to use for
|
||
its interactive commands. The default setting uses Emacs' standard
|
||
~completing-read~ mechanism.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq org-roam-completion-system 'default)
|
||
#+END_SRC
|
||
|
||
If you have installed Helm or Ivy, and have their modes enabled, under the
|
||
~'default~ setting they will be used.
|
||
|
||
In the rare scenario where you use Ivy globally, but prefer [[https://emacs-helm.github.io/helm/][Helm]] for org-roam
|
||
commands, set:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq org-roam-completion-system 'helm)
|
||
#+END_SRC
|
||
|
||
Other options include ~'ido~, and ~'ivy~.
|
||
|
||
* Roam Protocol
|
||
|
||
Org-roam extends ~org-protocol~ with 2 protocols: the ~roam-file~ and ~roam-ref~
|
||
protocols.
|
||
|
||
** Installation
|
||
|
||
To enable Org-roam's protocol extensions, you have to add the following to your
|
||
init file:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(require 'org-roam-protocol)
|
||
#+END_SRC
|
||
|
||
The instructions for setting up ~org-protocol~ are reproduced below.
|
||
|
||
We will also need to create a desktop application for ~emacsclient~. The
|
||
instructions for various platforms are shown below.
|
||
|
||
For Linux users, create a desktop application in
|
||
~~/.local/share/applications/org-protocol.desktop~:
|
||
|
||
#+begin_example
|
||
[Desktop Entry]
|
||
Name=Org-Protocol
|
||
Exec=emacsclient %u
|
||
Icon=emacs-icon
|
||
Type=Application
|
||
Terminal=false
|
||
MimeType=x-scheme-handler/org-protocol
|
||
#+end_example
|
||
|
||
Associate ~org-protocol://~ links with the desktop application by
|
||
running in your shell:
|
||
|
||
#+BEGIN_SRC bash
|
||
xdg-mime default org-protocol.desktop x-scheme-handler/org-protocol
|
||
#+END_SRC
|
||
|
||
To disable the "confirm" prompt in Chrome, you can also make Chrome show a
|
||
checkbox to tick, so that the ~Org-Protocol Client~ app will be used without
|
||
confirmation. To do this, run in a shell:
|
||
|
||
#+BEGIN_SRC bash
|
||
sudo mkdir -p /etc/opt/chrome/policies/managed/
|
||
sudo tee /etc/opt/chrome/policies/managed/external_protocol_dialog.json >/dev/null <<'EOF'
|
||
{
|
||
"ExternalProtocolDialogShowAlwaysOpenCheckbox": true
|
||
}
|
||
EOF
|
||
sudo chmod 644 /etc/opt/chrome/policies/managed/external_protocol_dialog.json
|
||
#+END_SRC
|
||
|
||
and then restart Chrome (for example, by navigating to <chrome://restart>) to
|
||
make the new policy take effect.
|
||
|
||
See [[https://www.chromium.org/administrators/linux-quick-start][here]] for more info on the ~/etc/opt/chrome/policies/managed~ directory and
|
||
[[https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ExternalProtocolDialogShowAlwaysOpenCheckbox][here]] for information on the ~ExternalProtocolDialogShowAlwaysOpenCheckbox~ policy.
|
||
|
||
For MacOS, we need to create our own application.
|
||
|
||
1. Launch Script Editor
|
||
2. Use the following script, paying attention to the path to ~emacsclient~:
|
||
|
||
#+begin_src emacs-lisp
|
||
on open location this_URL
|
||
set EC to "/usr/local/bin/emacsclient --no-wait "
|
||
set filePath to quoted form of this_URL
|
||
do shell script EC & filePath
|
||
tell application "Emacs" to activate
|
||
end open location
|
||
#+end_src
|
||
|
||
3. Save the script in ~/Applications/OrgProtocolClient.app~, changing the script type to
|
||
"Application", rather than "Script".
|
||
4. Edit ~/Applications/OrgProtocolClient.app/Contents/Info.plist~, adding the
|
||
following before the last ~</dict>~ tag:
|
||
|
||
#+begin_src text
|
||
<key>CFBundleURLTypes</key>
|
||
<array>
|
||
<dict>
|
||
<key>CFBundleURLName</key>
|
||
<string>org-protocol handler</string>
|
||
<key>CFBundleURLSchemes</key>
|
||
<array>
|
||
<string>org-protocol</string>
|
||
</array>
|
||
</dict>
|
||
</array>
|
||
#+end_src
|
||
|
||
5. Save the file, and run the ~OrgProtocolClient.app~ to register the protocol.
|
||
|
||
To disable the "confirm" prompt in Chrome, you can also make Chrome
|
||
show a checkbox to tick, so that the ~OrgProtocol~ app will be used
|
||
without confirmation. To do this, run in a shell:
|
||
|
||
#+BEGIN_SRC bash
|
||
defaults write com.google.Chrome ExternalProtocolDialogShowAlwaysOpenCheckbox -bool true
|
||
#+END_SRC
|
||
|
||
|
||
If you're using [[https://github.com/railwaycat/homebrew-emacsmacport][Emacs Mac Port]], it registered its `Emacs.app` as the default
|
||
handler for the URL scheme `org-protocol`. To make ~OrgProtocol.app~
|
||
the default handler instead, run:
|
||
|
||
#+BEGIN_SRC bash
|
||
defaults write com.apple.LaunchServices/com.apple.launchservices.secure LSHandlers -array-add \
|
||
'{"LSHandlerPreferredVersions" = { "LSHandlerRoleAll" = "-"; }; LSHandlerRoleAll = "org.yourusername.OrgProtocol"; LSHandlerURLScheme = "org-protocol";}'
|
||
#+END_SRC
|
||
|
||
Then restart your computer.
|
||
|
||
For Windows, create a temporary ~org-protocol.reg~ file:
|
||
|
||
#+BEGIN_SRC text
|
||
REGEDIT4
|
||
|
||
[HKEY_CLASSES_ROOT\org-protocol]
|
||
@="URL:Org Protocol"
|
||
"URL Protocol"=""
|
||
[HKEY_CLASSES_ROOT\org-protocol\shell]
|
||
[HKEY_CLASSES_ROOT\org-protocol\shell\open]
|
||
[HKEY_CLASSES_ROOT\org-protocol\shell\open\command]
|
||
@="\"C:\\Windows\\System32\\wsl.exe\" emacsclient \"%1\""
|
||
#+END_SRC
|
||
|
||
The above will forward the protocol to WSL. If you run Emacs natively on
|
||
Windows, replace the last line with:
|
||
|
||
#+BEGIN_SRC text
|
||
@="\"c:\\path\\to\\emacs\\bin\\emacsclientw.exe\" \"%1\""
|
||
#+END_SRC
|
||
|
||
After executing the .reg file, the protocol is registered and you can delete the
|
||
file.
|
||
|
||
** The roam-file protocol
|
||
|
||
This is a simple protocol that opens the path specified by the ~file~
|
||
key (e.g. ~org-protocol://roam-file?file=/tmp/file.org~). This is used
|
||
in the generated graph.
|
||
|
||
** The roam-ref protocol
|
||
|
||
This protocol finds or creates a new note with a given ~roam_key~:
|
||
|
||
[[file:images/roam-ref.gif]]
|
||
|
||
To use this, create the following [[https://en.wikipedia.org/wiki/Bookmarklet][bookmarklet]] in your browser:
|
||
|
||
#+BEGIN_SRC javascript
|
||
javascript:location.href =
|
||
'org-protocol://roam-ref?template=r&ref='
|
||
+ encodeURIComponent(location.href)
|
||
+ '&title='
|
||
+ encodeURIComponent(document.title)
|
||
+ '&body='
|
||
+ encodeURIComponent(window.getSelection())
|
||
#+END_SRC
|
||
|
||
or as a keybinding in ~qutebrowser~ in , using the ~config.py~ file (see
|
||
[[https://github.com/qutebrowser/qutebrowser/blob/master/doc/help/configuring.asciidoc][Configuring qutebrowser]]):
|
||
|
||
#+BEGIN_SRC python
|
||
config.bind("<Ctrl-r>", "open javascript:location.href='org-protocol://roam-ref?template=r&ref='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)")
|
||
#+END_SRC
|
||
|
||
where ~template~ is the template key for a template in
|
||
~org-roam-capture-ref-templates~ (see [[*The Templating System][The Templating System]]). These templates
|
||
should contain a ~#+roam_key: ${ref}~ in it.
|
||
|
||
* Daily-notes
|
||
|
||
Org-roam provides journaling capabilities akin to
|
||
[[#org-journal][Org-journal]] with ~org-roam-dailies~.
|
||
|
||
** Configuration
|
||
|
||
For ~org-roam-dailies~ to work, you need to define two variables:
|
||
|
||
- Variable: ~org-roam-dailies-directory~
|
||
|
||
Path to daily-notes.
|
||
|
||
- Variable: ~org-roam-dailies-capture-templates~
|
||
|
||
Capture templates for daily-notes in Org-roam.
|
||
|
||
Here is a sane default configuration:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq org-roam-dailies-directory "daily/")
|
||
|
||
(setq org-roam-dailies-capture-templates
|
||
'(("d" "default" entry
|
||
#'org-roam-capture--get-point
|
||
"* %?"
|
||
:file-name "daily/%<%Y-%m-%d>"
|
||
:head "#+title: %<%Y-%m-%d>\n\n")))
|
||
#+end_src
|
||
|
||
Make sure that ~org-roam-dailies-directory~ appears in ~:file-name~ for your
|
||
notes to be recognized as daily-notes. You can have different templates placing
|
||
their notes in different directories, but the one in
|
||
~org-roam-dailies-directory~ will be considered as the main one in commands.
|
||
|
||
See [[*The Templating System][The Templating System]] for creating new
|
||
templates. ~org-roam-dailies~ provides an extra ~:olp~ option which allows
|
||
specifying the outline-path to a heading:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq org-roam-dailies-capture-templates
|
||
'(("l" "lab" entry
|
||
#'org-roam-capture--get-point
|
||
"* %?"
|
||
:file-name "daily/%<%Y-%m-%d>"
|
||
:head "#+title: %<%Y-%m-%d>\n"
|
||
:olp ("Lab notes"))
|
||
|
||
("j" "journal" entry
|
||
#'org-roam-capture--get-point
|
||
"* %?"
|
||
:file-name "daily/%<%Y-%m-%d>"
|
||
:head "#+title: %<%Y-%m-%d>\n"
|
||
:olp ("Journal"))))
|
||
#+end_src
|
||
|
||
The template ~l~ will put its notes under the heading ‘Lab notes’, and the
|
||
template ~j~ will put its notes under the heading ‘Journal’.
|
||
|
||
** Capturing and finding daily-notes
|
||
|
||
- Function: ~org-roam-dailies-capture-today~ &optional goto
|
||
|
||
Create an entry in the daily note for today.
|
||
|
||
When ~goto~ is non-nil, go the note without creating an entry.
|
||
|
||
- Function: ~org-roam-dailies-find-today~
|
||
|
||
Find the daily note for today, creating it if necessary.
|
||
|
||
There are variants of those commands for ~-yesterday~ and ~-tomorrow~:
|
||
|
||
- Function: ~org-roam-dailies-capture-yesterday~ n &optional goto
|
||
|
||
Create an entry in the daily note for yesteday.
|
||
|
||
With numeric argument ~n~, use the daily note ~n~ days in the past.
|
||
|
||
- Function: ~org-roam-dailies-find-yesterday~
|
||
|
||
With numeric argument N, use the daily-note N days in the future.
|
||
|
||
There are also commands which allow you to use Emacs’s ~calendar~ to find the date
|
||
|
||
- Function: ~org-roam-dailies-capture-date~
|
||
|
||
Create an entry in the daily note for a date using the calendar.
|
||
|
||
Prefer past dates, unless ~prefer-future~ is non-nil.
|
||
|
||
With a 'C-u' prefix or when ~goto~ is non-nil, go the note without
|
||
creating an entry.
|
||
|
||
- Function: ~org-roam-dailies-find-date~
|
||
|
||
Find the daily note for a date using the calendar, creating it if necessary.
|
||
|
||
Prefer past dates, unless ~prefer-future~ is non-nil.
|
||
|
||
** Navigation
|
||
|
||
You can navigate between daily-notes:
|
||
|
||
- Function: ~org-roam-dailies-find-directory~
|
||
|
||
Find and open ~org-roam-dailies-directory~.
|
||
|
||
- Function: ~org-roam-dailies-find-previous-note~
|
||
|
||
When in an daily-note, find the previous one.
|
||
|
||
- Function: ~org-roam-dailies-find-next-note~
|
||
|
||
When in an daily-note, find the next one.
|
||
|
||
* Diagnosing and Repairing Files
|
||
|
||
Org-roam provides a utility for diagnosing and repairing problematic files via
|
||
~org-roam-doctor~. By default, ~org-roam-doctor~ runs the check on the current
|
||
Org-roam file. To run the check only for all Org-roam files, run ~C-u M-x
|
||
org-roam-doctor~, but note that this may take some time.
|
||
|
||
- Function: org-roam-doctor &optional this-buffer
|
||
|
||
Perform a check on Org-roam files to ensure cleanliness. If THIS-BUFFER, run
|
||
the check only for the current buffer.
|
||
|
||
The checks run are defined in ~org-roam-doctor--checkers~. By default, there are
|
||
checkers for broken links and invalid =#+roam_*= properties.
|
||
|
||
Each checker is an instance of ~org-roam-doctor-checker~. To define a checker,
|
||
use ~make-org-roam-doctor-checker~. Here is a sample definition:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(make-org-roam-doctor-checker
|
||
:name 'org-roam-doctor-broken-links
|
||
:description "Fix broken links."
|
||
:actions '(("d" . ("Unlink" . org-roam-doctor--remove-link))
|
||
("r" . ("Replace link" . org-roam-doctor--replace-link))
|
||
("R" . ("Replace link (keep label)" . org-roam-doctor--replace-link-keep-label))))
|
||
#+END_SRC
|
||
|
||
The ~:name~ property is the name of the function run. The function takes in the
|
||
Org parse tree, and returns a list of ~(point error-message)~. ~:description~ is
|
||
a short description of what the checker does. ~:actions~ is an alist containing
|
||
elements of the form ~(char . (prompt . function))~. These actions are defined
|
||
per checker, to perform autofixes for the errors. For each error detected,
|
||
~org-roam-doctor~ will move the point to the current error, and pop-up a help
|
||
window displaying the error message, as well as the list of actions that can be
|
||
taken provided in ~:actions~.
|
||
|
||
* Finding Unlinked References
|
||
|
||
Unlinked references are occurrences of strings of text that exactly match the
|
||
title or alias of an existing note in the Org-roam database. Org-roam provides
|
||
facilities for discovering these unlinked references, so one may decide whether
|
||
to convert them into links.
|
||
|
||
To use this feature, simply call ~M-x org-roam-unlinked-references~ from within
|
||
an Org-roam note. Internally, Org-roam uses [[https://github.com/BurntSushi/ripgrep][ripgrep]] and a clever PCRE regex to
|
||
find occurrences of the title or aliases of the currently open note in all
|
||
Org-roam files. Hence, this requires a version of ripgrep that is compiled with
|
||
PCRE support.
|
||
|
||
#+begin_quote
|
||
NOTE: Since ripgrep cannot read encrypted files, this function cannot find
|
||
unlinked references within encrypted files.
|
||
#+end_quote
|
||
|
||
* Performance Optimization
|
||
** TODO Profiling Key Operations
|
||
** Garbage Collection
|
||
|
||
During the cache-build process, Org-roam generates a lot of in-memory
|
||
data-structures (such as the Org file's AST), which are discarded after use.
|
||
These structures are garbage collected at regular intervals (see [[info:elisp#Garbage
|
||
Collection][info:elisp#Garbage Collection]]).
|
||
|
||
Org-roam provides the option ~org-roam-db-gc-threshold~ to temporarily change
|
||
the threshold value for GC to be triggered during these memory-intensive
|
||
operations. To reduce the number of garbage collection processes, one may set
|
||
~org-roam-db-gc-threshold~ to a high value (such as ~most-positive-fixnum~):
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq org-roam-db-gc-threshold most-positive-fixnum)
|
||
#+END_SRC
|
||
|
||
* _ Copying
|
||
:PROPERTIES:
|
||
:COPYING: t
|
||
:END:
|
||
|
||
#+BEGIN_QUOTE
|
||
Copyright (C) 2020-2020 Jethro Kuan <jethrokuan95@gmail.com>
|
||
|
||
You can redistribute this document and/or modify it under the terms
|
||
of the GNU General Public License as published by the Free Software
|
||
Foundation, either version 3 of the License, or (at your option) any
|
||
later version.
|
||
|
||
This document is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
General Public License for more details.
|
||
#+END_QUOTE
|
||
|
||
* Appendix
|
||
** Note-taking Workflows
|
||
- Books ::
|
||
- [[https://www.goodreads.com/book/show/34507927-how-to-take-smart-notes][How To Take Smart Notes]]
|
||
- Articles ::
|
||
- [[https://www.lesswrong.com/posts/NfdHG6oHBJ8Qxc26s/the-zettelkasten-method-1][The Zettelkasten Method - LessWrong 2.0]]
|
||
- [[https://reddit.com/r/RoamResearch/comments/eho7de/building_a_second_brain_in_roamand_why_you_might][Building a Second Brain in Roam...And Why You Might Want To : RoamResearch]]
|
||
- [[https://www.nateliason.com/blog/roam][Roam Research: Why I Love It and How I Use It - Nat Eliason]]
|
||
- [[https://twitter.com/adam_keesling/status/1196864424725774336?s=20][Adam Keesling's Twitter Thread]]
|
||
- [[https://blog.jethro.dev/posts/how_to_take_smart_notes_org/][How To Take Smart Notes With Org-mode · Jethro Kuan]]
|
||
- Threads ::
|
||
- [[https://news.ycombinator.com/item?id=22473209][Ask HN: How to Take Good Notes]]
|
||
- Videos ::
|
||
- [[https://www.youtube.com/watch?v=RvWic15iXjk][How to Use Roam to Outline a New Article in Under 20 Minutes]]
|
||
** Ecosystem
|
||
|
||
*** Browsing History with winner-mode
|
||
|
||
~winner-mode~ is a global minor mode that allows one to undo and redo changes in
|
||
the window configuration. It is included with GNU Emacs since version 20.
|
||
|
||
~winner-mode~ can be used as a simple version of browser history for Org-roam.
|
||
Each click through org-roam links (from both Org files and the backlinks buffer)
|
||
causes changes in window configuration, which can be undone and redone using
|
||
~winner-mode~. To use ~winner-mode~, simply enable it, and bind the appropriate
|
||
interactive functions:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(winner-mode +1)
|
||
(define-key winner-mode-map (kbd "<M-left>") #'winner-undo)
|
||
(define-key winner-mode-map (kbd "<M-right>") #'winner-redo)
|
||
|
||
#+END_SRC
|
||
*** Versioning Notes
|
||
|
||
Since Org-roam notes are just plain text, it is trivial to track changes in your
|
||
notes database using version control systems such as [[https://git-scm.com/][Git]]. Simply initialize
|
||
~org-roam-directory~ as a Git repository, and commit your files at regular or
|
||
appropriate intervals. [[https://magit.vc/][Magit]] is a great interface to Git within Emacs.
|
||
|
||
In addition, it may be useful to observe how a particular note has evolved, by
|
||
looking at the file history. [[https://gitlab.com/pidu/git-timemachine][Git-timemachine]] allows you to visit historic
|
||
versions of a tracked Org-roam note.
|
||
|
||
*** Full-text search interface with Deft
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: deft
|
||
:END:
|
||
|
||
[[https://jblevins.org/projects/deft/][Deft]] provides a nice interface for browsing and filtering org-roam notes.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package deft
|
||
:after org
|
||
:bind
|
||
("C-c n d" . deft)
|
||
:custom
|
||
(deft-recursive t)
|
||
(deft-use-filter-string-for-filename t)
|
||
(deft-default-extension "org")
|
||
(deft-directory "/path/to/org-roam-files/"))
|
||
#+END_SRC
|
||
|
||
If the title of the Org file is not the first line, you might not get nice
|
||
titles. You may choose to patch this to use ~org-roam~'s functionality. Here I'm
|
||
using [[https://github.com/raxod502/el-patch][el-patch]]:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package el-patch
|
||
:straight (:host github
|
||
:repo "raxod502/el-patch"
|
||
:branch "develop"))
|
||
|
||
(eval-when-compile
|
||
(require 'el-patch))
|
||
#+END_SRC
|
||
|
||
The Deft interface can slow down quickly when the number of files get huge.
|
||
[[https://github.com/hasu/notdeft][Notdeft]] is a fork of Deft that uses an external search engine and indexer.
|
||
|
||
*** Org-journal
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: org-journal
|
||
:END:
|
||
|
||
[[https://github.com/bastibe/org-journal][Org-journal]] provides journaling capabilities to Org-mode. A lot of its
|
||
functionalities have been incorporated into Org-roam under the name
|
||
[[*Daily-notes][~org-roam-dailies~]]. It remains a good tool if you want to isolate your verbose
|
||
journal entries from the ideas you would write on a scratchpad.
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package org-journal
|
||
:bind
|
||
("C-c n j" . org-journal-new-entry)
|
||
:custom
|
||
(org-journal-date-prefix "#+title: ")
|
||
(org-journal-file-format "%Y-%m-%d.org")
|
||
(org-journal-dir "/path/to/journal/files/")
|
||
(org-journal-date-format "%A, %d %B %Y"))
|
||
#+END_SRC
|
||
|
||
*** Note-taking Add-ons
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: note-taking-add-ons
|
||
:END:
|
||
|
||
These are some plugins that make note-taking in Org-mode more enjoyable.
|
||
|
||
**** Org-download
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: org-download
|
||
:END:
|
||
|
||
[[https://github.com/abo-abo/org-download][Org-download]] lets you screenshot and yank images from the web into your notes:
|
||
|
||
#+CAPTION: org-download
|
||
[[file:images/org-download.gif]]
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package org-download
|
||
:after org
|
||
:bind
|
||
(:map org-mode-map
|
||
(("s-Y" . org-download-screenshot)
|
||
("s-y" . org-download-yank))))
|
||
#+END_SRC
|
||
|
||
**** mathpix.el
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: mathpix.el
|
||
:END:
|
||
|
||
[[https://github.com/jethrokuan/mathpix.el][mathpix.el]] uses [[https://mathpix.com/][Mathpix's]] API to convert clips into latex equations:
|
||
|
||
#+CAPTION: mathpix
|
||
[[file:images/mathpix.gif]]
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package mathpix.el
|
||
:straight (:host github :repo "jethrokuan/mathpix.el")
|
||
:custom ((mathpix-app-id "app-id")
|
||
(mathpix-app-key "app-key"))
|
||
:bind
|
||
("C-x m" . mathpix-screenshot))
|
||
#+END_SRC
|
||
|
||
**** Org-noter / Interleave
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: org-noter-interleave
|
||
:END:
|
||
|
||
[[https://github.com/weirdNox/org-noter][Org-noter]] and
|
||
[[https://github.com/rudolfochrist/interleave][Interleave]] are both
|
||
projects that allow synchronised annotation of documents (PDF, EPUB
|
||
etc.) within Org-mode.
|
||
|
||
**** Bibliography
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: bibliography
|
||
:END:
|
||
|
||
[[https://github.com/org-roam/org-roam-bibtex][org-roam-bibtex]] offers
|
||
tight integration between
|
||
[[https://github.com/jkitchin/org-ref][org-ref]],
|
||
[[https://github.com/tmalsburg/helm-bibtex][helm-bibtex]] and
|
||
~org-roam~. This helps you manage your bibliographic notes under
|
||
~org-roam~.
|
||
|
||
For example, though helm-bibtex provides the ability to visit notes for
|
||
bibliographic entries, org-roam-bibtex extends it with the ability to visit the
|
||
file with the right =#+roam_key=.
|
||
|
||
**** Spaced Repetition
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: spaced-repetition
|
||
:END:
|
||
|
||
[[https://www.leonrische.me/fc/index.html][Org-fc]] is a spaced repetition system that scales well with a large number of
|
||
files. Other alternatives include [[https://orgmode.org/worg/org-contrib/org-drill.html][org-drill]], and [[https://github.com/abo-abo/pamparam][pamparam]].
|
||
|
||
* FAQ
|
||
** How do I have more than one Org-roam directory?
|
||
|
||
Emacs supports directory-local variables, allowing the value of
|
||
~org-roam-directory~ to be different in different directories. It does this by
|
||
checking for a file named ~.dir-locals.el~.
|
||
|
||
To add support for multiple directories, override the ~org-roam-directory~
|
||
variable using directory-local variables. This is what ~.dir-locals.el~ may
|
||
contain:
|
||
|
||
#+BEGIN_SRC emacs-lisp
|
||
((nil . ((org-roam-directory . ".")
|
||
(org-roam-db-location . "./org-roam.db"))))
|
||
#+END_SRC
|
||
|
||
All files within that directory will be treated as their own separate set of
|
||
Org-roam files. Remember to run ~org-roam-db-build-cache~ from a file within
|
||
that directory, at least once.
|
||
|
||
** How do I migrate from Roam Research?
|
||
|
||
Fabio has produced a command-line tool that converts markdown files exported
|
||
from Roam Research into Org-roam compatible markdown. More instructions are
|
||
provided [[https://github.com/fabioberger/roam-migration][in the repository]].
|
||
|
||
** How do I create a note whose title already matches one of the candidates?
|
||
|
||
This situation arises when, for example, one would like to create a note titled
|
||
"bar" when "barricade" already exists.
|
||
|
||
The solution is dependent on the mini-buffer completion framework in use. Here
|
||
are the solutions:
|
||
|
||
- Ivy :: call ~ivy-immediate-done~, typically bound to ~C-M-j~. Alternatively,
|
||
set ~ivy-use-selectable-prompt~ to ~t~, so that "bar" is now selectable.
|
||
- Helm :: Org-roam should provide a selectable "[?] bar" candidate at the top of
|
||
the candidate list.
|
||
|
||
* Keystroke Index
|
||
:PROPERTIES:
|
||
:APPENDIX: t
|
||
:INDEX: ky
|
||
:COOKIE_DATA: recursive
|
||
:END:
|
||
* Command Index
|
||
:PROPERTIES:
|
||
:APPENDIX: t
|
||
:INDEX: cp
|
||
:END:
|
||
* Function Index
|
||
:PROPERTIES:
|
||
:APPENDIX: t
|
||
:INDEX: fn
|
||
:END:
|
||
* Variable Index
|
||
:PROPERTIES:
|
||
:APPENDIX: t
|
||
:INDEX: vr
|
||
:END:
|
||
|
||
* Footnotes
|
||
|
||
[fn:1] Depending on your completion framework, you may need to press TAB to
|
||
see the list.
|
||
[fn:roam] To understand more about Roam, a collection of links are available in [[*Note-taking Workflows][Note-taking Workflows]].
|
||
|
||
# Local Variables:
|
||
# eval: (require 'ol-info)
|
||
# eval: (require 'ox-texinfo+ nil t)
|
||
# eval: (auto-fill-mode +1)
|
||
# before-save-hook: org-make-toc
|
||
# after-save-hook: (lambda nil (progn (require 'ox-texinfo nil t) (org-texinfo-export-to-info)))
|
||
# indent-tabs-mode: nil
|
||
# org-src-preserve-indentation: nil
|
||
# End:
|