Compare commits

..

63 Commits

Author SHA1 Message Date
eca07277ce (release): Org-roam v1.2.0 (#802) 2020-06-12 23:29:52 +08:00
48158e67d4 (feat): add org-roam-unlinked-references (#787)
`org-roam-unlinked-references` uses rg to search for unlinked references. Regex courtesy of @angelsl.

Co-authored-by: Leo Vivier <leo.vivier+dev@gmail.com>
2020-06-12 23:21:01 +08:00
278e3df95d (fix): Remove space in docstring (#800) 2020-06-12 13:54:49 +02:00
48d2c199ac (fix): Fix local-var loading for dev suite (#799) 2020-06-12 13:49:33 +02:00
7f7ba857de (feat): add support for headlines (#783)
Achieve feature parity between links to files and links to headlines.

Before, we used the `file:foo::*bar` format to link to the headline `bar` in file `foo`, but this was prone to breakage upon renaming the file or modifying the headline. This is not the case anymore. Now, we use `org-id` to create IDs for those headlines, which are then stored in our database to compute the relationships and jump around. Note that this will work even if you’re not using `org-id` in your global configuration for Org-mode.

Co-authored-by: Jethro Kuan <jethrokuan95@gmail.com>
2020-06-12 18:51:13 +08:00
cf368ab4d8 (chore): remove unused mkdocs.yml (#798) 2020-06-12 17:47:18 +08:00
43dbad1f62 (UX): Add more meaningful error message for sqlite3 (#776)
Co-authored-by: Jethro Kuan <jethrokuan95@gmail.com>
2020-06-12 17:14:59 +08:00
040913151f (docs): update docstring for org-roam-db-location (#797)
Closes #792
2020-06-12 13:59:25 +08:00
1a964520f2 (doc): Add documentation about multiple templates for capture (#796)
* Add sentence noting that you can have multiple templates

* Add sentence describing that `file-name` can specify directory

* Make changes in .org instead

* Fix grammar and reflow

Co-authored-by: Jethro Kuan <jethrokuan95@gmail.com>
2020-06-12 07:14:09 +02:00
39276362d7 (docs): add entries to changelog (#795) 2020-06-12 11:31:06 +08:00
1168c9b6da (fix): Fix syntax for calling compiled versions of functions (#791) 2020-06-11 08:39:12 +02:00
92e02b5d14 (internal): remove redundant org-ref require (#788) 2020-06-10 20:02:37 +08:00
26b90b28e3 (fix): fix false failure from case in org-roam-doctor 2020-06-10 18:33:12 +08:00
f4376f39a9 (docs): update roam-ref qutebrowser configuration (#780) 2020-06-09 16:49:11 +08:00
898c6c8178 (docs): Add link to Roam-migration (#779) 2020-06-09 16:11:03 +08:00
30599cc3e8 (fix): fix prop extraction failures (#772)
This fixes a bug introduced in #770. Interestingly,
`org-element-property` always returns the prop in allcaps, so a
string-equal would have been sufficient. This commit reverts all usages
of `org-roam--extract-global-props` to use the upcase version of the
properties.
2020-06-07 22:10:47 +08:00
9d5a34d0f4 (internal): lowercase all properties (#770) 2020-06-07 16:25:34 +08:00
N V
5bf3e596c8 (feat): prefer lowercase versions of org in-file settings (#769)
See #768
2020-06-07 13:55:07 +08:00
N V
14f83bdb07 (fix): org-roam-capture append to existing file (#767)
org-roam-capture was querying plist for :file-path
instead of :path.

See: #766
2020-06-07 13:29:26 +08:00
81e7a5b231 (fix): fix org-roam--list-files elisp fallback (#764)
Always fallback to the elisp implementation, when the shell commands
return garbage (possibly from shell configurations).
2020-06-06 19:27:15 +08:00
1756ec6441 (fix): fix bad behaviour on malformed properties (#763)
Org-roam now skips over bad properties and throws a warning for the
given file that contains a malformed property. This allows most of the
database rebuild to complete, and for the user to fix the offending
file.

Fixes #728.
2020-06-06 16:48:42 +08:00
c61f7e20f2 (fix): simplify org-roam--str-to-list (#762)
This simplifies `org-roam--str-to-list`, and ensures that it parses
numbers correctly too. Fixes #745.
2020-06-05 20:27:02 +08:00
563252a6f6 (fix): remove alias for org-roam-buffer-no-delete-other-windows (#761)
This variable is made obsolete, and replaced with
`org-roam-buffer-window-parameters`, but their shape are different and
cannot be used interchangeably.
2020-06-05 15:54:02 +08:00
fdaf07da43 (fix): fix update-tags to correct delete removed tags (#760)
see https://github.com/org-roam/org-roam/pull/759#discussion_r435704588
2020-06-05 14:33:39 +08:00
5d25c4552d (internal): change org-roam-db--update-tags to only add non-nil tags (#759) 2020-06-05 13:36:13 +08:00
c46d153fd3 (internal): Make org-roam-db--get non-interactive (#758) 2020-06-04 22:07:09 +08:00
0cd4bc05c5 (feat): make roam properties case-insensitive (#757) 2020-06-04 16:39:23 +08:00
c5e0c6b9fa (fix): fix bug in org-roam-buffer-get-create (#754) 2020-06-04 12:32:45 +08:00
721689d5b5 (feat): add org-roam-buffer-window-parameters (#750)
The variable `org-roam-buffer-window-parameters` gives more
flexibility in customizing the org-roam-buffer window parameters.
`org-roam-buffer-no-delete-other-windows` is deprecated in favour of
this.
2020-06-03 23:25:31 +08:00
d36d3185ae Remove reliance on the current buffer when opening the *org-roam* window (#731)
If the `org-roam-buffer--get-create' function is called from a hook
then `get-buffer-window' will return `nil' since the current buffer
may not have been placed in a window yet.  This eventually leads to an
error.

This change moves some code around so that we can use
`save-selected-window' to allow temporary focu
s on the org-roam
side window so the resizing functions can work.
Co-authored-by: Jethro Kuan <jethrokuan95@gmail.com>
2020-06-03 21:11:46 +08:00
3ad43b0823 (internal): make org-roam--org-link-file-bracket-re more intelligible (#749) 2020-06-03 12:38:56 +08:00
b2594b84ae (docs): add section introducing the Zettelkasten method (#719) 2020-05-31 14:22:44 +08:00
3440e647c0 (fix): add org-roam--directory-files-recursively (#737)
Emacs 26 does not have the follow-symlinks option in
`directory-files-recursively`, so we have to add it ourselves.
2020-05-30 22:32:30 +08:00
1d28b07a7c (fix): org-roam--list-files: canonicalize filenames (#735) 2020-05-30 20:32:32 +08:00
195669ad10 (docs): Add missing Org package-install instructions (#734) 2020-05-30 19:04:42 +08:00
47feff5a8b (feat): allow for symlinks in the org roam directory (#733) 2020-05-30 18:52:25 +08:00
N V
7200364d31 (internal): remove org-roam--touch-file (#718)
Unused function.
2020-05-28 02:37:01 -04:00
873a314746 (fix): hide citelinks if buffer has no ROAM_KEY (#717) 2020-05-28 14:23:18 +08:00
N V
91c905d7e3 (docs): org-roam.el clarify documentation (#716)
Fix typo, reword docstring, remove decorative ellipses
2020-05-28 14:12:01 +08:00
f9a9f15a8b (fix): don't print no citelinks if org-ref is not present (#714)
Change confusing behaviour where org-roam buffer prints "no citelinks"
even when org-ref is not present.
2020-05-28 13:53:10 +08:00
N V
9ddadc9c25 (internal): org-roam-doctor require s, dash (#715)
Silence flycheck warnings
2020-05-28 01:44:13 -04:00
d0fab34287 (fix): fix support for Emacs 26 built-in org (#711)
org-make-link-string was changed to org-link-make-string in org 9.3. But Emacs
26 ships with org 9.1. Defining an alias to the old function name when using an
older org version.

Co-authored-by: N V <44036031+progfolio@users.noreply.github.com>
2020-05-28 13:35:24 +08:00
N V
e3281fc31f (internal): Exclude org-roam-compat.el from linting (#713)
org-roam-compat.el may contain symbols that belong to other packages.
e.g. functions backported to older versions of Org mode.
2020-05-28 01:22:51 -04:00
N V
5ee38f2d89 (fix): autoloaded commands load org-roam-mode (#712)
Users should not have to explicitly enable the minor mode before using
autoloaded commands.
2020-05-28 00:25:19 -04:00
N V
2e220f511e (fix): org-roam-db-build-cache filter non-file input (#709)
If a shell command is used to find files, it may include
output from another command.

see: #706, #688
2020-05-27 15:15:55 +08:00
1581d875ce (fix): doctor: add ROAM_KEY to supported props (#708) 2020-05-27 13:53:30 +08:00
50cc81c76d (internal): use emacsql-sqlite3 everywhere (#701) 2020-05-27 13:20:06 +08:00
f95cea7067 (feat): doctor: add check for misspelled roam properties (#703) 2020-05-26 14:52:51 +08:00
41a1970c6f (internal): add BACKERS.md (#702) 2020-05-26 14:41:09 +08:00
8818f50f41 (fix): fix symlinked directories and files not picked up (#700)
The implementations for org-roam--list-files-{find,rg} did not follow
symlinks, which cause them to not pick up symlinked files and
directories.
2020-05-26 13:46:08 +08:00
ea6bd215fc (fix): set default org-roam-list-files-commands for windows to nil (#698) 2020-05-25 13:26:46 +08:00
N V
a05b1ebcc3 (internal): refactor org-roam-find-file logic (#691)
Fail faster in case of nested capture.
Simplify logic for completions.
2020-05-23 17:42:47 -04:00
N V
214f9df844 (fix): org-roam--list-files strip ANSI color codes (#689)
Prevent shell commands from passing ANSI color codes through to callers.

see: #688
2020-05-22 23:51:52 -04:00
N V
4f5a82e291 (internal): org-roam.el formatting (#687)
Organize org-roam.el:
- Move functions so they are defined before they are referenced
- Move defcustoms to appropriate section, sort alphabetically
- Move interactive commands to appropriate section, autoload, sort.

Should not change any behavior, but make review easier.
2020-05-22 21:34:50 -04:00
4d0b5734c8 (fix): fix org-roam--list-files escape (#684) 2020-05-22 21:14:03 +08:00
4cd0fe4e41 (internal): add rg and find support for org-roam--list-files (#664)
Speeds up org-roam--list-files using external tools. Simple benchmarks:

(benchmark 1000 '(org-roam--list-files-rg "./jethrokuan/braindump"))
"Elapsed time: 9.012230s (0.399595s in 5 GCs)"

(benchmark 1000 '(org-roam--list-files-find "./jethrokuan/braindump"))
"Elapsed time: 5.543965s (0.318566s in 4 GCs)"

(benchmark 1000 '(org-roam--list-files-elisp "./jethrokuan/braindump"))
"Elapsed time: 55.781495s (3.220956s in 41 GCs)"

Co-authored-by: N V <44036031+progfolio@users.noreply.github.com>
Co-authored-by: Jethro Kuan <jethrokuan95@gmail.com>
2020-05-22 14:25:29 +08:00
N V
1eefc264f5 (fix): org-roam-graph--build notify user when build starts (#683)
Displays a message to user to let them know the build (which may take
a variable amount of time) has started.
2020-05-21 22:19:27 -04:00
N V
525a58dd86 (fix): org-roam-graph--build in seperate process (#679)
org-roam-graph--build accepts a callback function which is passed the
resultant graph file as its sole argument. This prevents a race between
graph building and opening.

See: #666
2020-05-21 13:03:16 -04:00
4a9401dd40 (feat): org-roam-doctor: add ROAM_TAGS and ROAM_ALIAS checks (#680) 2020-05-21 21:08:52 +08:00
dd2406ec92 (fix): fix 'ref context not returning path to file (#678) 2020-05-21 13:14:06 +08:00
c4189ffa04 (internal): remove github stale bot (#676)
bad bot.
2020-05-20 13:42:37 +08:00
e3d101f495 (doc): Update org-roam-bibtex repo URL (#675) 2020-05-19 15:12:28 -04:00
2cced712fa (docs): add landing page (#673)
Fixes #623 
Co-authored-by: Jethro Kuan <jethrokuan95@gmail.com>
2020-05-19 23:41:48 +08:00
39 changed files with 1690 additions and 944 deletions

View File

@ -1,4 +1,6 @@
;;; Directory Local Variables ;;; Directory Local Variables
;;; For more information see (info "(emacs) Directory Variables") ;;; For more information see (info "(emacs) Directory Variables")
((emacs-lisp-mode . ((eval . (require 'org-roam-dev))))) ((emacs-lisp-mode
(eval . (require 'org-roam-dev))
(sentence-end-double-space . nil)))

View File

@ -1,19 +0,0 @@
name: Mark stale issues and pull requests
on:
schedule:
- cron: "0 0 * * *"
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'Stale issue message'
stale-pr-message: 'Stale pull request message'
stale-issue-label: 'no-issue-activity'
stale-pr-label: 'no-pr-activity'

View File

@ -54,9 +54,11 @@ jobs:
# The "all" rule is not used, because it treats compilation warnings # The "all" rule is not used, because it treats compilation warnings
# as failures, so linting and testing are run as separate steps. # as failures, so linting and testing are run as separate steps.
# org-roam-compat is excluded from linting because it contains
# symbols/aliases from other packages
- name: Lint - name: Lint
continue-on-error: false continue-on-error: false
run: ./makem.sh -vv --sandbox $SANDBOX_DIR lint run: ./makem.sh -vv --sandbox $SANDBOX_DIR --exclude org-roam-compat.el lint
- name: Test - name: Test
if: always() # Run test even if linting fails. if: always() # Run test even if linting fails.

5
BACKERS.md Normal file
View File

@ -0,0 +1,5 @@
# Backers
Many thanks to the following backers, your contributions are greatly appreciated!
- Nathan Tran

View File

@ -1,11 +1,38 @@
# Changelog # Changelog
## 1.2.0 (12-06-2020)
In this release, we improved the linking process by achieving feature parity between links to files and links to headlines. Before, we used the `file:foo::*bar` format to link to the headline `bar` in file `foo`, but this was prone to breakage upon renaming the file or modifying the headline. This is not the case anymore. Now, we use `org-id` to create IDs for those headlines, which are then stored in our database to compute the relationships and jump around. Note that this will work even if youre not using `org-id` in your global configuration for Org-mode.
This is a major step forward. Supporting the in-file structure of Org-mode files means that we can interface with many of its core-features like TODOs, properties, priorities, etc. UX will have to be figured out, but this release ushers in a new age in terms of functionalities.
We also add `org-roam-unlinked-references`, which naively finds text that could be references to the current Org-roam file.
### Breaking Changes
- [#701](https://github.com/org-roam/org-roam/pull/701) Use `emacsql-sqlite3` instead of `emacsql-sqlite` for better Windows compatibility. This requires the presence of the standard `sqlite3` binary on your machine.
- [#750](https://github.com/org-roam/org-roam/pull/750) Deprecate `org-roam-buffer-no-delete-other-windows` in favour of `org-roam-buffer-window-parameters`.
### Features
- [#787](https://github.com/org-roam/org-roam/pull/787) Add `org-roam-unlinked-references`
- [#783](https://github.com/org-roam/org-roam/pull/783) Add support for headlines
- [#757](https://github.com/org-roam/org-roam/pull/757) Roam global properties are now case-insensitive
- [#680](https://github.com/org-roam/org-roam/pull/680) , [#703](https://github.com/org-roam/org-roam/pull/703), [#708](https://github.com/org-roam/org-roam/pull/708) Add `org-roam-doctor` checkers for `ROAM_*` properties
- [#664](https://github.com/org-roam/org-roam/pull/664) Add support for shelling out to `rg` and `find` in `org-roam--list-files`
- [#679](https://github.com/org-roam/org-roam/pull/679), [#683](https://github.com/org-roam/org-roam/pull/683) Building of the graph now happens in a separate process
### Bugfixes
- [#714](https://github.com/org-roam/org-roam/pull/714) No longer print citelinks in backlinks buffer if there is no `ROAM_KEY` property or `org-ref` is not installed
- [#759](https://github.com/org-roam/org-roam/pull/759), [#760](https://github.com/org-roam/org-roam/pull/760) Tags are only added to the tags table if there are actually tags present
- [#700](https://github.com/org-roam/org-roam/pull/700), [#733](https://github.com/org-roam/org-roam/pull/733) Allow symlinks within the `org-roam` directory
## 1.1.1 (18-05-2020) ## 1.1.1 (18-05-2020)
In this release, we added two new features: In this release, we added two new features:
1. `org-roam-doctor`: a linting system that helps you discover possible problems with your Org-roam files. This is in the spirit of keeping notes in top quality. 1. `org-roam-doctor`: a linting system that helps you discover possible problems with your Org-roam files. This is in the spirit of keeping notes in top quality.
2. A tagging system: one can now use sub-directories, and the `#+ROAM_TAG` key add additional meta data to notes. For more information, see [here](https://org-roam.github.io/org-roam/manual/Tags.html#Tags). 2. A tagging system: one can now use sub-directories, and the `#+roam_tags` key add additional meta data to notes. For more information, see [here](https://org-roam.github.io/org-roam/manual/Tags.html#Tags).
As usual, this release comes with a multitude of bug-fixes and refactorings. As usual, this release comes with a multitude of bug-fixes and refactorings.

85
doc/css/styles.css Normal file
View File

@ -0,0 +1,85 @@
body {
margin: 20px;
background: #303030;
color: #f5f5f5;
font-size: 1.6rem;
font-weight: 300;
}
.container {
max-width: 800px;
}
.nav {
margin-top: 5rem;
}
.nav-item a {
/* color: #797979; */
color: #bebebe;
text-decoration: none;
font-family: "Consolas", "Monaco", "Menlo", monospace;
}
.nav-item a:hover {
cursor: pointer;
/* color: #4d4a4a; */
color: #dcdcdc;
border: none;
}
.hero {
color: #f5f5f5;
}
.hero div {
margin-bottom: 5rem;
}
.hero h3 {
/* font-family: "Edelsans", sans-serif; */
font-size: 5rem;
margin-bottom: 0;
}
.hero h5 {
margin-top: 1rem;
margin-bottom: 0;
/* font-weight: 200; */
font-weight: 250;
}
.grid-demo-col {
background: #e4e4e4;
}
a {
color: #cd86ff;
}
a:hover {
color: #dbb9f3;
}
img {
max-width: 100%;
}
.footer-links {
font-size: 1.5rem;
color: #f5f5f5;
text-decoration: none;
font-weight: 250;
}
.header {
font-weight: 200;
}
#footer {
margin-bottom: 3rem;
}
#footer h5 {
margin-bottom: 1.5rem;
}

BIN
doc/img/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

BIN
doc/img/screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

View File

@ -1,3 +1,175 @@
<html> <!DOCTYPE html>
<h1>--> <a href="manual/index.html">MANUAL HERE</a> <--</h1> <html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="An Effortless PKM System." />
<meta name="author" content="Org-roam Contributors" />
<title>Org-roam</title>
<link rel="stylesheet" href="https://unpkg.com/wingcss" />
<link rel="stylesheet" type="text/css" href="./css/styles.css" />
<script src="https://code.iconify.design/1/1.0.6/iconify.min.js"></script>
</head>
<body>
<section class="hero container center text-center">
<div>
<img src="./img/logo.png" alt="Org-roam Logo" height="200" />
<h3>Org-roam</h3>
<h5>A plain-text personal knowledge management system.</h5>
</div>
</section>
<section class="container center">
<div>
<img src="./img/screenshot.png" alt="screenshot" />
</div>
</section>
<section id="features" class="container center">
<div>
<h3 class="header">FEATURES</h3>
<div class="row">
<div class="col">
<h5 class="left">
<iconify-icon data-icon="fxemoji:lock"></iconify-icon> &nbsp;
Private and Secure
</h5>
<p class="content">
Edit your personal wiki completely offline, entirely in your
control. Encrypt your notes with GPG. Take lasting notes in
plain-text.
</p>
</div>
<div class="col">
<h5 class="left">
<iconify-icon data-icon="flat-color-icons:link"></iconify-icon>
&nbsp; Make Connections
</h5>
<p class="content">
Connect notes and thoughts together with ease using backlinks.
Discover surprising and previously unseen connections in your
notes with the built-in graph visualization.
</p>
</div>
</div>
<div class="row">
<div class="col">
<h5 class="left">
<iconify-icon data-icon="twemoji:puzzle-piece"></iconify-icon>
&nbsp; Extensible and Powerful
</h5>
<p class="content">
Leverage Emacs' fantastic text-editing interface, and the mature
Emacs and Org-mode ecosystem of packages.
</p>
</div>
<div class="col">
<h5 class="left">
<iconify-icon data-icon="logos:git-icon"></iconify-icon> &nbsp;
Free and Open Source
</h5>
<p class="content">
Org-roam is licensed under the GNU General Public License version
3 or later. You are free to extend its functionality and
contribute back. Find
us <a href="https://github.com/org-roam/org-roam">here</a>.
</p>
</div>
</div>
</div>
</section>
<section id="links" class="container">
<div>
<h3 class="header">LINKS</h3> New to Emacs and Org-mode, and trying to
find your way around? Org-roam has an inclusive community of users
passionate about Personal Knowledge Management -- we're happy to help!
You can find us on Discourse and Slack.
<ul>
<li>Read our documentation within Emacs, or on the <a href="https://org-roam.github.io/org-roam/manual/">Online Manual</a></li>
<li>Participate in our forum discussions on <a href="https://org-roam.discourse.group">Discourse</a></li>
<li>Chat with us on <a href="https://join.slack.com/t/orgroam/shared_invite/zt-deoqamys-043YQ~s5Tay3iJ5QRI~Lxg">Slack</a></li>
</ul>
</div>
</section>
<section id="footer" class="row container">
<div class="col">
<div class="row">
<h5 class="header">Ecosystem</h5>
</div>
<div class="row">
<a
class="content footer-links"
href="https://github.com/org-roam/org-roam-bibtex"
>org-roam-bibtex</a
>
</div>
<div class="row">
<a
class="content footer-links"
href="https://github.com/org-roam/org-roam-server"
>org-roam-server</a
>
</div>
<div class="row">
<a
class="content footer-links"
href="https://github.com/org-roam/company-org-roam"
>company-org-roam</a
>
</div>
</div>
<div class="col">
<div class="row">
<h5 class="header">Resources</h5>
</div>
<div class="row">
<a
class="content footer-links"
href="https://github.com/org-roam/org-roam/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc"
>Open Issues</a
>
</div>
<div class="row">
<a
class="content footer-links"
href="https://github.com/org-roam/org-roam/releases"
>Releases</a
>
</div>
</div>
<div class="col">
<div class="row">
<h5 class="header">Connect</h5>
</div>
<div class="row">
<a
class="content footer-links"
href="https://join.slack.com/t/orgroam/shared_invite/zt-deoqamys-043YQ~s5Tay3iJ5QRI~Lxg"
>Slack</a
>
</div>
<div class="row">
<a
class="content footer-links"
href="https://org-roam.discourse.group/"
>Discourse</a
>
</div>
</div>
</section>
</body>
</html> </html>

View File

@ -1,20 +1,20 @@
#+TITLE: Org-roam User Manual #+title: Org-roam User Manual
:PREAMBLE: :PREAMBLE:
#+AUTHOR: Jethro Kuan #+author: Jethro Kuan
#+EMAIL: jethrokuan95@gmail.com #+email: jethrokuan95@gmail.com
#+DATE: 2020-2020 #+date: 2020-2020
#+LANGUAGE: en #+language: en
#+TEXINFO_DIR_CATEGORY: Emacs #+texinfo_dir_category: Emacs
#+TEXINFO_DIR_TITLE: Org-roam: (org-roam). #+texinfo_dir_title: Org-roam: (org-roam).
#+TEXINFO_DIR_DESC: Rudimentary Roam Replica for Emacs. #+texinfo_dir_desc: Rudimentary Roam Replica for Emacs.
#+SUBTITLE: for version 1.1.1 #+subtitle: for version 1.2.0
#+OPTIONS: H:4 num:3 toc:2 creator:t #+options: H:4 num:3 toc:2 creator:t
#+PROPERTY: header-args :eval never #+property: header-args :eval never
#+TEXINFO: @noindent #+texinfo: @noindent
This manual is for Org-roam version 1.1.1. This manual is for Org-roam version 1.2.0.
#+BEGIN_QUOTE #+BEGIN_QUOTE
Copyright (C) 2020-2020 Jethro Kuan <jethrokuan95@gmail.com> Copyright (C) 2020-2020 Jethro Kuan <jethrokuan95@gmail.com>
@ -55,13 +55,63 @@ Org-roam provides several benefits over other tooling:
- 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 PR. - 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 PR.
- Leverages 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. - Leverages 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.
- 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. - 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.
* 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 also introduce terms commonly used within
the Zettelkasten community, which will also commonly appear in the Org-roam
forums and channels of discussion.
The Zettelkasten method of note-taking is designed to increase research
productivity: in particular, it acts 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.
In its paper form, the slip-box is 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.
Org-roam is the slip-box, digitalized in Org-mode. Every zettel (card) is a
plain-text, Org-mode file. These files are often placed in the same directory.
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. Org-roam also facilitates the linking of zettels using Org-mode ~file:~
links.
A slip-box requires a method of 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 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 * Installation
** _ :ignore:
Org-roam can be installed using Emacs' package manager or manually from its development repository. Org-roam can be installed using Emacs' package manager or manually from its
development repository.
** Installing from MELPA ** 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=: 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: - To use Melpa:
@ -79,6 +129,13 @@ Org-roam is available from Melpa and Melpa-Stable. If you haven't used Emacs' pa
'("melpa-stable" . "http://stable.melpa.org/packages/") t) '("melpa-stable" . "http://stable.melpa.org/packages/") t)
#+END_SRC #+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 Once you have added your preferred archive, you need to update the
local package list using: local package list using:
@ -97,7 +154,24 @@ Now see [[*Post-Installation Tasks][Post-Installation Tasks]].
** TODO Installing from the Git Repository ** TODO Installing from the Git Repository
** TODO Post-Installation Tasks ** Post-Installation Tasks
Org-roam uses ~emacsql-sqlite3~, which 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 * Getting Started
@ -185,16 +259,16 @@ Org-roam calls =org-roam--extract-titles= to extract titles. It uses the
variable =org-roam-title-sources=, to control how the titles are extracted. The variable =org-roam-title-sources=, to control how the titles are extracted. The
title extraction methods supported are: title extraction methods supported are:
1. ='title=: This extracts the title using the file =#+TITLE= property 1. ='title=: This extracts the title using the file =#+title= property
2. ='headline=: This extracts the title from the first headline in the Org file 2. ='headline=: This extracts the title from the first headline in the Org file
3. ='alias=: This extracts a list of titles using the =#ROAM_ALIAS= property. 3. ='alias=: This extracts a list of titles using the =#+roam_alias= property.
The aliases are space-delimited, and can be multi-worded using quotes The aliases are space-delimited, and can be multi-worded using quotes
Take for example the following org file: Take for example the following org file:
#+BEGIN_SRC org #+BEGIN_SRC org
#+TITLE: World War 2 #+title: World War 2
#+ROAM_ALIAS: "WWII" "World War II" #+roam_alias: "WWII" "World War II"
* Headline * Headline
#+END_SRC #+END_SRC
@ -225,7 +299,7 @@ Org-roam calls =org-roam--extract-tags= to extract tags from files. It uses the
variable =org-roam-tag-sources=, to control how tags are extracted. The tag variable =org-roam-tag-sources=, to control how tags are extracted. The tag
extraction methods supported are: extraction methods supported are:
1. ='prop=: This extracts tags from the =#+ROAM_TAGS= property. Tags are space delimited, and can be multi-word using double quotes. 1. ='prop=: This extracts tags from the =#+roam_tags= property. Tags are space delimited, and can be multi-word using double quotes.
2. ='all-directories=: All sub-directories relative to =org-roam-directory= are 2. ='all-directories=: All sub-directories relative to =org-roam-directory= are
extracted as tags. That is, if a file is located at relative path extracted as tags. That is, if a file is located at relative path
=foo/bar/file.org=, the file will have tags =foo= and =bar=. =foo/bar/file.org=, the file will have tags =foo= and =bar=.
@ -251,8 +325,8 @@ Refs are unique identifiers for files. Each note can only have 1 ref.
For example, a note for a website may contain a ref: For example, a note for a website may contain a ref:
#+BEGIN_SRC org #+BEGIN_SRC org
#+TITLE: Google #+title: Google
#+ROAM_KEY: https://www.google.com/ #+roam_key: https://www.google.com/
#+END_SRC #+END_SRC
These keys come in useful for when taking website notes, using the These keys come in useful for when taking website notes, using the
@ -262,8 +336,8 @@ Alternatively, add a ref for notes for a specific paper, using its
[[https://github.com/jkitchin/org-ref][org-ref]] citation key: [[https://github.com/jkitchin/org-ref][org-ref]] citation key:
#+BEGIN_SRC org #+BEGIN_SRC org
#+TITLE: Neural Ordinary Differential Equations #+title: Neural Ordinary Differential Equations
#+ROAM_KEY: cite:chen18_neural_ordin_differ_equat #+roam_key: cite:chen18_neural_ordin_differ_equat
#+END_SRC #+END_SRC
The backlinks buffer will show any cites of this key: e.g. The backlinks buffer will show any cites of this key: e.g.
@ -287,7 +361,9 @@ org-roam's templating system works, it may be useful to look into basic usage of
=org-capture=. =org-capture=.
Org-roam's templates can be customized by modifying the variable Org-roam's templates can be customized by modifying the variable
=org-roam-capture-templates=. =org-roam-capture-templates=. Just like the base =org-capture= this variable can
contain multiple templates, in which case you will be prompted on which one to
use when capturing a new note.
** Template Walkthrough ** Template Walkthrough
@ -298,7 +374,7 @@ the default template, reproduced below.
("d" "default" plain (function org-roam--capture-get-point) ("d" "default" plain (function org-roam--capture-get-point)
"%?" "%?"
:file-name "%<%Y%m%d%H%M%S>-${slug}" :file-name "%<%Y%m%d%H%M%S>-${slug}"
:head "#+TITLE: ${title}\n" :head "#+title: ${title}\n"
:unnarrowed t) :unnarrowed t)
#+END_SRC #+END_SRC
@ -311,9 +387,12 @@ the default template, reproduced below.
5. ="%?"= is the template inserted on each call to =org-roam-capture--capture=. 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 This template means don't insert any content, but place the cursor
here. here.
6. =:file-name= is the file-name template for a new note, if it doesn't 6. =:file-name= is the file-name template for a new note, if it doesn't yet
yet exist. This creates a file at path that looks like exist. This creates a file at path that looks like
=/path/to/org-roam-directory/20200213032037-foo.org=. =/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 7. =:head= contains the initial template to be inserted (once only), at
the beginning of the file. Here, the title global attribute is the beginning of the file. Here, the title global attribute is
inserted. inserted.
@ -354,7 +433,7 @@ directly to provide its third argument to specify UTC.
("d" "default" plain (function org-roam--capture-get-point) ("d" "default" plain (function org-roam--capture-get-point)
"%?" "%?"
:file-name "%(format-time-string \"%Y-%m-%d--%H-%M-%SZ--${slug}\" (current-time) t)" :file-name "%(format-time-string \"%Y-%m-%d--%H-%M-%SZ--${slug}\" (current-time) t)"
:head "#+TITLE: ${title}\n" :head "#+title: ${title}\n"
:unnarrowed t) :unnarrowed t)
#+END_SRC #+END_SRC
@ -466,7 +545,6 @@ number of password prompts, you may wish to cache the password.
- Variable: org-roam-encrypt-files - Variable: org-roam-encrypt-files
Whether to encrypt new files. If true, create files with .org.gpg extension. Whether to encrypt new files. If true, create files with .org.gpg extension.
* Graphing * Graphing
Org-roam provides graphing capabilities to explore interconnections between Org-roam provides graphing capabilities to explore interconnections between
@ -692,7 +770,7 @@ in the generated graph.
** The =roam-ref= Protocol ** The =roam-ref= Protocol
This protocol finds or creates a new note with a given =ROAM_KEY= (see [[*Anatomy of an Org-roam File][Anatomy of an Org-roam File]]): This protocol finds or creates a new note with a given ~roam_key~ (see [[*Anatomy of an Org-roam File][Anatomy of an Org-roam File]]):
[[file:images/roam-ref.gif]] [[file:images/roam-ref.gif]]
@ -706,26 +784,25 @@ javascript:location.href =
+ encodeURIComponent(document.title) + encodeURIComponent(document.title)
#+END_SRC #+END_SRC
or as a keybinding in =qutebrowser=, adding the following to the =autoconfig.yml= file: 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 yaml #+BEGIN_SRC python
settings: config.bind("<Ctrl-r>", "spawn bash -c 'emacsclient \"org-protocol://roam-ref?template=r&ref={url:pretty}&title={title}\" '")
bindings.commands:
global:
normal:
gc: open javascript:void(location.href='org-protocol://roam-ref?template=r&ref='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title))
#+END_SRC #+END_SRC
where =template= is the template key for a template in where ~template~ is the template key for a template in
=org-roam-capture-ref-templates= (see [[*The Templating System][The Templating System]]). These templates ~org-roam-capture-ref-templates~ (see [[*The Templating System][The Templating System]]). These templates
should contain a =#+ROAM_KEY: ${ref}= in it. should contain a ~#+roam_key: ${ref}~ in it.
* TODO Daily Notes
* Diagnosing and Repairing Files * Diagnosing and Repairing Files
Org-roam provides a utility for diagnosing and repairing problematic files via Org-roam provides a utility for diagnosing and repairing problematic files via
=org-roam-doctor=. By default, =org-roam-doctor= runs the check across all Org-roam ~org-roam-doctor~. By default, ~org-roam-doctor~ runs the check on the current
files, and this can take some time. To run the check only for the current file, Org-roam file. To run the check only for the current file, run =C-u M-x
run =C-u M-x org-roam-doctor=. org-roam-doctor=, but note that this may take some time.
- Function: org-roam-doctor &optional this-buffer - Function: org-roam-doctor &optional this-buffer
@ -751,7 +828,6 @@ 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 =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 window displaying the error message, as well as the list of actions that can be
taken provided in =:actions=. taken provided in =:actions=.
* _ Copying * _ Copying
:PROPERTIES: :PROPERTIES:
:COPYING: t :COPYING: t
@ -858,7 +934,7 @@ to see all dated entries.
:bind :bind
("C-c n j" . org-journal-new-entry) ("C-c n j" . org-journal-new-entry)
:custom :custom
(org-journal-date-prefix "#+TITLE: ") (org-journal-date-prefix "#+title: ")
(org-journal-file-format "%Y-%m-%d.org") (org-journal-file-format "%Y-%m-%d.org")
(org-journal-dir "/path/to/org-roam-files/") (org-journal-dir "/path/to/org-roam-files/")
(org-journal-date-format "%A, %d %B %Y")) (org-journal-date-format "%A, %d %B %Y"))
@ -876,8 +952,7 @@ These are some plugins that make note-taking in Org-mode more enjoyable.
:CUSTOM_ID: org-download :CUSTOM_ID: org-download
:END: :END:
[[https://github.com/abo-abo/org-download][Org-download]] lets you [[https://github.com/abo-abo/org-download][Org-download]] lets you screenshot and yank images from the web into your notes:
screenshot and yank images from the web into your notes:
#+CAPTION: org-download #+CAPTION: org-download
[[file:images/org-download.gif]] [[file:images/org-download.gif]]
@ -896,9 +971,7 @@ screenshot and yank images from the web into your notes:
:CUSTOM_ID: mathpix.el :CUSTOM_ID: mathpix.el
:END: :END:
[[https://github.com/jethrokuan/mathpix.el][mathpix.el]] uses [[https://github.com/jethrokuan/mathpix.el][mathpix.el]] uses [[https://mathpix.com/][Mathpix's]] API to convert clips into latex equations:
[[https://mathpix.com/][Mathpix's]] API to convert clips into latex
equations:
#+CAPTION: mathpix #+CAPTION: mathpix
[[file:images/mathpix.gif]] [[file:images/mathpix.gif]]
@ -927,7 +1000,7 @@ etc.) within Org-mode.
:CUSTOM_ID: bibliography :CUSTOM_ID: bibliography
:END: :END:
[[https://github.com/zaeph/org-roam-bibtex][org-roam-bibtex]] offers [[https://github.com/org-roam/org-roam-bibtex][org-roam-bibtex]] offers
tight integration between tight integration between
[[https://github.com/jkitchin/org-ref][org-ref]], [[https://github.com/jkitchin/org-ref][org-ref]],
[[https://github.com/tmalsburg/helm-bibtex][helm-bibtex]] and [[https://github.com/tmalsburg/helm-bibtex][helm-bibtex]] and
@ -939,11 +1012,8 @@ tight integration between
:CUSTOM_ID: spaced-repetition :CUSTOM_ID: spaced-repetition
:END: :END:
[[https://github.com/l3kn/org-fc/][Org-fc]] is a spaced repetition [[https://github.com/l3kn/org-fc/][Org-fc]] is a spaced repetition system that scales well with a large number of
system that scales well with a large number of files. Other alternatives files. Other alternatives include [[https://orgmode.org/worg/org-contrib/org-drill.html][org-drill]], and [[https://github.com/abo-abo/pamparam][pamparam]].
include
[[https://orgmode.org/worg/org-contrib/org-drill.html][org-drill]], and
[[https://github.com/abo-abo/pamparam][pamparam]].
* FAQ * FAQ
** How do I have more than one Org-roam directory? ** How do I have more than one Org-roam directory?
@ -964,9 +1034,12 @@ 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 set of Org-roam files. Remember to run =org-roam-db-build-cache= from a
file within that directory, at least once. file within that directory, at least once.
* _ :ignore: ** 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]].
# Local Variables: # Local Variables:
# eval: (refill-mode +1) # eval: (require 'ol-info)
# before-save-hook: org-make-toc # before-save-hook: org-make-toc
# after-save-hook: (lambda nil (progn (require 'ox-texinfo nil t) (org-texinfo-export-to-info))) # after-save-hook: (lambda nil (progn (require 'ox-texinfo nil t) (org-texinfo-export-to-info)))
# indent-tabs-mode: nil # indent-tabs-mode: nil

View File

@ -31,7 +31,7 @@ General Public License for more details.
@finalout @finalout
@titlepage @titlepage
@title Org-roam User Manual @title Org-roam User Manual
@subtitle for version 1.1.1 @subtitle for version 1.2.0
@author Jethro Kuan @author Jethro Kuan
@page @page
@vskip 0pt plus 1filll @vskip 0pt plus 1filll
@ -46,7 +46,7 @@ General Public License for more details.
@noindent @noindent
This manual is for Org-roam version 1.1.1. This manual is for Org-roam version 1.2.0.
@quotation @quotation
Copyright (C) 2020-2020 Jethro Kuan <jethrokuan95@@gmail.com> Copyright (C) 2020-2020 Jethro Kuan <jethrokuan95@@gmail.com>
@ -65,6 +65,7 @@ General Public License for more details.
@menu @menu
* Introduction:: * Introduction::
* A Brief Introduction to the Zettelkasten Method::
* Installation:: * Installation::
* Getting Started:: * Getting Started::
* Anatomy of an Org-roam File:: * Anatomy of an Org-roam File::
@ -75,17 +76,16 @@ General Public License for more details.
* Graphing:: * Graphing::
* Org-roam Completion System:: * Org-roam Completion System::
* Roam Protocol:: * Roam Protocol::
* Daily Notes::
* Diagnosing and Repairing Files:: * Diagnosing and Repairing Files::
* Appendix:: * Appendix::
* FAQ:: * FAQ::
* _: _ (2).
@detailmenu @detailmenu
--- The Detailed Node Listing --- --- The Detailed Node Listing ---
Installation Installation
* _::
* Installing from MELPA:: * Installing from MELPA::
* Installing from the Git Repository:: * Installing from the Git Repository::
* Post-Installation Tasks:: * Post-Installation Tasks::
@ -119,7 +119,7 @@ Graphing
Roam Protocol Roam Protocol
* _: _ (1). * _::
* Installation: Installation (1). * Installation: Installation (1).
* The @samp{roam-file} protocol:: * The @samp{roam-file} protocol::
* The @samp{roam-ref} Protocol:: * The @samp{roam-ref} Protocol::
@ -139,6 +139,7 @@ Ecosystem
FAQ FAQ
* How do I have more than one Org-roam directory?:: * How do I have more than one Org-roam directory?::
* How do I migrate from Roam Research?::
@end detailmenu @end detailmenu
@end menu @end menu
@ -176,25 +177,71 @@ Over the years, Emacs and Org-mode has developed into a mature system for plain-
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. 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 table @end table
@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 also introduce terms commonly used within
the Zettelkasten community, which will also commonly appear in the Org-roam
forums and channels of discussion.
The Zettelkasten method of note-taking is designed to increase research
productivity: in particular, it acts 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.
In its paper form, the slip-box is 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.
Org-roam is the slip-box, digitalized in Org-mode. Every zettel (card) is a
plain-text, Org-mode file. These files are often placed in the same directory.
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. Org-roam also facilitates the linking of zettels using Org-mode @code{file:}
links.
A slip-box requires a method of 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.
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 @node Installation
@chapter Installation @chapter Installation
Org-roam can be installed using Emacs' package manager or manually from its
development repository.
@menu @menu
* _::
* Installing from MELPA:: * Installing from MELPA::
* Installing from the Git Repository:: * Installing from the Git Repository::
* Post-Installation Tasks:: * Post-Installation Tasks::
@end menu @end menu
@node _
@section _ :ignore:
Org-roam can be installed using Emacs' package manager or manually from its development repository.
@node Installing from MELPA @node Installing from MELPA
@section 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 info:emacs#Packages. Then, add one of the archives to @samp{package-archives}: 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 @itemize
@item @item
@ -218,6 +265,13 @@ To use Melpa-Stable:
'("melpa-stable" . "http://stable.melpa.org/packages/") t) '("melpa-stable" . "http://stable.melpa.org/packages/") t)
@end lisp @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 Once you have added your preferred archive, you need to update the
local package list using: local package list using:
@ -238,7 +292,24 @@ Now see @ref{Post-Installation Tasks}.
@section @strong{TODO} Installing from the Git Repository @section @strong{TODO} Installing from the Git Repository
@node Post-Installation Tasks @node Post-Installation Tasks
@section @strong{TODO} 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 @node Getting Started
@chapter Getting Started @chapter Getting Started
@ -337,19 +408,19 @@ title extraction methods supported are:
@enumerate @enumerate
@item @item
@samp{'title}: This extracts the title using the file @samp{#+TITLE} property @samp{'title}: This extracts the title using the file @samp{#+title} property
@item @item
@samp{'headline}: This extracts the title from the first headline in the Org file @samp{'headline}: This extracts the title from the first headline in the Org file
@item @item
@samp{'alias}: This extracts a list of titles using the @samp{#ROAM_ALIAS} property. @samp{'alias}: This extracts a list of titles using the @samp{#+roam_alias} property.
The aliases are space-delimited, and can be multi-worded using quotes The aliases are space-delimited, and can be multi-worded using quotes
@end enumerate @end enumerate
Take for example the following org file: Take for example the following org file:
@example @example
#+TITLE: World War 2 #+title: World War 2
#+ROAM_ALIAS: "WWII" "World War II" #+roam_alias: "WWII" "World War II"
* Headline * Headline
@end example @end example
@ -388,7 +459,7 @@ extraction methods supported are:
@enumerate @enumerate
@item @item
@samp{'prop}: This extracts tags from the @samp{#+ROAM_TAGS} property. Tags are space delimited, and can be multi-word using double quotes. @samp{'prop}: This extracts tags from the @samp{#+roam_tags} property. Tags are space delimited, and can be multi-word using double quotes.
@item @item
@samp{'all-directories}: All sub-directories relative to @samp{org-roam-directory} are @samp{'all-directories}: All sub-directories relative to @samp{org-roam-directory} are
extracted as tags. That is, if a file is located at relative path extracted as tags. That is, if a file is located at relative path
@ -418,8 +489,8 @@ Refs are unique identifiers for files. Each note can only have 1 ref.
For example, a note for a website may contain a ref: For example, a note for a website may contain a ref:
@example @example
#+TITLE: Google #+title: Google
#+ROAM_KEY: https://www.google.com/ #+roam_key: https://www.google.com/
@end example @end example
These keys come in useful for when taking website notes, using the These keys come in useful for when taking website notes, using the
@ -429,8 +500,8 @@ Alternatively, add a ref for notes for a specific paper, using its
@uref{https://github.com/jkitchin/org-ref, org-ref} citation key: @uref{https://github.com/jkitchin/org-ref, org-ref} citation key:
@example @example
#+TITLE: Neural Ordinary Differential Equations #+title: Neural Ordinary Differential Equations
#+ROAM_KEY: cite:chen18_neural_ordin_differ_equat #+roam_key: cite:chen18_neural_ordin_differ_equat
@end example @end example
The backlinks buffer will show any cites of this key: e.g. The backlinks buffer will show any cites of this key: e.g.
@ -464,7 +535,9 @@ org-roam's templating system works, it may be useful to look into basic usage of
@samp{org-capture}. @samp{org-capture}.
Org-roam's templates can be customized by modifying the variable Org-roam's templates can be customized by modifying the variable
@samp{org-roam-capture-templates}. @samp{org-roam-capture-templates}. Just like the base @samp{org-capture} this variable can
contain multiple templates, in which case you will be prompted on which one to
use when capturing a new note.
@menu @menu
* Template Walkthrough:: * Template Walkthrough::
@ -481,7 +554,7 @@ the default template, reproduced below.
("d" "default" plain (function org-roam--capture-get-point) ("d" "default" plain (function org-roam--capture-get-point)
"%?" "%?"
:file-name "%<%Y%m%d%H%M%S>-$@{slug@}" :file-name "%<%Y%m%d%H%M%S>-$@{slug@}"
:head "#+TITLE: $@{title@}\n" :head "#+title: $@{title@}\n"
:unnarrowed t) :unnarrowed t)
@end lisp @end lisp
@ -501,9 +574,12 @@ The template is given a description of @samp{"default"}.
This template means don't insert any content, but place the cursor This template means don't insert any content, but place the cursor
here. here.
@item @item
@samp{:file-name} is the file-name template for a new note, if it doesn't @samp{:file-name} is the file-name template for a new note, if it doesn't yet
yet exist. This creates a file at path that looks like exist. This creates a file at path that looks like
@samp{/path/to/org-roam-directory/20200213032037-foo.org}. @samp{/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 @samp{private/$@{slug@}} will create notes in
@samp{/path/to/org-roam-directory/private}.
@item @item
@samp{:head} contains the initial template to be inserted (once only), at @samp{:head} contains the initial template to be inserted (once only), at
the beginning of the file. Here, the title global attribute is the beginning of the file. Here, the title global attribute is
@ -548,7 +624,7 @@ directly to provide its third argument to specify UTC@.
("d" "default" plain (function org-roam--capture-get-point) ("d" "default" plain (function org-roam--capture-get-point)
"%?" "%?"
:file-name "%(format-time-string \"%Y-%m-%d--%H-%M-%SZ--$@{slug@}\" (current-time) t)" :file-name "%(format-time-string \"%Y-%m-%d--%H-%M-%SZ--$@{slug@}\" (current-time) t)"
:head "#+TITLE: $@{title@}\n" :head "#+title: $@{title@}\n"
:unnarrowed t) :unnarrowed t)
@end lisp @end lisp
@ -840,13 +916,13 @@ Other options include @samp{'ido}, and @samp{'ivy}.
@chapter Roam Protocol @chapter Roam Protocol
@menu @menu
* _: _ (1). * _::
* Installation: Installation (1). * Installation: Installation (1).
* The @samp{roam-file} protocol:: * The @samp{roam-file} protocol::
* The @samp{roam-ref} Protocol:: * The @samp{roam-ref} Protocol::
@end menu @end menu
@node _ (1) @node _
@section _ :ignore: @section _ :ignore:
Org-roam extending @samp{org-protocol} with 2 protocols: the @samp{roam-file} Org-roam extending @samp{org-protocol} with 2 protocols: the @samp{roam-file}
@ -984,7 +1060,7 @@ in the generated graph.
@node The @samp{roam-ref} Protocol @node The @samp{roam-ref} Protocol
@section The @samp{roam-ref} Protocol @section The @samp{roam-ref} Protocol
This protocol finds or creates a new note with a given @samp{ROAM_KEY} (see @ref{Anatomy of an Org-roam File}): This protocol finds or creates a new note with a given @code{roam_key} (see @ref{Anatomy of an Org-roam File}):
@image{images/roam-ref,,,,gif} @image{images/roam-ref,,,,gif}
@ -998,27 +1074,27 @@ javascript:location.href =
+ encodeURIComponent(document.title) + encodeURIComponent(document.title)
@end example @end example
or as a keybinding in @samp{qutebrowser}, adding the following to the @samp{autoconfig.yml} file: 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 @example
settings: config.bind("<Ctrl-r>", "spawn bash -c 'emacsclient \"org-protocol://roam-ref?template=r&ref=@{url:pretty@}&title=@{title@}\" '")
bindings.commands:
global:
normal:
gc: open javascript:void(location.href='org-protocol://roam-ref?template=r&ref='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title))
@end example @end example
where @samp{template} is the template key for a template in where @code{template} is the template key for a template in
@samp{org-roam-capture-ref-templates} (see @ref{The Templating System}). These templates @code{org-roam-capture-ref-templates} (see @ref{The Templating System}). These templates
should contain a @samp{#+ROAM_KEY: $@{ref@}} in it. should contain a @code{#+roam_key: $@{ref@}} in it.
@node Daily Notes
@chapter @strong{TODO} Daily Notes
@node Diagnosing and Repairing Files @node Diagnosing and Repairing Files
@chapter Diagnosing and Repairing Files @chapter Diagnosing and Repairing Files
Org-roam provides a utility for diagnosing and repairing problematic files via Org-roam provides a utility for diagnosing and repairing problematic files via
@samp{org-roam-doctor}. By default, @samp{org-roam-doctor} runs the check across all Org-roam @code{org-roam-doctor}. By default, @code{org-roam-doctor} runs the check on the current
files, and this can take some time. To run the check only for the current file, Org-roam file. To run the check only for the current file, run @samp{C-u M-x
run @samp{C-u M-x org-roam-doctor}. org-roam-doctor}, but note that this may take some time.
@itemize @itemize
@item @item
@ -1167,7 +1243,7 @@ to see all dated entries.
:bind :bind
("C-c n j" . org-journal-new-entry) ("C-c n j" . org-journal-new-entry)
:custom :custom
(org-journal-date-prefix "#+TITLE: ") (org-journal-date-prefix "#+title: ")
(org-journal-file-format "%Y-%m-%d.org") (org-journal-file-format "%Y-%m-%d.org")
(org-journal-dir "/path/to/org-roam-files/") (org-journal-dir "/path/to/org-roam-files/")
(org-journal-date-format "%A, %d %B %Y")) (org-journal-date-format "%A, %d %B %Y"))
@ -1189,8 +1265,7 @@ These are some plugins that make note-taking in Org-mode more enjoyable.
@node Org-download @node Org-download
@unnumberedsubsubsec Org-download @unnumberedsubsubsec Org-download
@uref{https://github.com/abo-abo/org-download, Org-download} lets you @uref{https://github.com/abo-abo/org-download, Org-download} lets you screenshot and yank images from the web into your notes:
screenshot and yank images from the web into your notes:
@float Figure @float Figure
@image{images/org-download,,,,gif} @image{images/org-download,,,,gif}
@ -1209,9 +1284,7 @@ screenshot and yank images from the web into your notes:
@node mathpixel @node mathpixel
@unnumberedsubsubsec mathpix.el @unnumberedsubsubsec mathpix.el
@uref{https://github.com/jethrokuan/mathpix.el, mathpix.el} uses @uref{https://github.com/jethrokuan/mathpix.el, mathpix.el} uses @uref{https://mathpix.com/, Mathpix's} API to convert clips into latex equations:
@uref{https://mathpix.com/, Mathpix's} API to convert clips into latex
equations:
@float Figure @float Figure
@image{images/mathpix,,,,gif} @image{images/mathpix,,,,gif}
@ -1238,7 +1311,7 @@ etc.) within Org-mode.
@node Bibliography @node Bibliography
@unnumberedsubsubsec Bibliography @unnumberedsubsubsec Bibliography
@uref{https://github.com/zaeph/org-roam-bibtex, org-roam-bibtex} offers @uref{https://github.com/org-roam/org-roam-bibtex, org-roam-bibtex} offers
tight integration between tight integration between
@uref{https://github.com/jkitchin/org-ref, org-ref}, @uref{https://github.com/jkitchin/org-ref, org-ref},
@uref{https://github.com/tmalsburg/helm-bibtex, helm-bibtex} and @uref{https://github.com/tmalsburg/helm-bibtex, helm-bibtex} and
@ -1248,17 +1321,15 @@ tight integration between
@node Spaced Repetition @node Spaced Repetition
@unnumberedsubsubsec Spaced Repetition @unnumberedsubsubsec Spaced Repetition
@uref{https://github.com/l3kn/org-fc/, Org-fc} is a spaced repetition @uref{https://github.com/l3kn/org-fc/, Org-fc} is a spaced repetition system that scales well with a large number of
system that scales well with a large number of files. Other alternatives 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}.
include
@uref{https://orgmode.org/worg/org-contrib/org-drill.html, org-drill}, and
@uref{https://github.com/abo-abo/pamparam, pamparam}.
@node FAQ @node FAQ
@chapter FAQ @chapter FAQ
@menu @menu
* How do I have more than one Org-roam directory?:: * How do I have more than one Org-roam directory?::
* How do I migrate from Roam Research?::
@end menu @end menu
@node How do I have more than one Org-roam directory? @node How do I have more than one Org-roam directory?
@ -1280,8 +1351,10 @@ All files within that directory will be treated as their own separate
set of Org-roam files. Remember to run @samp{org-roam-db-build-cache} from a set of Org-roam files. Remember to run @samp{org-roam-db-build-cache} from a
file within that directory, at least once. file within that directory, at least once.
@node _ (2) @node How do I migrate from Roam Research?
@chapter _ :ignore: @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}.
Emacs 28.0.50 (Org mode 9.4) Emacs 28.0.50 (Org mode 9.4)
@bye @bye

View File

@ -1,40 +0,0 @@
site_name: "Org-roam"
repo_url: https://github.com/org-roam/org-roam/
edit_uri: edit/master/doc/
copyright: "Copyright (C) 2020 Jethro Kuan and contributors"
docs_dir: doc
extra:
social:
- type: 'slack'
link: 'https://join.slack.com/t/orgroam/shared_invite/zt-clh0g0tx-j8xg1kVxnrWdKt16gmSGPQ'
nav:
- Home: index.md
- A Tour of Org-roam: tour.md
- Installation: installation.md
- Configuration: configuration.md
- Anatomy of an Org-roam file: anatomy.md
- The Templating System: templating.md
- Ecosystem: ecosystem.md
- Similar Packages: comparison.md
- "Appendix: Note-taking Workflow": notetaking_workflow.md
- "Appendix: Roam Protocol": roam_protocol.md
- "Appendix: Org Export": org_export.md
markdown_extensions:
- admonition
- pymdownx.betterem:
smart_enable: all
- pymdownx.caret
- pymdownx.critic
- pymdownx.details
- pymdownx.mark
- pymdownx.smartsymbols
- pymdownx.superfences
- pymdownx.tasklist:
custom_checkbox: true
- pymdownx.tilde
theme:
name: 'material'
palette:
primary: 'deep purple'
accent: 'deep purple'

View File

@ -5,8 +5,8 @@
;; Author: Jethro Kuan <jethrokuan95@gmail.com> ;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/org-roam/org-roam ;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience ;; Keywords: org-mode, roam, convenience
;; Version: 1.1.1 ;; Version: 1.2.0
;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.3") (emacsql "3.0.0") (emacsql-sqlite "1.0.0")) ;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.3") (emacsql "3.0.0") (emacsql-sqlite3 "1.0.0"))
;; This file is NOT part of GNU Emacs. ;; This file is NOT part of GNU Emacs.
@ -41,12 +41,14 @@
(defvar org-roam-backlinks-mode) (defvar org-roam-backlinks-mode)
(defvar org-roam-last-window) (defvar org-roam-last-window)
(defvar org-ref-cite-types) ;; in org-ref-core.el (defvar org-ref-cite-types) ;; in org-ref-core.el
(defvar org-roam-mode)
(declare-function org-roam-db--ensure-built "org-roam-db") (declare-function org-roam-db--ensure-built "org-roam-db")
(declare-function org-roam--extract-ref "org-roam") (declare-function org-roam--extract-ref "org-roam")
(declare-function org-roam--get-title-or-slug "org-roam") (declare-function org-roam--get-title-or-slug "org-roam")
(declare-function org-roam--get-backlinks "org-roam") (declare-function org-roam--get-backlinks "org-roam")
(declare-function org-roam-backlinks-mode "org-roam") (declare-function org-roam-backlinks-mode "org-roam")
(declare-function org-roam-mode "org-roam")
(defcustom org-roam-buffer-position 'right (defcustom org-roam-buffer-position 'right
"Position of `org-roam' buffer. "Position of `org-roam' buffer.
@ -86,10 +88,10 @@ Has an effect if and only if `org-roam-buffer-position' is `top' or `bottom'."
:type 'hook :type 'hook
:group 'org-roam) :group 'org-roam)
(defcustom org-roam-buffer-no-delete-other-windows nil (defcustom org-roam-buffer-window-parameters nil
"The `no-delete-other-windows' parameter of the `org-roam-buffer' window. "Additional window parameters for the `org-roam-buffer' side window.
When non-nil, the window will not be closed when deleting other windows." For example: (setq org-roam-buffer-window-parameters '((no-other-window . t)))"
:type 'boolean :type '(alist)
:group 'org-roam) :group 'org-roam)
(defvar org-roam-buffer--current nil (defvar org-roam-buffer--current nil
@ -114,32 +116,32 @@ When non-nil, the window will not be closed when deleting other windows."
(defun org-roam-buffer--insert-citelinks () (defun org-roam-buffer--insert-citelinks ()
"Insert citation backlinks for the current buffer." "Insert citation backlinks for the current buffer."
(if-let* ((ref (with-temp-buffer (when-let ((org-ref-p (require 'org-ref nil t)) ;; Ensure that org-ref is present
(insert-buffer-substring org-roam-buffer--current) (ref (cdr (with-temp-buffer
(org-roam--extract-ref))) (insert-buffer-substring org-roam-buffer--current)
(org-ref-p (require 'org-ref nil t)) ; Ensure that org-ref is present (org-roam--extract-ref)))))
(key-backlinks (org-roam--get-backlinks (cdr ref))) (if-let* ((key-backlinks (org-roam--get-backlinks ref))
(grouped-backlinks (--group-by (nth 0 it) key-backlinks))) (grouped-backlinks (--group-by (nth 0 it) key-backlinks)))
(progn (progn
(insert (let ((l (length key-backlinks))) (insert (let ((l (length key-backlinks)))
(format "\n\n* %d %s\n" (format "\n\n* %d %s\n"
l (org-roam-buffer--pluralize "Cite backlink" l)))) l (org-roam-buffer--pluralize "Cite backlink" l))))
(dolist (group grouped-backlinks) (dolist (group grouped-backlinks)
(let ((file-from (car group)) (let ((file-from (car group))
(bls (cdr group))) (bls (cdr group)))
(insert (format "** [[file:%s][%s]]\n" (insert (format "** [[file:%s][%s]]\n"
file-from file-from
(org-roam--get-title-or-slug file-from))) (org-roam--get-title-or-slug file-from)))
(dolist (backlink bls) (dolist (backlink bls)
(pcase-let ((`(,file-from _ ,props) backlink)) (pcase-let ((`(,file-from _ ,props) backlink))
(insert (propertize (insert (propertize
(s-trim (s-replace "\n" " " (s-trim (s-replace "\n" " "
(plist-get props :content))) (plist-get props :content)))
'help-echo "mouse-1: visit backlinked note" 'help-echo "mouse-1: visit backlinked note"
'file-from file-from 'file-from file-from
'file-from-point (plist-get props :point))) 'file-from-point (plist-get props :point)))
(insert "\n\n")))))) (insert "\n\n"))))))
(insert "\n\n* No cite backlinks!"))) (insert "\n\n* No cite backlinks!"))))
(defun org-roam-buffer--insert-backlinks () (defun org-roam-buffer--insert-backlinks ()
"Insert the org-roam-buffer backlinks string for the current buffer." "Insert the org-roam-buffer backlinks string for the current buffer."
@ -242,8 +244,7 @@ Valid states are 'visible, 'exists and 'none."
(defun org-roam-buffer--get-create () (defun org-roam-buffer--get-create ()
"Set up the `org-roam' buffer at `org-roam-buffer-position'." "Set up the `org-roam' buffer at `org-roam-buffer-position'."
(let ((window (get-buffer-window)) (let ((position
(position
(if (member org-roam-buffer-position '(right left top bottom)) (if (member org-roam-buffer-position '(right left top bottom))
org-roam-buffer-position org-roam-buffer-position
(let ((text-quoting-style 'grave)) (let ((text-quoting-style 'grave))
@ -251,21 +252,24 @@ Valid states are 'visible, 'exists and 'none."
"Invalid org-roam-buffer-position: %s. Defaulting to \\='right" "Invalid org-roam-buffer-position: %s. Defaulting to \\='right"
org-roam-buffer-position)) org-roam-buffer-position))
'right))) 'right)))
(-> (get-buffer-create org-roam-buffer) (save-selected-window
(display-buffer-in-side-window (-> (get-buffer-create org-roam-buffer)
`((side . ,position) (display-buffer-in-side-window
(window-parameters . ((no-delete-other-windows . ,org-roam-buffer-no-delete-other-windows))))) `((side . ,position)
(select-window)) (window-parameters . ,org-roam-buffer-window-parameters)))
(pcase position (select-window))
((or 'right 'left) (pcase position
(org-roam-buffer--set-width (round (* (frame-width) org-roam-buffer-width)))) ((or 'right 'left)
((or 'top 'bottom) (org-roam-buffer--set-width
(org-roam-buffer--set-height (round (* (frame-height) org-roam-buffer-height))))) (round (* (frame-width) org-roam-buffer-width))))
(select-window window))) ((or 'top 'bottom)
(org-roam-buffer--set-height
(round (* (frame-height) org-roam-buffer-height))))))))
(defun org-roam-buffer-toggle-display () (defun org-roam-buffer-toggle-display ()
"Toggle display of the `org-roam-buffer'." "Toggle display of the `org-roam-buffer'."
(interactive) (interactive)
(unless org-roam-mode (org-roam-mode))
(setq org-roam-last-window (get-buffer-window)) (setq org-roam-last-window (get-buffer-window))
(pcase (org-roam-buffer--visibility) (pcase (org-roam-buffer--visibility)
('visible (delete-window (get-buffer-window org-roam-buffer))) ('visible (delete-window (get-buffer-window org-roam-buffer)))

View File

@ -5,8 +5,8 @@
;; Author: Jethro Kuan <jethrokuan95@gmail.com> ;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/org-roam/org-roam ;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience ;; Keywords: org-mode, roam, convenience
;; Version: 1.1.1 ;; Version: 1.2.0
;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.3") (emacsql "3.0.0") (emacsql-sqlite "1.0.0")) ;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.3") (emacsql "3.0.0") (emacsql-sqlite3 "1.0.0"))
;; This file is NOT part of GNU Emacs. ;; This file is NOT part of GNU Emacs.
@ -38,17 +38,19 @@
;; Declarations ;; Declarations
(defvar org-roam-encrypt-files) (defvar org-roam-encrypt-files)
(defvar org-roam-directory) (defvar org-roam-directory)
(defvar org-roam-mode)
(declare-function org-roam--get-title-path-completions "org-roam") (declare-function org-roam--get-title-path-completions "org-roam")
(declare-function org-roam--get-ref-path-completions "org-roam") (declare-function org-roam--get-ref-path-completions "org-roam")
(declare-function org-roam--file-path-from-id "org-roam") (declare-function org-roam--file-path-from-id "org-roam")
(declare-function org-roam--format-link "org-roam") (declare-function org-roam--format-link "org-roam")
(declare-function org-roam--title-to-slug "org-roam") (declare-function org-roam--title-to-slug "org-roam")
(declare-function org-roam-mode "org-roam")
(declare-function org-roam-completion--completing-read "org-roam-completion") (declare-function org-roam-completion--completing-read "org-roam-completion")
(defvar org-roam-capture--file-name-default "%<%Y%m%d%H%M%S>" (defvar org-roam-capture--file-name-default "%<%Y%m%d%H%M%S>"
"The default file name format for Org-roam templates.") "The default file name format for Org-roam templates.")
(defvar org-roam-capture--header-default "#+TITLE: ${title}\n" (defvar org-roam-capture--header-default "#+title: ${title}\n"
"The default capture header for Org-roam templates.") "The default capture header for Org-roam templates.")
(defvar org-roam-capture--file-path nil (defvar org-roam-capture--file-path nil
@ -83,7 +85,7 @@ note with the given `ref'.")
'(("d" "default" plain (function org-roam-capture--get-point) '(("d" "default" plain (function org-roam-capture--get-point)
"%?" "%?"
:file-name "%<%Y%m%d%H%M%S>-${slug}" :file-name "%<%Y%m%d%H%M%S>-${slug}"
:head "#+TITLE: ${title}\n" :head "#+title: ${title}\n"
:unnarrowed t)) :unnarrowed t))
"Capture templates for Org-roam. "Capture templates for Org-roam.
The capture templates are an extension of The capture templates are an extension of
@ -108,8 +110,8 @@ applies.
'(("r" "ref" plain (function org-roam-capture--get-point) '(("r" "ref" plain (function org-roam-capture--get-point)
"" ""
:file-name "${slug}" :file-name "${slug}"
:head "#+TITLE: ${title} :head "#+title: ${title}
#+ROAM_KEY: ${ref}\n" #+roam_key: ${ref}\n"
:unnarrowed t)) :unnarrowed t))
"The Org-roam templates used during a capture from the roam-ref protocol. "The Org-roam templates used during a capture from the roam-ref protocol.
Details on how to specify for the template is given in `org-roam-capture-templates'.") Details on how to specify for the template is given in `org-roam-capture-templates'.")
@ -265,8 +267,9 @@ This function is used solely in Org-roam's capture templates: see
('ref ('ref
(let ((completions (org-roam--get-ref-path-completions)) (let ((completions (org-roam--get-ref-path-completions))
(ref (cdr (assoc 'ref org-roam-capture--info)))) (ref (cdr (assoc 'ref org-roam-capture--info))))
(or (cdr (assoc ref completions)) (if-let ((pl (cdr (assoc ref completions))))
(org-roam-capture--new-file)))) (plist-get pl :path)
(org-roam-capture--new-file))))
(_ (error "Invalid org-roam-capture-context"))))) (_ (error "Invalid org-roam-capture-context")))))
(org-roam-capture--expand-template) (org-roam-capture--expand-template)
(org-roam-capture--put :file-path file-path) (org-roam-capture--put :file-path file-path)
@ -329,6 +332,7 @@ GOTO and KEYS argument have the same functionality as
"Launches an `org-capture' process for a new or existing note. "Launches an `org-capture' process for a new or existing note.
This uses the templates defined at `org-roam-capture-templates'." This uses the templates defined at `org-roam-capture-templates'."
(interactive) (interactive)
(unless org-roam-mode (org-roam-mode))
(when (org-roam-capture--in-process-p) (when (org-roam-capture--in-process-p)
(user-error "Nested Org-roam capture processes not supported")) (user-error "Nested Org-roam capture processes not supported"))
(let* ((completions (org-roam--get-title-path-completions)) (let* ((completions (org-roam--get-title-path-completions))
@ -336,7 +340,7 @@ This uses the templates defined at `org-roam-capture-templates'."
completions)) completions))
(res (cdr (assoc title-with-keys completions))) (res (cdr (assoc title-with-keys completions)))
(title (or (plist-get res :title) title-with-keys)) (title (or (plist-get res :title) title-with-keys))
(file-path (plist-get res :file-path))) (file-path (plist-get res :path)))
(let ((org-roam-capture--info (list (cons 'title title) (let ((org-roam-capture--info (list (cons 'title title)
(cons 'slug (org-roam--title-to-slug title)) (cons 'slug (org-roam--title-to-slug title))
(cons 'file file-path))) (cons 'file file-path)))

View File

@ -5,8 +5,8 @@
;; Author: Jethro Kuan <jethrokuan95@gmail.com> ;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/org-roam/org-roam ;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience ;; Keywords: org-mode, roam, convenience
;; Version: 1.1.1 ;; Version: 1.2.0
;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.3") (emacsql "3.0.0") (emacsql-sqlite "1.0.0")) ;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.3") (emacsql "3.0.0") (emacsql-sqlite3 "1.0.0"))
;; This file is NOT part of GNU Emacs. ;; This file is NOT part of GNU Emacs.
@ -80,6 +80,9 @@
(define-obsolete-function-alias 'org-roam-db--maybe-update 'org-roam-db--update-maybe (define-obsolete-function-alias 'org-roam-db--maybe-update 'org-roam-db--update-maybe
"org-roam 1.1.0") "org-roam 1.1.0")
(when (version< (org-version) "9.3")
(defalias 'org-link-make-string 'org-make-link-string))
;;;; Variables ;;;; Variables
(define-obsolete-variable-alias 'org-roam-graphviz-extra-options (define-obsolete-variable-alias 'org-roam-graphviz-extra-options
'org-roam-graph-extra-config "org-roam 1.0.0") 'org-roam-graph-extra-config "org-roam 1.0.0")
@ -95,6 +98,8 @@
'org-roam-dailies-capture-templates "org-roam 1.0.0") 'org-roam-dailies-capture-templates "org-roam 1.0.0")
(define-obsolete-variable-alias 'org-roam-date-filename-format (define-obsolete-variable-alias 'org-roam-date-filename-format
'org-roam-dailies-capture-templates "org-roam 1.0.0") 'org-roam-dailies-capture-templates "org-roam 1.0.0")
(make-obsolete-variable 'org-roam-buffer-no-delete-other-windows
'org-roam-buffer-window-parameters "org-roam 1.1.1")
(provide 'org-roam-compat) (provide 'org-roam-compat)

View File

@ -5,8 +5,8 @@
;; Author: Jethro Kuan <jethrokuan95@gmail.com> ;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/org-roam/org-roam ;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience ;; Keywords: org-mode, roam, convenience
;; Version: 1.1.1 ;; Version: 1.2.0
;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.3") (emacsql "3.0.0") (emacsql-sqlite "1.0.0")) ;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.3") (emacsql "3.0.0") (emacsql-sqlite3 "1.0.0"))
;; This file is NOT part of GNU Emacs. ;; This file is NOT part of GNU Emacs.

View File

@ -5,8 +5,8 @@
;; Author: Jethro Kuan <jethrokuan95@gmail.com> ;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/org-roam/org-roam ;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience ;; Keywords: org-mode, roam, convenience
;; Version: 1.1.1 ;; Version: 1.2.0
;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.3") (emacsql "3.0.0") (emacsql-sqlite "1.0.0")) ;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.3") (emacsql "3.0.0") (emacsql-sqlite3 "1.0.0"))
;; This file is NOT part of GNU Emacs. ;; This file is NOT part of GNU Emacs.
@ -41,11 +41,13 @@
"" ""
:immediate-finish t :immediate-finish t
:file-name "%<%Y-%m-%d>" :file-name "%<%Y-%m-%d>"
:head "#+TITLE: %<%Y-%m-%d>")) :head "#+title: %<%Y-%m-%d>"))
"Capture templates for daily notes in Org-roam.") "Capture templates for daily notes in Org-roam.")
;; Declarations ;; Declarations
(defvar org-roam-mode)
(declare-function org-roam--file-path-from-id "org-roam") (declare-function org-roam--file-path-from-id "org-roam")
(declare-function org-roam-mode "org-roam")
(defun org-roam-dailies--file-for-time (time) (defun org-roam-dailies--file-for-time (time)
"Create and find file for TIME." "Create and find file for TIME."
@ -59,18 +61,21 @@
(defun org-roam-dailies-today () (defun org-roam-dailies-today ()
"Create and find the daily note for today." "Create and find the daily note for today."
(interactive) (interactive)
(unless org-roam-mode (org-roam-mode))
(org-roam-dailies--file-for-time (current-time))) (org-roam-dailies--file-for-time (current-time)))
(defun org-roam-dailies-tomorrow (n) (defun org-roam-dailies-tomorrow (n)
"Create and find the daily note for tomorrow. "Create and find the daily note for tomorrow.
With numeric argument N, use N days in the future." With numeric argument N, use N days in the future."
(interactive "p") (interactive "p")
(unless org-roam-mode (org-roam-mode))
(org-roam-dailies--file-for-time (time-add (* n 86400) (current-time)))) (org-roam-dailies--file-for-time (time-add (* n 86400) (current-time))))
(defun org-roam-dailies-yesterday (n) (defun org-roam-dailies-yesterday (n)
"Create and find the file for yesterday. "Create and find the file for yesterday.
With numeric argument N, use N days in the past." With numeric argument N, use N days in the past."
(interactive "p") (interactive "p")
(unless org-roam-mode (org-roam-mode))
(org-roam-dailies-tomorrow (- n))) (org-roam-dailies-tomorrow (- n)))
(defun org-roam-dailies-date () (defun org-roam-dailies-date ()

View File

@ -5,8 +5,8 @@
;; Author: Jethro Kuan <jethrokuan95@gmail.com> ;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/org-roam/org-roam ;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience ;; Keywords: org-mode, roam, convenience
;; Version: 1.1.1 ;; Version: 1.2.0
;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.3") (emacsql "3.0.0") (emacsql-sqlite "1.0.0")) ;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.3") (emacsql "3.0.0") (emacsql-sqlite3 "1.0.0"))
;; This file is NOT part of GNU Emacs. ;; This file is NOT part of GNU Emacs.
@ -33,23 +33,26 @@
;;;; Library Requires ;;;; Library Requires
(eval-when-compile (require 'subr-x)) (eval-when-compile (require 'subr-x))
(require 'emacsql) (require 'emacsql)
(require 'emacsql-sqlite) (require 'emacsql-sqlite3)
(require 'seq)
(require 'org-roam-macs) (require 'org-roam-macs)
(defvar org-roam-directory) (defvar org-roam-directory)
(defvar org-roam-verbose) (defvar org-roam-verbose)
(defvar org-roam-file-name)
(declare-function org-roam--org-roam-file-p "org-roam") (declare-function org-roam--org-roam-file-p "org-roam")
(declare-function org-roam--extract-titles "org-roam") (declare-function org-roam--extract-titles "org-roam")
(declare-function org-roam--extract-ref "org-roam") (declare-function org-roam--extract-ref "org-roam")
(declare-function org-roam--extract-tags "org-roam") (declare-function org-roam--extract-tags "org-roam")
(declare-function org-roam--extract-headlines "org-roam")
(declare-function org-roam--extract-links "org-roam") (declare-function org-roam--extract-links "org-roam")
(declare-function org-roam--list-all-files "org-roam") (declare-function org-roam--list-all-files "org-roam")
(declare-function org-roam-buffer--update-maybe "org-roam-buffer") (declare-function org-roam-buffer--update-maybe "org-roam-buffer")
;;;; Options ;;;; Options
(defcustom org-roam-db-location nil (defcustom org-roam-db-location nil
"Location of the Org-roam database. "The full path to file where the Org-roam database is stored.
If this is non-nil, the Org-roam sqlite database is saved here. If this is non-nil, the Org-roam sqlite database is saved here.
It is the user's responsibility to set this correctly, especially It is the user's responsibility to set this correctly, especially
@ -57,11 +60,7 @@ when used with multiple Org-roam instances."
:type 'string :type 'string
:group 'org-roam) :group 'org-roam)
(defconst org-roam-db--version 5) (defconst org-roam-db--version 6)
(defconst org-roam-db--sqlite-available-p
(with-demoted-errors "Org-roam initialization: %S"
(emacsql-sqlite-ensure-binary)
t))
(defvar org-roam-db--connection (make-hash-table :test #'equal) (defvar org-roam-db--connection (make-hash-table :test #'equal)
"Database connection to Org-roam database.") "Database connection to Org-roam database.")
@ -69,8 +68,7 @@ when used with multiple Org-roam instances."
;;;; Core Functions ;;;; Core Functions
(defun org-roam-db--get () (defun org-roam-db--get ()
"Return the sqlite db file." "Return the sqlite db file."
(interactive "P") (or org-roam-db-location
(or org-roam-db-location
(expand-file-name "org-roam.db" org-roam-directory))) (expand-file-name "org-roam.db" org-roam-directory)))
(defun org-roam-db--get-connection () (defun org-roam-db--get-connection ()
@ -87,7 +85,7 @@ Performs a database upgrade when required."
(let* ((db-file (org-roam-db--get)) (let* ((db-file (org-roam-db--get))
(init-db (not (file-exists-p db-file)))) (init-db (not (file-exists-p db-file))))
(make-directory (file-name-directory db-file) t) (make-directory (file-name-directory db-file) t)
(let ((conn (emacsql-sqlite db-file))) (let ((conn (emacsql-sqlite3 db-file)))
(set-process-query-on-exit-flag (emacsql-process conn) nil) (set-process-query-on-exit-flag (emacsql-process conn) nil)
(puthash (file-truename org-roam-directory) (puthash (file-truename org-roam-directory)
conn conn
@ -123,6 +121,10 @@ SQL can be either the emacsql vector representation, or a string."
(hash :not-null) (hash :not-null)
(meta :not-null)]) (meta :not-null)])
(headlines
[(id :unique :primary-key)
(file :not-null)])
(links (links
[(from :not-null) [(from :not-null)
(to :not-null) (to :not-null)
@ -227,6 +229,13 @@ This is equivalent to removing the node from the graph."
:values $v1] :values $v1]
(list (vector file titles)))) (list (vector file titles))))
(defun org-roam-db--insert-headlines (headlines)
"Insert HEADLINES into the Org-roam cache."
(org-roam-db-query
[:insert :into headlines
:values $v1]
headlines))
(defun org-roam-db--insert-tags (file tags) (defun org-roam-db--insert-tags (file tags)
"Insert TAGS for a FILE into the Org-roam cache." "Insert TAGS for a FILE into the Org-roam cache."
(org-roam-db-query (org-roam-db-query
@ -263,12 +272,12 @@ This is equivalent to removing the node from the graph."
If the file does not have any connections, nil is returned." If the file does not have any connections, nil is returned."
(let* ((query "WITH RECURSIVE (let* ((query "WITH RECURSIVE
links_of(file, link) AS links_of(file, link) AS
(WITH roamlinks AS (SELECT * FROM links WHERE \"type\" = '\"roam\"'), (WITH filelinks AS (SELECT * FROM links WHERE \"type\" = '\"file\"'),
citelinks AS (SELECT * FROM links citelinks AS (SELECT * FROM links
JOIN refs ON links.\"to\" = refs.\"ref\" JOIN refs ON links.\"to\" = refs.\"ref\"
AND links.\"type\" = '\"cite\"') AND links.\"type\" = '\"cite\"')
SELECT \"from\", \"to\" FROM roamlinks UNION SELECT \"from\", \"to\" FROM filelinks UNION
SELECT \"to\", \"from\" FROM roamlinks UNION SELECT \"to\", \"from\" FROM filelinks UNION
SELECT \"file\", \"from\" FROM citelinks UNION SELECT \"file\", \"from\" FROM citelinks UNION
SELECT \"from\", \"file\" FROM citelinks), SELECT \"from\", \"file\" FROM citelinks),
connected_component(file) AS connected_component(file) AS
@ -285,12 +294,12 @@ This includes the file itself. If the file does not have any
connections, nil is returned." connections, nil is returned."
(let* ((query "WITH RECURSIVE (let* ((query "WITH RECURSIVE
links_of(file, link) AS links_of(file, link) AS
(WITH roamlinks AS (SELECT * FROM links WHERE \"type\" = '\"roam\"'), (WITH filelinks AS (SELECT * FROM links WHERE \"type\" = '\"file\"'),
citelinks AS (SELECT * FROM links citelinks AS (SELECT * FROM links
JOIN refs ON links.\"to\" = refs.\"ref\" JOIN refs ON links.\"to\" = refs.\"ref\"
AND links.\"type\" = '\"cite\"') AND links.\"type\" = '\"cite\"')
SELECT \"from\", \"to\" FROM roamlinks UNION SELECT \"from\", \"to\" FROM filelinks UNION
SELECT \"to\", \"from\" FROM roamlinks UNION SELECT \"to\", \"from\" FROM filelinks UNION
SELECT \"file\", \"from\" FROM citelinks UNION SELECT \"file\", \"from\" FROM citelinks UNION
SELECT \"from\", \"file\" FROM citelinks), SELECT \"from\", \"file\" FROM citelinks),
-- Links are traversed in a breadth-first search. In order to calculate the -- Links are traversed in a breadth-first search. In order to calculate the
@ -336,12 +345,13 @@ connections, nil is returned."
(defun org-roam-db--update-tags () (defun org-roam-db--update-tags ()
"Update the tags of the current buffer into the cache." "Update the tags of the current buffer into the cache."
(let* ((file (file-truename (buffer-file-name))) (let ((file (file-truename (buffer-file-name)))
(tags (org-roam--extract-tags))) (tags (org-roam--extract-tags)))
(org-roam-db-query [:delete :from tags (org-roam-db-query [:delete :from tags
:where (= file $s1)] :where (= file $s1)]
file) file)
(org-roam-db--insert-tags file tags))) (when tags
(org-roam-db--insert-tags file tags))))
(defun org-roam-db--update-refs () (defun org-roam-db--update-refs ()
"Update the ref of the current buffer into the cache." "Update the ref of the current buffer into the cache."
@ -352,7 +362,7 @@ connections, nil is returned."
(when-let ((ref (org-roam--extract-ref))) (when-let ((ref (org-roam--extract-ref)))
(org-roam-db--insert-ref file ref)))) (org-roam-db--insert-ref file ref))))
(defun org-roam-db--update-cache-links () (defun org-roam-db--update-links ()
"Update the file links of the current buffer in the cache." "Update the file links of the current buffer in the cache."
(let ((file (file-truename (buffer-file-name)))) (let ((file (file-truename (buffer-file-name))))
(org-roam-db-query [:delete :from links (org-roam-db-query [:delete :from links
@ -361,6 +371,15 @@ connections, nil is returned."
(when-let ((links (org-roam--extract-links))) (when-let ((links (org-roam--extract-links)))
(org-roam-db--insert-links links)))) (org-roam-db--insert-links links))))
(defun org-roam-db--update-headlines ()
"Update the file headlines of the current buffer into the cache."
(let* ((file (file-truename (buffer-file-name))))
(org-roam-db-query [:delete :from headlines
:where (= file $s1)]
file)
(when-let ((headlines (org-roam--extract-headlines)))
(org-roam-db--insert-headlines headlines))))
(defun org-roam-db--update-file (&optional file-path) (defun org-roam-db--update-file (&optional file-path)
"Update Org-roam cache for FILE-PATH." "Update Org-roam cache for FILE-PATH."
(when (org-roam--org-roam-file-p file-path) (when (org-roam--org-roam-file-p file-path)
@ -373,7 +392,8 @@ connections, nil is returned."
(org-roam-db--update-tags) (org-roam-db--update-tags)
(org-roam-db--update-titles) (org-roam-db--update-titles)
(org-roam-db--update-refs) (org-roam-db--update-refs)
(org-roam-db--update-cache-links) (org-roam-db--update-headlines)
(org-roam-db--update-links)
(org-roam-buffer--update-maybe :redisplay t)))))) (org-roam-buffer--update-maybe :redisplay t))))))
(defun org-roam-db-build-cache (&optional force) (defun org-roam-db-build-cache (&optional force)
@ -385,39 +405,53 @@ If FORCE, force a rebuild of the cache from scratch."
(org-roam-db) ;; To initialize the database, no-op if already initialized (org-roam-db) ;; To initialize the database, no-op if already initialized
(let* ((org-roam-files (org-roam--list-all-files)) (let* ((org-roam-files (org-roam--list-all-files))
(current-files (org-roam-db--get-current-files)) (current-files (org-roam-db--get-current-files))
all-files all-links all-titles all-refs all-tags) all-files all-headlines all-links all-titles all-refs all-tags)
;; Two-step building
;; First step: Rebuild files and headlines
(dolist (file org-roam-files) (dolist (file org-roam-files)
(let* ((attr (file-attributes file)) (let* ((attr (file-attributes file))
(atime (file-attribute-access-time attr)) (atime (file-attribute-access-time attr))
(mtime (file-attribute-modification-time attr))) (mtime (file-attribute-modification-time attr)))
(org-roam--with-temp-buffer (org-roam--with-temp-buffer file
(insert-file-contents file)
(let ((contents-hash (secure-hash 'sha1 (current-buffer)))) (let ((contents-hash (secure-hash 'sha1 (current-buffer))))
(unless (string= (gethash file current-files) (unless (string= (gethash file current-files)
contents-hash) contents-hash)
(org-roam-db--clear-file file) (org-roam-db--clear-file file)
(push (vector file contents-hash (list :atime atime :mtime mtime)) (push (vector file contents-hash (list :atime atime :mtime mtime))
all-files) all-files)
(when-let (links (org-roam--extract-links file)) (when-let (headlines (org-roam--extract-headlines file))
(push links all-links)) (push headlines all-headlines)))))))
(when-let (tags (org-roam--extract-tags file))
(push (vector file tags) all-tags))
(let ((titles (org-roam--extract-titles)))
(push (vector file titles)
all-titles))
(when-let* ((ref (org-roam--extract-ref))
(type (car ref))
(key (cdr ref)))
(setq all-refs (cons (vector key file type) all-refs))))
(remhash file current-files)))))
(dolist (file (hash-table-keys current-files))
;; These files are no longer around, remove from cache...
(org-roam-db--clear-file file))
(when all-files (when all-files
(org-roam-db-query (org-roam-db-query
[:insert :into files [:insert :into files
:values $v1] :values $v1]
all-files)) all-files))
(when all-headlines
(org-roam-db-query
[:insert :into headlines
:values $v1]
all-headlines))
;; Second step: Rebuild the rest
(dolist (file org-roam-files)
(org-roam--with-temp-buffer file
(let ((contents-hash (secure-hash 'sha1 (current-buffer))))
(unless (string= (gethash file current-files)
contents-hash)
(when-let (links (org-roam--extract-links file))
(push links all-links))
(when-let (tags (org-roam--extract-tags file))
(push (vector file tags) all-tags))
(let ((titles (org-roam--extract-titles)))
(push (vector file titles)
all-titles))
(when-let* ((ref (org-roam--extract-ref))
(type (car ref))
(key (cdr ref)))
(setq all-refs (cons (vector key file type) all-refs))))
(remhash file current-files))))
(dolist (file (hash-table-keys current-files))
;; These files are no longer around, remove from cache...
(org-roam-db--clear-file file))
(when all-links (when all-links
(org-roam-db-query (org-roam-db-query
[:insert :into links [:insert :into links
@ -439,13 +473,15 @@ If FORCE, force a rebuild of the cache from scratch."
:values $v1] :values $v1]
all-refs)) all-refs))
(let ((stats (list :files (length all-files) (let ((stats (list :files (length all-files)
:headlines (length all-headlines)
:links (length all-links) :links (length all-links)
:tags (length all-tags) :tags (length all-tags)
:titles (length all-titles) :titles (length all-titles)
:refs (length all-refs) :refs (length all-refs)
:deleted (length (hash-table-keys current-files))))) :deleted (length (hash-table-keys current-files)))))
(org-roam-message "files: %s, links: %s, tags: %s, titles: %s, refs: %s, deleted: %s" (org-roam-message "files: %s, headlines: %s, links: %s, tags: %s, titles: %s, refs: %s, deleted: %s"
(plist-get stats :files) (plist-get stats :files)
(plist-get stats :headlines)
(plist-get stats :links) (plist-get stats :links)
(plist-get stats :tags) (plist-get stats :tags)
(plist-get stats :titles) (plist-get stats :titles)

View File

@ -5,8 +5,8 @@
;; Author: Jethro Kuan <jethrokuan95@gmail.com> ;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/org-roam/org-roam ;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience ;; Keywords: org-mode, roam, convenience
;; Version: 1.1.1 ;; Version: 1.2.0
;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.3") (emacsql "3.0.0") (emacsql-sqlite "1.0.0")) ;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.3") (emacsql "3.0.0") (emacsql-sqlite3 "1.0.0"))
;; This file is NOT part of GNU Emacs. ;; This file is NOT part of GNU Emacs.
@ -34,7 +34,6 @@
;;; Code: ;;; Code:
(require 'emacsql) (require 'emacsql)
(emacsql-fix-vector-indentation) (emacsql-fix-vector-indentation)
(setq-local sentence-end-double-space nil)
(provide 'org-roam-dev) (provide 'org-roam-dev)
;;; org-roam-dev.el ends here ;;; org-roam-dev.el ends here

View File

@ -5,8 +5,8 @@
;; Author: Jethro Kuan <jethrokuan95@gmail.com> ;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/jethrokuan/org-roam ;; URL: https://github.com/jethrokuan/org-roam
;; Keywords: org-mode, roam, convenience ;; Keywords: org-mode, roam, convenience
;; Version: 1.1.1 ;; Version: 1.2.0
;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.3") (emacsql "3.0.0") (emacsql-sqlite "1.0.0")) ;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.3") (emacsql "3.0.0") (emacsql-sqlite3 "1.0.0"))
;; This file is NOT part of GNU Emacs. ;; This file is NOT part of GNU Emacs.
@ -44,15 +44,20 @@
;; Library Requires ;; Library Requires
(require 'cl-lib) (require 'cl-lib)
(require 'org) (require 'org)
(require 'org-roam-macs)
(require 'org-element) (require 'org-element)
(require 's)
(require 'dash)
(require 'org-roam-macs)
(declare-function org-roam-insert "org-roam") (declare-function org-roam-insert "org-roam")
(declare-function org-roam--get-roam-buffers "org-roam") (declare-function org-roam--get-roam-buffers "org-roam")
(declare-function org-roam--list-all-files "org-roam") (declare-function org-roam--list-all-files "org-roam")
(declare-function org-roam--org-roam-file-p "org-roam") (declare-function org-roam--org-roam-file-p "org-roam")
(declare-function org-roam--str-to-list "org-roam")
(declare-function org-roam-mode "org-roam")
(defvar org-roam-verbose) (defvar org-roam-verbose)
(defvar org-roam-mode)
(cl-defstruct (org-roam-doctor-checker (:copier nil)) (cl-defstruct (org-roam-doctor-checker (:copier nil))
(name 'missing-checker-name) (name 'missing-checker-name)
@ -66,7 +71,78 @@
:description "Fix broken links." :description "Fix broken links."
:actions '(("d" . ("Unlink" . org-roam-doctor--remove-link)) :actions '(("d" . ("Unlink" . org-roam-doctor--remove-link))
("r" . ("Replace link" . org-roam-doctor--replace-link)) ("r" . ("Replace link" . org-roam-doctor--replace-link))
("R" . ("Replace link (keep label)" . org-roam-doctor--replace-link-keep-label)))))) ("R" . ("Replace link (keep label)" . org-roam-doctor--replace-link-keep-label))))
(make-org-roam-doctor-checker
:name 'org-roam-doctor-check-roam-props
:description "Check #+roam_* properties.")
(make-org-roam-doctor-checker
:name 'org-roam-doctor-check-tags
:description "Check #+roam_tags.")
(make-org-roam-doctor-checker
:name 'org-roam-doctor-check-alias
:description "Check #+roam_alias.")))
(defconst org-roam-doctor--supported-roam-properties
'("roam_tags" "roam_alias" "roam_key")
"List of supported Org-roam properties.")
(defun org-roam-doctor-check-roam-props (ast)
"Checker for detecting invalid #+roam_* properties.
AST is the org-element parse tree."
(let (reports)
(org-element-map ast 'keyword
(lambda (kw)
(let ((key (org-element-property :key kw)))
(when (and (string-prefix-p "ROAM_" key t)
(not (member (downcase key) org-roam-doctor--supported-roam-properties)))
(push
`(,(org-element-property :begin kw)
,(concat "Possible mispelled key: "
(prin1-to-string key)
"\nOrg-roam supports the following keys: "
(s-join ", " org-roam-doctor--supported-roam-properties)))
reports)))))
reports))
(defun org-roam-doctor-check-tags (ast)
"Checker for detecting invalid #+roam_tags.
AST is the org-element parse tree."
(let (reports)
(org-element-map ast 'keyword
(lambda (kw)
(when (string-collate-equalp (org-element-property :key kw) "roam_tags" nil t)
(let ((tags (org-element-property :value kw)))
(condition-case nil
(org-roam--str-to-list tags)
(error
(push
`(,(org-element-property :begin kw)
,(concat "Unable to parse tags: "
tags
(when (s-contains? "," tags)
"\nCheck that your tags are not comma-separated.")))
reports)))))))
reports))
(defun org-roam-doctor-check-alias (ast)
"Checker for detecting invalid #+roam_alias.
AST is the org-element parse tree."
(let (reports)
(org-element-map ast 'keyword
(lambda (kw)
(when (string-collate-equalp (org-element-property :key kw) "roam_alias" nil t)
(let ((aliases (org-element-property :value kw)))
(condition-case nil
(org-roam--str-to-list aliases)
(error
(push
`(,(org-element-property :begin kw)
,(concat "Unable to parse aliases: "
aliases
(when (s-contains? "," aliases)
"\nCheck that your aliases are not comma-separated.")))
reports)))))))
reports))
(defun org-roam-doctor-broken-links (ast) (defun org-roam-doctor-broken-links (ast)
"Checker for detecting broken links. "Checker for detecting broken links.
@ -207,6 +283,7 @@ CHECKER is a org-roam-doctor checker instance."
"Perform a check on the current buffer to ensure cleanliness. "Perform a check on the current buffer to ensure cleanliness.
If CHECKALL, run the check for all Org-roam files." If CHECKALL, run the check for all Org-roam files."
(interactive "P") (interactive "P")
(unless org-roam-mode (org-roam-mode))
(let ((files (if checkall (let ((files (if checkall
(org-roam--list-all-files) (org-roam--list-all-files)
(unless (org-roam--org-roam-file-p) (unless (org-roam--org-roam-file-p)

View File

@ -5,8 +5,8 @@
;; Author: Jethro Kuan <jethrokuan95@gmail.com> ;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/org-roam/org-roam ;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience ;; Keywords: org-mode, roam, convenience
;; Version: 1.1.1 ;; Version: 1.2.0
;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.3") (emacsql "3.0.0") (emacsql-sqlite "1.0.0")) ;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.3") (emacsql "3.0.0") (emacsql-sqlite3 "1.0.0"))
;; This file is NOT part of GNU Emacs. ;; This file is NOT part of GNU Emacs.
@ -37,8 +37,10 @@
;;;; Declarations ;;;; Declarations
(defvar org-roam-directory) (defvar org-roam-directory)
(defvar org-roam-mode)
(declare-function org-roam--org-roam-file-p "org-roam") (declare-function org-roam--org-roam-file-p "org-roam")
(declare-function org-roam--path-to-slug "org-roam") (declare-function org-roam--path-to-slug "org-roam")
(declare-function org-roam-mode "org-roam")
;;;; Options ;;;; Options
(defcustom org-roam-graph-viewer (executable-find "firefox") (defcustom org-roam-graph-viewer (executable-find "firefox")
@ -163,7 +165,7 @@ The Org-roam database titles table is read, to obtain the list of titles.
The links table is then read to obtain all directed links, and formatted The links table is then read to obtain all directed links, and formatted
into a digraph." into a digraph."
(org-roam-db--ensure-built) (org-roam-db--ensure-built)
(org-roam--with-temp-buffer (org-roam--with-temp-buffer nil
(let* ((nodes (org-roam-db-query node-query)) (let* ((nodes (org-roam-db-query node-query))
(edges-query (edges-query
`[:with selected :as [:select [file] :from ,node-query] `[:with selected :as [:select [file] :from ,node-query]
@ -217,24 +219,31 @@ into a digraph."
(insert "}") (insert "}")
(buffer-string)))) (buffer-string))))
(defun org-roam-graph--build (&optional node-query) (defun org-roam-graph--build (&optional node-query callback)
"Generate a graph showing the relations between nodes in NODE-QUERY." "Generate a graph showing the relations between nodes in NODE-QUERY.
(let ((name org-roam-graph-executable)) Execute CALLBACK when process exits successfully.
(unless (stringp name) CALLBACK is passed the graph file as its sole argument."
(user-error "`org-roam-graph-executable' is not a string")) (unless (stringp org-roam-graph-executable)
(unless (executable-find org-roam-graph-executable) (user-error "`org-roam-graph-executable' is not a string"))
(user-error (concat "Cannot find executable \"%s\" to generate the graph. " (unless (executable-find org-roam-graph-executable)
"Please adjust `org-roam-graph-executable'") (user-error (concat "Cannot find executable \"%s\" to generate the graph. "
name)) "Please adjust `org-roam-graph-executable'")
(let* ((node-query (or node-query org-roam-graph-executable))
`[:select [file titles] (let* ((node-query (or node-query
:from titles `[:select [file titles] :from titles
,@(org-roam-graph--expand-matcher 'file t)])) ,@(org-roam-graph--expand-matcher 'file t)]))
(graph (org-roam-graph--dot node-query)) (graph (org-roam-graph--dot node-query))
(temp-dot (make-temp-file "graph." nil ".dot" graph)) (temp-dot (make-temp-file "graph." nil ".dot" graph))
(temp-graph (make-temp-file "graph." nil ".svg"))) (temp-graph (make-temp-file "graph." nil ".svg")))
(call-process name nil 0 nil temp-dot "-Tsvg" "-o" temp-graph) (org-roam-message "building graph")
temp-graph))) (make-process
:name "*org-roam-graph--build-process*"
:buffer "*org-roam-graph--build-process*"
:command `(,org-roam-graph-executable ,temp-dot "-Tsvg" "-o" ,temp-graph)
:sentinel (when callback
(lambda (process _event)
(when (= 0 (process-exit-status process))
(funcall callback temp-graph)))))))
(defun org-roam-graph--open (file) (defun org-roam-graph--open (file)
"Open FILE using `org-roam-graph-viewer' with `view-file' as a fallback." "Open FILE using `org-roam-graph-viewer' with `view-file' as a fallback."
@ -249,9 +258,10 @@ into a digraph."
('nil (view-file file)) ('nil (view-file file))
(_ (signal 'wrong-type-argument `((functionp stringp null) ,org-roam-graph-viewer))))) (_ (signal 'wrong-type-argument `((functionp stringp null) ,org-roam-graph-viewer)))))
(defun org-roam-graph--build-connected-component (file &optional max-distance) (defun org-roam-graph--build-connected-component (file &optional max-distance callback)
"Build a graph of nodes connected to FILE. "Build a graph of nodes connected to FILE.
If MAX-DISTANCE is non-nil, limit nodes to MAX-DISTANCE steps." If MAX-DISTANCE is non-nil, limit nodes to MAX-DISTANCE steps.
CALLBACK is passed to `org-roam-graph--build'."
(let* ((file (file-truename file)) (let* ((file (file-truename file))
(files (or (if (and max-distance (>= max-distance 0)) (files (or (if (and max-distance (>= max-distance 0))
(org-roam-db--links-with-max-distance file max-distance) (org-roam-db--links-with-max-distance file max-distance)
@ -260,7 +270,7 @@ If MAX-DISTANCE is non-nil, limit nodes to MAX-DISTANCE steps."
(query `[:select [file titles] (query `[:select [file titles]
:from titles :from titles
:where (in file [,@files])])) :where (in file [,@files])]))
(org-roam-graph--build query))) (org-roam-graph--build query callback)))
;;;; Commands ;;;; Commands
;;;###autoload ;;;###autoload
@ -275,6 +285,7 @@ ARG may be any of the following values:
- `\\[universal-argument]' - build the graph for FILE. - `\\[universal-argument]' - build the graph for FILE.
- `\\[universal-argument]' -N build the graph for FILE limiting nodes to N steps." - `\\[universal-argument]' -N build the graph for FILE limiting nodes to N steps."
(interactive "P") (interactive "P")
(unless org-roam-mode (org-roam-mode))
(let ((file (or file (buffer-file-name (buffer-base-buffer))))) (let ((file (or file (buffer-file-name (buffer-base-buffer)))))
(unless (or (not arg) (equal arg '(16))) (unless (or (not arg) (equal arg '(16)))
(unless file (unless file
@ -282,11 +293,9 @@ ARG may be any of the following values:
(unless (org-roam--org-roam-file-p file) (unless (org-roam--org-roam-file-p file)
(user-error "\"%s\" is not an org-roam file" file))) (user-error "\"%s\" is not an org-roam file" file)))
(pcase arg (pcase arg
('nil (org-roam-graph--open (org-roam-graph--build node-query))) ('nil (org-roam-graph--build node-query #'org-roam-graph--open))
('(4) (org-roam-graph--open (org-roam-graph--build-connected-component file))) ('(4) (org-roam-graph--build-connected-component file nil #'org-roam-graph--open))
((pred integerp) (let ((graph (org-roam-graph--build-connected-component file (abs arg)))) ((pred integerp) (org-roam-graph--build-connected-component file (abs arg) (when (>= arg 0) #'org-roam-graph--open)))
(when (>= arg 0)
(org-roam-graph--open graph))))
('(16) (org-roam-graph--build node-query)) ('(16) (org-roam-graph--build node-query))
('- (org-roam-graph--build-connected-component file)) ('- (org-roam-graph--build-connected-component file))
(_ (user-error "Unrecognized ARG: %s" arg))))) (_ (user-error "Unrecognized ARG: %s" arg)))))

View File

@ -5,8 +5,8 @@
;; Author: Jethro Kuan <jethrokuan95@gmail.com> ;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/org-roam/org-roam ;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience ;; Keywords: org-mode, roam, convenience
;; Version: 1.1.1 ;; Version: 1.2.0
;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.3") (emacsql "3.0.0") (emacsql-sqlite "1.0.0")) ;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.3") (emacsql "3.0.0") (emacsql-sqlite3 "1.0.0"))
;; This file is NOT part of GNU Emacs. ;; This file is NOT part of GNU Emacs.
@ -36,14 +36,18 @@
(defvar org-roam-verbose) (defvar org-roam-verbose)
(defmacro org-roam--with-temp-buffer (&rest body) (defmacro org-roam--with-temp-buffer (file &rest body)
"Execute BODY within a temp buffer. "Execute BODY within a temp buffer.
Like `with-temp-buffer', but propagates `org-roam-directory'." Like `with-temp-buffer', but propagates `org-roam-directory'.
(declare (indent 0) (debug t)) If FILE, set `org-roam-temp-file-name' to file and insert its contents."
(declare (indent 1) (debug t))
(let ((current-org-roam-directory (make-symbol "current-org-roam-directory"))) (let ((current-org-roam-directory (make-symbol "current-org-roam-directory")))
`(let ((,current-org-roam-directory org-roam-directory)) `(let ((,current-org-roam-directory org-roam-directory))
(with-temp-buffer (with-temp-buffer
(let ((org-roam-directory ,current-org-roam-directory)) (let ((org-roam-directory ,current-org-roam-directory))
(when ,file
(insert-file-contents ,file)
(setq-local org-roam-file-name ,file))
,@body))))) ,@body)))))
(defmacro org-roam--with-template-error (templates &rest body) (defmacro org-roam--with-template-error (templates &rest body)

View File

@ -4,7 +4,7 @@
;; Author: Jethro Kuan <jethrokuan95@gmail.com> ;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/org-roam/org-roam ;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience ;; Keywords: org-mode, roam, convenience
;; Version: 1.1.1 ;; Version: 1.2.0
;; Package-Requires: ((emacs "26.1") (org "9.3")) ;; Package-Requires: ((emacs "26.1") (org "9.3"))
;; This file is NOT part of GNU Emacs. ;; This file is NOT part of GNU Emacs.

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +1,2 @@
#+ROAM_ALIAS: "a1" "a 2" #+roam_alias: "a1" "a 2"
#+TITLE: t1 #+title: t1

View File

@ -1,3 +1,3 @@
#+TITLE: Bar #+title: Bar
This is file bar. Bar links to [[file:nested/bar.org][Nested Bar]]. This is file bar. Bar links to [[file:nested/bar.org][Nested Bar]].

View File

@ -1 +1 @@
#+TITLE: Base #+title: Base

View File

@ -1,4 +1,4 @@
#+TITLE: Foo #+title: Foo
This is the foo file. It contains a link to [[file:bar.org][Bar]]. This is the foo file. It contains a link to [[file:bar.org][Bar]].

View File

@ -1,3 +1,3 @@
#+TITLE: Nested Bar #+title: Nested Bar
This file is nested, 1 level deeper. It links to both [[file:../foo.org][Foo]] and [[file:foo.org][Nested Foo]]. This file is nested, 1 level deeper. It links to both [[file:../foo.org][Foo]] and [[file:foo.org][Nested Foo]].

View File

@ -1 +1 @@
#+TITLE: Deeply Nested File #+title: Deeply Nested File

View File

@ -1,3 +1,3 @@
#+TITLE: Nested Foo #+title: Nested Foo
This file has no links. This file has no links.

View File

@ -1,3 +1,3 @@
#+TITLE: Tagless File #+title: Tagless File
This file has no tags, and should not yield any tags on extracting via =#+ROAM_TAGS=. This file has no tags, and should not yield any tags on extracting via ~#+roam_tags~.

View File

@ -1,4 +1,4 @@
#+ROAM_TAGS: "t1" "t2 with space" t3 #+roam_tags: "t1" "t2 with space" t3
#+TITLE: Tags #+title: Tags
This file is used to test functionality for =(org-roam--extract-tags)= This file is used to test functionality for =(org-roam--extract-tags)=

View File

@ -1 +1 @@
#+ROAM_ALIAS: "roam" "alias" #+roam_alias: "roam" "alias"

View File

@ -1,4 +1,4 @@
#+TITLE: TITLE PROP #+title: TITLE PROP
#+ROAM_ALIAS: "roam" "alias" #+roam_alias: "roam" "alias"
* Headline * Headline

View File

@ -1 +1 @@
#+TITLE: Title #+title: Title

View File

@ -1,3 +1,3 @@
#+TITLE: Unlinked #+title: Unlinked
Nothing links here :( Nothing links here :(

View File

@ -1 +1 @@
#+ROAM_KEY: https://google.com/ #+roam_key: https://google.com/

View File

@ -22,7 +22,6 @@
;;; Code: ;;; Code:
(require 'buttercup) (require 'buttercup)
(require 'with-simulated-input)
(require 'org-roam) (require 'org-roam)
(require 'dash) (require 'dash)
@ -53,6 +52,25 @@
(delete-file (org-roam-db--get)) (delete-file (org-roam-db--get))
(org-roam-db--close)) (org-roam-db--close))
(describe "org-roam--str-to-list"
(it "nil"
(expect (org-roam--str-to-list nil)
:to-be
nil))
(it "\"multi word\" prop 123"
(expect (org-roam--str-to-list "\"multi word\" prop 123")
:to-equal
'("multi word" "prop" "123")))
(it "prop \"multi word\" 123"
(expect (org-roam--str-to-list "\"multi word\" prop 123")
:to-equal
'("multi word" "prop" "123")))
(it "errors on bad input"
(expect (org-roam--str-to-list 1)
:to-throw)
(expect (org-roam--str-to-list "\"hello")
:to-throw)))
(describe "Title extraction" (describe "Title extraction"
:var (org-roam-title-sources) :var (org-roam-title-sources)
(before-all (before-all
@ -270,199 +288,6 @@
:to-equal :to-equal
(list :files 0 :links 0 :tags 0 :titles 0 :refs 0 :deleted 0)))) (list :files 0 :links 0 :tags 0 :titles 0 :refs 0 :deleted 0))))
(xdescribe "org-roam-insert"
(before-each
(test-org-roam--init))
(after-each
(test-org-roam--teardown))
(it "temp1 -> foo"
(let ((buf (test-org-roam--find-file "temp1.org")))
(with-current-buffer buf
(with-simulated-input
"Foo RET"
(org-roam-insert))))
(expect (buffer-string) :to-match (regexp-quote "file:foo.org")))
(it "temp2 -> nested/foo"
(let ((buf (test-org-roam--find-file "temp2.org")))
(with-current-buffer buf
(with-simulated-input
"(nested) SPC Nested SPC Foo RET"
(org-roam-insert))))
(expect (buffer-string) :to-match (regexp-quote "file:nested/foo.org")))
(it "nested/temp3 -> foo"
(let ((buf (test-org-roam--find-file "nested/temp3.org")))
(with-current-buffer buf
(with-simulated-input
"Foo RET"
(org-roam-insert))))
(expect (buffer-string) :to-match (regexp-quote "file:../foo.org")))
(it "a/b/temp4 -> nested/foo"
(let ((buf (test-org-roam--find-file "a/b/temp4.org")))
(with-current-buffer buf
(with-simulated-input
"(nested) SPC Nested SPC Foo RET"
(org-roam-insert))))
(expect (buffer-string) :to-match (regexp-quote "file:../../nested/foo.org"))))
(xdescribe "rename file updates cache"
(before-each
(test-org-roam--init))
(after-each
(test-org-roam--teardown))
(it "foo -> new_foo"
(rename-file (test-org-roam--abs-path "foo.org")
(test-org-roam--abs-path "new_foo.org"))
;; Cache should be cleared of old file
(expect (caar (org-roam-db-query [:select (funcall count)
:from titles
:where (= file $s1)]
(test-org-roam--abs-path "foo.org"))) :to-be 0)
(expect (caar (org-roam-db-query [:select (funcall count)
:from refs
:where (= file $s1)]
(test-org-roam--abs-path "foo.org"))) :to-be 0)
(expect (caar (org-roam-db-query [:select (funcall count)
:from links
:where (= from $s1)]
(test-org-roam--abs-path "foo.org"))) :to-be 0)
;; Cache should be updated
(expect (org-roam-db-query [:select [to]
:from links
:where (= from $s1)]
(test-org-roam--abs-path "new_foo.org"))
:to-have-same-items-as
(list (list (test-org-roam--abs-path "bar.org"))))
(expect (org-roam-db-query [:select [from]
:from links
:where (= to $s1)]
(test-org-roam--abs-path "new_foo.org"))
:to-have-same-items-as
(list (list (test-org-roam--abs-path "nested/bar.org"))))
;; Links are updated
(expect (with-temp-buffer
(insert-file-contents (test-org-roam--abs-path "nested/bar.org"))
(buffer-string))
:to-match
(regexp-quote "[[file:../new_foo.org][Foo]]")))
(it "foo -> foo with spaces"
(rename-file (test-org-roam--abs-path "foo.org")
(test-org-roam--abs-path "foo with spaces.org"))
;; Cache should be cleared of old file
(expect (caar (org-roam-db-query [:select (funcall count)
:from titles
:where (= file $s1)]
(test-org-roam--abs-path "foo.org"))) :to-be 0)
(expect (caar (org-roam-db-query [:select (funcall count)
:from refs
:where (= file $s1)]
(test-org-roam--abs-path "foo.org"))) :to-be 0)
(expect (caar (org-roam-db-query [:select (funcall count)
:from links
:where (= from $s1)]
(test-org-roam--abs-path "foo.org"))) :to-be 0)
;; Cache should be updated
(expect (org-roam-db-query [:select [to]
:from links
:where (= from $s1)]
(test-org-roam--abs-path "foo with spaces.org"))
:to-have-same-items-as
(list (list (test-org-roam--abs-path "bar.org"))))
(expect (org-roam-db-query [:select [from]
:from links
:where (= to $s1)]
(test-org-roam--abs-path "foo with spaces.org"))
:to-have-same-items-as
(list (list (test-org-roam--abs-path "nested/bar.org"))))
;; Links are updated
(expect (with-temp-buffer
(insert-file-contents (test-org-roam--abs-path "nested/bar.org"))
(buffer-string))
:to-match
(regexp-quote "[[file:../foo with spaces.org][Foo]]")))
(it "no-title -> meaningful-title"
(rename-file (test-org-roam--abs-path "no-title.org")
(test-org-roam--abs-path "meaningful-title.org"))
;; File has no forward links
(expect (caar (org-roam-db-query [:select (funcall count)
:from links
:where (= from $s1)]
(test-org-roam--abs-path "no-title.org"))) :to-be 0)
(expect (caar (org-roam-db-query [:select (funcall count)
:from links
:where (= from $s1)]
(test-org-roam--abs-path "meaningful-title.org"))) :to-be 1)
;; Links are updated with the appropriate name
(expect (with-temp-buffer
(insert-file-contents (test-org-roam--abs-path "meaningful-title.org"))
(buffer-string))
:to-match
(regexp-quote "[[file:meaningful-title.org][meaningful-title]]")))
(it "web_ref -> hello"
(expect (org-roam-db-query
[:select [file] :from refs
:where (= ref $s1)]
"https://google.com/")
:to-equal
(list (list (test-org-roam--abs-path "web_ref.org"))))
(rename-file (test-org-roam--abs-path "web_ref.org")
(test-org-roam--abs-path "hello.org"))
(expect (org-roam-db-query
[:select [file] :from refs
:where (= ref $s1)]
"https://google.com/")
:to-equal (list (list (test-org-roam--abs-path "hello.org"))))
(expect (caar (org-roam-db-query
[:select [ref] :from refs
:where (= file $s1)]
(test-org-roam--abs-path "web_ref.org")))
:to-equal nil)))
(xdescribe "delete file updates cache"
(before-each
(test-org-roam--init))
(after-each
(test-org-roam--teardown))
(it "delete foo"
(delete-file (test-org-roam--abs-path "foo.org"))
(expect (caar (org-roam-db-query [:select (funcall count)
:from titles
:where (= file $s1)]
(test-org-roam--abs-path "foo.org"))) :to-be 0)
(expect (caar (org-roam-db-query [:select (funcall count)
:from refs
:where (= file $s1)]
(test-org-roam--abs-path "foo.org"))) :to-be 0)
(expect (caar (org-roam-db-query [:select (funcall count)
:from links
:where (= from $s1)]
(test-org-roam--abs-path "foo.org"))) :to-be 0))
(it "delete web_ref"
(expect (org-roam-db-query [:select * :from refs])
:to-have-same-items-as
(list (list "https://google.com/" (test-org-roam--abs-path "web_ref.org") "website")))
(delete-file (test-org-roam--abs-path "web_ref.org"))
(expect (org-roam-db-query [:select * :from refs])
:to-have-same-items-as
(list))))
(provide 'test-org-roam) (provide 'test-org-roam)
;;; test-org-roam.el ends here ;;; test-org-roam.el ends here