You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2178 lines
68 KiB
2178 lines
68 KiB
\input texinfo @c -*- texinfo -*- |
|
@c %**start of header |
|
@setfilename org-roam.info |
|
@settitle Org-roam User Manual |
|
@documentencoding UTF-8 |
|
@documentlanguage en |
|
@c %**end of header |
|
|
|
@copying |
|
@quotation |
|
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 quotation |
|
@end copying |
|
|
|
@dircategory Emacs |
|
@direntry |
|
* Org-roam: (org-roam). Rudimentary Roam Replica for Emacs. |
|
@end direntry |
|
|
|
@finalout |
|
@titlepage |
|
@title Org-roam User Manual |
|
@subtitle for version 1.2.3 |
|
@author Jethro Kuan |
|
@page |
|
@vskip 0pt plus 1filll |
|
@insertcopying |
|
@end titlepage |
|
|
|
@ifnottex |
|
@node Top |
|
@top Org-roam User Manual |
|
|
|
@noindent |
|
|
|
This manual is for Org-roam version 1.2.3. |
|
|
|
@quotation |
|
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 quotation |
|
@end ifnottex |
|
|
|
@menu |
|
* Introduction:: |
|
* Target Audience:: |
|
* A Brief Introduction to the Zettelkasten Method:: |
|
* Installation:: |
|
* Getting Started:: |
|
* Files:: |
|
* The Templating System:: |
|
* Concepts and Configuration:: |
|
* Inserting Links:: |
|
* Completions:: |
|
* Navigating Around:: |
|
* Encryption:: |
|
* Graphing:: |
|
* Minibuffer Completion:: |
|
* Roam Protocol:: |
|
* Daily-notes:: |
|
* Diagnosing and Repairing Files:: |
|
* Finding Unlinked References:: |
|
* Performance Optimization:: |
|
* Appendix:: |
|
* FAQ:: |
|
* Keystroke Index:: |
|
* Command Index:: |
|
* Function Index:: |
|
* Variable Index:: |
|
|
|
@detailmenu |
|
--- The Detailed Node Listing --- |
|
|
|
A Brief Introduction to the Zettelkasten Method |
|
|
|
* Fleeting notes:: |
|
* Permanent notes:: |
|
|
|
Installation |
|
|
|
* Installing from MELPA:: |
|
* Installing from Apt:: |
|
* Installing from the Git Repository:: |
|
* Post-Installation Tasks:: |
|
|
|
Files |
|
|
|
* File Titles:: |
|
* File Tags:: |
|
* File Refs:: |
|
|
|
File Titles |
|
|
|
* Customizing Title Extraction:: |
|
|
|
File Tags |
|
|
|
* Customizing Tag Extraction:: |
|
|
|
The Templating System |
|
|
|
* Template Walkthrough:: |
|
* Org-roam Template Expansion:: |
|
|
|
Concepts and Configuration |
|
|
|
* Directories and Files:: |
|
* The Org-roam Buffer:: |
|
* Org-roam Files:: |
|
* Org-roam Faces:: |
|
* The Database:: |
|
|
|
Completions |
|
|
|
* Link Completion:: |
|
* Tag Completion:: |
|
|
|
Link Completion |
|
|
|
* Link Completions Everywhere:: |
|
|
|
Navigating Around |
|
|
|
* Index File:: |
|
|
|
Graphing |
|
|
|
* Graph Options:: |
|
* Excluding Nodes and Edges:: |
|
|
|
Roam Protocol |
|
|
|
* Installation: Installation (1). |
|
* The roam-file protocol:: |
|
* The roam-ref protocol:: |
|
|
|
Daily-notes |
|
|
|
* Configuration:: |
|
* Capturing and finding daily-notes:: |
|
* Navigation:: |
|
|
|
Performance Optimization |
|
|
|
* Profiling Key Operations:: |
|
* Garbage Collection:: |
|
|
|
Appendix |
|
|
|
* Note-taking Workflows:: |
|
* Ecosystem:: |
|
|
|
Ecosystem |
|
|
|
* Browsing History with winner-mode:: |
|
* Versioning Notes:: |
|
* Full-text search interface with Deft:: |
|
* Org-journal:: |
|
* Note-taking Add-ons:: |
|
|
|
Note-taking Add-ons |
|
|
|
* Org-download:: |
|
* mathpix.el: mathpixel. |
|
* Org-noter / Interleave:: |
|
* Bibliography:: |
|
* Spaced Repetition:: |
|
|
|
FAQ |
|
|
|
* How do I have more than one Org-roam directory?:: |
|
* How do I migrate from Roam Research?:: |
|
* How do I create a note whose title already matches one of the candidates?:: |
|
|
|
@end detailmenu |
|
@end menu |
|
|
|
@node Introduction |
|
@chapter Introduction |
|
|
|
Org-roam is a tool for network thought. It reproduces some of @uref{https://roamresearch.com/, Roam |
|
Research's} @footnote{To understand more about Roam, a collection of links are available in @ref{Note-taking Workflows}.} features within the all-powerful @uref{https://orgmode.org/, Org-mode}. |
|
|
|
Org-roam is a solution for effortless non-hierarchical note-taking with |
|
Org-mode. With Org-roam, notes flow naturally, making note-taking fun and easy. |
|
Org-roam keeps closely to Org syntax, and will work for anyone already using |
|
Org-mode for their personal wiki. |
|
|
|
Org-roam gains its superpowers by leveraging the mature ecosystem around |
|
Org-mode. For example, it has first-class support for @uref{https://github.com/jkitchin/org-ref, org-ref} for citation |
|
management. |
|
|
|
Org-roam aims to implement the core features of Roam, leveraging the |
|
mature ecosystem around Org-mode where possible. Eventually, we hope |
|
to further introduce features enabled by the Emacs ecosystem. |
|
|
|
Org-roam provides several benefits over other tooling: |
|
|
|
@itemize |
|
@item |
|
@strong{Privacy and Security:} Keep your personal wiki entirely offline and in your |
|
control. Encrypt your notes with GPG@. |
|
|
|
@item |
|
@strong{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. |
|
|
|
@item |
|
@strong{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. |
|
|
|
@item |
|
@strong{Leverage the Org-mode ecosystem:} Over the years, 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. |
|
|
|
@item |
|
@strong{Built on Emacs:} Emacs is also a fantastic interface for editing text, and we |
|
can inherit many of the powerful text-navigation and editing packages |
|
available to Emacs. |
|
@end itemize |
|
|
|
@node Target Audience |
|
@chapter Target Audience |
|
|
|
Org-roam is a tool that will appear unfriendly to anyone unfamiliar with Emacs |
|
and Org-mode, but is also extremely powerful to those willing to put effort in |
|
mastering the intricacies of the tools. Org-roam stands on the shoulders on |
|
giants. Emacs was first created in 1976, and remains a top tier tool 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 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. |
|
|
|
@quotation |
|
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 quotation |
|
|
|
@node A Brief Introduction to the Zettelkasten Method |
|
@chapter 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. |
|
|
|
@menu |
|
* Fleeting notes:: |
|
* Permanent notes:: |
|
@end menu |
|
|
|
@node Fleeting notes |
|
@section Fleeting notes |
|
|
|
A slip-box requires a method for quickly capturing ideas. These are called |
|
@strong{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 |
|
@code{org-capture} (see @ref{Capture,,,org,}), or using Org-roam's daily notes |
|
functionality (see @ref{Daily-notes}). This provides a central inbox for collecting |
|
thoughts, to be processed later into permanent notes. |
|
|
|
@node Permanent notes |
|
@section Permanent notes |
|
|
|
Permanent notes are further split into two categories: @strong{literature notes} and |
|
@strong{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. |
|
|
|
@node Installation |
|
@chapter Installation |
|
|
|
Org-roam can be installed using Emacs' package manager or manually from its |
|
development repository. |
|
|
|
@menu |
|
* Installing from MELPA:: |
|
* Installing from Apt:: |
|
* Installing from the Git Repository:: |
|
* Post-Installation Tasks:: |
|
@end menu |
|
|
|
@node Installing from MELPA |
|
@section 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 @ref{Packages,,,emacs,}. Then, add one of the |
|
archives to @samp{package-archives}: |
|
|
|
@itemize |
|
@item |
|
To use Melpa: |
|
@end itemize |
|
|
|
@lisp |
|
(require 'package) |
|
(add-to-list 'package-archives |
|
'("melpa" . "http://melpa.org/packages/") t) |
|
@end lisp |
|
|
|
@itemize |
|
@item |
|
To use Melpa-Stable: |
|
@end itemize |
|
|
|
@lisp |
|
(require 'package) |
|
(add-to-list 'package-archives |
|
'("melpa-stable" . "http://stable.melpa.org/packages/") t) |
|
@end lisp |
|
|
|
Org-roam also depends on a recent version of Org, which can be obtained in Org's |
|
package repository (see @ref{Installation,,,org,}). To use Org's ELPA archive: |
|
|
|
@lisp |
|
(add-to-list 'package-archives '("org" . "https://orgmode.org/elpa/") t) |
|
@end lisp |
|
|
|
Once you have added your preferred archive, you need to update the |
|
local package list using: |
|
|
|
@example |
|
M-x package-refresh-contents RET |
|
@end example |
|
|
|
Once you have done that, you can install Org-roam and its dependencies |
|
using: |
|
|
|
@example |
|
M-x package-install RET org-roam RET |
|
@end example |
|
|
|
Now see @ref{Post-Installation Tasks}. |
|
|
|
@node Installing from Apt |
|
@section Installing from Apt |
|
|
|
Users of Debian 11 or later or Ubuntu 20.10 or later can simply install Org-roam |
|
using Apt: |
|
|
|
@example |
|
apt-get install elpa-org-roam |
|
@end example |
|
|
|
Org-roam will then be autoloaded into Emacs. |
|
|
|
@node Installing from the Git Repository |
|
@section Installing from the Git Repository |
|
|
|
You may install Org-roam directly from the repository on @uref{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: |
|
|
|
@example |
|
git clone https://github.com/org-roam/org-roam.git /path/to/org/roam |
|
@end example |
|
|
|
where @code{./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 @code{require} the |
|
Org-roam library. Add the following code to your @code{.emacs}: |
|
|
|
@lisp |
|
(add-to-list 'load-path "/path/to/org/roam") |
|
(require 'org-roam) |
|
@end lisp |
|
|
|
You now have Org-roam installed. However, you don't necessarily have the |
|
dependencies that it requires. These include: |
|
|
|
@itemize |
|
@item |
|
dash |
|
|
|
@item |
|
f |
|
|
|
@item |
|
s |
|
|
|
@item |
|
org |
|
|
|
@item |
|
emacsql |
|
|
|
@item |
|
emacsql-sqlite3 |
|
@end itemize |
|
|
|
You can install this manually as well, or get the latest version from MELPA@. You |
|
may wish to use @uref{https://github.com/jwiegley/use-package, use-package}, @uref{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 @code{/doc} |
|
subdirectory of the Org-roam repository, and run the following: |
|
|
|
@example |
|
make infodir=/path/to/my/info/files install-info |
|
@end example |
|
|
|
Where @code{/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 @code{.emacs} file: |
|
|
|
@lisp |
|
(require 'info) |
|
(add-to-list 'Info-default-directory-list |
|
"/path/to/my/info/files") |
|
@end lisp |
|
|
|
You can also use one of the default locations, such as: |
|
|
|
@itemize |
|
@item |
|
@emph{usr/local/share/info} |
|
|
|
@item |
|
@emph{usr/share/info} |
|
|
|
@item |
|
@emph{usr/local/share/info} |
|
@end itemize |
|
|
|
If you do this, you'll need to make sure you have write-access to that location, |
|
or run the above @code{make} command as root. |
|
|
|
Now that the info file is ready, you need to add it to the corresponding @code{dir} |
|
file: |
|
|
|
@example |
|
install-info /path/to/my/info/files/org-roam.info /path/to/my/info/files/dir |
|
@end example |
|
|
|
@node Post-Installation Tasks |
|
@section Post-Installation Tasks |
|
|
|
Org-roam uses @code{emacsql-sqlite3}, which requires @code{sqlite3} to be located on |
|
@code{exec-path}. Please ensure that @code{sqlite3} is installed appropriately on your |
|
operating system. You can verify that this is the case by executing: |
|
|
|
@lisp |
|
(executable-find "sqlite3") |
|
@end lisp |
|
|
|
If you have @code{sqlite3} installed, and @code{executable-find} still reports @code{nil}, then |
|
it is likely that the path to the executable is not a member of the Emacs |
|
variable @code{exec-path}. You may rectify this by manually adding the path within |
|
your Emacs configuration: |
|
|
|
@lisp |
|
(add-to-list 'exec-path "path/to/sqlite3") |
|
@end lisp |
|
|
|
@node Getting Started |
|
@chapter Getting Started |
|
|
|
This short tutorial describes the essential commands used in Org-roam, to help |
|
you get started. |
|
|
|
First, it is important to understand how Org-roam was designed. Org-roam was |
|
built to support a workflow that was not possible with vanilla Org-mode. This |
|
flow is modelled after the @uref{https://zettelkasten.de/, Zettelkasten Method}, and many of @uref{https://roamresearch.com, Roam Research's} |
|
workflows. Org-roam does not magically make note-taking better -- this often |
|
requires a radical change in your current note-taking workflow. To understand |
|
more about the methods and madness, see @ref{Note-taking Workflows}. |
|
|
|
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 @code{org-roam-directory}. This variable needs to be set before any calls to |
|
Org-roam functions, including enabling @code{org-roam-mode}. For this tutorial, |
|
create an empty directory, and set @code{org-roam-directory}: |
|
|
|
@lisp |
|
(make-directory "~/org-roam") |
|
(setq org-roam-directory "~/org-roam") |
|
@end lisp |
|
|
|
We encourage using a flat hierarchy for storing notes, but some prefer using |
|
folders for storing specific kinds of notes (e.g. websites, papers). This is |
|
fine; Org-roam searches recursively within @code{org-roam-directory} for notes. |
|
Instead of relying on the file hierarchy for any form of categorization, one |
|
should use links between files to establish connections between notes. |
|
|
|
Next, we need to enable the global minor mode @code{org-roam-mode}. This sets up |
|
Emacs with several hooks, building a cache that is kept consistent as your |
|
slip-box grows. We recommend starting @code{org-roam-mode} on startup: |
|
|
|
@lisp |
|
(add-hook 'after-init-hook 'org-roam-mode) |
|
@end lisp |
|
|
|
To build the cache manually, one can run @code{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. |
|
|
|
Let us now create our first note. Call @code{M-x org-roam-find-file}. This shows a |
|
list of titles for notes that reside in @code{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 @code{RET} should begin the note |
|
creation process. This process uses @code{org-capture}'s templating system, and can |
|
be customized (see @ref{The Templating System}). Using the default template, pressing |
|
@code{C-c C-c} finishes the note capture. |
|
|
|
By default, Org-roam updates the cache asynchronously in the background to |
|
avoid getting in the way of writing. Org-roam queues updates to the files, |
|
waits for you to be idle for 2 seconds, and then automatically triggers |
|
updating the cache. After the cache has been updated, running @code{M-x |
|
org-roam-find-file} again should show the note you have created, and selecting |
|
that entry will bring you to that note @footnote{Depending on your completion framework, you may need to press TAB to |
|
see the list.}. One can customize the waiting |
|
time by setting @code{org-roam-db-update-idle-seconds}; or change the cache update |
|
to be triggered immediately after buffer save by setting |
|
@code{org-roam-db-update-method} to @code{'immediate}. |
|
|
|
Org-roam makes it easy to create notes, and link them together. To link notes |
|
together, we call @code{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 @code{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 @ref{Roam Protocol}). |
|
|
|
@node Files |
|
@chapter Files |
|
|
|
In Org-roam, notes typically consist of multiple files, where each file is a |
|
zettel. |
|
|
|
While the bulk of Org-roam's functionality is built on top of vanilla Org-mode, |
|
Org-roam adds several Org-roam-specific keywords to support additional |
|
functionality. |
|
|
|
This section explains the important components of a file, and the extensions to |
|
Org-mode. |
|
|
|
@menu |
|
* File Titles:: |
|
* File Tags:: |
|
* File Refs:: |
|
@end menu |
|
|
|
@node File Titles |
|
@section File Titles |
|
|
|
To easily find a note, a title needs to be prescribed to a note. |
|
|
|
A note can have many titles: this allows a note to be referred to by different |
|
names, which is especially useful for topics or concepts with acronyms. For |
|
example, for a note like ``World War 2'', it may be desirable to also refer to it |
|
using the acronym ``WWII''. |
|
|
|
Org-roam calls @code{org-roam--extract-titles} to extract titles. It uses the |
|
variable @code{org-roam-title-sources}, to control how the titles are extracted. The |
|
title extraction methods supported are: |
|
|
|
@itemize |
|
@item |
|
@code{'title}: This extracts the title using the file @code{#+title} property |
|
|
|
@item |
|
@code{'headline}: This extracts the title from the first headline in the Org file |
|
|
|
@item |
|
@code{'alias}: This extracts a list of titles using the @code{#+roam_alias} property. |
|
The aliases are space-delimited, and can be multi-worded using quotes. |
|
@end itemize |
|
|
|
Take for example the following org file: |
|
|
|
@example |
|
#+title: World War 2 |
|
#+roam_alias: "WWII" "World War II" |
|
|
|
* Headline |
|
@end example |
|
|
|
@multitable {aaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaa} |
|
@headitem Method |
|
@tab Titles |
|
@item @code{'title} |
|
@tab '(``World War 2'') |
|
@item @code{'headline} |
|
@tab '(``Headline'') |
|
@item @code{'alias} |
|
@tab '(``WWII'' ``World War II'') |
|
@end multitable |
|
|
|
If no title is provided, Org-roam defaults to using the file-path. |
|
|
|
@menu |
|
* Customizing Title Extraction:: |
|
@end menu |
|
|
|
@node Customizing Title Extraction |
|
@subsection Customizing Title Extraction |
|
|
|
To control how Org-roam extracts titles, customize @code{org-roam-title-sources}. If |
|
all methods of title extraction return no results, the file-name is used as the |
|
note's title. |
|
|
|
@defopt org-roam-title-sources |
|
|
|
The list of sources from which to retrieve a note title. |
|
Each element in the list is either: |
|
@end defopt |
|
|
|
@itemize |
|
@item |
|
a symbol -- this symbol corresponds to a title retrieval function, which |
|
returns the list of titles for the current buffer |
|
@itemize |
|
@item |
|
a list of symbols -- symbols in the list are treated as with (1). The |
|
return value of this list is the first symbol in the list returning a |
|
non-nil value. |
|
@end itemize |
|
|
|
The return results of the root list are concatenated. |
|
|
|
For example the setting: '((title headline) alias) means the following: |
|
|
|
@itemize |
|
@item |
|
Return the 'title + 'alias, if the title of current buffer is non-empty; |
|
|
|
@item |
|
Or return 'headline + 'alias otherwise. |
|
@end itemize |
|
|
|
The currently supported symbols are: |
|
|
|
@code{'title} |
|
The @code{#+title} property of org file. |
|
|
|
@code{'alias} |
|
The @code{#+roam_alias} property of the org file, using |
|
space-delimited strings. |
|
|
|
@code{'headline} |
|
The first headline in the org file. |
|
@end itemize |
|
|
|
Adding your own title extraction method requires two steps. First, define a |
|
method @code{(defun org-roam--extract-titles-foo () ...)}, where @code{foo} a |
|
self-prescribed name for the title extraction method. This method takes no |
|
arguments, and returns a list of strings (titles). Finally, push the symbol |
|
@code{foo} into @code{org-roam-title-sources}. You may need to rebuild the cache from |
|
scratch to re-process all files to pick up the new titles. |
|
|
|
@node File Tags |
|
@section File Tags |
|
|
|
Tags are used as meta-data for files: they facilitate interactions with notes |
|
where titles are insufficient. For example, tags allow for categorization of |
|
notes: differentiating between bibliographical and structure notes during |
|
interactive commands. |
|
|
|
By default, tags are extracted from the @code{#+roam_tags} property. To add |
|
additional extraction methods, see @ref{Customizing Tag Extraction}. |
|
|
|
@menu |
|
* Customizing Tag Extraction:: |
|
@end menu |
|
|
|
@node Customizing Tag Extraction |
|
@subsection Customizing Tag Extraction |
|
|
|
Org-roam calls @code{org-roam--extract-tags} to extract tags from files. The variable |
|
@code{org-roam-tag-sources}, to control how tags are extracted. |
|
|
|
@defopt org-roam-tag-sources |
|
@end defopt |
|
|
|
Sources to obtain tags from. |
|
|
|
It should be a list of symbols representing any of the following extraction |
|
methods: |
|
|
|
@code{'prop} |
|
Extract tags from the @code{#+roam_tags} property. |
|
Tags are space delimited. |
|
Tags may contain spaces if they are double-quoted. |
|
e.g. @code{#+roam_tags: TAG "tag with spaces"} |
|
|
|
@code{'vanilla} |
|
Extract vanilla org-mode tags, including @code{#+FILETAGS} and |
|
inherited tags. |
|
|
|
@code{'all-directories} |
|
Extract sub-directories relative to @code{org-roam-directory}. |
|
That is, if a file is located at relative path foo/bar/file.org, |
|
the file will have tags ``foo'' and ``bar''. |
|
|
|
@code{'last-directory} |
|
Extract the last directory relative to `org-roam-directory'. |
|
That is, if a file is located at relative path foo/bar/file.org, |
|
the file will have tag \``bar\''. |
|
|
|
@code{'first-directory} |
|
Extract the first directory relative to @code{org-roam-directory}. |
|
That is, if a file is located at relative path foo/bar/file.org, |
|
the file will have tag ``foo'' |
|
|
|
By default, only the @code{'prop} extraction method is enabled. To enable the other |
|
extraction methods, you may modify @code{org-roam-tag-sources}, for example: |
|
|
|
@lisp |
|
(setq org-roam-tag-sources '(prop last-directory)) |
|
@end lisp |
|
|
|
Adding your own tag extraction method requires two steps. First, define a method |
|
@code{(defun org-roam--extract-tags-foo (file) ...)}, where @code{foo} a self-prescribed |
|
name for the tag extraction method. This method takes the file path as an |
|
argument, and returns a list of strings (titles). Finally, push the symbol @code{foo} |
|
into @code{org-roam-tag-sources}. You may need to rebuild the cache from scratch to |
|
re-process all files to pick up the new tags. |
|
|
|
@node File Refs |
|
@section File Refs |
|
|
|
Refs are unique identifiers for files. For example, a note for a website may |
|
contain a ref: |
|
|
|
@example |
|
#+title: Google |
|
#+roam_key: https://www.google.com/ |
|
@end example |
|
|
|
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 |
|
@uref{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 |
|
@code{roam-ref} protocol (see @ref{Roam Protocol}). |
|
|
|
@uref{https://github.com/jkitchin/org-ref, org-ref} citation keys can also be used as refs: |
|
|
|
@example |
|
#+title: Neural Ordinary Differential Equations |
|
#+roam_key: cite:chen18_neural_ordin_differ_equat |
|
@end example |
|
|
|
@float Figure |
|
@image{images/org-ref-citelink,,,,png} |
|
@caption{org-ref-citelink} |
|
@end float |
|
|
|
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. |
|
|
|
@node The Templating System |
|
@chapter The Templating System |
|
|
|
Rather than creating blank files on @code{org-roam-insert} and @code{org-roam-find-file}, |
|
it may be desirable to prefill the file with templated content. This may |
|
include: |
|
|
|
@itemize |
|
@item |
|
Time of creation |
|
|
|
@item |
|
File it was created from |
|
|
|
@item |
|
Clipboard content |
|
|
|
@item |
|
Any other data you may want to input manually |
|
@end itemize |
|
|
|
This requires a complex template insertion system. Fortunately, Org ships with a |
|
powerful one: @code{org-capture} (see @ref{capture,,,org,}). However, org-capture was not |
|
designed for such use. Org-roam abuses @code{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 @code{org-capture}. |
|
|
|
For these reasons, Org-roam capture templates are not compatible with regular |
|
@code{org-capture}. Hence, Org-roam's templates can be customized by instead |
|
modifying the variable @code{org-roam-capture-templates}. Just like |
|
@code{org-capture-templates}, @code{org-roam-capture-templates} can contain multiple |
|
templates. If @code{org-roam-capture-templates} only contains one template, there |
|
will be no prompt for template selection. |
|
|
|
@menu |
|
* Template Walkthrough:: |
|
* Org-roam Template Expansion:: |
|
@end menu |
|
|
|
@node Template Walkthrough |
|
@section Template Walkthrough |
|
|
|
To demonstrate the additions made to org-capture templates. Here, we walkthrough |
|
the default template, reproduced below. |
|
|
|
@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 lisp |
|
|
|
@itemize |
|
@item |
|
The template has short key @code{"d"}. If you have only one template, org-roam |
|
automatically chooses this template for you. |
|
|
|
@item |
|
The template is given a description of @code{"default"}. |
|
|
|
@item |
|
@code{plain} text is inserted. Other options include Org headings via |
|
@code{entry}. |
|
|
|
@item |
|
@code{(function org-roam--capture-get-point)} should not be changed. |
|
|
|
@item |
|
@code{"%?"} is the template inserted on each call to @code{org-roam-capture--capture}. |
|
This template means don't insert any content, but place the cursor here. |
|
|
|
@item |
|
@code{: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 |
|
@code{/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 @code{private/$@{slug@}} will create notes in |
|
@code{/path/to/org-roam-directory/private}. |
|
|
|
@item |
|
@code{:head} contains the initial template to be inserted (once only), at |
|
the beginning of the file. Here, the title global attribute is |
|
inserted. |
|
|
|
@item |
|
@code{:unnarrowed t} tells org-capture to show the contents for the whole |
|
file, rather than narrowing to just the entry. |
|
@end itemize |
|
|
|
Other options you may want to learn about include @code{:immediate-finish}. |
|
|
|
@node Org-roam Template Expansion |
|
@section 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 @ref{Template Walkthrough, , Template |
|
Walkthrough}. |
|
|
|
In org-roam templates, the @code{$@{var@}} syntax allows for the expansion of |
|
variables, stored in @code{org-roam-capture--info}. For example, during |
|
@code{org-roam-insert}, the user is prompted for a title. Upon entering a |
|
non-existent title, the @code{title} key in @code{org-roam-capture--info} is set to the |
|
provided title. @code{$@{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 @code{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 |
|
@uref{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: |
|
@code{"%<%Y%m%d%H%M%S>-$@{title@}"}, with the title @code{"Foo"}. The template is first |
|
expanded into @code{%<%Y%m%d%H%M%S>-Foo}. Then org-capture expands @code{%<%Y%m%d%H%M%S>} |
|
with timestamp: e.g. @code{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 @code{%(EXP)} template expansion to call @code{format-time-string} |
|
directly to provide its third argument to specify UTC@. |
|
|
|
@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 lisp |
|
|
|
@node Concepts and Configuration |
|
@chapter 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 @code{M-x customize-group |
|
org-roam}. |
|
|
|
@menu |
|
* Directories and Files:: |
|
* The Org-roam Buffer:: |
|
* Org-roam Files:: |
|
* Org-roam Faces:: |
|
* The Database:: |
|
@end menu |
|
|
|
@node Directories and Files |
|
@section Directories and Files |
|
|
|
This section concerns the placement and creation of files. |
|
|
|
@defvar 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. |
|
@end defvar |
|
|
|
@defvar 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. |
|
@end defvar |
|
|
|
@defvar org-roam-file-exclude-regexp |
|
|
|
Files matching this regular expression are excluded from the Org-roam. |
|
@end defvar |
|
|
|
@node The Org-roam Buffer |
|
@section The Org-roam Buffer |
|
|
|
The Org-roam buffer displays backlinks for the currently active Org-roam note. |
|
|
|
@defopt org-roam-buffer |
|
|
|
The name of the org-roam buffer. Defaults to @code{*org-roam*}. |
|
@end defopt |
|
|
|
@defopt org-roam-buffer-position |
|
|
|
The position of the Org-roam buffer side window. Valid values are @code{'left}, |
|
@code{'right}, @code{'top}, @code{'bottom}. |
|
@end defopt |
|
|
|
@defopt org-roam-buffer-width |
|
|
|
Width of @code{org-roam-buffer}. Has an effect only if @code{org-roam-buffer-position} is |
|
@code{'left} or @code{'right}. |
|
@end defopt |
|
|
|
@defopt org-roam-buffer-height |
|
|
|
Height of @code{org-roam-buffer}. Has an effect only if @code{org-roam-buffer-position} is |
|
@code{'top} or @code{'bottom}. |
|
@end defopt |
|
|
|
@defopt 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 |
|
@code{delete-other-windows}, by setting it with the following: |
|
|
|
@code{(setq org-roam-buffer-window-parameters '((no-delete-other-windows . t)))} |
|
@end defopt |
|
|
|
@node Org-roam Files |
|
@section Org-roam Files |
|
|
|
Org-roam files are created and prefilled using Org-roam's templating |
|
system. The templating system is customizable (see @ref{The Templating System}). |
|
|
|
@node Org-roam Faces |
|
@section 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. |
|
|
|
@defopt org-roam-link-use-custom-faces |
|
|
|
When @code{t}, use custom faces only inside Org-roam notes. |
|
When @code{everywhere}, the custom face is applied additionally to non Org-roam notes. |
|
When @code{nil}, do not use Org-roam's custom faces. |
|
@end defopt |
|
|
|
The @code{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 @code{org-roam-link-current} face corresponds to links to the same file it is in. |
|
|
|
The @code{org-roam-link-invalid} face is applied to links that are broken. These are |
|
links to files or IDs that cannot be found. |
|
|
|
@node The Database |
|
@section @strong{TODO} The Database |
|
|
|
Org-roam is backed by a Sqlite database. |
|
|
|
@defopt org-roam-db-update-method |
|
|
|
Method to update the Org-roam database. |
|
|
|
@code{'immediate}: Update the database immediately upon file changes. |
|
|
|
@code{'idle-timer}: Updates the database if dirty, if Emacs idles for |
|
@code{org-roam-db-update-idle-seconds}. |
|
@end defopt |
|
|
|
@defopt org-roam-db-update-idle-seconds |
|
|
|
Number of idle seconds before triggering an Org-roam database update. This is |
|
only valid if @code{org-roam-db-update-method} is @code{'idle-timer}. |
|
@end defopt |
|
|
|
@node Inserting Links |
|
@chapter Inserting Links |
|
|
|
The preferred mode of linking is via @code{file} links to files, and @code{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. |
|
|
|
@code{file} links can be inserted via @code{org-roam-insert}. Links to headlines can be |
|
inserted by navigating to the desired headline and calling @code{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 |
|
@code{org-insert-link}. |
|
|
|
An alternative mode of insertion is using Org-roam's @code{roam} links. Org-roam |
|
registers this link type, and interprets the path as follows: |
|
|
|
@itemize |
|
@item |
|
@code{[[roam:title]]}links to an Org-roam file with title or alias ``title'' |
|
|
|
@item |
|
@code{[[roam:*headline]]}links to the headline ``headline'' in the current |
|
Org-roam file |
|
|
|
@item |
|
@code{[[roam:title*headline]]}links to the headline ``headline'' in the Org-roam |
|
file with title or alias ``title'' |
|
|
|
@end itemize |
|
|
|
@defopt 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 @code{"%s"}. |
|
|
|
If your version of Org is at least @code{9.2}, consider styling the link differently, |
|
by customizing the @code{org-roam-link}, and @code{org-roam-link-current} faces. |
|
@end defopt |
|
|
|
@defopt org-roam-link-auto-replace |
|
|
|
When non-nil, @code{roam} links will be replaced with @code{file} or @code{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 @code{t}. |
|
@end defopt |
|
|
|
@node Completions |
|
@chapter Completions |
|
|
|
Completions for Org-roam are provided via @code{completion-at-point}. Completion |
|
suggestions are implemented as separate functions. Org-roam installs all |
|
functions in @code{org-roam-completion-functions} to @code{completion-at-point-functions}. |
|
|
|
@defvar org-roam-completion-functions |
|
|
|
The list of functions to be used with @code{completion-at-point}. |
|
@end defvar |
|
|
|
@defopt org-roam-completion-ignore-case |
|
|
|
When non-nil, the @code{roam} link completions are ignore case. For example, |
|
calling @code{completion-at-point} within @code{[[roam:fo]]} will present a completion |
|
for a file with title ``Foo''. Defaults to @code{t}. |
|
@end defopt |
|
|
|
To use the completions from Org-roam with @code{company-mode}, prepend @code{company-capf} |
|
to variable @code{company-backends}. |
|
|
|
@menu |
|
* Link Completion:: |
|
* Tag Completion:: |
|
@end menu |
|
|
|
@node Link Completion |
|
@section Link Completion |
|
|
|
@code{roam} links support auto-completion via @code{completion-at-point}: simply call |
|
@code{M-x completion-at-point} within a roam link. That is, where the @code{|} character |
|
represents the cursor: |
|
|
|
@itemize |
|
@item |
|
@code{[[|]]}: completes for a file title |
|
|
|
@item |
|
@code{[[roam:]]}: completes for a file title |
|
|
|
@item |
|
@code{[[*|]]}: completes for a headline within this file |
|
|
|
@item |
|
@code{[[foo*|]]}: completes a headline within the file with title ``foo'' |
|
|
|
@item |
|
@code{[[roam:foo*|]]} completes a headline within the file with title ``foo'' |
|
@end itemize |
|
|
|
Completions account for the current input. For example, for @code{[[f|]]}, the |
|
completions (by default) only show for files with titles that start with ``f''. |
|
|
|
@defun org-roam-link-complete-at-point |
|
|
|
Do appropriate completion for the link at point. |
|
@end defun |
|
|
|
@menu |
|
* Link Completions Everywhere:: |
|
@end menu |
|
|
|
@node Link Completions Everywhere |
|
@subsection 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 @code{org-roam-completion-everywhere} to @code{t} will enable word-at-point |
|
completions. |
|
|
|
@defopt org-roam-completion-everywhere |
|
|
|
If non-nil, provide completions from the current word at point. That is, in |
|
the scenario @code{this is a sent|}, calling @code{completion-at-point} will show |
|
completions for titles that begin with ``sent''. |
|
@end defopt |
|
|
|
@node Tag Completion |
|
@section Tag Completion |
|
|
|
Org-roam facilitates the insertion of existing tags via @code{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 @code{#+roam_tags:}, completions for these will |
|
appear as-you-type if they match. |
|
|
|
This functionality is implemented in @code{org-roam-complete-tags-at-point}. |
|
|
|
@node Navigating Around |
|
@chapter Navigating Around |
|
|
|
@menu |
|
* Index File:: |
|
@end menu |
|
|
|
@node Index File |
|
@section 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 |
|
@code{org-roam-index-file}. |
|
|
|
@defvar 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 @code{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 @code{org-roam-index} whose |
|
title is @code{"Index"}. |
|
@end defvar |
|
|
|
@defun org-roam-find-index |
|
|
|
Opens the Index file in the current @code{org-roam-directory}. |
|
@end defun |
|
|
|
@node Encryption |
|
@chapter 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 @code{org-roam-encrypt-files} |
|
to @code{t}. When enabled, new files are created with the @code{.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. |
|
|
|
@defopt org-roam-encrypt-files |
|
|
|
Whether to encrypt new files. If true, create files with .org.gpg extension. |
|
@end defopt |
|
|
|
@node Graphing |
|
@chapter Graphing |
|
|
|
Org-roam provides graphing capabilities to explore interconnections between |
|
notes. This is done by performing SQL queries and generating images using |
|
@uref{https://graphviz.org/, Graphviz}. The graph can also be navigated: see @ref{Roam Protocol}. |
|
|
|
The entry point to graph creation is @code{org-roam-graph}. |
|
|
|
@defun 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: |
|
|
|
@itemize |
|
@item |
|
@code{nil} show the graph. |
|
|
|
@item |
|
@code{C-u} show the graph for FILE@. |
|
|
|
@item |
|
@code{C-u N} show the graph for FILE limiting nodes to N steps. |
|
|
|
@item |
|
@code{C-u C-u} build the graph. |
|
|
|
@item |
|
@code{C-u -} build the graph for FILE@. |
|
|
|
@item |
|
@code{C-u -N} build the graph for FILE limiting nodes to N steps. |
|
@end itemize |
|
@end defun |
|
|
|
@defopt 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 @code{neato} in place of @code{dot}, which generates a more |
|
compact graph layout. |
|
@end defopt |
|
|
|
@defopt 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: |
|
|
|
@itemize |
|
@item |
|
A string, which is a path to the program used |
|
|
|
@item |
|
a function accepting a single argument: the graph file path. |
|
@end itemize |
|
|
|
@code{nil} uses @code{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: |
|
|
|
@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 lisp |
|
@end defopt |
|
|
|
@menu |
|
* Graph Options:: |
|
* Excluding Nodes and Edges:: |
|
@end menu |
|
|
|
@node Graph Options |
|
@section Graph Options |
|
|
|
Graphviz provides many options for customizing the graph output, and Org-roam |
|
supports some of them. See @uref{https://graphviz.gitlab.io/_pages/doc/info/attrs.html} |
|
for customizable options. |
|
|
|
@defopt org-roam-graph-extra-config |
|
|
|
Extra options passed to graphviz for the digraph (The ``G'' attributes). |
|
Example: @code{'~(("rankdir" . "LR"))} |
|
@end defopt |
|
|
|
@defopt org-roam-graph-node-extra-config |
|
|
|
Extra options for nodes in the graphviz output (The ``N'' attributes). |
|
Example: @code{'(("color" . "skyblue"))} |
|
@end defopt |
|
|
|
@defopt org-roam-graph-edge-extra-config |
|
|
|
Extra options for edges in the graphviz output (The ``E'' attributes). |
|
Example: @code{'(("dir" . "back"))} |
|
@end defopt |
|
|
|
@defopt org-roam-graph-edge-cites-extra-config |
|
|
|
Extra options for citation edges in the graphviz output. |
|
Example: @code{'(("color" . "red"))} |
|
@end defopt |
|
|
|
@node Excluding Nodes and Edges |
|
@section Excluding Nodes and Edges |
|
|
|
One may want to exclude certain files to declutter the graph. |
|
|
|
@defopt 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. |
|
@end defopt |
|
|
|
@example |
|
(setq org-roam-graph-exclude-matcher '("private" "dailies")) |
|
@end example |
|
|
|
This setting excludes all files whose path contain ``private'' or ``dailies''. |
|
|
|
@node Minibuffer Completion |
|
@chapter Minibuffer Completion |
|
|
|
Org-roam allows customization of which minibuffer completion system to use for |
|
its interactive commands. The default setting uses Emacs' standard |
|
@code{completing-read} mechanism. |
|
|
|
@lisp |
|
(setq org-roam-completion-system 'default) |
|
@end lisp |
|
|
|
If you have installed Helm or Ivy, and have their modes enabled, under the |
|
@code{'default} setting they will be used. |
|
|
|
In the rare scenario where you use Ivy globally, but prefer @uref{https://emacs-helm.github.io/helm/, Helm} for org-roam |
|
commands, set: |
|
|
|
@lisp |
|
(setq org-roam-completion-system 'helm) |
|
@end lisp |
|
|
|
Other options include @code{'ido}, and @code{'ivy}. |
|
|
|
@node Roam Protocol |
|
@chapter Roam Protocol |
|
|
|
Org-roam extends @code{org-protocol} with 2 protocols: the @code{roam-file} and @code{roam-ref} |
|
protocols. |
|
|
|
@menu |
|
* Installation: Installation (1). |
|
* The roam-file protocol:: |
|
* The roam-ref protocol:: |
|
@end menu |
|
|
|
@node Installation (1) |
|
@section Installation |
|
|
|
To enable Org-roam's protocol extensions, you have to add the following to your |
|
init file: |
|
|
|
@lisp |
|
(require 'org-roam-protocol) |
|
@end lisp |
|
|
|
The instructions for setting up @code{org-protocol} are reproduced below. |
|
|
|
We will also need to create a desktop application for @code{emacsclient}. The |
|
instructions for various platforms are shown below. |
|
|
|
For Linux users, create a desktop application in |
|
@code{~/.local/share/applications/org-protocol.desktop}: |
|
|
|
@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 @code{org-protocol://} links with the desktop application by |
|
running in your shell: |
|
|
|
@example |
|
xdg-mime default org-protocol.desktop x-scheme-handler/org-protocol |
|
@end example |
|
|
|
To disable the ``confirm'' prompt in Chrome, you can also make Chrome show a |
|
checkbox to tick, so that the @code{Org-Protocol Client} app will be used without |
|
confirmation. To do this, run in a shell: |
|
|
|
@example |
|
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 example |
|
|
|
and then restart Chrome (for example, by navigating to <chrome://restart>) to |
|
make the new policy take effect. |
|
|
|
See @uref{https://www.chromium.org/administrators/linux-quick-start, here} for more info on the @code{/etc/opt/chrome/policies/managed} directory and |
|
@uref{https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ExternalProtocolDialogShowAlwaysOpenCheckbox, here} for information on the @code{ExternalProtocolDialogShowAlwaysOpenCheckbox} policy. |
|
|
|
For MacOS, we need to create our own application. |
|
|
|
@itemize |
|
@item |
|
Launch Script Editor |
|
|
|
@item |
|
Use the following script, paying attention to the path to @code{emacsclient}: |
|
@end itemize |
|
|
|
@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 lisp |
|
|
|
@itemize |
|
@item |
|
Save the script in @code{/Applications/OrgProtocolClient.app}, changing the script type to |
|
``Application'', rather than ``Script''. |
|
|
|
@item |
|
Edit @code{/Applications/OrgProtocolClient.app/Contents/Info.plist}, adding the |
|
following before the last @code{</dict>} tag: |
|
@end itemize |
|
|
|
@example |
|
<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 example |
|
|
|
@itemize |
|
@item |
|
Save the file, and run the @code{OrgProtocolClient.app} to register the protocol. |
|
@end itemize |
|
|
|
To disable the ``confirm'' prompt in Chrome, you can also make Chrome |
|
show a checkbox to tick, so that the @code{OrgProtocol} app will be used |
|
without confirmation. To do this, run in a shell: |
|
|
|
@example |
|
defaults write com.google.Chrome ExternalProtocolDialogShowAlwaysOpenCheckbox -bool true |
|
@end example |
|
|
|
|
|
If you're using @uref{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 @code{OrgProtocol.app} |
|
the default handler instead, run: |
|
|
|
@example |
|
defaults write com.apple.LaunchServices/com.apple.launchservices.secure LSHandlers -array-add \ |
|
'@{"LSHandlerPreferredVersions" = @{ "LSHandlerRoleAll" = "-"; @}; LSHandlerRoleAll = "org.yourusername.OrgProtocol"; LSHandlerURLScheme = "org-protocol";@}' |
|
@end example |
|
|
|
Then restart your computer. |
|
|
|
For Windows, create a temporary @code{org-protocol.reg} file: |
|
|
|
@example |
|
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 example |
|
|
|
The above will forward the protocol to WSL@. If you run Emacs natively on |
|
Windows, replace the last line with: |
|
|
|
@example |
|
@@="\"c:\\path\\to\\emacs\\bin\\emacsclientw.exe\" \"%1\"" |
|
@end example |
|
|
|
After executing the .reg file, the protocol is registered and you can delete the |
|
file. |
|
|
|
@node The roam-file protocol |
|
@section The roam-file protocol |
|
|
|
This is a simple protocol that opens the path specified by the @code{file} |
|
key (e.g. @code{org-protocol://roam-file?file=/tmp/file.org}). This is used |
|
in the generated graph. |
|
|
|
@node The roam-ref protocol |
|
@section The roam-ref protocol |
|
|
|
This protocol finds or creates a new note with a given @code{roam_key} (see @ref{Files}): |
|
|
|
@image{images/roam-ref,,,,gif} |
|
|
|
To use this, create the following @uref{https://en.wikipedia.org/wiki/Bookmarklet, bookmarklet} in your browser: |
|
|
|
@example |
|
javascript:location.href = |
|
'org-protocol://roam-ref?template=r&ref=' |
|
+ encodeURIComponent(location.href) |
|
+ '&title=' |
|
+ encodeURIComponent(document.title) |
|
+ '&body=' |
|
+ encodeURIComponent(window.getSelection()) |
|
@end example |
|
|
|
or as a keybinding in @code{qutebrowser} in , using the @code{config.py} file (see |
|
@uref{https://github.com/qutebrowser/qutebrowser/blob/master/doc/help/configuring.asciidoc, Configuring qutebrowser}): |
|
|
|
@example |
|
config.bind("<Ctrl-r>", "open javascript:location.href='org-protocol://roam-ref?template=r&ref='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)") |
|
@end example |
|
|
|
where @code{template} is the template key for a template in |
|
@code{org-roam-capture-ref-templates} (see @ref{The Templating System}). These templates |
|
should contain a @code{#+roam_key: $@{ref@}} in it. |
|
|
|
@node Daily-notes |
|
@chapter Daily-notes |
|
|
|
Org-roam provides journaling capabilities akin to |
|
@ref{Org-journal} with @code{org-roam-dailies}. |
|
|
|
@menu |
|
* Configuration:: |
|
* Capturing and finding daily-notes:: |
|
* Navigation:: |
|
@end menu |
|
|
|
@node Configuration |
|
@section Configuration |
|
|
|
For @code{org-roam-dailies} to work, you need to define two variables: |
|
|
|
@defvar @code{org-roam-dailies-directory} |
|
|
|
Path to daily-notes. |
|
@end defvar |
|
|
|
@defvar @code{org-roam-dailies-capture-templates} |
|
|
|
Capture templates for daily-notes in Org-roam. |
|
@end defvar |
|
|
|
Here is a sane default configuration: |
|
|
|
@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 lisp |
|
|
|
Make sure that @code{org-roam-dailies-directory} appears in @code{: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 |
|
@code{org-roam-dailies-directory} will be considered as the main one in commands. |
|
|
|
See @ref{The Templating System} for creating new |
|
templates. @code{org-roam-dailies} provides an extra @code{:olp} option which allows |
|
specifying the outline-path to a heading: |
|
|
|
@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 lisp |
|
|
|
The template @code{l} will put its notes under the heading ‘Lab notes’, and the |
|
template @code{j} will put its notes under the heading ‘Journal’. |
|
|
|
@node Capturing and finding daily-notes |
|
@section Capturing and finding daily-notes |
|
|
|
@defun @code{org-roam-dailies-capture-today} &optional goto |
|
|
|
Create an entry in the daily note for today. |
|
|
|
When @code{goto} is non-nil, go the note without creating an entry. |
|
@end defun |
|
|
|
@defun @code{org-roam-dailies-find-today} |
|
|
|
Find the daily note for today, creating it if necessary. |
|
@end defun |
|
|
|
There are variants of those commands for @code{-yesterday} and @code{-tomorrow}: |
|
|
|
@defun @code{org-roam-dailies-capture-yesterday} n &optional goto |
|
|
|
Create an entry in the daily note for yesteday. |
|
|
|
With numeric argument @code{n}, use the daily note @code{n} days in the past. |
|
@end defun |
|
|
|
@defun @code{org-roam-dailies-find-yesterday} |
|
|
|
With numeric argument N, use the daily-note N days in the future. |
|
@end defun |
|
|
|
There are also commands which allow you to use Emacs’s @code{calendar} to find the date |
|
|
|
@defun @code{org-roam-dailies-capture-date} |
|
|
|
Create an entry in the daily note for a date using the calendar. |
|
|
|
Prefer past dates, unless @code{prefer-future} is non-nil. |
|
|
|
With a 'C-u' prefix or when @code{goto} is non-nil, go the note without |
|
creating an entry. |
|
@end defun |
|
|
|
@defun @code{org-roam-dailies-find-date} |
|
|
|
Find the daily note for a date using the calendar, creating it if necessary. |
|
|
|
Prefer past dates, unless @code{prefer-future} is non-nil. |
|
@end defun |
|
|
|
@node Navigation |
|
@section Navigation |
|
|
|
You can navigate between daily-notes: |
|
|
|
@defun @code{org-roam-dailies-find-directory} |
|
|
|
Find and open @code{org-roam-dailies-directory}. |
|
@end defun |
|
|
|
@defun @code{org-roam-dailies-find-previous-note} |
|
|
|
When in an daily-note, find the previous one. |
|
@end defun |
|
|
|
@defun @code{org-roam-dailies-find-next-note} |
|
|
|
When in an daily-note, find the next one. |
|
@end defun |
|
|
|
@node Diagnosing and Repairing Files |
|
@chapter Diagnosing and Repairing Files |
|
|
|
Org-roam provides a utility for diagnosing and repairing problematic files via |
|
@code{org-roam-doctor}. By default, @code{org-roam-doctor} runs the check on the current |
|
Org-roam file. To run the check only for all Org-roam files, run @code{C-u M-x |
|
org-roam-doctor}, but note that this may take some time. |
|
|
|
@defun 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. |
|
@end defun |
|
|
|
The checks run are defined in @code{org-roam-doctor--checkers}. By default, there are |
|
checkers for broken links and invalid @samp{#+roam_*} properties. |
|
|
|
Each checker is an instance of @code{org-roam-doctor-checker}. To define a checker, |
|
use @code{make-org-roam-doctor-checker}. Here is a sample definition: |
|
|
|
@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 lisp |
|
|
|
The @code{:name} property is the name of the function run. The function takes in the |
|
Org parse tree, and returns a list of @code{(point error-message)}. @code{:description} is |
|
a short description of what the checker does. @code{:actions} is an alist containing |
|
elements of the form @code{(char . (prompt . function))}. These actions are defined |
|
per checker, to perform autofixes for the errors. For each error detected, |
|
@code{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 @code{:actions}. |
|
|
|
@node Finding Unlinked References |
|
@chapter 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 @code{M-x org-roam-unlinked-references} from within |
|
an Org-roam note. Internally, Org-roam uses @uref{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. |
|
|
|
@quotation |
|
NOTE: Since ripgrep cannot read encrypted files, this function cannot find |
|
unlinked references within encrypted files. |
|
|
|
@end quotation |
|
|
|
@node Performance Optimization |
|
@chapter Performance Optimization |
|
|
|
@menu |
|
* Profiling Key Operations:: |
|
* Garbage Collection:: |
|
@end menu |
|
|
|
@node Profiling Key Operations |
|
@section @strong{TODO} Profiling Key Operations |
|
|
|
@node Garbage Collection |
|
@section 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 @ref{Garbage Collection,info:elisp#Garbage Collection,,elisp,}). |
|
|
|
Org-roam provides the option @code{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 |
|
@code{org-roam-db-gc-threshold} to a high value (such as @code{most-positive-fixnum}): |
|
|
|
@lisp |
|
(setq org-roam-db-gc-threshold most-positive-fixnum) |
|
@end lisp |
|
|
|
@node Appendix |
|
@chapter Appendix |
|
|
|
@menu |
|
* Note-taking Workflows:: |
|
* Ecosystem:: |
|
@end menu |
|
|
|
@node Note-taking Workflows |
|
@section Note-taking Workflows |
|
|
|
@itemize |
|
@item |
|
Books@itemize |
|
@item |
|
@uref{https://www.goodreads.com/book/show/34507927-how-to-take-smart-notes, How To Take Smart Notes} |
|
@end itemize |
|
|
|
@item |
|
Articles@itemize |
|
@item |
|
@uref{https://www.lesswrong.com/posts/NfdHG6oHBJ8Qxc26s/the-zettelkasten-method-1, The Zettelkasten Method - LessWrong 2.0} |
|
|
|
@item |
|
@uref{https://reddit.com/r/RoamResearch/comments/eho7de/building_a_second_brain_in_roamand_why_you_might, Building a Second Brain in Roam@dots{}And Why You Might Want To : RoamResearch} |
|
|
|
@item |
|
@uref{https://www.nateliason.com/blog/roam, Roam Research: Why I Love It and How I Use It - Nat Eliason} |
|
|
|
@item |
|
@uref{https://twitter.com/adam_keesling/status/1196864424725774336?s=20, Adam Keesling's Twitter Thread} |
|
|
|
@item |
|
@uref{https://blog.jethro.dev/posts/how_to_take_smart_notes_org/, How To Take Smart Notes With Org-mode · Jethro Kuan} |
|
@end itemize |
|
|
|
@item |
|
Threads@itemize |
|
@item |
|
@uref{https://news.ycombinator.com/item?id=22473209, Ask HN: How to Take Good Notes} |
|
@end itemize |
|
|
|
@item |
|
Videos@itemize |
|
@item |
|
@uref{https://www.youtube.com/watch?v=RvWic15iXjk, How to Use Roam to Outline a New Article in Under 20 Minutes} |
|
@end itemize |
|
@end itemize |
|
|
|
@node Ecosystem |
|
@section Ecosystem |
|
|
|
@menu |
|
* Browsing History with winner-mode:: |
|
* Versioning Notes:: |
|
* Full-text search interface with Deft:: |
|
* Org-journal:: |
|
* Note-taking Add-ons:: |
|
@end menu |
|
|
|
@node Browsing History with winner-mode |
|
@subsection Browsing History with winner-mode |
|
|
|
@code{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. |
|
|
|
@code{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 |
|
@code{winner-mode}. To use @code{winner-mode}, simply enable it, and bind the appropriate |
|
interactive functions: |
|
|
|
@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 lisp |
|
|
|
@node Versioning Notes |
|
@subsection 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 @uref{https://git-scm.com/, Git}. Simply initialize |
|
@code{org-roam-directory} as a Git repository, and commit your files at regular or |
|
appropriate intervals. @uref{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. @uref{https://gitlab.com/pidu/git-timemachine, Git-timemachine} allows you to visit historic |
|
versions of a tracked Org-roam note. |
|
|
|
@node Full-text search interface with Deft |
|
@subsection Full-text search interface with Deft |
|
|
|
@uref{https://jblevins.org/projects/deft/, Deft} provides a nice interface for browsing and filtering org-roam notes. |
|
|
|
@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 lisp |
|
|
|
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 @code{org-roam}'s functionality. Here I'm |
|
using @uref{https://github.com/raxod502/el-patch, el-patch}: |
|
|
|
@lisp |
|
(use-package el-patch |
|
:straight (:host github |
|
:repo "raxod502/el-patch" |
|
:branch "develop")) |
|
|
|
(eval-when-compile |
|
(require 'el-patch)) |
|
|
|
(use-package deft |
|
;; same as above... |
|
:config/el-patch |
|
(defun deft-parse-title (file contents) |
|
"Parse the given FILE and CONTENTS and determine the title. |
|
If `deft-use-filename-as-title' is nil, the title is taken to |
|
be the first non-empty line of the FILE. Else the base name of the FILE is |
|
used as title." |
|
(el-patch-swap (if deft-use-filename-as-title |
|
(deft-base-filename file) |
|
(let ((begin (string-match "^.+$" contents))) |
|
(if begin |
|
(funcall deft-parse-title-function |
|
(substring contents begin (match-end 0)))))) |
|
(org-roam-db--get-title file)))) |
|
@end lisp |
|
|
|
The Deft interface can slow down quickly when the number of files get huge. |
|
@uref{https://github.com/hasu/notdeft, Notdeft} is a fork of Deft that uses an external search engine and indexer. |
|
|
|
@node Org-journal |
|
@subsection Org-journal |
|
|
|
@uref{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 |
|
@ref{Daily-notes, , @code{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. |
|
|
|
@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 lisp |
|
|
|
@node Note-taking Add-ons |
|
@subsection Note-taking Add-ons |
|
|
|
These are some plugins that make note-taking in Org-mode more enjoyable. |
|
|
|
@menu |
|
* Org-download:: |
|
* mathpix.el: mathpixel. |
|
* Org-noter / Interleave:: |
|
* Bibliography:: |
|
* Spaced Repetition:: |
|
@end menu |
|
|
|
@node Org-download |
|
@unnumberedsubsubsec Org-download |
|
|
|
@uref{https://github.com/abo-abo/org-download, Org-download} lets you screenshot and yank images from the web into your notes: |
|
|
|
@float Figure |
|
@image{images/org-download,,,,gif} |
|
@caption{org-download} |
|
@end float |
|
|
|
@lisp |
|
(use-package org-download |
|
:after org |
|
:bind |
|
(:map org-mode-map |
|
(("s-Y" . org-download-screenshot) |
|
("s-y" . org-download-yank)))) |
|
@end lisp |
|
|
|
@node mathpixel |
|
@unnumberedsubsubsec mathpix.el |
|
|
|
@uref{https://github.com/jethrokuan/mathpix.el, mathpix.el} uses @uref{https://mathpix.com/, Mathpix's} API to convert clips into latex equations: |
|
|
|
@float Figure |
|
@image{images/mathpix,,,,gif} |
|
@caption{mathpix} |
|
@end float |
|
|
|
@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 lisp |
|
|
|
@node Org-noter / Interleave |
|
@unnumberedsubsubsec Org-noter / Interleave |
|
|
|
@uref{https://github.com/weirdNox/org-noter, Org-noter} and |
|
@uref{https://github.com/rudolfochrist/interleave, Interleave} are both |
|
projects that allow synchronised annotation of documents (PDF, EPUB |
|
etc.) within Org-mode. |
|
|
|
@node Bibliography |
|
@unnumberedsubsubsec Bibliography |
|
|
|
@uref{https://github.com/org-roam/org-roam-bibtex, org-roam-bibtex} offers |
|
tight integration between |
|
@uref{https://github.com/jkitchin/org-ref, org-ref}, |
|
@uref{https://github.com/tmalsburg/helm-bibtex, helm-bibtex} and |
|
@code{org-roam}. This helps you manage your bibliographic notes under |
|
@code{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 @samp{#+roam_key}. |
|
|
|
@node Spaced Repetition |
|
@unnumberedsubsubsec Spaced Repetition |
|
|
|
@uref{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 @uref{https://orgmode.org/worg/org-contrib/org-drill.html, org-drill}, and @uref{https://github.com/abo-abo/pamparam, pamparam}. |
|
|
|
@node FAQ |
|
@chapter FAQ |
|
|
|
@menu |
|
* How do I have more than one Org-roam directory?:: |
|
* How do I migrate from Roam Research?:: |
|
* How do I create a note whose title already matches one of the candidates?:: |
|
@end menu |
|
|
|
@node How do I have more than one Org-roam directory? |
|
@section How do I have more than one Org-roam directory? |
|
|
|
Emacs supports directory-local variables, allowing the value of |
|
@code{org-roam-directory} to be different in different directories. It does this by |
|
checking for a file named @code{.dir-locals.el}. |
|
|
|
To add support for multiple directories, override the @code{org-roam-directory} |
|
variable using directory-local variables. This is what @code{.dir-locals.el} may |
|
contain: |
|
|
|
@lisp |
|
((nil . ((org-roam-directory . ".") |
|
(org-roam-db-location . "./org-roam.db")))) |
|
@end lisp |
|
|
|
All files within that directory will be treated as their own separate set of |
|
Org-roam files. Remember to run @code{org-roam-db-build-cache} from a file within |
|
that directory, at least once. |
|
|
|
@node How do I migrate from Roam Research? |
|
@section 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 @uref{https://github.com/fabioberger/roam-migration, in the repository}. |
|
|
|
@node How do I create a note whose title already matches one of the candidates? |
|
@section 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: |
|
|
|
@itemize |
|
@item |
|
Ivycall @code{ivy-immediate-done}, typically bound to @code{C-M-j}. Alternatively, |
|
set @code{ivy-use-selectable-prompt} to @code{t}, so that ``bar'' is now selectable. |
|
|
|
@item |
|
HelmOrg-roam should provide a selectable ``[?] bar'' candidate at the top of |
|
the candidate list. |
|
@end itemize |
|
|
|
@node Keystroke Index |
|
@appendix Keystroke Index |
|
|
|
@printindex ky |
|
|
|
@node Command Index |
|
@appendix Command Index |
|
|
|
@printindex cp |
|
|
|
@node Function Index |
|
@appendix Function Index |
|
|
|
@printindex fn |
|
|
|
@node Variable Index |
|
@appendix Variable Index |
|
|
|
@printindex vr |
|
|
|
Emacs 28.0.50 (Org mode 9.5) |
|
@bye
|
|
|