Compare commits

...

97 Commits

Author SHA1 Message Date
cce2db8b5a (release): v1.1.1 (#668) 2020-05-18 22:04:51 +08:00
2147adf95c Create FUNDING.yml 2020-05-18 21:27:31 +08:00
d2654f6023 (docs): add a nice default theme (#667) 2020-05-18 19:15:12 +08:00
N V
78b518efd3 (fix): org-roam-capture--capture shadow org-capture-templates-contexts (#662)
Lexically bind org-capture-templates-contexts to nil before calling org-capture
with org-roam-capture-templates. Otherwise, contexts may shadow
org-roam-templates which have same keys as org-capture-templates.

mentioned in #651
2020-05-17 11:51:25 -04:00
N V
1b5e55b6c4 (fix): org-roam-capture allow creating new file (#661)
Set title correctly when no match found in prompt's candidates.
fixes #651
2020-05-17 11:36:15 -04:00
4b45f1dbf5 (fix): fix link updating on file-renames (#660)
Fixes #647: file: links are now updated to reflect the directory change.
Also fixes #554: rename-files to directories are also resolved correctly now.

Co-authored-by: Leo Vivier <leo.vivier+dev@gmail.com>
2020-05-17 18:51:52 +08:00
N V
e0aee184a7 (fix): prevent org-roam-version from loading org-roam-dev (#659)
Instead of visiting file, insert library into temp buffer.
Prevents loading .dir-local dev environment, accompanying unsafe-variable prompt.
Prevents interference with org-roam.el if already open.
2020-05-17 03:41:40 -04:00
N V
eae97487dc (internal): fix free variable reference (#658)
Define org-roam-backlinks-mode before it is referenced.
2020-05-17 02:56:15 -04:00
N V
f5a9dfab9b (fix): Require seq.el (#657)
seq.el is is not guaranteed to be loaded otherwise.
2020-05-17 02:20:48 -04:00
N V
7844827757 (feature): org-roam-diagnostics command (#653)
Automates collection of user environment information.
2020-05-17 01:57:38 -04:00
N V
74f12ee8aa (internal): org-roam-version save-excursion (#656)
Restore user's point in org-roam.el
2020-05-17 01:46:41 -04:00
N V
055669817a (feature): org-roam-version command (#655)
Useful for diagnostic information.
Should be supplemented with finer grained info (commit hash would be
ideal) once we figure out a more sophisticated approach.
2020-05-17 13:33:53 +08:00
N V
1fc08b4428 (internal): inline minor-mode keymaps (#654)
define-minor-mode macro creates appropriate symbol/documentation for
inlined keymaps.
2020-05-17 01:24:21 -04:00
N V
cfe3b19a73 (doc): bug_report.md request more info (#652)
Request interactive commands for more build/version info.
Request Org mode version.
2020-05-16 23:24:29 -04:00
1bc1559743 (fix): fix regression in find-ref (#650)
Fixes #649.
2020-05-17 00:09:58 +02:00
265182a698 (fix): adapt find-ref to new format (#646) 2020-05-16 14:03:37 +02:00
4b4ebf76c7 (fix): fix parsing for ido (#645)
This reverts commit 47763f49fd, after #643
reverted completions from hash-table to alist.
2020-05-16 19:38:52 +08:00
3bc174a6f0 (fix): reimplement mtime sorting (#642) 2020-05-16 19:32:23 +08:00
8091f4598e (internal): revert completions from hash table to alist (#643)
Initially we thought that using hash-tables would shave some seconds
because searching for a key is O(1), but when we present completions, we
typically want them sorted, and hash-tables do not support sorted keys.

Co-authored-by: Leo Vivier <leo.vivier+dev@gmail.com>
2020-05-16 18:17:37 +08:00
1267a43043 (fix): refactor get-ref-path-completions (#633)
* (fix): refactor get-ref-path-completions

* Remove leftover variable

Co-authored-by: Jethro Kuan <jethrokuan95@gmail.com>
2020-05-16 08:40:41 +02:00
N V
8ff09b4b6d (docs): Mention steps to provide backtrace in bug_report.md (#641) 2020-05-15 22:54:37 -04:00
2499c7e220 (feat): add COMPLETIONS argument to insert and find-file (#637)
Needed for smoother interaction with ORB.  I’ve elected to keep FILTER-FN for
the moment, even though it’s a bit redundant, and the description in the
docstring is not correct with the addition of tags.
2020-05-16 01:29:18 +02:00
d816250614 (fix): move from alist to hash for find-ref (#640) 2020-05-16 01:23:36 +02:00
47763f49fd (fix): fix parsing of new hash-table for ido
* Use hash-table-keys to extract titles for ido

* Same change for helm
2020-05-16 01:01:35 +02:00
9961a22a8c (fix): replace if with when (#632) 2020-05-15 20:23:06 +08:00
f390593cfb (feat): Add a tagging system (#604)
Tags are used as meta-data for files: they facilitate interactions with notes where titles are insufficient. For example, tags allow for categorization of notes: differentiating between bibliographical and structure notes during interactive commands.

Co-authored-by: Leo Vivier <leo.vivier+dev@gmail.com>
Co-authored-by: N V <44036031+progfolio@users.noreply.github.com>
2020-05-15 16:10:11 +08:00
N V
59c18c0e8c (internal): org-roam-dev -> sentence-end-double-space nil (#629)
Required by CI.
2020-05-15 13:11:19 +08:00
3df3b6519c (doc): fix org-roam-buffer-no-delete-other-windows (#628)
It appears the option has changed name, but this was not yet reflected
in the documentation.
2020-05-14 22:52:27 +02:00
b47b76aa41 (refactor): refactor title extraction (#625)
Introduces '(org-roam-title-sources), which can be a list of lists. Each symbol corresponds to a function, that when called returns a list of titles. If the element is a list, use the first function in the list that returns a successful result.
2020-05-14 19:45:07 +08:00
abb36d11ef (docs): remove redundant word in docstring (#626) 2020-05-14 19:04:59 +08:00
e55a38530d (fix): fix org-roam-doctor broken-link checker (#624)
The checker originally returns reports of wrong format when there are no
errors
2020-05-14 13:51:35 +08:00
80bc19cbda (docs): update manual location (#622) 2020-05-13 20:19:31 +08:00
85b3e488b2 (ci): fix 2020-05-13 19:56:06 +08:00
5a9f765a49 (ci): move images to the correct location 2020-05-13 19:54:08 +08:00
1c7c5b3b9b (ci): add nojekyll to docs 2020-05-13 19:48:39 +08:00
4266a81b51 (ci): build the correct folder, clean builds 2020-05-13 19:43:36 +08:00
36940e1eef Revert "(ci): deploy docs to docs branch"
This reverts commit 176aac67e6.
2020-05-13 19:39:12 +08:00
176aac67e6 (ci): deploy docs to docs branch 2020-05-13 19:36:36 +08:00
376ff71616 (ci): run doc build commands directly (#621) 2020-05-13 19:35:48 +08:00
232921b9a1 (docs): track landing page (#620) 2020-05-13 19:26:37 +08:00
9e2998c580 (ci): remove old docs, add landing page (#619) 2020-05-13 19:24:17 +08:00
e44b84b791 (ci): make multi-page manual (#618) 2020-05-13 18:56:42 +08:00
5e63bf32ed (ci): makeinfo -> texinfo (#617) 2020-05-13 18:49:18 +08:00
e62bda799a (docs): use gh actions to deploy documentation (#616) 2020-05-13 18:45:32 +08:00
46975107a2 (internal): remove assignment in issue templates (#615) 2020-05-13 17:58:34 +08:00
N V
b388fd3db2 (refactor): org-roam-db--clear pull tables from schemata (#611)
Programatically pull tables from schemata, rather than manually
specifying each table.
2020-05-13 02:24:50 -04:00
N V
e0cefa7377 (refactor): org-roam-db--clear-file pull tables from schemata (#613)
Programatically pull tables from schemata, rather than manually
specifying.
2020-05-13 14:14:46 +08:00
N V
fca1777648 (internal): Summarize features (#608)
* (internal): Summarize features

Replace generic package description in features' first line summary.

Co-authored-by: Leo Vivier <leo.vivier+dev@gmail.com>
2020-05-12 15:06:19 -04:00
N V
1722fae9af (internal): org-roam-dev use directory-local variable (#607)
Add .dir-locals.el to load org-roam-dev for all source files.
2020-05-12 13:46:12 -04:00
N V
3727f015cd (internal): add org-roam-dev.el (#606)
Help ensure source code consistency.
emacsql indentation for now, but can easily be expanded as needed.
2020-05-13 01:21:54 +08:00
a85205e7bc (fix): Respect org-roam-file-extensions during file creation (#602) 2020-05-12 19:08:00 +08:00
b4927abbd7 (fix): Enforce default for ‘org-roam-index-file’ (#599) 2020-05-12 16:12:14 +08:00
N V
ad5fca5440 "Refactor org-roam-message as a function" (#595)
* Refactor org-roam-message as a function

Add to commentary that org-roam-macs may contain other utility
functions (similar to org-macs).

* Fix typos

* Try again

* Fix typo

* fix syntax error

* fix syntax error

* Apply args correctly

* Refactor with funcall

* Revert "Refactor with funcall"

This reverts commit 0807252d64.

Co-authored-by: Leo Vivier <leo.vivier+dev@gmail.com>
2020-05-10 23:17:55 +02:00
3efe315ff1 (internal): add org-roam-message (#593)
This macro simplifies message printing, so we can respect
`org-roam-verbose` in more places. Also silences more messages when
`org-roam-verbose` set to false.
2020-05-10 16:44:28 +08:00
d68d1f8ebb (feat): add org-roam-doctor (#570)
`org-roam-doctor` provides a diagnostic tool for checking an Org-roam
file for things that are broken. Currently implemented is a check for
broken links, and methods to fix them. The checker is designed to be
extensible.
2020-05-10 13:57:18 +08:00
c70f2d5f54 (fix): update repo root to group (#591) 2020-05-10 13:48:16 +08:00
d3206b797a (docs): link to discourse in README (#577)
Also, add information about Graphviz on the README.

Co-authored-by: Jethro Kuan <jethrokuan95@gmail.com>
2020-05-09 19:54:05 +08:00
dee540b62f (fix): do not store empty-string refs in db (#586)
* (fix): do not store empty-string refs in db

* Error when ROAM_KEY is empty

* Handle nil

Co-authored-by: Jethro Kuan <jethrokuan95@gmail.com>
2020-05-09 13:47:56 +02:00
46fd2a9a68 (fix): allow group templates in capture-templates (#584)
Co-authored-by: N V <44036031+progfolio@users.noreply.github.com>
2020-05-09 18:08:08 +08:00
c1bfa99ace (fix): make graph--build error on non-string (#580)
* (fix): make graph--build error on non-string

* Replace let* with let

* Fix wording
2020-05-07 20:38:17 +02:00
9bc80ff9f7 (fix): improve error message on missing executable (#579) 2020-05-08 01:44:28 +08:00
1912beebc3 (docs): mention where to modify org-roam templates (#575)
Addresses #573
2020-05-07 16:33:42 +08:00
f8f7e6009c (internal): add longer sleep time to tests (#574) 2020-05-07 15:41:58 +08:00
689f559080 (doc): Add a gif for ORB (#571) 2020-05-06 18:59:09 +08:00
3ca2d9f4ca (doc): Improve wording 'A Preview' (#568)
* (doc): Improve wording of the first paragraph

Can’t believe nobody told us that we used ‘screenshot’ instead of
‘screencast’. :(

* Fill to 72
2020-05-05 14:19:00 +08:00
cd0850f1c1 (feat): simplify format of INFO for find-ref and add FILTER (#567)
* (feat): simplify format of `INFO` for find-ref

The format of the `INFO` argument of `org-roam-find` has been simplified, thanks
to the split of `type` and `ref` in the db permitted by #547.

The non-interactive behaviour of `org-roam-find-ref` has also been isolated
into `org-roam--find-ref`.  Even if it makes us repeat ourselves a bit, it
avoids having to nil the interactive argument just to get the non-interactive
us, which I think is better syntax.

* (feat): implement get-ref-path-completions filtering
2020-05-04 22:31:28 +02:00
11e15594cc (feat): add custom face for invalid links (#564)
* (feat): add custom face for links without destinations

* Rename to ‘invalid’

* Update docstring

* Remove ‘typically’
2020-05-04 15:47:27 +02:00
f6e84caf72 (chore): inherit org-roam-link-current from org-link (#563)
A better default for org-roam-link-current is the original org-link
face, rather than org-block.
2020-05-04 20:58:12 +08:00
11d239d661 (feat): fix citation links not showing up in graph (#547)
This change adds a `type` column to the refs column, and strips the prefix before storing the key in the `refs` table.
2020-05-04 20:44:15 +08:00
7df50c14ec (internal): make lint errors fail CI, and disable spellcheck during linting (#561)
- make lint errors fail CI
- disable indentation linting
- disable package linting for org-roam-macs.el
- disable spellcheck for checkdoc
- fixes compilation errors
2020-05-04 15:17:39 +08:00
a723199d68 (feat): apply error face if file link is broken (#560) 2020-05-04 12:57:43 +08:00
N V
1bbfb0cdc9 (ehancement): Improve org-roam-graph (#559)
Allow showing/building the whole graph from any buffer.
Allow programatically specifying connected component path.
2020-05-03 18:03:02 -04:00
69d4f05a13 (feat): add prefix argument to force database rebuild (#553)
* (feat): add prefix argument to force database rebuild

* Update changelog
2020-05-03 18:40:32 +08:00
4cad2cf6e6 (internal): use Make and Org to build manual (#546) 2020-05-03 18:06:27 +08:00
e698ed7f53 Generate cite backlinks using all org ref cite types (#551)
This would fail on pathological cases where the key itself contains other prefixes e.g. if the key
is `cite:parencite:autocite:key`. Although this is unlikely...

To use org-ref-cite-types, we must ensure that org-ref is loaded. This would likely already be done
otherwise as the user is obviously using cite links.
2020-05-02 18:50:11 +08:00
0132546e56 Create stale.yml 2020-05-01 20:16:57 +08:00
a8e2544435 graph: add an option of wrapping the title (#542)
Co-authored-by: Jethro Kuan <jethrokuan95@gmail.com>
2020-05-01 19:49:46 +08:00
1ad3539c54 (fix): ensure that multicite links are correctly split (#545)
* Ensure that multicite links are correctly split

org-ref multi-citations are handled by "cite:key1,key2". In the org-roam databases this was
previously stored as a single "cite" link to the (non-existing) key "key1,key2". This means that
cite backlinks and cite graph behaviour does not work correctly for these links.

This fix will split any cite links with a comma into separate links to each individual ref

* Refactor with ->>

* Refactor to use org-ref-split-and-strip-string instead

* Update changelog with #545

* (fix): optimize processing

* (fix): avoid repetition

Co-authored-by: Leo Vivier <leo.vivier+dev@gmail.com>
2020-05-01 11:57:28 +02:00
5b773b687b (doc): add key-binding for index in default configs (#543)
* (doc): add key-binding for index in default configs

* (fix): rename org-roam-find-index to -jump-to-index
2020-05-01 09:07:37 +02:00
08aa5c630d (feat): reintroduce org-roam-link-current face (#516) 2020-04-30 20:20:33 +08:00
e05ee1240d (feat) cond display relative subdir in title for selection (#427)
* (feat) cond display relative subdir in title for selection

A title can now be constructed as ‘subdir/file-title’ where ‘subdir’ is the
sub-directory relative from ‘org-roam-directory’.

When ‘org-roam-title-include-subdirs’ is non-nil, ‘org-roam--extract-titles’
now outputs titles in this format.

* (fix) improve docstrings

* (feat) add var for modifying subdir-separator

* (fix) nitpick docstring

* (doc) document subdir creation in templates with :file-name

* (feat) make subdir-format accept a function

* (fix) respect docstring one-line-description

* (fix) address checkdoc errors

* (fix) also add subdirs when db--update-titles

* (feat) improve modularisation

`org-roam--extract-titles' is now reverted to its default definition, i.e. it
doesn’t format the titles.  In its stead,
`org-roam--extract-and-format-titles' is created to both extract the titles
and process all of them with `org-roam--format-title', which is a much better
way to do this.

* Refactor with ->>

* Refactor with let*

Pretty sure I got confused because I thought I needed to use the result of the
db-queryr.

* Remove useless ->>
2020-04-30 13:13:19 +02:00
65d99e998c (feat): prettier graph defaults (#541)
Use settings provided by @tecosaur. Closes #539.
2020-04-30 13:56:54 +08:00
ea3f5d00a0 (feat) expand rel-links upon extraction (#520) 2020-04-30 13:44:45 +08:00
7680663205 (feat): optionally use headline as title (#538)
Optionally pulls title from the first headline in Org file. Closes #506.
2020-04-29 12:42:55 +08:00
d0819aeffb (feat) implement org-roam-find-index (#513) 2020-04-29 12:08:42 +08:00
bd4b9d41e8 (bugfix): quote graphviz configuration options (#537)
Always quote graphviz configuration options. This allows passing
configurations with spaces. Fixes #535.
2020-04-29 11:30:39 +08:00
4142300501 (internal): refactor org-roam--pluralize (#525) 2020-04-26 19:07:19 +08:00
487025aa2f (chore): remove org-roam-completion-fuzzy-match (#523)
Remove the fuzzy matching variable introduced in #289. The rationale is
addressed in
https://github.com/jethrokuan/org-roam/issues/514#issuecomment-619438401:
Helm, Ido and Ivy have their own mechanisms for fuzzy search, and can be
tweaked using their own configuration options outside of org-roam, e.g.
through `ivy-re-builders-alist`.
2020-04-26 18:32:27 +08:00
bd3c97bb30 (feat) conditionally pluralize heading in org-roam-buffer (#521) 2020-04-26 17:51:32 +08:00
265a3054be (fix): resolve symlinks during cache build (#524)
Fixes #518.
2020-04-26 17:42:57 +08:00
8bb2465e61 (docs): update reference to Roam Protocol documentation (#519)
Co-authored-by: Jethro Kuan <jethrokuan95@gmail.com>
2020-04-26 17:29:21 +08:00
c3a5544da9 (docs): add docs for qutebrowser keybindings (#512) 2020-04-26 17:23:11 +08:00
963692f353 (bugfix): Fix invalid usage of error handler (#511)
The error handler was never invoked when executing `org-roam-graph-viewer` failed
2020-04-25 18:53:09 +08:00
d01f7b2daf (bugfix): fix inserting backup files into database (#509)
In #470, the `and` clause was removed, so `org-roam--org-roam-file-p`
returns `t` on `foo.org~` backup files. This PR adds that back in.

In addition, the `after-save-hook` function was not checking for whether
the file was within the org-roam system, which meant files from outside
`org-roam` would also be added into the database. This PR adds a guard
clause.
2020-04-22 14:35:47 +08:00
8a99febd0b (fix): lowercase username in url to org-roam-bibtex (#505) 2020-04-22 14:28:30 +08:00
b5786edb30 (docs): Fix org-roam-protocol JS Bookmarklet (#508) 2020-04-22 13:57:12 +08:00
dce8c47d6e (docs): mention org-roam-bibtex (#503) 2020-04-21 20:55:12 +08:00
57 changed files with 4755 additions and 1578 deletions

4
.dir-locals.el Normal file
View File

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

12
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,12 @@
# These are supported funding model platforms
github: [jethrokuan, zaeph]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@ -1,14 +1,15 @@
---
name: Bug Report
about: Something's not working.
title: ''
labels: ''
assignees: 'jethrokuan'
title: ""
labels: ""
assignees: ""
---
### Description
#### Steps to Reproduce
<!--
Example:
@ -18,13 +19,25 @@ Example:
...
-->
#### Backtrace
<!--
Will help us track and understand issues faster.
How to provide a backtrace:
1. M-x toggle-debug-on-error
2. Trigger error. The debugger buffer should pop up.
3. Copy the contents of the debugger buffer and paste here
-->
#### Expected Results
<!-- Example: File A is there -->
#### Actual Results
<!-- Example: File A is missing -->
### Versions
- Emacs (`C-h v emacs-version`): vX.X.X
### Environment
<!-- Please M-x org-roam-diagnostics and paste results here -->
- Org-roam commit: https://github.com/jethrokuan/org-roam/commit/commithashhere

View File

@ -1,9 +1,9 @@
---
name: Feature Request
about: Create a feature request to improve Org-roam
title: ''
labels: 'enhancement'
assignees: 'jethrokuan'
title: ""
labels: "enhancement"
assignees: ""
---
### Brief Abstract
@ -13,4 +13,5 @@ assignees: 'jethrokuan'
### Proposed Implementation (if any)
### Please check the following:
- [ ] No similar feature requests

31
.github/workflows/docs.yml vendored Normal file
View File

@ -0,0 +1,31 @@
# * docs.yml --- Build the documentation and publish to Github Pages
name: "Docs"
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: true
steps:
- uses: actions/checkout@v2
- name: Install deps
run: |
sudo apt-get install texinfo
- name: Build docs
continue-on-error: false
run: make html
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@releases/v3
with:
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
BRANCH: gh-pages # The branch the action should deploy to.
FOLDER: doc # The folder the action should deploy.
CLEAN: true

19
.github/workflows/stale.yml vendored Normal file
View File

@ -0,0 +1,19 @@
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

@ -29,7 +29,6 @@ on:
push:
branches:
- master
- develop
jobs:
build:
@ -56,7 +55,7 @@ jobs:
# as failures, so linting and testing are run as separate steps.
- name: Lint
continue-on-error: true
continue-on-error: false
run: ./makem.sh -vv --sandbox $SANDBOX_DIR lint
- name: Test

13
.gitignore vendored
View File

@ -1,2 +1,15 @@
/.sandbox/
**/*.elc
/doc/dir
/doc/*.info
/doc/*.pdf
/doc/*.epub
/doc/META_INF/
/doc/OEBPS/
/doc/dir
/doc/epub.xml
/doc/org-roam/
/doc/mimetype
/doc/stats/
/config.mk
/doc/manual/

View File

@ -1,5 +1,45 @@
# Changelog
## 1.1.1 (18-05-2020)
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.
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).
As usual, this release comes with a multitude of bug-fixes and refactorings.
### Breaking Changes
- [#523](https://github.com/org-roam/org-roam/pull/523) remove `org-roam-completion-fuzzy-match` in favor of using completion mechanism's configuration options directly
- [#547](https://github.com/org-roam/org-roam/pull/547) Deprecate `org-roam-db--maybe-update`, in favour of `org-roam-db--update-maybe`
- [#604](https://github.com/org-roam/org-roam/pull/604) Deprecate `org-roam-title-include-subdirs`, `org-roam-title-subdir-format` `org-roam-title-subdir-separator`, for a more general tagging system built on subdirectories
### Bugfixes
- [#509](https://github.com/org-roam/org-roam/pull/509) fix backup files being tracked in database
- [#509](https://github.com/org-roam/org-roam/pull/509) fix external org files being tracked in database
- [#537](https://github.com/org-roam/org-roam/pull/537) quote graphviz node and edge configuration options to allow multi-word configurations
- [#545](https://github.com/org-roam/org-roam/pull/545) fix `org-roam--extract-links` to ensure that multiple citations (`cite:key1,key2`) are split correctly
- [#547](https://github.com/org-roam/org-roam/pull/547) Fix unlinked citations
- [#660](https://github.com/org-roam/org-roam/pull/660) fix rename-file advice not working for renaming to directories
- [#660](https://github.com/org-roam/org-roam/pull/660) fix links breaking within file on file movement
### Features
- [#538](https://github.com/org-roam/org-roam/pull/538) Optionally use text in first headline as title
- [#553](https://github.com/org-roam/org-roam/pull/553) Add prefix argument to `org-roam-db-build-cache` for forcing rebuilds
- [#560](https://github.com/org-roam/org-roam/pull/560) Apply 'error face to distinguish broken links
- [#570](https://github.com/org-roam/org-roam/pull/570) Add `org-roam-doctor` to diagnose org-roam files
- [#625](https://github.com/org-roam/org-roam/pull/625) Add `org-roam-title-sources` to control how titles are retrieved within notes
- [#604](https://github.com/org-roam/org-roam/pull/604) Add a tagging system. `org-roam-tag-sources` controls how tags are retrieved from notes
### Internal Changes
- [#547](https://github.com/org-roam/org-roam/pull/547) Added `type` column to the `refs` table
- [#606](https://github.com/org-roam/org-roam/pull/606) Added `org-roam-dev.el` for developer coding standards
- [#622](https://github.com/org-roam/org-roam/pull/622) Online documentation now points to the Org-based documentation
## 1.1.0 (21-04-2020)
To the average user, this release is mainly a bugfix release with additional options to customize. However, the changes made to the source is significant. Most notably, in this release:
@ -8,31 +48,35 @@ To the average user, this release is mainly a bugfix release with additional opt
2. [@kljohann](https://github.com/kljohann) did some fantastic work on graph generation: allowing building images for connected components within the graph up to a specified distance
3. We also started supporting `org-ref` natively: cite links now show up in both the graph and the org-roam buffer.
In the coming months, you can expect work on bigger projects (e.g. revamping the org-roam buffer).
In the coming months, you can expect work on bigger projects (e.g. revamping the org-roam buffer).
### Breaking Changes
* [#385](https://github.com/jethrokuan/org-roam/pull/385) Deprecate `org-roam-graph-node-shape` in favour of `org-roam-graph-node-extra-config`.
* [#473](https://github.com/jethrokuan/org-roam/pull/473) Deprecate `org-roam-date-filename-format` and `org-roam-date-title-format`, in favour of `org-roam-dailies-capture-templates`.
- [#385](https://github.com/org-roam/org-roam/pull/385) Deprecate `org-roam-graph-node-shape` in favour of `org-roam-graph-node-extra-config`.
- [#473](https://github.com/org-roam/org-roam/pull/473) Deprecate `org-roam-date-filename-format` and `org-roam-date-title-format`, in favour of `org-roam-dailies-capture-templates`.
### New Features
* [#350](https://github.com/jethrokuan/org-roam/pull/350) Add `org-roam-db-location` to customize location of org-roam database.
* [#359](https://github.com/jethrokuan/org-roam/pull/359) Add `org-roam-verbose` to allow or silence printing of information.
* [#374](https://github.com/jethrokuan/org-roam/pull/374) Add support for `org-ref` `cite:` links
* [#380](https://github.com/jethrokuan/org-roam/pull/380) Allow `org-roam-buffer-position` to also be `top` or `bottom`
* [#385](https://github.com/jethrokuan/org-roam/pull/385) Add `org-roam-graph-node-extra-config` to configure Graphviz nodes
* [#398](https://github.com/jethrokuan/org-roam/pull/398), [#418](https://github.com/jethrokuan/org-roam/pull/418) Add graph building for connected components
* [#435](https://github.com/jethrokuan/org-roam/pull/435) Add `org-roam-graph-edge-extra-config` to configure Graphviz edges
* [#439](https://github.com/jethrokuan/org-roam/pull/439) Add support for `org-ref` citations to display as edges in graph. Add `org-roam-graph-edge-cites-extra-config` to configure these edges
* [#465](https://github.com/jethrokuan/org-roam/pull/465) Add `org-roam-file-extensions` to allow detection of org files with different file extensions
* [#488](https://github.com/jethrokuan/org-roam/pull/488) Allow a function for `org-roam-graph-viewer`
* [#491](https://github.com/jethrokuan/org-roam/pull/491) Use TITLE as description when linking before first heading
- [#350](https://github.com/org-roam/org-roam/pull/350) Add `org-roam-db-location` to customize location of org-roam database.
- [#359](https://github.com/org-roam/org-roam/pull/359) Add `org-roam-verbose` to allow or silence printing of information.
- [#374](https://github.com/org-roam/org-roam/pull/374) Add support for `org-ref` `cite:` links
- [#380](https://github.com/org-roam/org-roam/pull/380) Allow `org-roam-buffer-position` to also be `top` or `bottom`
- [#385](https://github.com/org-roam/org-roam/pull/385) Add `org-roam-graph-node-extra-config` to configure Graphviz nodes
- [#398](https://github.com/org-roam/org-roam/pull/398), [#418](https://github.com/org-roam/org-roam/pull/418) Add graph building for connected components
- [#435](https://github.com/org-roam/org-roam/pull/435) Add `org-roam-graph-edge-extra-config` to configure Graphviz edges
- [#439](https://github.com/org-roam/org-roam/pull/439) Add support for `org-ref` citations to display as edges in graph. Add `org-roam-graph-edge-cites-extra-config` to configure these edges
- [#465](https://github.com/org-roam/org-roam/pull/465) Add `org-roam-file-extensions` to allow detection of org files with different file extensions
- [#488](https://github.com/org-roam/org-roam/pull/488) Allow a function for `org-roam-graph-viewer`
- [#491](https://github.com/org-roam/org-roam/pull/491) Use TITLE as description when linking before first heading
### Bugfixes
* [#470](https://github.com/jethrokuan/org-roam/pull/470) Add workaround for undocumented `file-truename` behaviour in `org-roam--org-roam-file-p`.
- [#470](https://github.com/org-roam/org-roam/pull/470) Add workaround for undocumented `file-truename` behaviour in `org-roam--org-roam-file-p`.
### Internal Changes
* [#363](https://github.com/jethrokuan/org-roam/pull/363), [#473](https://github.com/jethrokuan/org-roam/pull/473) Modularize org-roam features.
* [#497](https://github.com/jethrokuan/org-roam/pull/497) Simplify `org-roam--list-files` implementation
- [#363](https://github.com/org-roam/org-roam/pull/363), [#473](https://github.com/org-roam/org-roam/pull/473) Modularize org-roam features.
- [#497](https://github.com/org-roam/org-roam/pull/497) Simplify `org-roam--list-files` implementation
## 1.0.0 (23-03-2020)
@ -40,16 +84,18 @@ Org-roam is now on MELPA! We have squashed most of the bugs, and Org-roam has
been stable for the most part.
### New Features
* [#269](https://github.com/jethrokuan/org-roam/pull/269) Add `org-roam-graphviz-extra-options`
* [#257](https://github.com/jethrokuan/org-roam/pull/257) Add a company-backend `company-org-roam`
* [#284](https://github.com/jethrokuan/org-roam/pull/284), [#289](https://github.com/jethrokuan/org-roam/pull/289) Configurable `org-roam-completion-system` with options `'default`, `'ido`, `'ivy` and `'helm`
* [#289](https://github.com/jethrokuan/org-roam/pull/289) Add customizable `org-roam-fuzzy-match` to allow fuzzy-matching of candidates
* [#290](https://github.com/jethrokuan/org-roam/pull/290) Add `org-roam-date-title-format` and `org-roam-date-filename-format` for customizing Org-roam's date files
* [#296](https://github.com/jethrokuan/org-roam/pull/296) Allow multiple exclusion matchers in `org-roam-graph-exclude-matcher`
- [#269](https://github.com/org-roam/org-roam/pull/269) Add `org-roam-graphviz-extra-options`
- [#257](https://github.com/org-roam/org-roam/pull/257) Add a company-backend `company-org-roam`
- [#284](https://github.com/org-roam/org-roam/pull/284), [#289](https://github.com/org-roam/org-roam/pull/289) Configurable `org-roam-completion-system` with options `'default`, `'ido`, `'ivy` and `'helm`
- [#289](https://github.com/org-roam/org-roam/pull/289) Add customizable `org-roam-fuzzy-match` to allow fuzzy-matching of candidates
- [#290](https://github.com/org-roam/org-roam/pull/290) Add `org-roam-date-title-format` and `org-roam-date-filename-format` for customizing Org-roam's date files
- [#296](https://github.com/org-roam/org-roam/pull/296) Allow multiple exclusion matchers in `org-roam-graph-exclude-matcher`
### Bugfixes
* [#293](https://github.com/jethrokuan/org-roam/pull/293) Fix capture templates not working as expected for `org-roam-find-file`
* [#275](https://github.com/jethrokuan/org-roam/pull/275) Fix database rebuild when `org-roam-directory` is set locally
- [#293](https://github.com/org-roam/org-roam/pull/293) Fix capture templates not working as expected for `org-roam-find-file`
- [#275](https://github.com/org-roam/org-roam/pull/275) Fix database rebuild when `org-roam-directory` is set locally
## 1.0.0-rc1 (06-03-2020)
@ -59,82 +105,95 @@ backing storage has been changed to a SQLite database, and a
templating system using `org-capture` is introduced.
### Breaking Changes
* [#200](https://github.com/jethrokuan/org-roam/pull/200) Move Org-roam cache into a SQLite database.
* [#203](https://github.com/jethrokuan/org-roam/pull/203) Roam protocol is deprecated, in favour of extending org-roam-protocol.
- [#200](https://github.com/org-roam/org-roam/pull/200) Move Org-roam cache into a SQLite database.
- [#203](https://github.com/org-roam/org-roam/pull/203) Roam protocol is deprecated, in favour of extending org-roam-protocol.
### New Features
* [#182](https://github.com/jethrokuan/org-roam/pull/182) Support file name aliases via `#+ROAM_ALIAS`.
* [#216](https://github.com/jethrokuan/org-roam/pull/216) Adds templating functionality by extending org-capture.
* [#232](https://github.com/jethrokuan/org-roam/pull/232) Adds a prefix key to `org-roam-show-graph`, to generate graph without opening it.
* [#233](https://github.com/jethrokuan/org-roam/pull/233) Adds `org-roam-graph-exclude-matcher`, which allows exclusion of nodes from graph.
* [#247](https://github.com/jethrokuan/org-roam/pull/247) Add `org-roam-backlink` face, which allows customizing backlinks appearance
* [#259](https://github.com/jethrokuan/org-roam/pull/259) Add optional initial-prompt to `org-roam-find-file`
- [#182](https://github.com/org-roam/org-roam/pull/182) Support file name aliases via `#+ROAM_ALIAS`.
- [#216](https://github.com/org-roam/org-roam/pull/216) Adds templating functionality by extending org-capture.
- [#232](https://github.com/org-roam/org-roam/pull/232) Adds a prefix key to `org-roam-show-graph`, to generate graph without opening it.
- [#233](https://github.com/org-roam/org-roam/pull/233) Adds `org-roam-graph-exclude-matcher`, which allows exclusion of nodes from graph.
- [#247](https://github.com/org-roam/org-roam/pull/247) Add `org-roam-backlink` face, which allows customizing backlinks appearance
- [#259](https://github.com/org-roam/org-roam/pull/259) Add optional initial-prompt to `org-roam-find-file`
### Bugfixes
* [#207](https://github.com/jethrokuan/org-roam/pull/207), [#221](https://github.com/jethrokuan/org-roam/pull/221) small bugfixes to Org-roam graph generation
* [#230](https://github.com/jethrokuan/org-roam/pull/230) remove nonspacing marks from filenames, to prevent cross-platform errors
- [#207](https://github.com/org-roam/org-roam/pull/207), [#221](https://github.com/org-roam/org-roam/pull/221) small bugfixes to Org-roam graph generation
- [#230](https://github.com/org-roam/org-roam/pull/230) remove nonspacing marks from filenames, to prevent cross-platform errors
### New Contributors
* [@acowley][https://github.com/acowley]
* [@teesloane][https://github.com/teesloane]
- [@acowley][https://github.com/acowley]
- [@teesloane][https://github.com/teesloane]
## 0.1.2 (2020-02-21)
### Breaking Changes
* [#143](https://github.com/jethrokuan/org-roam/pull/143) `org-roam-mode` is now a global mode. The installation instructions have changed accordingly.
* [#103](https://github.com/jethrokuan/org-roam/pull/103) Change `org-roam-file-format` to a function: `org-roam-file-name-function` to allow more flexible file name customizaton. Also changes `org-roam-use-timestamp-as-filename` to `org-roam-filename-noconfirm` to better describe what it does.
- [#143](https://github.com/org-roam/org-roam/pull/143) `org-roam-mode` is now a global mode. The installation instructions have changed accordingly.
- [#103](https://github.com/org-roam/org-roam/pull/103) Change `org-roam-file-format` to a function: `org-roam-file-name-function` to allow more flexible file name customizaton. Also changes `org-roam-use-timestamp-as-filename` to `org-roam-filename-noconfirm` to better describe what it does.
### New Features
* [#145](https://github.com/jethrokuan/org-roam/pull/145) `org-roam-show-graph`: Fallback to Emacs SVG viewer
* [#141](https://github.com/jethrokuan/org-roam/pull/141) add variable `org-roam-new-file-directory` for new Org-roam files
* [#138](https://github.com/jethrokuan/org-roam/pull/138) add `org-roam-switch-to-buffer`
* [#124](https://github.com/jethrokuan/org-roam/pull/124), [#141](https://github.com/jethrokuan/org-roam/pull/141) Maintain cache consistency on file rename and delete
* [#87](https://github.com/jethrokuan/org-roam/pull/87), [#90](https://github.com/jethrokuan/org-roam/pull/90) Support encrypted Org files
* [#110](https://github.com/jethrokuan/org-roam/pull/110) Add prefix to `org-roam-insert`, for inserting titles down-cased
* [#99](https://github.com/jethrokuan/org-roam/pull/99) Add keybinding so that `<return>` or `mouse-1` in the backlinks buffer visits the source file of the backlink at point
- [#145](https://github.com/org-roam/org-roam/pull/145) `org-roam-show-graph`: Fallback to Emacs SVG viewer
- [#141](https://github.com/org-roam/org-roam/pull/141) add variable `org-roam-new-file-directory` for new Org-roam files
- [#138](https://github.com/org-roam/org-roam/pull/138) add `org-roam-switch-to-buffer`
- [#124](https://github.com/org-roam/org-roam/pull/124), [#141](https://github.com/org-roam/org-roam/pull/141) Maintain cache consistency on file rename and delete
- [#87](https://github.com/org-roam/org-roam/pull/87), [#90](https://github.com/org-roam/org-roam/pull/90) Support encrypted Org files
- [#110](https://github.com/org-roam/org-roam/pull/110) Add prefix to `org-roam-insert`, for inserting titles down-cased
- [#99](https://github.com/org-roam/org-roam/pull/99) Add keybinding so that `<return>` or `mouse-1` in the backlinks buffer visits the source file of the backlink at point
### Changes
* [#108](https://github.com/jethrokuan/org-roam/pull/108) Locally overwrite the link following behaviour in the org-roam-buffer to open files in the same window `org-roam` was called from
- [#108](https://github.com/org-roam/org-roam/pull/108) Locally overwrite the link following behaviour in the org-roam-buffer to open files in the same window `org-roam` was called from
### Bugfixes
* [#86](https://github.com/jethrokuan/org-roam/pull/86) Fix `org-roam--parse-content` incorrect `:to` computation for nested files
* [#98](https://github.com/jethrokuan/org-roam/pull/98) Fix `org-roam--find-file` picking up temporary files
* [#136](https://github.com/jethrokuan/org-roam/pull/136) Misc bugfixes
- [#86](https://github.com/org-roam/org-roam/pull/86) Fix `org-roam--parse-content` incorrect `:to` computation for nested files
- [#98](https://github.com/org-roam/org-roam/pull/98) Fix `org-roam--find-file` picking up temporary files
- [#136](https://github.com/org-roam/org-roam/pull/136) Misc bugfixes
### Internal
* [#122](https://github.com/jethrokuan/org-roam/pull/122), [#128](https://github.com/jethrokuan/org-roam/pull/128) Improve performance of post-command-hook
* [#92](https://github.com/jethrokuan/org-roam/pull/92), [#105](https://github.com/jethrokuan/org-roam/pull/105) Add tests for core functionality
- [#122](https://github.com/org-roam/org-roam/pull/122), [#128](https://github.com/org-roam/org-roam/pull/128) Improve performance of post-command-hook
- [#92](https://github.com/org-roam/org-roam/pull/92), [#105](https://github.com/org-roam/org-roam/pull/105) Add tests for core functionality
### New Contributors
* [@frigge](https://github.com/frigge)
* [@juergenhoetzel](https://github.com/juergenhoetzel)
* [@chip2n](https://github.com/chip2n)
* [@l3kn](https://github.com/l3kn)
* [@jdormit](https://github.com/jdormit)
* [@herbertjones](https://github.com/herbertjones)
* [@CeleritasCelery](https://github.com/CeleritasCelery)
* [@daniel-koudouna](https://github.com/daniel-koudouna)
- [@frigge](https://github.com/frigge)
- [@juergenhoetzel](https://github.com/juergenhoetzel)
- [@chip2n](https://github.com/chip2n)
- [@l3kn](https://github.com/l3kn)
- [@jdormit](https://github.com/jdormit)
- [@herbertjones](https://github.com/herbertjones)
- [@CeleritasCelery](https://github.com/CeleritasCelery)
- [@daniel-koudouna](https://github.com/daniel-koudouna)
## 0.1.1 (2020-02-15)
Mostly a documentation/cleanup release.
### New Features
* [#62](https://github.com/jethrokuan/org-roam/pull/62) Add the options `org-roam-use-timestamps-as-filename` and `org-roam-file-format`, more in documentation.
- [#62](https://github.com/org-roam/org-roam/pull/62) Add the options `org-roam-use-timestamps-as-filename` and `org-roam-file-format`, more in documentation.
### Breaking Changes
* [#62](https://github.com/jethrokuan/org-roam/pull/62) The ID (file-name) workflow is no longer first-class, but a fallback when titles don't exist.
- [#62](https://github.com/org-roam/org-roam/pull/62) The ID (file-name) workflow is no longer first-class, but a fallback when titles don't exist.
### Changes
* [#66](https://github.com/jethrokuan/org-roam/pull/66), [#68](https://github.com/jethrokuan/org-roam/pull/68): Improved the quality of the package in preparation of submission to MELPA
* [#73](https://github.com/jethrokuan/org-roam/pull/73): Added CI to the project via Github Issues (Thanks [@alphapapa](https://github.com/alphapapa/) for scripts and setup)
* [#69](https://github.com/jethrokuan/org-roam/pull/69), [#72](https://github.com/jethrokuan/org-roam/pull/72), [#75](https://github.com/jethrokuan/org-roam/pull/75): Major cleanup and de-duplication of code
- [#66](https://github.com/org-roam/org-roam/pull/66), [#68](https://github.com/org-roam/org-roam/pull/68): Improved the quality of the package in preparation of submission to MELPA
- [#73](https://github.com/org-roam/org-roam/pull/73): Added CI to the project via Github Issues (Thanks [@alphapapa](https://github.com/alphapapa/) for scripts and setup)
- [#69](https://github.com/org-roam/org-roam/pull/69), [#72](https://github.com/org-roam/org-roam/pull/72), [#75](https://github.com/org-roam/org-roam/pull/75): Major cleanup and de-duplication of code
### Bugfixes
* [#67](https://github.com/jethrokuan/org-roam/pull/67): Fixed `org-roam--make-file` not creating files with extensions
* [#71](https://github.com/jethrokuan/org-roam/pull/71), [#78](https://github.com/jethrokuan/org-roam/pull/78): Fixed `org-roam-insert` not inserting correct paths
* [#82](https://github.com/jethrokuan/org-roam/pull/82): Fixed nested Org-roam files not being detected as part of Org-roam
- [#67](https://github.com/org-roam/org-roam/pull/67): Fixed `org-roam--make-file` not creating files with extensions
- [#71](https://github.com/org-roam/org-roam/pull/71), [#78](https://github.com/org-roam/org-roam/pull/78): Fixed `org-roam-insert` not inserting correct paths
- [#82](https://github.com/org-roam/org-roam/pull/82): Fixed nested Org-roam files not being detected as part of Org-roam
<!-- Local Variables: -->
<!-- eval: (auto-fill-mode -1) -->

View File

@ -54,3 +54,17 @@ endif
.DEFAULT: init
init:
@./makem.sh $(DEBUG) $(VERBOSE) $(SANDBOX) $(INSTALL_DEPS) $(INSTALL_LINTERS)
docs:
@$(MAKE) -C doc all
html:
@$(MAKE) -C doc html-dir
install: install-docs
install-docs: docs
@$(MAKE) -C doc install-docs
install-info: info
@$(MAKE) -C doc install-info

View File

@ -1,6 +1,5 @@
[![License GPL 3][badge-license]](http://www.gnu.org/licenses/gpl-3.0.txt)
[![Documentation Status](https://readthedocs.org/projects/org-roam/badge/?version=latest)](https://org-roam.readthedocs.io/en/latest/?badge=latest)
[![GitHub Release](https://img.shields.io/github/v/release/jethrokuan/org-roam)](https://img.shields.io/github/v/release/jethrokuan/org-roam)
[![GitHub Release](https://img.shields.io/github/v/release/org-roam/org-roam)](https://img.shields.io/github/v/release/org-roam/org-roam)
[![MELPA](https://melpa.org/packages/org-roam-badge.svg)](https://melpa.org/#/org-roam)
## Synopsis
@ -22,20 +21,20 @@ describing Org-roam and the concepts behind it:
[![Making Connections in your Notes](http://img.youtube.com/vi/Lg61ocfxk3c/0.jpg)](http://www.youtube.com/watch?v=Lg61ocfxk3c "Making Connections in your Notes")
As of February 2020, it is in a very early stage of development.
Important links:
- **[Documentation][docs]**
- **[Org-roam Slack][slack]**
- **[Discourse][discourse]**
- **[Slack][slack]**
## A Preview
Here's a screenshot of `org-roam`. The `org-roam` buffer shows
backlinks for the active org buffer in the left window, as well as the
surrounding content in the backlink file. The database is built once,
and updated incrementally. The graph is generated from the link
structure, and can be used to navigate to the respective files.
Here's a screencast of Org-roam. The `org-roam-buffer` (window on the
right) shows backlinks for the active Org-roam buffer (window on the
left), as well as the surrounding content in the backlink file. The
database is built once, and updated incrementally. The graph is
generated from the link structure, and can be used to navigate to the
respective files.
![img](doc/images/org-roam-graph.gif)
@ -51,7 +50,7 @@ Here's a sample configuration with using `use-package`:
```emacs-lisp
(use-package org-roam
:hook
:hook
(after-init . org-roam-mode)
:custom
(org-roam-directory "/path/to/org-files/")
@ -63,9 +62,15 @@ Here's a sample configuration with using `use-package`:
(("C-c n i" . org-roam-insert))))
```
`org-roam-graph` by default expects to find the `dot` executable
from the `graphviz` package in the `exec-path`.
Ensure `graphviz` is installed and found if you want to use this
feature or customize your configuration for `org-roam-graph` to use a
different tool.
For more detailed installation and configuration instructions (including for
Doom and Spacemacs users), please see [the
documentation](https://org-roam.readthedocs.io/en/master/installation/).
documentation][docs].
## Knowledge Bases using Org-roam
@ -90,5 +95,6 @@ General Public License, Version 3
[roamresearch]: https://www.roamresearch.com/
[org]: https://orgmode.org/
[badge-license]: https://img.shields.io/badge/license-GPL_3-green.svg
[docs]: https://org-roam.readthedocs.io/
[docs]: https://org-roam.github.io/org-roam/manual/
[discourse]: https://org-roam.discourse.group/
[slack]: https://join.slack.com/t/orgroam/shared_invite/zt-deoqamys-043YQ~s5Tay3iJ5QRI~Lxg

106
default.mk Normal file
View File

@ -0,0 +1,106 @@
TOP := $(dir $(lastword $(MAKEFILE_LIST)))
## User options ######################################################
#
# You can override these settings in "config.mk" or on the command
# line.
#
# You might also want to set LOAD_PATH. If you do, then it must
# contain "-L .".
#
# If you don't do so, then the default is set in the "Load-Path"
# section below. The default assumes that all dependencies are
# installed either at "../<DEPENDENCY>", or when using package.el
# at "ELPA_DIR/<DEPENDENCY>-<HIGHEST-VERSION>".
sharedir ?= $(HOME)/.local/share
lispdir ?= $(sharedir)/emacs/site-lisp/org-roam
infodir ?= $(sharedir)/info
docdir ?= $(sharedir)/doc/org-roam
statsdir ?= $(TOP)/doc/stats
CP ?= install -p -m 644
MKDIR ?= install -p -m 755 -d
RMDIR ?= rm -rf
TAR ?= tar
SED ?= sed
EMACSBIN ?= emacs
BATCH = $(EMACSBIN) -Q --batch $(LOAD_PATH)
INSTALL_INFO ?= $(shell command -v ginstall-info || printf install-info)
MAKEINFO ?= makeinfo
MANUAL_HTML_ARGS ?= --css-ref /assets/page.css
## Files #############################################################
PKG = org-roam
PACKAGES = org-roam
TEXIPAGES = $(addsuffix .texi,$(PACKAGES))
INFOPAGES = $(addsuffix .info,$(PACKAGES))
HTMLFILES = $(addsuffix .html,$(PACKAGES))
HTMLDIRS = $(PACKAGES)
PDFFILES = $(addsuffix .pdf,$(PACKAGES))
EPUBFILES = $(addsuffix .epub,$(PACKAGES))
ELS = org-roam-buffer.el
ELS += org-roam-capture.el
ELS += org-roam-compat.el
ELS += org-roam-completion.el
ELS += org-roam-dailies.el
ELS += org-roam-db.el
ELS += org-roam.el
ELS += org-roam-graph.el
ELS += org-roam-macs.el
ELS += org-roam-protocol.el
ELCS = $(ELS:.el=.elc)
ELMS = org-roam.el $(filter-out $(addsuffix .el,$(PACKAGES)),$(ELS))
ELGS = org-roam-autoloads.el org-roam-version.el
## Versions ##########################################################
VERSION ?= $(shell test -e $(TOP).git && git describe --tags --abbrev=0 | cut -c2-)
EMACS_VERSION = 26.1
EMACSOLD := $(shell $(BATCH) --eval \
"(and (version< emacs-version \"$(EMACS_VERSION)\") (princ \"true\"))")
ifeq "$(EMACSOLD)" "true"
$(error At least version $(EMACS_VERSION) of Emacs is required)
endif
## Load-Path #########################################################
ifndef LOAD_PATH
ELPA_DIR ?= $(HOME)/.emacs.d/elpa
SYSTYPE := $(shell $(EMACSBIN) -Q --batch --eval "(princ system-type)")
ifeq ($(SYSTYPE), windows-nt)
CYGPATH := $(shell cygpath --version 2>/dev/null)
endif
LOAD_PATH = -L $(TOP)
# When making changes here, then don't forget to adjust "Makefile",
# ".travis.yml", ".github/ISSUE_TEMPLATE/bug_report.md",
# `magit-emacs-Q-command' and the "Installing from the Git Repository"
# info node accordingly. Also don't forget to "rgrep \b<pkg>\b".
endif # ifndef LOAD_PATH
ifndef ORG_LOAD_PATH
ORG_LOAD_PATH = $(LOAD_PATH)
ORG_LOAD_PATH += -L $(TOP)../ox-texinfo-plus
ORG_LOAD_PATH += -L $(TOP)../org-mode/contrib/lisp
ORG_LOAD_PATH += -L $(TOP)../org-mode/lisp
endif
## Publish ###########################################################
PUBLISH_TARGETS ?= html html-dir pdf epub
DOCBOOK_XSL ?= /usr/share/xml/docbook/stylesheet/docbook-xsl/epub/docbook.xsl
EPUBTRASH = epub.xml META-INF OEBPS

0
doc/.nojekyll Normal file
View File

37
doc/AUTHORS.md Normal file
View File

@ -0,0 +1,37 @@
Authors
=======
The following people have contributed to Org-Roam.
Names below are sorted alphabetically.
Author
------
- Jethro Kuan <jethrokuan95@gmail.com>
Maintainers
----------
- Jethro Kuan <jethrokuan95@gmail.com>
- Leo Vivier <leo.vivier+dev@gmail.com>
Contributors
------------
- Alexey Shmalko <rasen.dubi@gmail.com>
- James Ravn <james@r-vn.org>
- Jethro Kuan <jethrokuan95@gmail.com>
- Johann Klähn <johann@jklaehn.de>
- Josh English <josh@joshenglish.com>
- Jürgen Hötzel <juergen@archlinux.org>
- Langston Barrett <langston.barrett@gmail.com>
- Leo Vivier <leo.vivier+dev@gmail.com>
- Michael Glaesemann <grzm@seespotcode.net>
- Michael Herold <github@michaeljherold.com>
- Noboru <noboru.ota@gmail.com>
- N V <44036031+progfolio@users.noreply.github.com>
- Rafael Accácio Nogueira <raccacio@poli.ufrj.br>
- Roland Coeurjoly <rolandcoeurjoly@gmail.com>
- Sayan <dit7ya@users.noreply.github.com>
- Tim Quelch <tim@quelch.name>

130
doc/Makefile Normal file
View File

@ -0,0 +1,130 @@
-include ../config.mk
include ../default.mk
###################################################################
MANUAL_HTML_ARGS = --css-ref assets/page.css
.PHONY: texi install clean AUTHORS.md stats
all: info
## Build #############################################################
info: $(INFOPAGES) dir
html: $(HTMLFILES)
pdf: $(PDFFILES)
epub: $(EPUBFILES)
%.info: %.texi
@printf "Generating $@\n"
@$(MAKEINFO) --no-split $< -o $@
dir: org-roam.info
@printf "Generating dir\n"
@echo $^ | xargs -n 1 $(INSTALL_INFO) --dir=$@
%.html: %.texi
@printf "Generating $@\n"
@$(MAKEINFO) --html --no-split $(MANUAL_HTML_ARGS) $<
html-dir:
@printf "Generating org-roam/*.html\n"
@$(MAKEINFO) --html $(MANUAL_HTML_ARGS) org-roam.texi
mv org-roam manual
cp -r assets manual
cp -r images manual
%.pdf: %.texi
@printf "Generating $@\n"
@texi2pdf --clean $< > /dev/null
%.epub: %.texi
@printf "Generating $@\n"
@$(MAKEINFO) --docbook $< -o epub.xml
@xsltproc $(DOCBOOK_XSL) epub.xml 2> /dev/null
@echo "application/epub+zip" > mimetype
@zip -X --quiet --recurse-paths -0 $@ mimetype
@zip -X --quiet --recurse-paths -9 --no-dir-entries $@ META-INF OEBPS
@$(RMDIR) $(EPUBTRASH)
## Install ###########################################################
install: install-info install-docs
install-docs: install-info
@$(MKDIR) $(DESTDIR)$(docdir)
$(CP) AUTHORS.md $(DESTDIR)$(docdir)
install-info: info
@$(MKDIR) $(DESTDIR)$(infodir)
$(CP) $(INFOPAGES) $(DESTDIR)$(infodir)
## Clean #############################################################
clean:
@printf "Cleaning doc/*...\n"
@$(RMDIR) dir $(INFOPAGES) $(HTMLFILES) $(HTMLDIRS) $(PDFFILES)
@$(RMDIR) $(EPUBFILES) $(EPUBTRASH)
## Release management ################################################
ORG_ARGS = --batch -Q $(ORG_LOAD_PATH)
ORG_ARGS += -l ox-extra -l ox-texinfo+
ORG_ARGS += --eval "(or (require 'org-man nil t) (require 'ol-man))"
ORG_EVAL = --eval "(ox-extras-activate '(ignore-headlines))"
ORG_EVAL += --eval "(setq indent-tabs-mode nil)"
ORG_EVAL += --eval "(setq org-src-preserve-indentation nil)"
ORG_EVAL += --funcall org-texinfo-export-to-texinfo
# This target first bumps version strings in the Org source. The
# necessary tools might be missing so other targets do not depend
# on this target and it has to be run explicitly when appropriate.
#
# AMEND=t make texi Update manual to be amended to HEAD.
# VERSION=N make texi Update manual for release.
#
texi:
@$(EMACSBIN) $(ORG_ARGS) $(PKG).org $(ORG_EVAL)
@printf "\n" >> $(PKG).texi
@rm -f $(PKG).texi~
stats:
@printf "Generating statistics\n"
@gitstats -c style=/assets/stats.css -c max_authors=999 $(TOP) $(statsdir)
authors: AUTHORS.md
AUTHORS.md:
@printf "Generating AUTHORS.md..."
@test -e $(TOP).git \
&& (printf "$$AUTHORS_HEADER\n" > $@ \
&& git log --pretty=format:'- %aN <%aE>' | sort -u >> $@ \
&& printf "done\n" ; ) \
|| printf "FAILED (non-fatal)\n"
# Templates ##########################################################
define AUTHORS_HEADER
Authors
=======
The following people have contributed to Org-Roam.
Names below are sorted alphabetically.
Author
------
- Jethro Kuan <jethrokuan95@gmail.com>
Maintainers
----------
- Jethro Kuan <jethrokuan95@gmail.com>
- Leo Vivier <leo.vivier+dev@gmail.com>
Contributors
------------
endef
export AUTHORS_HEADER

View File

@ -1,41 +0,0 @@
The bulk of Org-roam's functionality is built on top of vanilla
Org-mode. However, to support additional functionality, Org-roam adds
several Org-roam-specific keywords. These functionality are not
crucial to effective use of Org-roam.
## File Aliases
Suppose you want a note to be referred to by different names (e.g.
"World War 2", "WWII"). You may specify such aliases using the
`#+ROAM_ALIAS` attribute:
```org
#+TITLE: World War 2
#+ROAM_ALIAS: "WWII" "World War II"
```
## File Refs
Refs are unique identifiers for files. Each note can only have 1 ref.
For example, a note for a website may contain a ref:
```org
#+TITLE: Google
#+ROAM_KEY: https://www.google.com/
```
These keys come in useful for when taking website notes, using the
`roam-ref` protocol (see [Roam Protocol](roam_protocol.md)).
Alternatively, add a ref for notes for a specific paper, using its
[org-ref](https://github.com/jkitchin/org-ref) citation key:
```org
#+TITLE: Neural Ordinary Differential Equations
#+ROAM_KEY: cite:chen18_neural_ordin_differ_equat
```
The backlinks buffer will show any cites of this key: e.g.
![org-ref-citelink](images/org-ref-citelink.png)

442
doc/assets/page.css Normal file
View File

@ -0,0 +1,442 @@
/* Import Inter font */
/* More info at https://github.com/xz/fonts */
@import url("https://fonts.xz.style/serve/inter.css");
:root {
--nc-font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
--nc-font-mono: "Courier New", Courier, "Ubuntu Mono", "Liberation Mono",
monospace;
--nc-tx-1: #000000;
--nc-tx-2: #1a1a1a;
--nc-bg-1: #ffffff;
--nc-bg-2: #f6f8fa;
--nc-bg-3: #e5e7eb;
--nc-lk-1: #0070f3;
--nc-lk-2: #0366d6;
--nc-lk-tx: #ffffff;
--nc-ac-1: #79ffe1;
--nc-ac-tx: #0c4047;
}
@media (prefers-color-scheme: dark) {
:root {
--nc-tx-1: #ffffff;
--nc-tx-2: #eeeeee;
--nc-bg-1: #000000;
--nc-bg-2: #111111;
--nc-bg-3: #222222;
--nc-lk-1: #3291ff;
--nc-lk-2: #0070f3;
--nc-lk-tx: #ffffff;
--nc-ac-1: #7928ca;
--nc-ac-tx: #ffffff;
}
}
* {
/* Reset margins and padding */
margin: 0;
padding: 0;
}
address,
area,
article,
aside,
audio,
blockquote,
datalist,
details,
dl,
fieldset,
figure,
form,
input,
iframe,
img,
meter,
nav,
ol,
optgroup,
option,
output,
p,
pre,
progress,
ruby,
section,
table,
textarea,
ul,
video {
/* Margins for most elements */
margin-bottom: 1rem;
}
html,
input,
select,
button {
/* Set body font family and some finicky elements */
font-family: var(--nc-font-sans);
}
body {
/* Center body in page */
margin: 0 auto;
max-width: 750px;
padding: 2rem;
border-radius: 6px;
overflow-x: hidden;
background: var(--nc-bg-1);
/* Main body text */
color: var(--nc-tx-2);
font-size: 1.03rem;
line-height: 1.5;
}
::selection {
/* Set background color for selected text */
background: var(--nc-ac-1);
color: var(--nc-ac-tx);
}
p {
margin-bottom: 1rem;
}
h1,
h2,
h3,
h4,
h5,
h6 {
line-height: 1;
color: var(--nc-tx-1);
padding-top: 0.875rem;
}
h1,
h2,
h3 {
color: var(--nc-tx-1);
padding-bottom: 2px;
margin-bottom: 8px;
border-bottom: 1px solid var(--nc-bg-2);
}
h4,
h5,
h6 {
margin-bottom: 0.3rem;
}
h1 {
font-size: 2.25rem;
}
h2 {
font-size: 1.85rem;
}
h3 {
font-size: 1.55rem;
}
h4 {
font-size: 1.25rem;
}
h5 {
font-size: 1rem;
}
h6 {
font-size: 0.875rem;
}
a {
color: var(--nc-lk-1);
}
a:hover {
color: var(--nc-lk-2);
}
abbr:hover {
/* Set the '?' cursor while hovering an abbreviation */
cursor: help;
}
blockquote {
padding: 1.5rem;
background: var(--nc-bg-2);
border-left: 5px solid var(--nc-bg-3);
}
abbr {
cursor: help;
}
blockquote *:last-child {
padding-bottom: 0;
margin-bottom: 0;
}
header {
background: var(--nc-bg-2);
border-bottom: 1px solid var(--nc-bg-3);
padding: 2rem 1.5rem;
/* This sets the right and left margins to cancel out the body's margins. It's width is still the same, but the background stretches across the page's width. */
margin: -2rem calc(0px - (50vw - 50%)) 2rem;
/* Shorthand for:
margin-top: -2rem;
margin-bottom: 2rem;
margin-left: calc(0px - (50vw - 50%));
margin-right: calc(0px - (50vw - 50%)); */
padding-left: calc(50vw - 50%);
padding-right: calc(50vw - 50%);
}
header h1,
header h2,
header h3 {
padding-bottom: 0;
border-bottom: 0;
}
header > *:first-child {
margin-top: 0;
padding-top: 0;
}
header > *:last-child {
margin-bottom: 0;
}
.button,
button,
input[type="submit"],
input[type="reset"],
input[type="button"] {
font-size: 1rem;
display: inline-block;
padding: 6px 12px;
text-align: center;
text-decoration: none;
white-space: nowrap;
background: var(--nc-lk-1);
color: var(--nc-lk-tx);
border: 0;
border-radius: 4px;
box-sizing: border-box;
cursor: pointer;
color: var(--nc-lk-tx);
}
.button[disabled],
button[disabled],
input[type="submit"][disabled],
input[type="reset"][disabled],
input[type="button"][disabled] {
cursor: default;
opacity: 0.5;
/* Set the [X] cursor while hovering a disabled link */
cursor: not-allowed;
}
.button:focus,
.button:hover,
button:focus,
button:hover,
input[type="submit"]:focus,
input[type="submit"]:hover,
input[type="reset"]:focus,
input[type="reset"]:hover,
input[type="button"]:focus,
input[type="button"]:hover {
background: var(--nc-lk-2);
}
code,
pre,
kbd,
samp {
/* Set the font family for monospaced elements */
font-family: var(--nc-font-mono);
}
code,
samp,
kbd,
pre {
/* The main preformatted style. This is changed slightly across different cases. */
background: var(--nc-bg-2);
border: 1px solid var(--nc-bg-3);
border-radius: 4px;
padding: 3px 6px;
font-size: 0.9rem;
}
kbd {
/* Makes the kbd element look like a keyboard key */
border-bottom: 3px solid var(--nc-bg-3);
}
pre {
padding: 1rem 1.4rem;
max-width: 100%;
overflow: auto;
}
pre code {
/* When <code> is in a <pre>, reset it's formatting to blend in */
background: inherit;
font-size: inherit;
color: inherit;
border: 0;
padding: 0;
margin: 0;
}
code pre {
/* When <pre> is in a <code>, reset it's formatting to blend in */
display: inline;
background: inherit;
font-size: inherit;
color: inherit;
border: 0;
padding: 0;
margin: 0;
}
details {
/* Make the <details> look more "clickable" */
padding: 0.6rem 1rem;
background: var(--nc-bg-2);
border: 1px solid var(--nc-bg-3);
border-radius: 4px;
}
summary {
/* Makes the <summary> look more like a "clickable" link with the pointer cursor */
cursor: pointer;
font-weight: bold;
}
details[open] {
/* Adjust the <details> padding while open */
padding-bottom: 0.75rem;
}
details[open] summary {
/* Adjust the <details> padding while open */
margin-bottom: 6px;
}
details[open] > *:last-child {
/* Resets the bottom margin of the last element in the <details> while <details> is opened. This prevents double margins/paddings. */
margin-bottom: 0;
}
dt {
font-weight: bold;
}
dd::before {
/* Add an arrow to data table definitions */
content: "→ ";
}
hr {
/* Reset the border of the <hr> separator, then set a better line */
border: 0;
border-bottom: 1px solid var(--nc-bg-3);
margin: 1rem auto;
}
fieldset {
margin-top: 1rem;
padding: 2rem;
border: 1px solid var(--nc-bg-3);
border-radius: 4px;
}
legend {
padding: auto 0.5rem;
}
textarea {
/* Don't let the <textarea> extend off the screen naturally or when dragged by the user */
max-width: 100%;
}
ol,
ul {
/* Replace the browser default padding */
padding-left: 2rem;
}
li {
margin-top: 0.4rem;
}
ul ul,
ol ul,
ul ol,
ol ol {
margin-bottom: 0;
}
mark {
padding: 3px 6px;
background: var(--nc-ac-1);
color: var(--nc-ac-tx);
}
textarea,
select,
input {
padding: 6px 12px;
margin-bottom: 0.5rem;
background: var(--nc-bg-2);
color: var(--nc-tx-2);
/* Set a border of the same color as the main background. It isn't visible on idle, but prevents the cell from growing in size when a darker border is set on focus. */
border: 1px solid var(--nc-bg-2);
border-radius: 4px;
box-shadow: none;
box-sizing: border-box;
}
textarea:focus,
select:focus,
input[type]:focus {
border: 1px solid var(--nc-bg-3);
/* Reset any browser default outlines */
outline: 0;
}
img {
max-width: 100%;
}
/* Customizations */
.menu-comment {
font-weight: bold;
border: 0;
margin: 0;
padding: 0;
font-size: 1.2rem;
}

View File

@ -1,11 +0,0 @@
---
title: "Comparing Org-roam With Other Packages"
metaTitle: "Comparing Org-roam With Other Packages"
metaDescription: "Comparing Org-roam With Other Packages"
---
# Org-brain
# Zetteldeft
# Org-zettelkasten

View File

@ -1,142 +0,0 @@
The number of configuration options is deliberately kept small, to
keep the Org-roam codebase manageable. However, we attempt to
accommodate as many usage styles as possible.
All of Org-roam's customization options can be viewed via `M-x
customize-group org-roam`.
## Setting the Org-roam Directory
Set `org-roam-directory` to the folder containing all your Org files:
```emacs-lisp
(setq org-roam-directory "/path/to/org/")
```
Every Org file, at any level of nesting, within `/path/to/org/` is
considered part of the Org-roam ecosystem.
### Having More Than One Org-roam Directory
Emacs supports directory-local variables, allowing the value of
`org-roam-directory` to be different in different directories. It does
this by checking for a file named `.dir-locals.el`.
To add support for multiple directories, override the
`org-roam-directory` variable using directory-local variables. This is
what `.dir-locals.el` may contain:
```emacs-lisp
((nil . ((org-roam-directory . "/path/to/here/"))))
```
All files within that directory will be treated as their own separate
set of Org-roam files. Remember to run `org-roam-db-build-cache` from a
file within that directory, at least once.
## Org-roam Buffer
The Org-roam buffer defaults to popping up from the right. You may
choose to set it to pop up from the left with `(setq
org-roam-buffer-position 'left)`.
The Org-roam buffer name can also be renamed: e.g. `(setq
org-roam-buffer "*my-buffer-name*")`.
The Org-roam buffer width is adjustable via `org-roam-buffer-width`.
The value of `org-roam-buffer-width` set as a percentage of the total
frame width. For example:
```emacs-lisp
(setq org-roam-buffer-width 0.4)
```
Will result in the Org-roam buffer taking up 40% of the screen width.
You can change backlinks appearance in the buffer by customizing
`org-roam-backlink` face (`M-x customize-face org-roam-backlink`).
## Org-roam Links
By default, links are inserted with the title as the link description.
This can make them hard to distinguish from external links. You may
choose add special indicators for Org-roam links by tweaking
`org-roam-link-title-format`, for example:
```emacs-lisp
(setq org-roam-link-title-format "R:%s")
```
If your version of Org is at least `9.2`, you may also choose to
simply style the link differently, by customizing `org-roam-link` face
(`M-x customize-face org-roam-link`).
## Org-roam Files
Org-roam files are created and prefilled using Org-roam's templating
system. The templating system is customizable, and the system is
described in detail in the [Org-roam Template](templating.md) page.
### Encryption
Encryption (via GPG) can be enabled for all new files by setting
`org-roam-encrypt-files` to `t`. When enabled, new files are created
with the `.org.gpg` extension and decryption are handled automatically
by EasyPG.
Note that Emacs will prompt for a password for encrypted files during
cache updates if it requires reading the encrypted file. To reduce the
number of password prompts, you may wish to cache the password.
## Org-roam Graph Viewer
Org-roam generates an SVG image using
[Graphviz](https://graphviz.org/). To setup graph navigation, see the
[Graph Setup](graph_setup.md) page.
Org-roam tries its best to locate the Graphviz executable from your
`PATH`, but if it fails to do so, you may set it manually:
```
(setq org-roam-graph-executable "/path/to/dot")
```
You may also choose to use `neato` in place of `dot`, which generates a more compact graph layout.
```
(setq org-roam-graph-executable "/path/to/neato")
(setq org-roam-graph-extra-config '(("overlap" . "false")))
```
Org-roam also attempts to use Firefox (located on `PATH`) to view the
SVG, you may choose to set it to any compatible program:
```
(setq org-roam-graph-viewer "/path/to/image-viewer")
```
### Excluding Nodes and Edges
One may want to exclude certain files to declutter the graph. You can do so by setting `org-roam-graph-exclude-matcher`.
```
(setq org-roam-graph-exclude-matcher '("private" "dailies"))
```
This setting excludes all files whose path contain "private" or "dailies".
## Org-roam Completion System
Org-roam offers completion when choosing note titles etc.
The completion system is configurable. The default setting,
```
(setq org-roam-completion-system 'default)
```
uses Emacs' standard `completing-read`. If you prefer [Helm](https://emacs-helm.github.io/helm/), use
```
(setq org-roam-completion-system 'helm)
```
Other options included `'ido`, and `'ivy'`.

View File

@ -1,134 +0,0 @@
A number of packages work well combined with Org-Roam:
## Deft
[Deft][deft] provides a nice interface for browsing and filtering
org-roam notes.
```emacs-lisp
(use-package deft
:after org
:bind
("C-c n d" . deft)
:custom
(deft-recursive t)
(deft-use-filter-string-for-filename t)
(deft-default-extension "org")
(deft-directory "/path/to/org-roam-files/"))
```
If the title of the Org file is not the first line, you might not get
nice titles. You may choose to patch this to use `org-roam`'s
functionality. Here I'm using [el-patch](https://github.com/raxod502/el-patch):
```emacs-lisp
(use-package el-patch
:straight (:host github
:repo "raxod502/el-patch"
:branch "develop"))
(eval-when-compile
(require 'el-patch))
(use-package deft
;; same as above...
:config/el-patch
(defun deft-parse-title (file contents)
"Parse the given FILE and CONTENTS and determine the title.
If `deft-use-filename-as-title' is nil, the title is taken to
be the first non-empty line of the FILE. Else the base name of the FILE is
used as title."
(el-patch-swap (if deft-use-filename-as-title
(deft-base-filename file)
(let ((begin (string-match "^.+$" contents)))
(if begin
(funcall deft-parse-title-function
(substring contents begin (match-end 0))))))
(org-roam--get-title-or-slug file))))
```
The Deft interface can slow down quickly when the number of files get
huge. [Notdeft][notdeft] is a fork of Deft that uses an external
search engine and indexer.
## Org-journal
[Org-journal](https://github.com/bastibe/org-journal) is a more powerful
alternative to the simple function `org-roam-dailies-today`. It provides better
journaling capabilities, and a nice calendar interface to see all dated entries.
```emacs-lisp
(use-package org-journal
:bind
("C-c n j" . org-journal-new-entry)
:custom
(org-journal-date-prefix "#+TITLE: ")
(org-journal-file-format "%Y-%m-%d.org")
(org-journal-dir "/path/to/org-roam-files/")
(org-journal-date-format "%A, %d %B %Y"))
```
## Note-taking Add-ons
These are some plugins that make note-taking in Org-mode more
enjoyable.
### Org-download
[Org-download][org-download] lets you screenshot and yank images from
the web into your notes:
![org-download](images/org-download.gif)
```emacs-lisp
(use-package org-download
:after org
:bind
(:map org-mode-map
(("s-Y" . org-download-screenshot)
("s-y" . org-download-yank))))
```
### mathpix.el
[mathpix.el][mathpix-el] uses [Mathpix's](https://mathpix.com/) API to convert clips into
latex equations:
![mathpix](images/mathpix.gif)
```emacs-lisp
(use-package mathpix.el
:straight (:host github :repo "jethrokuan/mathpix.el")
:custom ((mathpix-app-id "app-id")
(mathpix-app-key "app-key"))
:bind
("C-x m" . mathpix-screenshot))
```
### Org-noter / Interleave
[Org-noter][org-noter] and [Interleave][interleave] are both projects
that allow synchronised annotation of documents (PDF, EPUB etc.)
within Org-mode.
### Org-ref
[Org-ref][org-ref] does citation and bibliography management in
Org-mode, and a great tool for scientific notes.
### Spaced Repetition
[Org-fc][org-fc] is a spaced repetition system that scales well with a
large number of files. Other alternatives include
[org-drill][org-drill], and [pamparam][pamparam].
[deft]: https://jblevins.org/projects/deft/
[notdeft]: https://github.com/hasu/notdeft
[org-download]: https://github.com/abo-abo/org-download
[mathpix-el]: https://github.com/jethrokuan/mathpix.el
[org-noter]: https://github.com/weirdNox/org-noter
[interleave]: https://github.com/rudolfochrist/interleave
[org-ref]: https://github.com/jkitchin/org-ref
[org-fc]: https://github.com/l3kn/org-fc/
[org-drill]: https://orgmode.org/worg/org-contrib/org-drill.html
[pamparam]: https://github.com/abo-abo/pamparam

15
doc/htmlxref.cnf Normal file
View File

@ -0,0 +1,15 @@
# https://www.gnu.org/software/texinfo/manual/texinfo/html_node/HTML-Xref-Configuration.html
EMACS = https://www.gnu.org/software/emacs/manual
auth mono ${EMACS}/html_mono/auth.html
auth node ${EMACS}/html_node/auth/
ediff mono ${EMACS}/html_mono/ediff.html
ediff node ${EMACS}/html_node/ediff/
elisp mono ${EMACS}/html_mono/elisp.html
elisp node ${EMACS}/html_node/elisp/
emacs mono ${EMACS}/html_mono/emacs.html
emacs node ${EMACS}/html_node/emacs/

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

3
doc/index.html Normal file
View File

@ -0,0 +1,3 @@
<html>
<h1>--> <a href="manual/index.html">MANUAL HERE</a> <--</h1>
</html>

View File

@ -1,62 +0,0 @@
![org-roam][org-roam-intro-image]
## What is Org-roam?
Org-roam is a [Roam][roamresearch] replica built around the
all-powerful [Org-mode][org].
Org-roam is a solution for effortless non-hierarchical note-taking
with Org-mode. With Org-roam, notes flow naturally, making note-taking
fun and easy. Org-roam should also work as a plug-and-play solution
for anyone already using Org-mode for their personal wiki.
To understand more about Roam, a collection of links are available in
[the appendix](notetaking_workflow.md).
Org-roam aims to implement the core features of Roam, leveraging the
mature ecosystem around Org-mode where possible. Eventually, we hope
to further introduce features enabled by the Emacs ecosystem.
## Why use Org-roam?
##### Private and Secure
Edit your personal wiki completely offline, entirely in your control.
Encrypt your notes with GPG.
##### Longevity
Unlike web solutions like Roam research, the notes are first and
foremost plain Org-mode files -- Org-roam simply builds up an
auxilliary database to give the personal wiki superpowers. Having your
notes in plain-text is crucial for the longevity of your wiki. Never
have to worry about proprietary web solutions being taken down. Edit
your plain-text notes in notepad if all other editors cease to exist.
##### Free and Open-source
Org-roam is free and open-source, which means that if you feel unhappy
with any part of Org-roam, you may choose to extend Org-roam, or open
a PR.
##### Leverage the Org-mode Ecosystem
Over the years, Emacs and Org-mode has developed into a mature system
for plain-text organization. Building upon Org-mode already puts
Org-roam light-years ahead of many other solutions.
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.
There are several packages that are similar to Org-roam, see the
[Comparison](comparison.md) page for a detailed comparison.
## Project Status
As of March 2020, most of the core functionality and interfaces have
stabilized, and a stable release is near.
[org-roam-intro-image]: images/org-roam-intro.png
[roamresearch]: https://www.roamresearch.com/
[org]: https://orgmode.org/

View File

@ -1,195 +0,0 @@
## Basic Install and Configuration
Org-roam is now available on MELPA, so you can install it via the following
command:
```
M-x package-install RET org-roam RET
```
Alternatively, you may use package managers such as [straight][straight] or
[quelpa][quelpa] to install the package.
The recommended method of configuration is to use [use-package][use-package].
```emacs-lisp
(use-package org-roam
:hook
(after-init . org-roam-mode)
:custom
(org-roam-directory "/path/to/org-files/")
:bind (:map org-roam-mode-map
(("C-c n l" . org-roam)
("C-c n f" . org-roam-find-file)
("C-c n b" . org-roam-switch-to-buffer)
("C-c n g" . org-roam-graph))
:map org-mode-map
(("C-c n i" . org-roam-insert))))
```
Or without `use-package`:
```emacs-lisp
(require 'org-roam)
(define-key org-roam-mode-map (kbd "C-c n l") #'org-roam)
(define-key org-roam-mode-map (kbd "C-c n f") #'org-roam-find-file)
(define-key org-roam-mode-map (kbd "C-c n b") #'org-roam-switch-to-buffer)
(define-key org-roam-mode-map (kbd "C-c n g") #'org-roam-graph)
(define-key org-mode-map (kbd "C-c n i") #'org-roam-insert)
(org-roam-mode +1)
```
The [Configuration](configuration.md) page details some of the common
configuration options available.
### Completion
Link auto-completion is offered via
[company-org-roam](https://github.com/jethrokuan/company-org-roam/), refer to
the documentation there for further details.
## Spacemacs
If you are using Spacemacs, install org-roam by creating a simple layer that
wraps Org-roam. Paste the following into a new file
`~/.emacs.d/private/org-roam/packages.el`.
```emacs-lisp
(defconst org-roam-packages
'(org-roam))
(defun org-roam/init-org-roam ()
(use-package org-roam
:hook
(after-init . org-roam-mode)
:custom
(org-roam-directory "/path/to/org-files/")
:init
(progn
(spacemacs/declare-prefix "ar" "org-roam")
(spacemacs/set-leader-keys
"arl" 'org-roam
"art" 'org-roam-dailies-today
"arf" 'org-roam-find-file
"arg" 'org-roam-graph)
(spacemacs/declare-prefix-for-mode 'org-mode "mr" "org-roam")
(spacemacs/set-leader-keys-for-major-mode 'org-mode
"rl" 'org-roam
"rt" 'org-roam-dailies-today
"rb" 'org-roam-switch-to-buffer
"rf" 'org-roam-find-file
"ri" 'org-roam-insert
"rg" 'org-roam-graph))))
```
Next, append `org-roam` to the `dotspacemacs-configuration-layers`
list in your `.spacemacs` configuration file. Reload (`SPC f e R`) or
restart Emacs to load `org-roam`. It's functions are available under
the prefix `SPC a r` and `, r` when visiting an org-mode buffer.
If you also have the ranger layer installed, the prefix 'ar' conflict
with that of the ranger layer. You might want to change it to 'aor'
(also change the 'ar' to 'aor' in the other key-binding declarations)
## Doom Emacs
[Doom Emacs][doom] has a `+roam` flag on its `org` module for easy
installation and configuration. Simply add the flag to the `org` section
of your `~/.doom.d/init.el` and run `~/.emacs.d/bin/doom sync`.
[use-package]: https://github.com/jwiegley/use-package
[straight]: https://github.com/raxod502/straight.el
[quelpa]: https://github.com/quelpa/quelpa
[doom]: https://github.com/hlissner/doom-emacs
[doom-getting-started]: https://github.com/hlissner/doom-emacs/blob/develop/docs/getting_started.org#configuring-packages
## Windows
On Windows, if you follow the installation instructions above, you will likely get the error message: **"No EmacSQL SQLite binary available, aborting"**, and `org-roam` won't start properly.
You need to do some additional steps to get `org-roam` to work.
Essentially, you will need to have a binary file for `emacsql-sqlite` so that your Emacs can work with `sqlite` database -- `org-roam` uses it to track backlinks. The following options have been reported to work by Windows users in the community.
Option 1. **Windows Subsystem for Linux (WSL)**
: This option lets you use Linux on your Windows machine. It's Linux, so you don't need to do anything specific for Windows.
Option 2. **mingw-x64**
: Use mingw-x64. You would spend a bit of time to download it, and get familiar with how it works. You should be able to use Linux tools within your Windows [more contribution welcome].
Option 3. **scoop**
: Use [scoop](https://scoop.sh/) to install a couple of software tools (make and gcc) and manually compile a binary (`.exe`) file yourself. Find a short step-by-step guide below.
Option 4. **emacsql-sqlite3**
: Use another Emacs package called [`emacsql-sqlite3`](https://github.com/cireu/emacsql-sqlite3). You can download an [official binary](https://sqlite.org/download.html) for `sqlite3`. `emacsql-sqlite3` lets you use it. For this option to work, you need to adjust the `org-roam` source code, and get your modified version to work in your Emacs environment. Find a suggestion below.
### scoop
**Step 1.** In PowerShell, install `scoop` ([instruction here](https://scoop.sh/)).
```powershell
iwr -useb get.scoop.sh | iex
```
**Step 2.** In PowerShell, install `make` and `gcc` via scoop
```powershell
scoop install make gcc
```
**Step 3.** In Emacs, install the `emacsql-sqlite` package for your Emacs if it is not done yet.
**Step 4.** In PowerShell, move to the directory where `emacsql.c` is stored.
With MELPA, it is likely to be under your ELPA folder:
```
~\AppData\Roaming\.emacs.d\elpa\emacsql-sqlite-20190727.1710\sqlite
```
With Doom Emacs, it should be under your `.emacs\.local`:
```
~\.emacs.d\.local\straight\build\emacsql-sqlite\sqlite
```
Check the files via `dir` command. You should see these files:
```powershell
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 22/03/2020 12:10 PM 5170 emacsql.c
-a---- 22/03/2020 12:10 PM 439 Makefile
-a---- 22/03/2020 12:10 PM 7516138 sqlite3.c
-a---- 22/03/2020 12:10 PM 526684 sqlite3.h
```
**Step 5.** Compile the `.exe` file with `make`
```powershell
make emacsql-sqlite CC=gcc LDLIBS=
```
You will see the process triggered with lots of text automatically scrolling down; it may take a couple of minutes for compilation to finish.
Once compilation is done, check that `emacsql-sqlite.exe` has been added to the directory.
**Step 6.** Relaunch Emacs, use `org-roam`
When you start `org-roam` (e.g. via `org-roam-mode`), now you should no longer see the "No EmacSQL SQLite binary available, aborting" error. You are good to go.
### emacsql-sqlite3
1. In Emacs, install the `emacsql-sqlite3` package
2. Using your text editor, etc. modify `org-roam-db.el`:
1. Replace `(require 'emacsql-sqlite)` with `(require 'emacsql-sqlite3)`
2. Comment/deactivate the complete `(defconst org-roam-db--sqlite-available-p ... )`
3. In `(defun org-roam-db ...`, replace `emacsql-sqlite`
with `emacsql-sqlite3`
3. If you compile `.el` files, ensure to replace `org-roam-db.elc` with the new source you modified.

View File

@ -1,24 +0,0 @@
## Recommended Books
- [How to Take Smart Notes][1]
## Articles
- [How to Take Smart Notes in Org-mode - Jethro Kuan][7]
- [The Zettelkasten Method - LessWrong 2.0][3]
- [Building a second brain in Roam][4]
- [Roam: Why I Love It and How I Use It][5]
- [Adam Keesling's Twitter Thread][6]
## Threads
- [Ask HN: How to Take Good Notes][8]
## What to Do With Your Notes
- [How to Use Roam to Outline a New Article in Under 20 Minutes][2]
[1]: https://www.goodreads.com/book/show/34507927-how-to-take-smart-notes?ac=1&from_search=true&qid=6L8iEE1FIA&rank=1
[2]: https://www.youtube.com/watch?v=RvWic15iXjk
[3]: https://www.lesswrong.com/posts/NfdHG6oHBJ8Qxc26s/the-zettelkasten-method-1
[4]: https://reddit.com/r/RoamResearch/comments/eho7de/building_a_second_brain_in_roamand_why_you_might
[5]: https://www.nateliason.com/blog/roam
[6]: https://twitter.com/adam_keesling/status/1196864424725774336?s=20
[7]: https://blog.jethro.dev/posts/how_to_take_smart_notes_org/
[8]: https://news.ycombinator.com/item?id=22473209

974
doc/org-roam.org Normal file
View File

@ -0,0 +1,974 @@
#+TITLE: Org-roam User Manual
:PREAMBLE:
#+AUTHOR: Jethro Kuan
#+EMAIL: jethrokuan95@gmail.com
#+DATE: 2020-2020
#+LANGUAGE: en
#+TEXINFO_DIR_CATEGORY: Emacs
#+TEXINFO_DIR_TITLE: Org-roam: (org-roam).
#+TEXINFO_DIR_DESC: Rudimentary Roam Replica for Emacs.
#+SUBTITLE: for version 1.1.1
#+OPTIONS: H:4 num:3 toc:2 creator:t
#+PROPERTY: header-args :eval never
#+TEXINFO: @noindent
This manual is for Org-roam version 1.1.1.
#+BEGIN_QUOTE
Copyright (C) 2020-2020 Jethro Kuan <jethrokuan95@gmail.com>
You can redistribute this document and/or modify it under the terms of the GNU
General Public License as published by the Free Software Foundation, either
version 3 of the License, or (at your option) any later version.
This document is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
#+END_QUOTE
:END:
* Introduction
Org-roam is a [[https://roamresearch.com/][Roam Research]] replica built around the
all-powerful [[https://orgmode.org/][Org-mode]].
Org-roam is a solution for effortless non-hierarchical note-taking
with Org-mode. With Org-roam, notes flow naturally, making note-taking
fun and easy. Org-roam should also work as a plug-and-play solution
for anyone already using Org-mode for their personal wiki.
To understand more about Roam, a collection of links are available in
[[*Note-taking Workflows][Note-taking Workflows]].
Org-roam aims to implement the core features of Roam, leveraging the
mature ecosystem around Org-mode where possible. Eventually, we hope
to further introduce features enabled by the Emacs ecosystem.
Org-roam provides several benefits over other tooling:
- Privacy and Security :: Edit your personal wiki completely offline, entirely in your control. Encrypt your notes with GPG.
- Longevity of Plain Text :: Unlike web solutions like Roam research, the notes are first and foremost plain Org-mode files -- Org-roam simply builds up an auxilliary database to give the personal wiki superpowers. Having your notes in plain-text is crucial for the longevity of your wiki. Never have to worry about proprietary web solutions being taken down. Edit your plain-text notes in notepad if all other editors cease to exist
- Free and Open Source :: Org-roam is free and open-source, which means that if you feel unhappy with any part of Org-roam, you may choose to extend Org-roam, or open a 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.
- 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.
* Installation
** _ :ignore:
Org-roam can be installed using Emacs' package manager or manually from its development repository.
** Installing from MELPA
Org-roam is available from Melpa and Melpa-Stable. If you haven't used Emacs' package manager before, you may familiarize yourself with it by reading the documentation in the Emacs manual, see info:emacs#Packages. Then, add one of the archives to =package-archives=:
- To use Melpa:
#+BEGIN_SRC emacs-lisp
(require 'package)
(add-to-list 'package-archives
'("melpa" . "http://melpa.org/packages/") t)
#+END_SRC
- To use Melpa-Stable:
#+BEGIN_SRC emacs-lisp
(require 'package)
(add-to-list 'package-archives
'("melpa-stable" . "http://stable.melpa.org/packages/") t)
#+END_SRC
Once you have added your preferred archive, you need to update the
local package list using:
#+BEGIN_EXAMPLE
M-x package-refresh-contents RET
#+END_EXAMPLE
Once you have done that, you can install Org-roam and its dependencies
using:
#+BEGIN_EXAMPLE
M-x package-install RET org-roam RET
#+END_EXAMPLE
Now see [[*Post-Installation Tasks][Post-Installation Tasks]].
** TODO Installing from the Git Repository
** TODO Post-Installation Tasks
* Getting Started
This short tutorial describes the essential commands used in Org-roam, to help
you get started.
First, it is important to understand how Org-roam was designed. Org-roam was
built to support a workflow that was not possible with vanilla Org-mode. This
flow is modelled after the [[https://zettelkasten.de/][Zettelkasten Method]], and many of [[https://roamresearch.com][Roam Research's]]
workflows. Org-roam does not magically make note-taking better -- this often
requires a radical change in your current note-taking workflow. To understand
more about the methods and madness, see [[*Note-taking Workflows][Note-taking Workflows]].
To begin using Org-roam, one should set the =org-roam-directory= to the directory
containing your notes. For this tutorial, create an empty directory, and set the
=org-roam-directory=:
#+BEGIN_SRC emacs-lisp
(make-directory "~/org-roam")
(setq org-roam-directory "~/org-roam")
#+END_SRC
We encourage using a flat hierarchy for storing notes, but some prefer using
folders for storing specific kinds of notes (e.g. websites, papers). This is
fine; Org-roam searches recursively within =org-roam-directory= for any notes.
Instead of relying on the file hierarchy for any form of categorization, we
solely rely on links between files to establish connections between notes.
Next, we need to enable the global minor mode =org-roam-mode=. This sets up Emacs
with several hooks, builds a cache and keeps it consistent. We recommend
starting =org-roam-mode= on startup:
#+BEGIN_SRC emacs-lisp
(add-hook 'after-init-hook 'org-roam-mode)
#+END_SRC
To build the cache manually, one can run =M-x org-roam-db-build-cache=. The cache
is a sqlite database named =org-roam.db=, which defaults to residing in the root
=org-roam-directory=. Cache builds may take a while the first time, but is often
instantaneous in subsequent runs.
Let us now create our first note. Call =M-x org-roam-find-file=. This shows a list
of titles for notes that reside in =org-roam-directory=. It should show nothing
right now, since there are no notes in the directory. Entering the title of the
note you wish to create, and pressing =RET= should begin the note creation
process. This process uses =org-capture='s templating system, and can be freely
customized (see [[*The Templating System][The Templating System]]). Using the default template, pressing =C-c
C-c= finishes the note capture. Running =M-x org-roam-find-file= again should show
the note you have created, and selecting that entry will bring you to that note.
The crux of Org-roam is making it easy to create notes, and link them together.
To link notes together, we call =M-x org-roam-insert=. This brings up a prompt
with a list of title for existing notes. Selecting an existing entry will create
and insert a link to the current file. Entering a non-existent title will create
a new note with that title. Good usage of Org-roam requires liberally linking
files: this facilitates building up a dense knowledge graph of inter-connected
notes.
Org-roam provides an interface to view backlinks. It shows backlinks for the
currently active Org-roam note, along with some surrounding context. To toggle
the visibility of this buffer, call =M-x org-roam=.
For a visual representation of the notes and their connections, Org-roam also
provides graphing capabilities, using Graphviz. It generates graphs with notes
as nodes, and links between them as edges. The generated graph can be used to
navigate to the files, but this requires some additional setup (see [[*Roam Protocol][Roam
Protocol]]).
* Anatomy of an Org-roam File
The bulk of Org-roam's functionality is built on top of vanilla
Org-mode. However, to support additional functionality, Org-roam adds
several Org-roam-specific keywords. These functionality are not crucial
to effective use of Org-roam.
** Titles
To easily find a note, a title needs to be prescribed to a note. A note can have
many titles: this allows a note to be referred to by different names, which is
especially useful for topics or concepts with acronyms. For example, for a note
like "World War 2", it may be desirable to also refer to it using the acronym
"WWII".
Org-roam calls =org-roam--extract-titles= to extract titles. It uses the
variable =org-roam-title-sources=, to control how the titles are extracted. The
title extraction methods supported are:
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
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
Take for example the following org file:
#+BEGIN_SRC org
#+TITLE: World War 2
#+ROAM_ALIAS: "WWII" "World War II"
* Headline
#+END_SRC
| Method | Titles |
|-------------+--------------------------|
| ='title= | '("World War 2") |
| ='headline= | '("Headline") |
| ='alias= | '("WWII" "World War II") |
One can freely control which extraction methods to use by customizing
=org-roam-title-sources=: see the doc-string for the variable for more
information. If all methods of title extraction return no results, the file-name
is used in place of the titles for completions.
If you wish to add your own title extraction method, you may push a symbol
='foo= into =org-roam-title-sources=, and define a
=org-roam--extract-titles-foo= which accepts no arguments. See
=org-roam--extract-titles-title= for an example.
** Tags
Tags are used as meta-data for files: they facilitate interactions with notes
where titles are insufficient. For example, tags allow for categorization of
notes: differentiating between bibliographical and structure notes during interactive commands.
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
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.
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
=foo/bar/file.org=, the file will have tags =foo= and =bar=.
3. ='last-directory=: Extracts the last directory relative to
=org-roam-directory= as the tag. That is, if a file is located at relative
path =foo/bar/file.org=, the file will have tag =bar=.
By default, only the ='prop= extraction method is enabled. To enable the other
extraction methods, you may modify =org-roam-tag-sources=:
#+BEGIN_SRC emacs-lisp
(setq org-roam-tag-sources '(prop last-directory))
#+END_SRC
If you wish to add your own tag extraction method, you may push a symbol ='foo=
into =org-roam-tag-sources=, and define a =org-roam--extract-tags-foo= which
accepts the absolute file path as its argument. See
=org-roam--extract-tags-prop= for an example.
** File Refs
Refs are unique identifiers for files. Each note can only have 1 ref.
For example, a note for a website may contain a ref:
#+BEGIN_SRC org
#+TITLE: Google
#+ROAM_KEY: https://www.google.com/
#+END_SRC
These keys come in useful for when taking website notes, using the
=roam-ref= protocol (see [[*Roam Protocol][Roam Protocol]]).
Alternatively, add a ref for notes for a specific paper, using its
[[https://github.com/jkitchin/org-ref][org-ref]] citation key:
#+BEGIN_SRC org
#+TITLE: Neural Ordinary Differential Equations
#+ROAM_KEY: cite:chen18_neural_ordin_differ_equat
#+END_SRC
The backlinks buffer will show any cites of this key: e.g.
#+CAPTION: org-ref-citelink
[[file:images/org-ref-citelink.png]]
* The Templating System
Rather than creating blank files on =org-roam-insert= and =org-roam-find-file=, it
may be desirable to prefill the file with templated content. This may include:
- Time of creation
- File it was created from
- Clipboard content
- Any other data you may want to input manually
This requires a complex template insertion system. Fortunately, Org ships with a
powerful one: =org-capture=. However, org-capture was not designed for such use.
Org-roam abuses =org-capture=, extending its syntax. To first understand how
org-roam's templating system works, it may be useful to look into basic usage of
=org-capture=.
Org-roam's templates can be customized by modifying the variable
=org-roam-capture-templates=.
** Template Walkthrough
To demonstrate the additions made to org-capture templates. Here, we walkthrough
the default template, reproduced below.
#+BEGIN_SRC emacs-lisp
("d" "default" plain (function org-roam--capture-get-point)
"%?"
:file-name "%<%Y%m%d%H%M%S>-${slug}"
:head "#+TITLE: ${title}\n"
:unnarrowed t)
#+END_SRC
1. The template has short key ="d"=. If you have only one template,
org-roam automatically chooses this template for you.
2. The template is given a description of ="default"=.
3. =plain= text is inserted. Other options include Org headings via
=entry=.
4. =(function org-roam--capture-get-point)= should not be changed.
5. ="%?"= is the template inserted on each call to =org-roam-capture--capture=.
This template means don't insert any content, but place the cursor
here.
6. =:file-name= is the file-name template for a new note, if it doesn't
yet exist. This creates a file at path that looks like
=/path/to/org-roam-directory/20200213032037-foo.org=.
7. =:head= contains the initial template to be inserted (once only), at
the beginning of the file. Here, the title global attribute is
inserted.
8. =:unnarrowed t= tells org-capture to show the contents for the whole
file, rather than narrowing to just the entry.
Other options you may want to learn about include =:immediate-finish=.
** Org-roam Template Expansion
Org-roam's template definitions also extend org-capture's template syntax, to
allow prefilling of strings. We have seen a glimpse of this in [[*Template Walkthrough][Template
Walkthrough]].
In org-roam templates, the =${var}= syntax allows for the expansion of
variables, stored in =org-roam-capture--info=. For example, during
=org-roam-insert=, the user is prompted for a title. Upon entering a
non-existent title, the =title= key in =org-roam-capture--info= is set to the
provided title. =${title}= is then expanded into the provided title during the
org-capture process. Any variables that do not contain strings, are prompted for
values using =completing-read=.
After doing this expansion, the org-capture's template expansion system
is used to fill up the rest of the template. You may read up more on
this on [[https://orgmode.org/manual/Template-expansion.html#Template-expansion][org-capture's documentation page]].
To illustrate this dual expansion process, take for example the template string:
="%<%Y%m%d%H%M%S>-${title}"=, with the title ="Foo"=. The template is first
expanded into =%<%Y%m%d%H%M%S>-Foo=. Then org-capture expands =%<%Y%m%d%H%M%S>=
with timestamp: e.g. =20200213032037-Foo=.
All of the flexibility afforded by Emacs and Org-mode are available. For
example, if you want to encode a UTC timestamp in the filename, you can take
advantage of org-mode's =%(EXP)= template expansion to call =format-time-string=
directly to provide its third argument to specify UTC.
#+BEGIN_SRC emacs-lisp
("d" "default" plain (function org-roam--capture-get-point)
"%?"
:file-name "%(format-time-string \"%Y-%m-%d--%H-%M-%SZ--${slug}\" (current-time) t)"
:head "#+TITLE: ${title}\n"
:unnarrowed t)
#+END_SRC
* Concepts and Configuration
The number of configuration options is deliberately kept small, to keep
the Org-roam codebase manageable. However, we attempt to accommodate as
many usage styles as possible.
All of Org-roam's customization options can be viewed via
=M-x customize-group org-roam=.
** Directories and Files
This section concerns the placement and creation of files.
- Variable: org-roam-directory
This is the default path to Org-roam files. All Org files, at any level of
nesting, are considered part of the Org-roam.
- Variable: org-roam-db-location
Location of the Org-roam database. If this is non-nil, the Org-roam sqlite
database is saved here.
It is the users responsibility to set this correctly, especially when used
with multiple Org-roam instances.
** The Org-roam Buffer
The Org-roam buffer displays backlinks for the currently active Org-roam note.
- User Option: org-roam-buffer
The name of the org-roam buffer. Defaults to =*org-roam*=.
- User Option: org-roam-buffer-position
The position of the Org-roam buffer side window. Valid values are ='left=,
='right=, ='top=, ='bottom=.
- User Option: org-roam-buffer-width
Width of =org-roam-buffer=. Has an effect only if =org-roam-buffer-position= is
='left= or ='right=.
- User Option: org-roam-buffer-height
Height of =org-roam-buffer=. Has an effect only if =org-roam-buffer-position= is
='top= or ='bottom=.
- User Option: org-roam-buffer-no-delete-other-windows
The =no-delete-window= parameter for the org-roam buffer. Setting it to ='t= prevents the window from being deleted when calling =delete-other-windows=.
** Org-roam Links
Org-roam links are regular =file:= links in Org-mode. By default, links are
inserted with the title as the link description with =org-roam-insert=.
- User Option: org-roam-link-title-format
To distinguish between org-roam links and regular links, one may choose to use
special indicators for Org-roam links. Defaults to ="%s"=.
If your version of Org is at least =9.2=, consider styling the link differently,
by customizing the =org-roam-link=, and =org-roam-link-current= faces.
** Org-roam Files
Org-roam files are created and prefilled using Org-roam's templating
system. The templating system is customizable (see [[*The Templating System][The Templating System]]).
* Navigating Around
** Index File
As your collection grows, you might want to create an index where you keep links
to your main files.
In Org-roam, you can define the path to your index file by setting
=org-roam-index-file=.
- Variable: org-roam-index-file
Path to the Org-roam index file.
The path can be a string or a function. If it is a string, it should be the
path (absolute or relative to =org-roam-directory=) to the index file. If it
is is a function, the function should return the path to the index file.
Otherwise, the index is assumed to be a note in =org-roam-index= whose
title is ="Index"=.
- Function: org-roam-find-index
Opens the Index file in the current =org-roam-directory=.
* Encryption
One may wish to keep private, encrypted files. Org-roam supports encryption (via
GPG), which can be enabled for all new files by setting =org-roam-encrypt-files=
to =t=. When enabled, new files are created with the =.org.gpg= extension and
decryption are handled automatically by EasyPG.
Note that Emacs will prompt for a password for encrypted files during
cache updates if it requires reading the encrypted file. To reduce the
number of password prompts, you may wish to cache the password.
- Variable: org-roam-encrypt-files
Whether to encrypt new files. If true, create files with .org.gpg extension.
* Graphing
Org-roam provides graphing capabilities to explore interconnections between
notes. This is done by performing SQL queries and generating images using
[[https://graphviz.org/][Graphviz]]. The graph can also be navigated: see [[*Roam Protocol][Roam Protocol]].
The entry point to graph creation is =org-roam-graph=.
- Function: org-roam-graph & optional arg file node-query
Build and possibly display a graph for FILE from NODE-QUERY.
If FILE is nil, default to current buffers file name.
ARG may be any of the following values:
- =nil= show the graph.
- =C-u= show the graph for FILE.
- =C-u N= show the graph for FILE limiting nodes to N steps.
- =C-u C-u= build the graph.
- =C-u -= build the graph for FILE.
- =C-u -N= build the graph for FILE limiting nodes to N steps.
- User Option: org-roam-graph-executable
Path to the graphing executable (in this case, Graphviz). Set this if Org-roam is unable to find the Graphviz executable on your system.
You may also choose to use =neato= in place of =dot=, which generates a more
compact graph layout.
- User Option: org-roam-graph-viewer
Org-roam defaults to using Firefox (located on PATH) to view the SVG, but you may choose to set it to:
1. A string, which is a path to the program used
2. a function accepting a single argument: the graph file path.
=nil= uses =view-file= to view the graph.
** Graph Options
Graphviz provides many options for customizing the graph output, and Org-roam supports some of them. See https://graphviz.gitlab.io/_pages/doc/info/attrs.html for customizable options.
- User Option: org-roam-graph-extra-config
Extra options passed to graphviz for the digraph (The "G" attributes).
Example: ='=(("rankdir" . "LR"))=
- User Option: org-roam-graph-node-extra-config
Extra options for nodes in the graphviz output (The "N" attributes).
Example: ='(("color" . "skyblue"))=
- User Option: org-roam-graph-edge-extra-config
Extra options for edges in the graphviz output (The "E" attributes).
Example: ='(("dir" . "back"))=
- User Option: org-roam-graph-edge-cites-extra-config
Extra options for citation edges in the graphviz output.
Example: ='(("color" . "red"))=
** Excluding Nodes and Edges
One may want to exclude certain files to declutter the graph.
- User Option: org-roam-graph-exclude-matcher
Matcher for excluding nodes from the generated graph. Any nodes and links for
file paths matching this string is excluded from the graph.
If value is a string, the string is the only matcher.
If value is a list, all file paths matching any of the strings
are excluded.
#+BEGIN_EXAMPLE
(setq org-roam-graph-exclude-matcher '("private" "dailies"))
#+END_EXAMPLE
This setting excludes all files whose path contain "private" or "dailies".
* Org-roam Completion System
Org-roam offers completion when choosing note titles etc. The completion
system is configurable. The default setting,
#+BEGIN_SRC emacs-lisp
(setq org-roam-completion-system 'default)
#+END_SRC
uses Emacs' standard =completing-read=. If you prefer
[[https://emacs-helm.github.io/helm/][Helm]], use
#+BEGIN_SRC emacs-lisp
(setq org-roam-completion-system 'helm)
#+END_SRC
Other options include ='ido=, and ='ivy=.
* Roam Protocol
** _ :ignore:
Org-roam extending =org-protocol= with 2 protocols: the =roam-file=
and =roam-ref= protocol.
** Installation
To enable Org-roam's protocol extensions, you have to add the following to your init file:
#+BEGIN_SRC emacs-lisp
(require 'org-roam-protocol)
#+END_SRC
The instructions for setting up =org-protocol== are reproduced below.
We will also need to create a desktop application for =emacsclient=. The
instructions for various platforms are shown below.
For Linux users, create a desktop application in =~/.local/share/applications/org-protocol.desktop=:
#+begin_example
[Desktop Entry]
Name=Org-Protocol
Exec=emacsclient %u
Icon=emacs-icon
Type=Application
Terminal=false
MimeType=x-scheme-handler/org-protocol
#+end_example
Associate =org-protocol://= links with the desktop application by
running in your shell:
#+BEGIN_SRC bash
xdg-mime default org-protocol.desktop x-scheme-handler/org-protocol
#+END_SRC
To disable the "confirm" prompt in Chrome, you can also make Chrome
show a checkbox to tick, so that the =Org-Protocol Client= app will be used
without confirmation. To do this, run in a shell:
#+BEGIN_SRC bash
sudo mkdir -p /etc/opt/chrome/policies/managed/
sudo tee /etc/opt/chrome/policies/managed/external_protocol_dialog.json >/dev/null <<'EOF'
{
"ExternalProtocolDialogShowAlwaysOpenCheckbox": true
}
EOF
sudo chmod 644 /etc/opt/chrome/policies/managed/external_protocol_dialog.json
#+END_SRC
and then restart Chrome (for example, by navigating to <chrome://restart>) to
make the new policy take effect.
See [[https://www.chromium.org/administrators/linux-quick-start][here]] for more info on the =/etc/opt/chrome/policies/managed= directory and
[[https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ExternalProtocolDialogShowAlwaysOpenCheckbox][here]] for information on the =ExternalProtocolDialogShowAlwaysOpenCheckbox= policy.
For MacOS, one solution is to use [[https://github.com/sveinbjornt/Platypus][Platypus]]. Here are the instructions for
setting up with Platypus and Chrome:
1. Install and launch Platypus (with [[https://brew.sh/][Homebrew]]):
#+BEGIN_SRC bash
brew cask install platypus
#+END_SRC
2. Create a script =launch_emacs.sh=:
#+BEGIN_SRC bash
#!/usr/bin/env bash
/usr/local/bin/emacsclient --no-wait $1
#+END_SRC
3. Create a Platypus app with the following settings:
#+begin_example
| Setting | Value |
|--------------------------------+---------------------------|
| App Name | "OrgProtocol" |
| Script Type | "env" · "/usr/bin/env" |
| Script Path | "path/to/launch-emacs.sh" |
| Interface | None |
| Accept dropped items | true |
| Remain running after execution | false |
#+end_example
Inside =Settings=:
#+begin_example
| Setting | Value |
|--------------------------------+----------------|
| Accept dropped files | true |
| Register as URI scheme handler | true |
| Protocol | "org-protocol" |
#+end_example
To disable the "confirm" prompt in Chrome, you can also make Chrome
show a checkbox to tick, so that the =OrgProtocol= app will be used
without confirmation. To do this, run in a shell:
#+BEGIN_SRC bash
defaults write com.google.Chrome ExternalProtocolDialogShowAlwaysOpenCheckbox -bool true
#+END_SRC
If you're using [[https://github.com/railwaycat/homebrew-emacsmacport][Emacs Mac Port]], it registered its `Emacs.app` as the default
handler for the URL scheme `org-protocol`. To make =OrgProtocol.app=
the default handler instead, run:
#+BEGIN_SRC bash
defaults write com.apple.LaunchServices/com.apple.launchservices.secure LSHandlers -array-add \
'{"LSHandlerPreferredVersions" = { "LSHandlerRoleAll" = "-"; }; LSHandlerRoleAll = "org.yourusername.OrgProtocol"; LSHandlerURLScheme = "org-protocol";}'
#+END_SRC
Then restart your computer.
** The =roam-file= protocol
This is a simple protocol that opens the path specified by the =file=
key (e.g. =org-protocol://roam-file?file=/tmp/file.org=). This is used
in the generated graph.
** The =roam-ref= Protocol
This protocol finds or creates a new note with a given =ROAM_KEY= (see [[*Anatomy of an Org-roam File][Anatomy of an Org-roam File]]):
[[file:images/roam-ref.gif]]
To use this, create a Firefox bookmarklet as follows:
#+BEGIN_SRC javascript
javascript:location.href =
'org-protocol://roam-ref?template=r&ref='
+ encodeURIComponent(location.href)
+ '&title='
+ encodeURIComponent(document.title)
#+END_SRC
or as a keybinding in =qutebrowser=, adding the following to the =autoconfig.yml= file:
#+BEGIN_SRC yaml
settings:
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
where =template= is the template key for a template in
=org-roam-capture-ref-templates= (see [[*The Templating System][The Templating System]]). These templates
should contain a =#+ROAM_KEY: ${ref}= in it.
* Diagnosing and Repairing Files
Org-roam provides a utility for diagnosing and repairing problematic files via
=org-roam-doctor=. By default, =org-roam-doctor= runs the check across all Org-roam
files, and this can take some time. To run the check only for the current file,
run =C-u M-x org-roam-doctor=.
- Function: org-roam-doctor &optional this-buffer
Perform a check on Org-roam files to ensure cleanliness. If THIS-BUFFER, run
the check only for the current buffer.
The checks run are defined in =org-roam-doctor--checkers=. Each checker is an instance of =org-roam-doctor-checker=. To define a checker, use =make-org-roam-doctor-checker=. Here is a sample definition:
#+BEGIN_SRC emacs-lisp
(make-org-roam-doctor-checker
:name 'org-roam-doctor-broken-links
:description "Fix broken links."
:actions '(("d" . ("Unlink" . org-roam-doctor--remove-link))
("r" . ("Replace link" . org-roam-doctor--replace-link))
("R" . ("Replace link (keep label)" . org-roam-doctor--replace-link-keep-label))))
#+END_SRC
The =:name= property is the name of the function run. The function takes in the
Org parse tree, and returns a list of =(point error-message)=. =:description= is a
short description of what the checker does. =:actions= is an alist containing
elements of the form =(char . (prompt . function))=. These actions are defined per
checker, to perform autofixes for the errors. For each error detected,
=org-roam-doctor= will move the point to the current error, and pop-up a help
window displaying the error message, as well as the list of actions that can be
taken provided in =:actions=.
* _ Copying
:PROPERTIES:
:COPYING: t
:END:
#+BEGIN_QUOTE
Copyright (C) 2020-2020 Jethro Kuan <jethrokuan95@gmail.com>
You can redistribute this document and/or modify it under the terms
of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any
later version.
This document is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
#+END_QUOTE
* Appendix
** Note-taking Workflows
- Books ::
- [[https://www.goodreads.com/book/show/34507927-how-to-take-smart-notes][How To Take Smart Notes]]
- Articles ::
- [[https://www.lesswrong.com/posts/NfdHG6oHBJ8Qxc26s/the-zettelkasten-method-1][The Zettelkasten Method - LessWrong 2.0]]
- [[https://reddit.com/r/RoamResearch/comments/eho7de/building_a_second_brain_in_roamand_why_you_might][Building a Second Brain in Roam...And Why You Might Want To : RoamResearch]]
- [[https://www.nateliason.com/blog/roam][Roam Research: Why I Love It and How I Use It - Nat Eliason]]
- [[https://twitter.com/adam_keesling/status/1196864424725774336?s=20][Adam Keesling's Twitter Thread]]
- [[https://blog.jethro.dev/posts/how_to_take_smart_notes_org/][How To Take Smart Notes With Org-mode · Jethro Kuan]]
- Threads ::
- [[https://news.ycombinator.com/item?id=22473209][Ask HN: How to Take Good Notes]]
- Videos ::
- [[https://www.youtube.com/watch?v=RvWic15iXjk][How to Use Roam to Outline a New Article in Under 20 Minutes]]
** Ecosystem
A number of packages work well combined with Org-Roam:
*** Deft
:PROPERTIES:
:CUSTOM_ID: deft
:END:
[[https://jblevins.org/projects/deft/][Deft]] provides a nice interface
for browsing and filtering org-roam notes.
#+BEGIN_SRC emacs-lisp
(use-package deft
:after org
:bind
("C-c n d" . deft)
:custom
(deft-recursive t)
(deft-use-filter-string-for-filename t)
(deft-default-extension "org")
(deft-directory "/path/to/org-roam-files/"))
#+END_SRC
If the title of the Org file is not the first line, you might not get
nice titles. You may choose to patch this to use =org-roam='s
functionality. Here I'm using
[[https://github.com/raxod502/el-patch][el-patch]]:
#+BEGIN_SRC emacs-lisp
(use-package el-patch
:straight (:host github
:repo "raxod502/el-patch"
:branch "develop"))
(eval-when-compile
(require 'el-patch))
(use-package deft
;; same as above...
:config/el-patch
(defun deft-parse-title (file contents)
"Parse the given FILE and CONTENTS and determine the title.
If `deft-use-filename-as-title' is nil, the title is taken to
be the first non-empty line of the FILE. Else the base name of the FILE is
used as title."
(el-patch-swap (if deft-use-filename-as-title
(deft-base-filename file)
(let ((begin (string-match "^.+$" contents)))
(if begin
(funcall deft-parse-title-function
(substring contents begin (match-end 0))))))
(org-roam--get-title-or-slug file))))
#+END_SRC
The Deft interface can slow down quickly when the number of files get
huge. [[https://github.com/hasu/notdeft][Notdeft]] is a fork of Deft
that uses an external search engine and indexer.
*** Org-journal
:PROPERTIES:
:CUSTOM_ID: org-journal
:END:
[[https://github.com/bastibe/org-journal][Org-journal]] is a more
powerful alternative to the simple function =org-roam-dailies-today=. It
provides better journaling capabilities, and a nice calendar interface
to see all dated entries.
#+BEGIN_SRC emacs-lisp
(use-package org-journal
:bind
("C-c n j" . org-journal-new-entry)
:custom
(org-journal-date-prefix "#+TITLE: ")
(org-journal-file-format "%Y-%m-%d.org")
(org-journal-dir "/path/to/org-roam-files/")
(org-journal-date-format "%A, %d %B %Y"))
#+END_SRC
*** Note-taking Add-ons
:PROPERTIES:
:CUSTOM_ID: note-taking-add-ons
:END:
These are some plugins that make note-taking in Org-mode more enjoyable.
**** Org-download
:PROPERTIES:
:CUSTOM_ID: org-download
:END:
[[https://github.com/abo-abo/org-download][Org-download]] lets you
screenshot and yank images from the web into your notes:
#+CAPTION: org-download
[[file:images/org-download.gif]]
#+BEGIN_SRC emacs-lisp
(use-package org-download
:after org
:bind
(:map org-mode-map
(("s-Y" . org-download-screenshot)
("s-y" . org-download-yank))))
#+END_SRC
**** mathpix.el
:PROPERTIES:
:CUSTOM_ID: mathpix.el
:END:
[[https://github.com/jethrokuan/mathpix.el][mathpix.el]] uses
[[https://mathpix.com/][Mathpix's]] API to convert clips into latex
equations:
#+CAPTION: mathpix
[[file:images/mathpix.gif]]
#+BEGIN_SRC emacs-lisp
(use-package mathpix.el
:straight (:host github :repo "jethrokuan/mathpix.el")
:custom ((mathpix-app-id "app-id")
(mathpix-app-key "app-key"))
:bind
("C-x m" . mathpix-screenshot))
#+END_SRC
**** Org-noter / Interleave
:PROPERTIES:
:CUSTOM_ID: org-noter-interleave
:END:
[[https://github.com/weirdNox/org-noter][Org-noter]] and
[[https://github.com/rudolfochrist/interleave][Interleave]] are both
projects that allow synchronised annotation of documents (PDF, EPUB
etc.) within Org-mode.
**** Bibliography
:PROPERTIES:
:CUSTOM_ID: bibliography
:END:
[[https://github.com/zaeph/org-roam-bibtex][org-roam-bibtex]] offers
tight integration between
[[https://github.com/jkitchin/org-ref][org-ref]],
[[https://github.com/tmalsburg/helm-bibtex][helm-bibtex]] and
=org-roam=. This helps you manage your bibliographic notes under
=org-roam=.
**** Spaced Repetition
:PROPERTIES:
:CUSTOM_ID: spaced-repetition
:END:
[[https://github.com/l3kn/org-fc/][Org-fc]] is a spaced repetition
system that scales well with a large number of files. Other alternatives
include
[[https://orgmode.org/worg/org-contrib/org-drill.html][org-drill]], and
[[https://github.com/abo-abo/pamparam][pamparam]].
* FAQ
** How do I have more than one Org-roam directory?
Emacs supports directory-local variables, allowing the value of
=org-roam-directory= to be different in different directories. It does this by
checking for a file named =.dir-locals.el=.
To add support for multiple directories, override the =org-roam-directory=
variable using directory-local variables. This is what =.dir-locals.el= may
contain:
#+BEGIN_SRC emacs-lisp
((nil . ((org-roam-directory . "/path/to/here/"))))
#+END_SRC
All files within that directory will be treated as their own separate
set of Org-roam files. Remember to run =org-roam-db-build-cache= from a
file within that directory, at least once.
* _ :ignore:
# Local Variables:
# eval: (refill-mode +1)
# before-save-hook: org-make-toc
# after-save-hook: (lambda nil (progn (require 'ox-texinfo nil t) (org-texinfo-export-to-info)))
# indent-tabs-mode: nil
# org-src-preserve-indentation: nil
# End:

1287
doc/org-roam.texi Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,61 +0,0 @@
While exporting your documents to another format such as HTML -- whether using Org's in-built export or ox-hugo -- you can add a backlinks section which would display the backlinks to the current file. This is done via org-export's preprocessing hooks. See more at [Advanced Export Configuration (The Org Manual)](https://orgmode.org/manual/Advanced-Export-Configuration.html#Advanced-Export-Configuration).
Following are two different configs that might be suitable for different use-cases. Add one of these snippets in your Emacs init file.
### Only Backlinks
This will display only the backlinks and not the contents.
```emacs-lisp
(defun my/org-roam--backlinks-list (file)
(if (org-roam--org-roam-file-p file)
(--reduce-from
(concat acc (format "- [[file:%s][%s]]\n"
(file-relative-name (car it) org-roam-directory)
(org-roam--get-title-or-slug (car it))))
"" (org-roam-db-query [:select [from] :from links :where (= to $s1)] file))
""))
(defun my/org-export-preprocessor (backend)
(let ((links (my/org-roam--backlinks-list (buffer-file-name))))
(unless (string= links "")
(save-excursion
(goto-char (point-max))
(insert (concat "\n* Backlinks\n") links)))))
(add-hook 'org-export-before-processing-hook 'my/org-export-preprocessor)
```
### Backlinks and Contents
This would insert both backlinks and the contents, just like the org-roam buffer. This might be especially useful if you host a web version of your personal knowledgebase and want to browse the files along with the backlinks from mobile devices.
```emacs-lisp
(defun my/org-roam--backlinks-list-with-content (file)
(with-temp-buffer
(if-let* ((backlinks (org-roam--get-backlinks file))
(grouped-backlinks (--group-by (nth 0 it) backlinks)))
(progn
(insert (format "\n\n* %d Backlinks\n"
(length backlinks)))
(dolist (group grouped-backlinks)
(let ((file-from (car group))
(bls (cdr group)))
(insert (format "** [[file:%s][%s]]\n"
file-from
(org-roam--get-title-or-slug file-from)))
(dolist (backlink bls)
(pcase-let ((`(,file-from _ ,props) backlink))
(insert (s-trim (s-replace "\n" " " (plist-get props :content))))
(insert "\n\n")))))))
(buffer-string)))
(defun my/org-export-preprocessor (backend)
(let ((links (my/org-roam--backlinks-list-with-content (buffer-file-name))))
(unless (string= links "")
(save-excursion
(goto-char (point-max))
(insert (concat "\n* Backlinks\n") links)))))
(add-hook 'org-export-before-processing-hook 'my/org-export-preprocessor)
```

View File

@ -1,2 +0,0 @@
mkdocs-material==4.6.2
pymdown-extensions==6.3

View File

@ -1,161 +0,0 @@
## What is Roam protocol?
Org-roam extending `org-protocol` with 2 protocols: the `roam-file`
and `roam-ref` protocol.
## The `roam-file` protocol
This is a simple protocol that opens the path specified by the `file`
key (e.g. `org-protocol://roam-file?file=/tmp/file.org`). This is used
in the generated graph.
## The `roam-ref` Protocol
This protocol finds or creates a new note with a given `ROAM_KEY` (see
[Anatomy](anatomy.md)):
![roam-ref](images/roam-ref.gif)
To use this, create a Firefox bookmarklet as follows:
```javascript
javascript:location.href =
'org-protocol:/roam-ref?template=r&ref='
+ encodeURIComponent(location.href)
+ '&title='
+ encodeURIComponent(document.title)
```
where `template` is the template key for a template in
`org-roam-capture-ref-templates`. More documentation on the templating
system can be found [here](templating.md).
These templates should contain a `#+ROAM_KEY: ${ref}` in it.
## Setting up Org-roam protocol
To enable org-roam's protocol extensions, you have to add the
following to your init file:
```emacs-lisp
(require 'org-roam-protocol)
```
The instructions for setting up `org-protocol` can be found
[here][org-protocol-inst], but they are reproduced below.
We will also need to create a desktop application for `emacsclient`.
The instructions for various platforms are shown below:
## Linux
Create a desktop application. I place mine in
`~/.local/share/applications/org-protocol.desktop`:
```
[Desktop Entry]
Name=Org-Protocol
Exec=emacsclient %u
Icon=emacs-icon
Type=Application
Terminal=false
MimeType=x-scheme-handler/org-protocol
```
Associate `org-protocol://` links with the desktop application by
running in your shell:
```bash
xdg-mime default org-protocol.desktop x-scheme-handler/org-protocol
```
To disable the "confirm" prompt in Chrome, you can also make Chrome
show a checkbox to tick, so that the `Org-Protocol Client` app will be used
without confirmation. To do this, run in a shell:
```sh
sudo mkdir -p /etc/opt/chrome/policies/managed/
sudo tee /etc/opt/chrome/policies/managed/external_protocol_dialog.json >/dev/null <<'EOF'
{
"ExternalProtocolDialogShowAlwaysOpenCheckbox": true
}
EOF
sudo chmod 644 /etc/opt/chrome/policies/managed/external_protocol_dialog.json
```
and then restart Chrome (for example, by navigating to <chrome://restart>) to
make the new policy take effect.
See [here](https://www.chromium.org/administrators/linux-quick-start)
for more info on the `/etc/opt/chrome/policies/managed` directory and
[here](https://cloud.google.com/docs/chrome-enterprise/policies/?policy=ExternalProtocolDialogShowAlwaysOpenCheckbox)
for information on the `ExternalProtocolDialogShowAlwaysOpenCheckbox`
policy.
## Mac OS
One solution is to use
[Platypus](https://github.com/sveinbjornt/Platypus). Here are the
instructions for setting up with Platypus and Chrome:
1. Install and launch Platypus (with [Homebrew](https://brew.sh/)):
```sh
brew cask install platypus
```
2. Create a script `launch_emacs.sh`:
```
#!/usr/bin/env bash
/usr/local/bin/emacsclient --no-wait $1
```
3. Create a Platypus app with the following settings:
```
| Setting | Value |
|--------------------------------+---------------------------|
| App Name | "OrgProtocol" |
| Script Type | "env" · "/usr/bin/env" |
| Script Path | "path/to/launch-emacs.sh" |
| Interface | None |
| Accept dropped items | true |
| Remain running after execution | false |
```
Inside `Settings`:
```
| Setting | Value |
|--------------------------------+----------------|
| Accept dropped files | true |
| Register as URI scheme handler | true |
| Protocol | "org-protocol" |
```
To disable the "confirm" prompt in Chrome, you can also make Chrome
show a checkbox to tick, so that the `OrgProtocol` app will be used
without confirmation. To do this, run in a shell:
```sh
defaults write com.google.Chrome ExternalProtocolDialogShowAlwaysOpenCheckbox -bool true
```
##### Note for Emacs Mac Port
If you're using [Emacs Mac Port](https://github.com/railwaycat/homebrew-emacsmacport), it
registered its `Emacs.app` as the default handler for the URL scheme
`org-protocol`. We have to make our `OrgProtocol.app` the default
handler instead (replace `org.yourusername.OrgProtocol` with your app
identifier):
```
$ defaults write com.apple.LaunchServices/com.apple.launchservices.secure LSHandlers -array-add \
'{"LSHandlerPreferredVersions" = { "LSHandlerRoleAll" = "-"; }; LSHandlerRoleAll = "org.yourusername.OrgProtocol"; LSHandlerURLScheme = "org-protocol";}'
```
Then restart your computer.
[org-protocol-inst]: https://orgmode.org/worg/org-contrib/org-protocol.html

View File

@ -1,119 +0,0 @@
Rather than creating blank files on `org-roam-insert` and
`org-roam-find-file`, it is may be desirable to prefill the file with
content. This may include:
- Time of creation
- File it was created from
- Clipboard content
- Any other data you may want to input manually
This requires a complex template insertion system, but fortunately,
Org ships with a powerful one: `org-capture`. However, org-capture was
not designed for such use. Org-roam abuses `org-capture` to some
extent, extending its syntax. To first understand how org-roam's
templating system works, it may be useful to look into org-capture.
## Org-roam Templates
The org-roam capture template extends org-capture's template with 2
additional properties:
1. `:file-name`: This is the file name template used when a new note
is created.
2. `:head`: This is the template that is inserted on initial note
creation.
### Org-roam Template Expansion
Org-roam's template definitions also extend org-capture's template
syntax, to allow prefilling of strings. In many scenarios,
`org-roam--capture` is passed a mapping between variables and strings.
For example, during `org-roam-insert`, a title is prompted for. If the
title doesn't already exist, we would like to create a new file,
without prompting for the title again.
Variables passed are expanded with the `${var}` syntax. For example,
during `org-roam-insert`, `${title}` is prefilled for expansion. Any
variables that do not contain strings, are prompted for values using
`completing-read`.
After doing this expansion, the org-capture's template expansion
system is used to fill up the rest of the template. You may read up
more on this on [org-capture's documentation
page](https://orgmode.org/manual/Template-expansion.html#Template-expansion).
For example, take the template: `"%<%Y%m%d%H%M%S>-${title}"`, with the title
`"Foo"`. The template is first expanded into `%<%Y%m%d%H%M%S>-Foo`. Then
org-capture expands `%<%Y%m%d%H%M%S>` with timestamp: e.g.
`20200213032037-Foo`.
All of the flexibility afforded by emacs and org-mode are
available. For example, if you want to encode a UTC timestamp in the
filename, you can take advantage of org-mode's `%(EXP)` template
expansion to call `format-time-string` directly to provide its third
argument to specify UTC.
``` emacs-lisp
("d" "default" plain (function org-roam--capture-get-point)
"%?"
:file-name "%(format-time-string \"%Y-%m-%d--%H-%M-%SZ--${slug}\" (current-time) t)"
:head "#+TITLE: ${title}\n"
:unnarrowed t)
```
Similarly, if you want to change how titles are transformed into
slugs, you can override `org-roam--title-to-slug`. For example, to use
hyphens instead of underscores:
``` emacs-lisp
(defun org-roam--title-to-slug (title)
"Convert TITLE to a filename-suitable slug. Uses hyphens rather than underscores."
(cl-flet* ((nonspacing-mark-p (char)
(eq 'Mn (get-char-code-property char 'general-category)))
(strip-nonspacing-marks (s)
(apply #'string (seq-remove #'nonspacing-mark-p
(ucs-normalize-NFD-string s))))
(cl-replace (title pair)
(replace-regexp-in-string (car pair) (cdr pair) title)))
(let* ((pairs `(("[^[:alnum:][:digit:]]" . "-") ;; convert anything not alphanumeric
("--*" . "-") ;; remove sequential underscores
("^-" . "") ;; remove starting underscore
("-$" . ""))) ;; remove ending underscore
(slug (-reduce-from #'cl-replace (strip-nonspacing-marks title) pairs)))
(s-downcase slug))))
```
This templating system is used throughout org-roam templates.
### Template examples
Here I walkthrough the default template, reproduced below.
```
("d" "default" plain (function org-roam--capture-get-point)
"%?"
:file-name "%<%Y%m%d%H%M%S>-${slug}"
:head "#+TITLE: ${title}\n"
:unnarrowed t)
```
1. The template has short key `"d"`. If you have only one template,
org-roam automatically chooses this template for you.
2. The template is given a description of `"default"`.
3. `plain` text is inserted. Other options include Org headings via
`entry`.
4. `(function org-roam--capture-get-point)` should not be changed.
5. `"%?"` is the template inserted on each call to `org-roam--capture`.
This template means don't insert any content, but place the cursor
here.
6. `:file-name` is the file-name template for a new note, if it
doesn't yet exist. This creates a file at path that looks like
`/path/to/org-roam-directory/20200213032037-foo.org`.
7. `:head` contains the initial template to be inserted (once only),
at the beginning of the file. Here, the title global attribute is
inserted.
8. `:unnarrowed t` tells org-capture to show the contents for the
whole file, rather than narrowing to just the entry.
Other options you may want to learn about include `:immediate-finish`.

View File

@ -1,70 +0,0 @@
Org-roam was built to support a workflow that was not possible with
vanilla Org-mode. This flow is modelled after the [Zettelkasten
method][zettelkasten], and many of [Roam Research][roam]'s workflows.
It is crucial to understand that Org-roam does not auto-magically make
note-taking better -- it's changing the note-taking workflow that
does.
To understand more about the methods and madness, the [Note-Taking
Workflow][appendix:ntw] page contains a page of useful references. The
author has also written [a post][jethro-blog-post] about how he uses
Org-roam.
## Activating Org-roam
Org-roam's entry point is the global minor `org-roam-mode`. This sets
up Emacs with several hooks, for keeping the org-roam cache
consistently updated, as well as showing the backlinks buffer.
The cache is a sqlite database named `org-roam.db`, which resides at
the root of the `org-roam-directory`. Activating `org-roam-mode`
builds the cache, which may take a while the first time, but is
generally instantaneous in subsequent runs. To build the cache
manually again, run `M-x org-roam-db-build-cache`.
## Finding a Note
`org-roam-find-file` shows the list of titles for notes that reside in
`org-roam-directory`. Selecting a note title will bring you to the
corresponding note. Entering a title of a note that does not yet exist
will create a new note with that title.
![org-roam-find-file](images/org-roam-find-file.gif)
Note that in the above image, the [ivy](https://github.com/abo-abo/swiper)
completion frontend is used. The default frontend has some usability issues with
non-matching candidates (e.g. when you want to enter a title of a new note,
there is no completion candidate), so either `ivy` or `helm` is recommended.
## Inserting Links
`org-roam-insert` insert links to existing (or new) notes. Entering a
non-existent title will also create a new note with that title.
![org-roam-insert](images/org-roam-insert-filetag.gif)
Good usage of Org-roam requires liberally linking files. This allows
the build-up of a dense knowledge graph.
## The Org-roam Buffer
The Org-roam buffer is often displayed in the side window. It shows
backlinks for the currently active Org-roam note, along with some
surrounding context.
![org-roam-buffer](images/org-roam-buffer.gif)
## Exporting the Graph
Org-roam also uses Graphviz to generate a graph, with notes as nodes,
and links between them as edges. The generated graph can be used to
navigate to the files, but this requires some additional setup
described in the [Roam Protocol][appendix:roam-protocol] page.
![org-roam-graph](images/org-roam-graph.gif)
[zettelkasten]: https://zettelkasten.de/
[appendix:ntw]: notetaking_workflow.md
[appendix:roam-protocol]: roam_protocol.md
[roam]: https://www.roamresearch.com/
[jethro-blog-post]: https://blog.jethro.dev/posts/how_to_take_smart_notes_org/

View File

@ -155,7 +155,8 @@ function elisp-checkdoc-file {
(when makem-checkdoc-errors-p
(kill-emacs 1))))
(setq checkdoc-spellcheck-documentation-flag t)
(setq sentence-end-double-space nil)
(setq checkdoc-spellcheck-documentation-flag nil)
(makem-checkdoc-files-and-exit)
EOF
echo $file
@ -325,7 +326,7 @@ function dirnames {
function filter-files-exclude-default {
# Filter out paths (STDIN) which should be excluded by default.
egrep -v "(/\.cask/|-autoloads.el|.dir-locals)"
egrep -v "(/\.cask/|-autoloads.el|-macs.el|.dir-locals)"
}
function filter-files-exclude-args {
@ -694,7 +695,7 @@ function lint {
lint-checkdoc
lint-compile
lint-declare
lint-indent
# lint-indent
lint-package
lint-regexps
}

View File

@ -1,5 +1,5 @@
site_name: "Org-roam"
repo_url: https://github.com/jethrokuan/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

View File

@ -1,11 +1,11 @@
;;; org-roam-buffer.el --- Roam Research replica with Org-mode -*- coding: utf-8; lexical-binding: t -*-
;;; org-roam-buffer.el --- Metadata buffer -*- coding: utf-8; lexical-binding: t; -*-
;; Copyright © 2020 Jethro Kuan <jethrokuan95@gmail.com>
;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/jethrokuan/org-roam
;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience
;; Version: 1.1.0
;; Version: 1.1.1
;; 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"))
;; This file is NOT part of GNU Emacs.
@ -40,6 +40,8 @@
(defvar org-return-follows-link)
(defvar org-roam-backlinks-mode)
(defvar org-roam-last-window)
(defvar org-ref-cite-types) ;; in org-ref-core.el
(declare-function org-roam-db--ensure-built "org-roam-db")
(declare-function org-roam--extract-ref "org-roam")
(declare-function org-roam--get-title-or-slug "org-roam")
@ -100,16 +102,28 @@ When non-nil, the window will not be closed when deleting other windows."
'font-lock-face
'org-document-title)))
(defun org-roam-buffer--pluralize (string number)
"Conditionally pluralize STRING if NUMBER is above 1."
(let ((l (pcase number
((pred (listp)) (length number))
((pred (integerp)) number)
(wrong-type (signal 'wrong-type-argument
`((listp integerp)
,wrong-type))))))
(concat string (when (> l 1) "s"))))
(defun org-roam-buffer--insert-citelinks ()
"Insert citation backlinks for the current buffer."
(if-let* ((roam-key (with-temp-buffer
(insert-buffer-substring org-roam-buffer--current)
(org-roam--extract-ref)))
(key-backlinks (org-roam--get-backlinks (s-chop-prefix "cite:" roam-key)))
(if-let* ((ref (with-temp-buffer
(insert-buffer-substring org-roam-buffer--current)
(org-roam--extract-ref)))
(org-ref-p (require 'org-ref nil t)) ; Ensure that org-ref is present
(key-backlinks (org-roam--get-backlinks (cdr ref)))
(grouped-backlinks (--group-by (nth 0 it) key-backlinks)))
(progn
(insert (format "\n\n* %d Cite backlinks\n"
(length key-backlinks)))
(insert (let ((l (length key-backlinks)))
(format "\n\n* %d %s\n"
l (org-roam-buffer--pluralize "Cite backlink" l))))
(dolist (group grouped-backlinks)
(let ((file-from (car group))
(bls (cdr group)))
@ -133,8 +147,9 @@ When non-nil, the window will not be closed when deleting other windows."
(backlinks (org-roam--get-backlinks file-path))
(grouped-backlinks (--group-by (nth 0 it) backlinks)))
(progn
(insert (format "\n\n* %d Backlinks\n"
(length backlinks)))
(insert (let ((l (length backlinks)))
(format "\n\n* %d %s\n"
l (org-roam-buffer--pluralize "Backlink" l))))
(dolist (group grouped-backlinks)
(let ((file-from (car group))
(bls (cdr group)))
@ -178,6 +193,7 @@ When non-nil, the window will not be closed when deleting other windows."
(run-hooks 'org-roam-buffer-prepare-hook)
(read-only-mode 1)))))
(cl-defun org-roam-buffer--update-maybe (&key redisplay)
"Reconstructs `org-roam-buffer'.
This needs to be quick or infrequent, because this is run at

View File

@ -1,11 +1,11 @@
;;; org-roam-capture.el --- Roam Research replica with Org-mode -*- coding: utf-8; lexical-binding: t -*-
;;; org-roam-capture.el --- Capture functionality -*- coding: utf-8; lexical-binding: t; -*-
;; Copyright © 2020 Jethro Kuan <jethrokuan95@gmail.com>
;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/jethrokuan/org-roam
;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience
;; Version: 1.1.0
;; Version: 1.1.1
;; 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"))
;; This file is NOT part of GNU Emacs.
@ -33,6 +33,7 @@
(require 'org-capture)
(require 'dash)
(require 's)
(require 'cl-lib)
;; Declarations
(defvar org-roam-encrypt-files)
@ -129,9 +130,11 @@ Details on how to specify for the template is given in `org-roam-capture-templat
(defun org-roam-capture--in-process-p ()
"Return non-nil if a `org-roam-capture' buffer exists."
(cl-some (lambda (buffer)
(and (eq (buffer-local-value 'major-mode (current-buffer)) 'org-mode)
(plist-get (buffer-local-value 'org-capture-current-plist (current-buffer)) :org-roam)))
(buffer-list)))
(and (eq (buffer-local-value 'major-mode buffer)
'org-mode)
(plist-get (buffer-local-value 'org-capture-current-plist buffer)
:org-roam)))
(buffer-list)))
(defun org-roam-capture--fill-template (str &optional info)
"Expands the template STR, returning the string.
@ -277,23 +280,21 @@ This function is used solely in Org-roam's capture templates: see
(defun org-roam-capture--convert-template (template)
"Convert TEMPLATE from Org-roam syntax to `org-capture-templates' syntax."
(let* ((copy (copy-tree template))
converted
org-roam-plist
key
val)
;;put positional args on converted template
(dotimes (_ 5)
(push (pop copy) converted))
(while (setq key (pop copy)
val (pop copy))
(if (member key org-roam-capture--template-keywords)
(progn
(push val org-roam-plist)
(push key org-roam-plist))
(push key converted)
(push val converted)))
(append (nreverse converted) `(:org-roam ,org-roam-plist))))
(pcase template
(`(,_key ,_description) template)
(`(,key ,description ,type ,target . ,rest)
(let ((converted `(,key ,description ,type ,target
,(unless (keywordp (car rest)) (pop rest))))
org-roam-plist
options)
(while rest
(let* ((key (pop rest))
(val (pop rest))
(custom (member key org-roam-capture--template-keywords)))
(push val (if custom org-roam-plist options))
(push key (if custom org-roam-plist options))))
(append converted options `(:org-roam ,org-roam-plist))))
(_ (user-error "Invalid capture template format: %s" template))))
(defun org-roam-capture--find-file-h ()
"Opens the newly created template file.
@ -311,12 +312,13 @@ Suitable for moving point."
:group 'org-roam
:type 'hook)
(defun org-roam--capture (&optional goto keys)
(defun org-roam-capture--capture (&optional goto keys)
"Create a new file, and return the path to the edited file.
The templates are defined at `org-roam-capture-templates'. The
GOTO and KEYS argument have the same functionality as
`org-capture'."
(let ((org-capture-templates (mapcar #'org-roam-capture--convert-template org-roam-capture-templates)))
(let ((org-capture-templates (mapcar #'org-roam-capture--convert-template org-roam-capture-templates))
org-capture-templates-contexts)
(when (= (length org-capture-templates) 1)
(setq keys (caar org-capture-templates)))
(add-hook 'org-capture-after-finalize-hook #'org-roam-capture--save-file-maybe-h)
@ -330,14 +332,20 @@ This uses the templates defined at `org-roam-capture-templates'."
(when (org-roam-capture--in-process-p)
(user-error "Nested Org-roam capture processes not supported"))
(let* ((completions (org-roam--get-title-path-completions))
(title (org-roam-completion--completing-read "File: " completions))
(file-path (cdr (assoc title completions))))
(title-with-keys (org-roam-completion--completing-read "File: "
completions))
(res (cdr (assoc title-with-keys completions)))
(title (or (plist-get res :title) title-with-keys))
(file-path (plist-get res :file-path)))
(let ((org-roam-capture--info (list (cons 'title title)
(cons 'slug (org-roam--title-to-slug title))
(cons 'file file-path)))
(org-roam-capture--context 'capture))
(setq org-roam-capture-additional-template-props (list :capture-fn 'org-roam-capture))
(org-roam--capture))))
(condition-case err
(org-roam-capture--capture)
(error (user-error "%s. Please adjust `org-roam-capture-templates'"
(error-message-string err)))))))
(provide 'org-roam-capture)

View File

@ -1,11 +1,11 @@
;;; org-roam-compat.el --- Compatibility Code -*- coding: utf-8; lexical-binding: t -*-
;;; org-roam-compat.el --- Compatibility Code -*- coding: utf-8; lexical-binding: t; -*-
;; Copyright © 2020 Jethro Kuan <jethrokuan95@gmail.com>
;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/jethrokuan/org-roam
;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience
;; Version: 1.1.0
;; Version: 1.1.1
;; 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"))
;; This file is NOT part of GNU Emacs.
@ -71,17 +71,22 @@
"org-roam 1.0.0")
(define-obsolete-function-alias 'org-roam-graph-build 'org-roam-graph
"org-roam 1.0.0")
(define-obsolete-function-alias 'org-roam-find-index 'org-roam-jump-to-index
"org-roam 1.1.0")
(define-obsolete-function-alias 'org-roam--pluralize 'org-roam-buffer--pluralize
"org-roam 1.1.0")
(define-obsolete-function-alias 'org-roam--capture 'org-roam-capture--capture
"org-roam 1.1.0")
(define-obsolete-function-alias 'org-roam-db--maybe-update 'org-roam-db--update-maybe
"org-roam 1.1.0")
;;;; Variables
(define-obsolete-variable-alias 'org-roam-graphviz-extra-options
'org-roam-graph-extra-config "org-roam 1.0.0")
(define-obsolete-variable-alias 'org-roam-grapher-extra-options
'org-roam-graph-extra-config "org-roam 1.0.0")
(make-obsolete-variable 'org-roam-graph-node-shape 'org-roam-graph-node-extra-config "org-roam 1.0.0")
(defcustom org-roam-graph-node-shape "ellipse"
"Shape of graph nodes."
:type 'string
:group 'org-roam)
(define-obsolete-variable-alias 'org-roam-graph-node-shape
'org-roam-graph-node-extra-config "org-roam 1.0.0")
(define-obsolete-variable-alias 'org-roam--db-connection
'org-roam-db--connection "org-roam 1.0.0")
(define-obsolete-variable-alias 'org-roam--current-buffer

View File

@ -1,11 +1,11 @@
;;; org-roam-completion.el --- Roam Research replica with Org-mode -*- coding: utf-8; lexical-binding: t -*-
;;; org-roam-completion.el --- Completion features -*- coding: utf-8; lexical-binding: t; -*-
;; Copyright © 2020 Jethro Kuan <jethrokuan95@gmail.com>
;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/jethrokuan/org-roam
;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience
;; Version: 1.1.0
;; Version: 1.1.1
;; 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"))
;; This file is NOT part of GNU Emacs.
@ -47,11 +47,6 @@
(function :tag "Custom function"))
:group 'org-roam)
(defcustom org-roam-completion-fuzzy-match nil
"Whether to fuzzy match Org-roam's completion candidates."
:type 'boolean
:group 'org-roam)
(defun org-roam-completion--helm-candidate-transformer (candidates _source)
"Transforms CANDIDATES for Helm-based completing read.
SOURCE is not used."
@ -82,9 +77,7 @@ Return user choice."
:require-match require-match
:action (prog1 action
(setq action nil))
:caller 'org-roam--completing-read
:re-builder (if org-roam-completion-fuzzy-match 'ivy--regex-fuzzy
'regexp-quote))
:caller 'org-roam--completing-read)
(user-error "Please install ivy from \
https://github.com/abo-abo/swiper")))
((eq org-roam-completion-system 'helm)
@ -96,8 +89,7 @@ https://github.com/emacs-helm/helm"))
:candidates (mapcar #'car choices)
:filtered-candidate-transformer
(and (not require-match)
#'org-roam-completion--helm-candidate-transformer)
:fuzzy-match org-roam-completion-fuzzy-match))
#'org-roam-completion--helm-candidate-transformer)))
(buf (concat "*org-roam "
(s-downcase (s-chop-suffix ":" (s-trim prompt)))
"*")))

View File

@ -1,11 +1,11 @@
;;; org-roam-dialies.el --- Roam Research replica with Org-mode -*- coding: utf-8; lexical-binding: t -*-
;;; org-roam-dailies.el --- Daily notes for Org-roam -*- coding: utf-8; lexical-binding: t; -*-
;;;
;; Copyright © 2020 Jethro Kuan <jethrokuan95@gmail.com>
;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/jethrokuan/org-roam
;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience
;; Version: 1.1.0
;; Version: 1.1.1
;; 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"))
;; This file is NOT part of GNU Emacs.
@ -34,6 +34,7 @@
;;; Library Requires
(require 'org-capture)
(require 'org-roam-capture)
(require 'org-roam-macs)
(defvar org-roam-dailies-capture-templates
'(("d" "daily" plain (function org-roam-capture--get-point)
@ -52,7 +53,8 @@
(org-roam-capture--info (list (cons 'time time)))
(org-roam-capture--context 'dailies))
(add-hook 'org-capture-after-finalize-hook #'org-roam-capture--find-file-h)
(org-roam--capture)))
(org-roam--with-template-error 'org-roam-dailies-capture-templates
(org-roam-capture--capture))))
(defun org-roam-dailies-today ()
"Create and find the daily note for today."
@ -69,7 +71,7 @@ With numeric argument N, use N days in the future."
"Create and find the file for yesterday.
With numeric argument N, use N days in the past."
(interactive "p")
(org-roam-tomorrow (- n)))
(org-roam-dailies-tomorrow (- n)))
(defun org-roam-dailies-date ()
"Create the file for any date using the calendar interface."
@ -78,4 +80,5 @@ With numeric argument N, use N days in the past."
(org-roam-dailies--file-for-time time)))
(provide 'org-roam-dailies)
;;; org-roam-dailies.el ends here

View File

@ -1,11 +1,11 @@
;;; org-roam-db.el --- Roam Research replica with Org-mode -*- coding: utf-8; lexical-binding: t -*-
;;; org-roam-db.el --- Org-roam database API -*- coding: utf-8; lexical-binding: t; -*-
;; Copyright © 2020 Jethro Kuan <jethrokuan95@gmail.com>
;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/jethrokuan/org-roam
;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience
;; Version: 1.1.0
;; Version: 1.1.1
;; 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"))
;; This file is NOT part of GNU Emacs.
@ -39,11 +39,13 @@
(defvar org-roam-directory)
(defvar org-roam-verbose)
(declare-function org-roam--extract-titles "org-roam")
(declare-function org-roam--extract-ref "org-roam")
(declare-function org-roam--extract-links "org-roam")
(declare-function org-roam--list-files "org-roam")
(declare-function org-roam-buffer--update-maybe "org-roam-buffer")
(declare-function org-roam--org-roam-file-p "org-roam")
(declare-function org-roam--extract-titles "org-roam")
(declare-function org-roam--extract-ref "org-roam")
(declare-function org-roam--extract-tags "org-roam")
(declare-function org-roam--extract-links "org-roam")
(declare-function org-roam--list-all-files "org-roam")
(declare-function org-roam-buffer--update-maybe "org-roam-buffer")
;;;; Options
(defcustom org-roam-db-location nil
@ -55,7 +57,7 @@ when used with multiple Org-roam instances."
:type 'string
:group 'org-roam)
(defconst org-roam-db--version 2)
(defconst org-roam-db--version 5)
(defconst org-roam-db--sqlite-available-p
(with-demoted-errors "Org-roam initialization: %S"
(emacsql-sqlite-ensure-binary)
@ -93,7 +95,7 @@ Performs a database upgrade when required."
(when init-db
(org-roam-db--init conn))
(let* ((version (caar (emacsql conn "PRAGMA user_version")))
(version (org-roam-db--maybe-update conn version)))
(version (org-roam-db--update-maybe conn version)))
(cond
((> version org-roam-db--version)
(emacsql-close conn)
@ -119,7 +121,7 @@ SQL can be either the emacsql vector representation, or a string."
'((files
[(file :unique :primary-key)
(hash :not-null)
(last-modified :not-null)])
(meta :not-null)])
(links
[(from :not-null)
@ -127,13 +129,18 @@ SQL can be either the emacsql vector representation, or a string."
(type :not-null)
(properties :not-null)])
(tags
[(file :unique :primary-key)
(tags)])
(titles
[(file :not-null)
titles])
(refs
[(ref :unique :not-null)
(file :not-null)])))
(file :not-null)
(type :not-null)])))
(defun org-roam-db--init (db)
"Initialize database DB with the correct schema and user version."
@ -142,16 +149,16 @@ SQL can be either the emacsql vector representation, or a string."
(emacsql db [:create-table $i1 $S2] table schema))
(emacsql db (format "PRAGMA user_version = %s" org-roam-db--version))))
(defun org-roam-db--maybe-update (db version)
(defun org-roam-db--update-maybe (db version)
"Upgrades the database schema for DB, if VERSION is old."
(emacsql-with-transaction db
'ignore
(when (= version 1)
(progn
(warn "No good way to perform a DB upgrade, rebuilding from scratch...")
(delete-file (org-roam-db--get))
(org-roam-db-build-cache)))
version))
(if (< version org-roam-db--version)
(progn
(org-roam-message (format "Upgrading the Org-roam database from version %d to version %d"
version org-roam-db--version))
(org-roam-db-build-cache t))))
version)
(defun org-roam-db--close (&optional db)
"Closes the database connection for database DB.
@ -185,32 +192,27 @@ the current `org-roam-directory'."
"Clears all entries in the caches."
(interactive)
(when (file-exists-p (org-roam-db--get))
(org-roam-db-query [:delete :from files])
(org-roam-db-query [:delete :from titles])
(org-roam-db-query [:delete :from links])
(org-roam-db-query [:delete :from refs])))
(dolist (table (mapcar #'car org-roam-db--table-schemata))
(org-roam-db-query `[:delete :from ,table]))))
(defun org-roam-db--clear-file (&optional filepath)
"Remove any related links to the file at FILEPATH.
This is equivalent to removing the node from the graph."
(let* ((path (or filepath
(buffer-file-name)))
(file (file-truename path)))
(org-roam-db-query [:delete :from files
:where (= file $s1)]
file)
(org-roam-db-query [:delete :from links
:where (= from $s1)]
file)
(org-roam-db-query [:delete :from titles
:where (= file $s1)]
file)
(org-roam-db-query [:delete :from refs
:where (= file $s1)]
file)))
(let ((file (file-truename (or filepath
(buffer-file-name (buffer-base-buffer))))))
(dolist (table (mapcar #'car org-roam-db--table-schemata))
(org-roam-db-query `[:delete :from ,table
:where (= ,(if (eq table 'links) 'from 'file) $s1)]
file))))
;;;;; Insertion
(defun org-roam-db--insert-meta (file hash meta)
"Insert HASH and META for a FILE into the Org-roam cache."
(org-roam-db-query
[:insert :into files
:values $v1]
(list (vector file hash meta))))
(defun org-roam-db--insert-links (links)
"Insert LINKS into the Org-roam cache."
(org-roam-db-query
@ -225,12 +227,20 @@ This is equivalent to removing the node from the graph."
:values $v1]
(list (vector file titles))))
(defun org-roam-db--insert-tags (file tags)
"Insert TAGS for a FILE into the Org-roam cache."
(org-roam-db-query
[:insert :into tags
:values $v1]
(list (vector file tags))))
(defun org-roam-db--insert-ref (file ref)
"Insert REF for FILE into the Org-roam cache."
(org-roam-db-query
[:insert :into refs
:values $v1]
(list (vector ref file))))
(let ((key (cdr ref))
(type (car ref)))
(org-roam-db-query
[:insert :into refs :values $v1]
(list (vector key file type)))))
;;;;; Fetching
(defun org-roam-db--get-current-files ()
@ -270,8 +280,9 @@ If the file does not have any connections, nil is returned."
files))
(defun org-roam-db--links-with-max-distance (file max-distance)
"Return all files reachable from/connected to FILE in at most MAX-DISTANCE steps,
including the file itself. If the file does not have any connections, nil is returned."
"Return all files connected to FILE in at most MAX-DISTANCE steps.
This includes the file itself. If the file does not have any
connections, nil is returned."
(let* ((query "WITH RECURSIVE
links_of(file, link) AS
(WITH roamlinks AS (SELECT * FROM links WHERE \"type\" = '\"roam\"'),
@ -302,13 +313,35 @@ including the file itself. If the file does not have any connections, nil is re
files))
;;;;; Updating
(defun org-roam-db--update-meta ()
"Update the metadata of the current buffer into the cache."
(let* ((file (file-truename (buffer-file-name)))
(attr (file-attributes file))
(atime (file-attribute-access-time attr))
(mtime (file-attribute-modification-time attr))
(hash (secure-hash 'sha1 (current-buffer))))
(org-roam-db-query [:delete :from files
:where (= file $s1)]
file)
(org-roam-db--insert-meta file hash (list :atime atime :mtime mtime))))
(defun org-roam-db--update-titles ()
"Update the title of the current buffer into the cache."
(let ((file (file-truename (buffer-file-name))))
(let* ((file (file-truename (buffer-file-name)))
(title (org-roam--extract-titles)))
(org-roam-db-query [:delete :from titles
:where (= file $s1)]
file)
(org-roam-db--insert-titles file (org-roam--extract-titles))))
(org-roam-db--insert-titles file title)))
(defun org-roam-db--update-tags ()
"Update the tags of the current buffer into the cache."
(let* ((file (file-truename (buffer-file-name)))
(tags (org-roam--extract-tags)))
(org-roam-db-query [:delete :from tags
:where (= file $s1)]
file)
(org-roam-db--insert-tags file tags)))
(defun org-roam-db--update-refs ()
"Update the ref of the current buffer into the cache."
@ -330,43 +363,53 @@ including the file itself. If the file does not have any connections, nil is re
(defun org-roam-db--update-file (&optional file-path)
"Update Org-roam cache for FILE-PATH."
(let (buf)
(if file-path
(setq buf (find-file-noselect file-path))
(setq buf (current-buffer)))
(with-current-buffer buf
(save-excursion
(org-roam-db--update-titles)
(org-roam-db--update-refs)
(org-roam-db--update-cache-links)
(org-roam-buffer--update-maybe :redisplay t)))))
(when (org-roam--org-roam-file-p file-path)
(let ((buf (or (and file-path
(find-file-noselect file-path t))
(current-buffer))))
(with-current-buffer buf
(save-excursion
(org-roam-db--update-meta)
(org-roam-db--update-tags)
(org-roam-db--update-titles)
(org-roam-db--update-refs)
(org-roam-db--update-cache-links)
(org-roam-buffer--update-maybe :redisplay t))))))
;;;;; org-roam-db-build-cache
(defun org-roam-db-build-cache ()
"Build the cache for `org-roam-directory'."
(interactive)
(defun org-roam-db-build-cache (&optional force)
"Build the cache for `org-roam-directory'.
If FORCE, force a rebuild of the cache from scratch."
(interactive "P")
(when force (delete-file (org-roam-db--get)))
(org-roam-db--close) ;; Force a reconnect
(org-roam-db) ;; To initialize the database, no-op if already initialized
(let* ((org-roam-files (org-roam--list-files org-roam-directory))
(let* ((org-roam-files (org-roam--list-all-files))
(current-files (org-roam-db--get-current-files))
(time (current-time))
all-files all-links all-titles all-refs)
all-files all-links all-titles all-refs all-tags)
(dolist (file org-roam-files)
(org-roam--with-temp-buffer
(insert-file-contents file)
(let ((contents-hash (secure-hash 'sha1 (current-buffer))))
(unless (string= (gethash file current-files)
contents-hash)
(org-roam-db--clear-file file)
(setq all-files
(cons (vector file contents-hash time) all-files))
(when-let (links (org-roam--extract-links file))
(setq all-links (append links all-links)))
(let ((titles (org-roam--extract-titles)))
(setq all-titles (cons (vector file titles) all-titles)))
(when-let ((ref (org-roam--extract-ref)))
(setq all-refs (cons (vector ref file) all-refs))))
(remhash file current-files))))
(let* ((attr (file-attributes file))
(atime (file-attribute-access-time attr))
(mtime (file-attribute-modification-time attr)))
(org-roam--with-temp-buffer
(insert-file-contents file)
(let ((contents-hash (secure-hash 'sha1 (current-buffer))))
(unless (string= (gethash file current-files)
contents-hash)
(org-roam-db--clear-file file)
(push (vector file contents-hash (list :atime atime :mtime mtime))
all-files)
(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))
@ -385,6 +428,11 @@ including the file itself. If the file does not have any connections, nil is re
[:insert :into titles
:values $v1]
all-titles))
(when all-tags
(org-roam-db-query
[:insert :into tags
:values $v1]
all-tags))
(when all-refs
(org-roam-db-query
[:insert :into refs
@ -392,16 +440,17 @@ including the file itself. If the file does not have any connections, nil is re
all-refs))
(let ((stats (list :files (length all-files)
:links (length all-links)
:tags (length all-tags)
:titles (length all-titles)
:refs (length all-refs)
:deleted (length (hash-table-keys current-files)))))
(when org-roam-verbose
(message "files: %s, links: %s, titles: %s, refs: %s, deleted: %s"
(plist-get stats :files)
(plist-get stats :links)
(plist-get stats :titles)
(plist-get stats :refs)
(plist-get stats :deleted)))
(org-roam-message "files: %s, links: %s, tags: %s, titles: %s, refs: %s, deleted: %s"
(plist-get stats :files)
(plist-get stats :links)
(plist-get stats :tags)
(plist-get stats :titles)
(plist-get stats :refs)
(plist-get stats :deleted))
stats)))
(provide 'org-roam-db)

40
org-roam-dev.el Normal file
View File

@ -0,0 +1,40 @@
;;; org-roam-dev.el --- Org-roam development code -mode -*- coding: utf-8; lexical-binding: t; -*-
;; Copyright © 2020 Jethro Kuan <jethrokuan95@gmail.com>
;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience
;; Version: 1.1.1
;; 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"))
;; This file is NOT part of GNU Emacs.
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
;;; Commentary:
;;
;; This library provides code for org-roam developers.
;; It is intended to be loaded before editing org-roam source files.
;; It ensures consistent application of various developer settings.
;;
;;; Code:
(require 'emacsql)
(emacsql-fix-vector-indentation)
(setq-local sentence-end-double-space nil)
(provide 'org-roam-dev)
;;; org-roam-dev.el ends here

231
org-roam-doctor.el Normal file
View File

@ -0,0 +1,231 @@
;;; org-roam-doctor.el --- Linter for Org-roam files -*- coding: utf-8; lexical-binding: t; -*-
;;
;; Copyright © 2020 Jethro Kuan <jethrokuan95@gmail.com>
;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/jethrokuan/org-roam
;; Keywords: org-mode, roam, convenience
;; Version: 1.1.1
;; 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"))
;; This file is NOT part of GNU Emacs.
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
;;; Commentary:
;;
;; This library provides `org-roam-doctor', a utility for diagnosing and fixing
;; Org-roam files. Running `org-roam-doctor' launches a list of checks defined
;; by `org-roam-doctor--checkers'. Every checker is an instance of
;; `org-roam-doctor-checker'.
;;
;; Each checker is given the Org parse tree (AST), and is expected to return a
;; list of errors. The checker can also provide "actions" for auto-fixing errors
;; (see `org-roam-doctor--remove-link' for an example).
;;
;; The UX experience is inspired by both org-lint and checkdoc, and their code
;; is heavily referenced.
;;
;;; Code:
;; Library Requires
(require 'cl-lib)
(require 'org)
(require 'org-roam-macs)
(require 'org-element)
(declare-function org-roam-insert "org-roam")
(declare-function org-roam--get-roam-buffers "org-roam")
(declare-function org-roam--list-all-files "org-roam")
(declare-function org-roam--org-roam-file-p "org-roam")
(defvar org-roam-verbose)
(cl-defstruct (org-roam-doctor-checker (:copier nil))
(name 'missing-checker-name)
(description "")
(actions nil))
(defconst org-roam-doctor--checkers
(list
(make-org-roam-doctor-checker
:name 'org-roam-doctor-broken-links
:description "Fix broken links."
:actions '(("d" . ("Unlink" . org-roam-doctor--remove-link))
("r" . ("Replace link" . org-roam-doctor--replace-link))
("R" . ("Replace link (keep label)" . org-roam-doctor--replace-link-keep-label))))))
(defun org-roam-doctor-broken-links (ast)
"Checker for detecting broken links.
AST is the org-element parse tree."
(let (reports)
(org-element-map ast 'link
(lambda (l)
(when (equal "file" (org-element-property :type l))
(let ((file (org-element-property :path l)))
(or (file-exists-p file)
(file-remote-p file)
(push
`(,(org-element-property :begin l)
,(format (if (org-element-lineage l '(link))
"Link to non-existent image file \"%s\"\
in link description"
"Link to non-existent local file \"%s\"")
file))
reports))))))
reports))
(defun org-roam-doctor--check (buffer checkers)
"Check BUFFER for errors.
CHECKERS is the list of checkers used."
(with-current-buffer buffer
(save-excursion
(goto-char (point-min))
(let* ((ast (org-element-parse-buffer))
(errors (sort (cl-mapcan
(lambda (c)
(mapcar
(lambda (report)
(list (set-marker (make-marker) (car report))
(nth 1 report) c))
(save-excursion
(funcall
(org-roam-doctor-checker-name c)
ast))))
checkers)
#'car-less-than-car)))
(dolist (e errors)
(pcase-let ((`(,m ,msg ,checker) e))
(switch-to-buffer buffer)
(goto-char m)
(org-reveal)
(undo-boundary)
(org-roam-doctor--resolve msg checker)
(set-marker m nil)))
errors))))
;;; Actions
(defun org-roam-doctor--recursive-edit ()
"Launch into a recursive edit."
(message "When you're done editing press C-M-c to continue.")
(recursive-edit))
(defun org-roam-doctor--skip ()
"Skip the current error."
(org-roam-message "Skipping..."))
(defun org-roam-doctor--replace-link ()
"Replace the current link with a new link."
(save-match-data
(unless (org-in-regexp org-link-bracket-re 1)
(user-error "No link at point"))
(let ((orig (buffer-string))
(p (point)))
(condition-case nil
(save-excursion
(replace-match "")
(org-roam-insert))
(quit (progn
(replace-buffer-contents orig)
(goto-char p)))))))
(defun org-roam-doctor--replace-link-keep-label ()
"Replace the current link with a new link, keeping the current link's label."
(save-match-data
(unless (org-in-regexp org-link-bracket-re 1)
(user-error "No link at point"))
(let ((orig (buffer-string))
(p (point)))
(condition-case nil
(save-excursion
(let ((label (if (match-end 2)
(match-string-no-properties 2)
(org-link-unescape (match-string-no-properties 1)))))
(replace-match "")
(org-roam-insert nil nil label)))
(quit (progn
(replace-buffer-contents orig)
(goto-char p)))))))
(defun org-roam-doctor--remove-link ()
"Unlink the text at point."
(unless (org-in-regexp org-link-bracket-re 1)
(user-error "No link at point"))
(save-excursion
(let ((label (if (match-end 2)
(match-string-no-properties 2)
(org-link-unescape (match-string-no-properties 1)))))
(delete-region (match-beginning 0) (match-end 0))
(insert label))))
(defun org-roam-doctor--resolve (msg checker)
"Resolve an error.
MSG is the error that was found, which is displayed in a help buffer.
CHECKER is a org-roam-doctor checker instance."
(let ((actions (org-roam-doctor-checker-actions checker))
c)
(push '("e" . ("Edit" . org-roam-doctor--recursive-edit)) actions)
(push '("s" . ("Skip" . org-roam-doctor--skip)) actions)
(with-output-to-temp-buffer "*Org-roam-doctor Help*"
(mapc #'princ
(list "Error message:\n " msg "\n\n"))
(dolist (action actions)
(princ (format "[%s]: %s\n"
(car action)
(cadr action))))
(princ "\n\n"))
(shrink-window-if-larger-than-buffer
(get-buffer-window "*Org-roam-doctor Help*"))
(message "Press key for command:")
(unwind-protect
(progn
(cl-loop
do (setq c (char-to-string (read-char-exclusive)))
until (assoc c actions)
do (message "Please enter a valid key for command:"))
(funcall (cddr (assoc c actions)))
(redisplay))
(when (get-buffer-window "*Org-roam-doctor Help*")
(delete-window (get-buffer-window "*Org-roam-doctor Help*"))
(kill-buffer "*Org-roam-doctor Help*")))))
;;;###autoload
(defun org-roam-doctor (&optional checkall)
"Perform a check on the current buffer to ensure cleanliness.
If CHECKALL, run the check for all Org-roam files."
(interactive "P")
(let ((files (if checkall
(org-roam--list-all-files)
(unless (org-roam--org-roam-file-p)
(user-error "Not in an org-roam file"))
`(,(buffer-file-name)))))
(org-roam-doctor-start files org-roam-doctor--checkers)))
(defun org-roam-doctor-start (files checkers)
"Lint FILES using CHECKERS."
(save-window-excursion
(let ((existing-buffers (org-roam--get-roam-buffers)))
(dolist (f files)
(let ((buf (find-file-noselect f)))
(org-roam-doctor--check buf checkers)
(unless (memq buf existing-buffers)
(save-buffer buf)
(kill-buffer buf))))))
(org-roam-message "Linting completed."))
(provide 'org-roam-doctor)
;;; org-roam-doctor.el ends here

View File

@ -1,11 +1,11 @@
;;; org-roam-graph.el --- Roam Research replica with Org-mode -*- coding: utf-8; lexical-binding: t -*-
;;; org-roam-graph.el --- Graphing API -*- coding: utf-8; lexical-binding: t; -*-
;; Copyright © 2020 Jethro Kuan <jethrokuan95@gmail.com>
;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/jethrokuan/org-roam
;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience
;; Version: 1.1.0
;; Version: 1.1.1
;; 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"))
;; This file is NOT part of GNU Emacs.
@ -53,8 +53,8 @@ It may be one of the following:
(const :tag "view-file"))
:group 'org-roam)
(defcustom org-roam-graph-executable (executable-find "dot")
"Path to graphing executable."
(defcustom org-roam-graph-executable "dot"
"Path to graphing executable, or its name."
:type 'string
:group 'org-roam)
@ -65,14 +65,20 @@ Example:
:type '(alist)
:group 'org-roam)
(defcustom org-roam-graph-node-extra-config nil
(defcustom org-roam-graph-node-extra-config
'(("shape" . "underline")
("style" . "rounded,filled")
("fillcolor" . "#EEEEEE")
("color" . "#C9C9C9")
("fontcolor" . "#111111"))
"Extra options for graphviz nodes.
Example:
'((\"color\" . \"skyblue\"))"
:type '(alist)
:group 'org-roam)
(defcustom org-roam-graph-edge-extra-config nil
(defcustom org-roam-graph-edge-extra-config
'(("color" . "#333333"))
"Extra options for graphviz edges.
Example:
'((\"dir\" . \"back\"))"
@ -91,6 +97,19 @@ Example:
:type 'number
:group 'org-roam)
(defcustom org-roam-graph-shorten-titles 'truncate
"Determines how long titles appear in graph nodes.
Recognized values are the symbols `truncate' and `wrap', in which
cases the title will be truncated or wrapped, respectively, if it
is longer than `org-roam-graph-max-title-length'.
All other values including nil will have no effect."
:type '(choice
(const :tag "truncate" truncate)
(const :tag "wrap" wrap)
(const :tag "no" nil))
:group 'org-roam)
(defcustom org-roam-graph-exclude-matcher nil
"Matcher for excluding nodes from the generated graph.
Any nodes and links for file paths matching this string is
@ -154,7 +173,8 @@ into a digraph."
`[:with selected :as [:select [file] :from ,node-query]
:select :distinct [file from]
:from links :inner :join refs :on (and (= links:to refs:ref)
(= links:type "cite"))
(= links:type "cite")
(= refs:type "cite"))
:where (and (in file selected) (in from selected))])
(edges (org-roam-db-query edges-query))
(edges-cites (org-roam-db-query edges-cites-query)))
@ -163,7 +183,8 @@ into a digraph."
(insert (org-roam-graph--dot-option option) ";\n"))
(dolist (attribute '("node" "edge"))
(insert (format " %s [%s];\n" attribute
(mapconcat #'org-roam-graph--dot-option
(mapconcat (lambda (var)
(org-roam-graph--dot-option var nil "\""))
(symbol-value
(intern (concat "org-roam-graph-" attribute "-extra-config")))
","))))
@ -171,7 +192,10 @@ into a digraph."
(let* ((file (xml-escape-string (car node)))
(title (or (caadr node)
(org-roam--path-to-slug file)))
(shortened-title (s-truncate org-roam-graph-max-title-length title))
(shortened-title (pcase org-roam-graph-shorten-titles
(`truncate (s-truncate org-roam-graph-max-title-length title))
(`wrap (s-word-wrap org-roam-graph-max-title-length title))
(_ title)))
(node-properties
`(("label" . ,(s-replace "\"" "\\\"" shortened-title))
("URL" . ,(concat "org-protocol://roam-file?file=" (url-hexify-string file)))
@ -195,19 +219,22 @@ into a digraph."
(defun org-roam-graph--build (&optional node-query)
"Generate a graph showing the relations between nodes in NODE-QUERY."
(unless org-roam-graph-executable
(user-error "Can't find %s executable. Please check if it is in your path"
org-roam-graph-executable))
(let* ((node-query (or node-query
`[:select [file titles]
:from titles
,@(org-roam-graph--expand-matcher 'file t)]))
(graph (org-roam-graph--dot node-query))
(temp-dot (make-temp-file "graph." nil ".dot" graph))
(temp-graph (make-temp-file "graph." nil ".svg")))
(call-process org-roam-graph-executable nil 0 nil
temp-dot "-Tsvg" "-o" temp-graph)
temp-graph))
(let ((name org-roam-graph-executable))
(unless (stringp name)
(user-error "`org-roam-graph-executable' is not a string"))
(unless (executable-find org-roam-graph-executable)
(user-error (concat "Cannot find executable \"%s\" to generate the graph. "
"Please adjust `org-roam-graph-executable'")
name))
(let* ((node-query (or node-query
`[:select [file titles]
:from titles
,@(org-roam-graph--expand-matcher 'file t)]))
(graph (org-roam-graph--dot node-query))
(temp-dot (make-temp-file "graph." nil ".dot" graph))
(temp-graph (make-temp-file "graph." nil ".svg")))
(call-process name nil 0 nil temp-dot "-Tsvg" "-o" temp-graph)
temp-graph)))
(defun org-roam-graph--open (file)
"Open FILE using `org-roam-graph-viewer' with `view-file' as a fallback."
@ -216,7 +243,7 @@ into a digraph."
(if (executable-find org-roam-graph-viewer)
(condition-case err
(call-process org-roam-graph-viewer nil 0 nil file)
((error (user-error "Failed to open org-roam graph: %s" err))))
(error (user-error "Failed to open org-roam graph: %s" err)))
(user-error "Executable not found: \"%s\"" org-roam-graph-viewer)))
((pred functionp) (funcall org-roam-graph-viewer file))
('nil (view-file file))
@ -248,15 +275,16 @@ ARG may be any of the following values:
- `\\[universal-argument]' - build the graph for FILE.
- `\\[universal-argument]' -N build the graph for FILE limiting nodes to N steps."
(interactive "P")
(let ((file (or file (buffer-file-name))))
(unless file
(user-error "Cannot build graph for nil file. Is current buffer visiting a file?"))
(unless (org-roam--org-roam-file-p file)
(user-error "\"%s\" is not an org-roam file" file))
(let ((file (or file (buffer-file-name (buffer-base-buffer)))))
(unless (or (not arg) (equal arg '(16)))
(unless file
(user-error "Cannot build graph for nil file. Is current buffer visiting a file?"))
(unless (org-roam--org-roam-file-p file)
(user-error "\"%s\" is not an org-roam file" file)))
(pcase arg
('nil (org-roam-graph--open (org-roam-graph--build node-query)))
('(4) (org-roam-graph--open (org-roam-graph--build-connected-component file)))
((pred integerp) (let ((graph (org-roam-graph--build-connected-component (buffer-file-name) (abs arg))))
((pred integerp) (let ((graph (org-roam-graph--build-connected-component file (abs arg))))
(when (>= arg 0)
(org-roam-graph--open graph))))
('(16) (org-roam-graph--build node-query))

View File

@ -1,11 +1,11 @@
;;; org-roam-macs.el --- Roam Research replica with Org-mode -*- coding: utf-8; lexical-binding: t -*-
;;; org-roam-macs.el --- Macros/utility functions -*- coding: utf-8; lexical-binding: t; -*-
;; Copyright © 2020 Jethro Kuan <jethrokuan95@gmail.com>
;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/jethrokuan/org-roam
;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience
;; Version: 1.1.0
;; Version: 1.1.1
;; 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"))
;; This file is NOT part of GNU Emacs.
@ -27,12 +27,15 @@
;;; Commentary:
;;
;; This library implements macros used throughout org-roam
;; This library implements macros and utility functions used throughout
;; org-roam.
;;
;;
;;; Code:
;;;; Library Requires
(defvar org-roam-verbose)
(defmacro org-roam--with-temp-buffer (&rest body)
"Execute BODY within a temp buffer.
Like `with-temp-buffer', but propagates `org-roam-directory'."
@ -43,6 +46,24 @@ Like `with-temp-buffer', but propagates `org-roam-directory'."
(let ((org-roam-directory ,current-org-roam-directory))
,@body)))))
(defmacro org-roam--with-template-error (templates &rest body)
"Eval BODY, and point to TEMPLATES on error.
Provides more informative error messages so that users know where
to look.
\(fn TEMPLATES BODY...)"
(declare (debug (form body)) (indent 1))
`(condition-case err
,@body
(error (user-error "%s. Please adjust `%s'"
(error-message-string err)
,templates))))
(defun org-roam-message (format-string &rest args)
"Pass FORMAT-STRING and ARGS to `message' when `org-roam-verbose' is t."
(when org-roam-verbose
(apply #'message `(,(concat "(org-roam) " format-string) ,@args))))
(provide 'org-roam-macs)
;;; org-roam-macs.el ends here

View File

@ -1,10 +1,10 @@
;;; org-roam-protocol.el --- Protocol handler for roam:// links -*- coding: utf-8; lexical-binding: t -*-
;;; org-roam-protocol.el --- Protocol handler for roam:// links -*- coding: utf-8; lexical-binding: t; -*-
;; Copyright © 2020 Jethro Kuan <jethrokuan95@gmail.com>
;; Author: Jethro Kuan <jethrokuan95@gmail.com>
;; URL: https://github.com/jethrokuan/org-roam
;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience
;; Version: 1.1.0
;; Version: 1.1.1
;; Package-Requires: ((emacs "26.1") (org "9.3"))
;; This file is NOT part of GNU Emacs.
@ -62,8 +62,9 @@ It opens or creates a note with the given ref.
(org-roam-capture--info decoded-alist)
(template (cdr (assoc 'template decoded-alist))))
(raise-frame)
(org-roam--capture nil template)
(message "Item captured.")))
(org-roam--with-template-error 'org-roam-capture-ref-templates
(org-roam-capture--capture nil template))
(org-roam-message "Item captured.")))
nil)
(defun org-roam-protocol-open-file (info)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
#+TITLE: Base

View File

@ -0,0 +1 @@
#+TITLE: Deeply Nested File

View File

@ -1,3 +1,5 @@
no title in this file :O
links to itself, with no title: [[file:no-title.org][no-title]]
* Headline title

View File

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

View File

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

View File

@ -0,0 +1 @@
#+ROAM_ALIAS: "roam" "alias"

View File

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

View File

@ -0,0 +1 @@
* Headline

View File

@ -0,0 +1 @@
#+TITLE: Title

View File

@ -1,4 +1,4 @@
;;; test-org-roam.el --- Tests for org-roam -*- lexical-binding: t; -*-
;;; test-org-roam.el --- Tests for Org-roam -*- lexical-binding: t; -*-
;; Copyright (C) 2020 Jethro Kuan
@ -19,237 +19,395 @@
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;;
;;; Code:
;;;; Requirements
(require 'buttercup)
(require 'with-simulated-input)
(require 'org-roam)
(require 'dash)
(defun org-roam-test-abs-path (file-path)
(defun test-org-roam--abs-path (file-path)
"Get absolute FILE-PATH from `org-roam-directory'."
(file-truename (expand-file-name file-path org-roam-directory)))
(defun org-roam-test-find-new-file (path)
(defun test-org-roam--find-file (path)
"PATH."
(let ((path (org-roam-test-abs-path path)))
(let ((path (test-org-roam--abs-path path)))
(make-directory (file-name-directory path) t)
(find-file path)))
(defvar org-roam-test-directory (file-truename (concat default-directory "tests/roam-files"))
(defvar test-org-roam-directory (file-truename (concat default-directory "tests/roam-files"))
"Directory containing org-roam test org files.")
(defun org-roam-test-init ()
(defun test-org-roam--init ()
"."
(org-roam-db--close)
(let ((original-dir org-roam-test-directory)
(let ((original-dir test-org-roam-directory)
(new-dir (expand-file-name (make-temp-name "org-roam") temporary-file-directory)))
(copy-directory original-dir new-dir)
(setq org-roam-directory new-dir)
(org-roam-mode +1)))
(org-roam-mode +1)
(sleep-for 2)))
(defun test-org-roam--teardown ()
(org-roam-mode -1)
(delete-file (org-roam-db--get))
(org-roam-db--close))
(describe "Title extraction"
:var (org-roam-title-sources)
(before-all
(test-org-roam--init))
(after-all
(test-org-roam--teardown))
(cl-flet
((test (fn file)
(let ((buf (find-file-noselect
(test-org-roam--abs-path file))))
(with-current-buffer buf
(funcall fn)))))
(it "extracts title from title property"
(expect (test #'org-roam--extract-titles-title
"titles/title.org")
:to-equal
'("Title"))
(expect (test #'org-roam--extract-titles-title
"titles/aliases.org")
:to-equal
nil)
(expect (test #'org-roam--extract-titles-title
"titles/headline.org")
:to-equal
nil)
(expect (test #'org-roam--extract-titles-title
"titles/combination.org")
:to-equal
'("TITLE PROP")))
(it "extracts alias"
(expect (test #'org-roam--extract-titles-alias
"titles/title.org")
:to-equal
nil)
(expect (test #'org-roam--extract-titles-alias
"titles/aliases.org")
:to-equal
'("roam" "alias"))
(expect (test #'org-roam--extract-titles-alias
"titles/headline.org")
:to-equal
nil)
(expect (test #'org-roam--extract-titles-alias
"titles/combination.org")
:to-equal
'("roam" "alias")))
(it "extracts headlines"
(expect (test #'org-roam--extract-titles-alias
"titles/title.org")
:to-equal
nil)
(expect (test #'org-roam--extract-titles-headline
"titles/aliases.org")
:to-equal
nil)
(expect (test #'org-roam--extract-titles-headline
"titles/headline.org")
:to-equal
'("Headline"))
(expect (test #'org-roam--extract-titles-headline
"titles/combination.org")
:to-equal
'("Headline")))
(describe "uses org-roam-title-sources correctly"
(it "'((title headline) alias)"
(expect (let ((org-roam-title-sources '((title headline) alias)))
(test #'org-roam--extract-titles
"titles/combination.org"))
:to-equal
'("TITLE PROP" "roam" "alias")))
(it "'((headline title) alias)"
(expect (let ((org-roam-title-sources '((headline title) alias)))
(test #'org-roam--extract-titles
"titles/combination.org"))
:to-equal
'("Headline" "roam" "alias")))
(it "'(headline alias title)"
(expect (let ((org-roam-title-sources '(headline alias title)))
(test #'org-roam--extract-titles
"titles/combination.org"))
:to-equal
'("Headline" "roam" "alias" "TITLE PROP"))))))
(describe "Tag extraction"
:var (org-roam-tag-sources)
(before-all
(test-org-roam--init))
(after-all
(test-org-roam--teardown))
(cl-flet
((test (fn file)
(let* ((fname (test-org-roam--abs-path file))
(buf (find-file-noselect fname)))
(with-current-buffer buf
(funcall fn fname)))))
(it "extracts from prop"
(expect (test #'org-roam--extract-tags-prop
"tags/tag.org")
:to-equal
'("t1" "t2 with space" "t3"))
(expect (test #'org-roam--extract-tags-prop
"tags/no_tag.org")
:to-equal
nil))
(it "extracts from all directories"
(expect (test #'org-roam--extract-tags-all-directories
"base.org")
:to-equal
nil)
(expect (test #'org-roam--extract-tags-all-directories
"tags/tag.org")
:to-equal
'("tags"))
(expect (test #'org-roam--extract-tags-all-directories
"nested/deeply/deeply_nested_file.org")
:to-equal
'("nested" "deeply")))
(it "extracts from last directory"
(expect (test #'org-roam--extract-tags-last-directory
"base.org")
:to-equal
nil)
(expect (test #'org-roam--extract-tags-last-directory
"tags/tag.org")
:to-equal
'("tags"))
(expect (test #'org-roam--extract-tags-last-directory
"nested/deeply/deeply_nested_file.org")
:to-equal
'("deeply")))
(describe "uses org-roam-tag-sources correctly"
(it "'(prop)"
(expect (let ((org-roam-tag-sources '(prop)))
(test #'org-roam--extract-tags
"tags/tag.org"))
:to-equal
'("t1" "t2 with space" "t3")))
(it "'(prop all-directories)"
(expect (let ((org-roam-tag-sources '(prop all-directories)))
(test #'org-roam--extract-tags
"tags/tag.org"))
:to-equal
'("t1" "t2 with space" "t3" "tags"))))))
;;; Tests
(describe "org-roam-db-build-cache"
(it "initializes correctly"
(org-roam-test-init)
(org-roam-db-build-cache)
(xdescribe "org-roam-db-build-cache"
(before-each
(test-org-roam--init))
(after-each
(test-org-roam--teardown))
(it "initializes correctly"
;; Cache
(expect (caar (org-roam-db-query [:select (funcall count) :from files])) :to-be 8)
(expect (caar (org-roam-db-query [:select (funcall count) :from links])) :to-be 5)
(expect (caar (org-roam-db-query [:select (funcall count) :from titles])) :to-be 8)
(expect (caar (org-roam-db-query [:select (funcall count) :from titles
:where titles :is-null])) :to-be 2)
:where titles :is-null])) :to-be 1)
(expect (caar (org-roam-db-query [:select (funcall count) :from refs])) :to-be 1)
;; TODO Test files
;; Links
(expect (caar (org-roam-db-query [:select (funcall count) :from links
:where (= from $s1)]
(org-roam-test-abs-path "foo.org"))) :to-be 1)
(test-org-roam--abs-path "foo.org"))) :to-be 1)
(expect (caar (org-roam-db-query [:select (funcall count) :from links
:where (= from $s1)]
(org-roam-test-abs-path "nested/bar.org"))) :to-be 2)
(test-org-roam--abs-path "nested/bar.org"))) :to-be 2)
;; Links -- File-to
(expect (caar (org-roam-db-query [:select (funcall count) :from links
:where (= to $s1)]
(org-roam-test-abs-path "nested/foo.org"))) :to-be 1)
(test-org-roam--abs-path "nested/foo.org"))) :to-be 1)
(expect (caar (org-roam-db-query [:select (funcall count) :from links
:where (= to $s1)]
(org-roam-test-abs-path "nested/bar.org"))) :to-be 1)
(test-org-roam--abs-path "nested/bar.org"))) :to-be 1)
(expect (caar (org-roam-db-query [:select (funcall count) :from links
:where (= to $s1)]
(org-roam-test-abs-path "unlinked.org"))) :to-be 0)
(test-org-roam--abs-path "unlinked.org"))) :to-be 0)
;; TODO Test titles
(expect (org-roam-db-query [:select * :from titles])
:to-have-same-items-as
(list (list (org-roam-test-abs-path "alias.org")
(list (list (test-org-roam--abs-path "alias.org")
(list "t1" "a1" "a 2"))
(list (org-roam-test-abs-path "bar.org")
(list (test-org-roam--abs-path "bar.org")
(list "Bar"))
(list (org-roam-test-abs-path "foo.org")
(list (test-org-roam--abs-path "foo.org")
(list "Foo"))
(list (org-roam-test-abs-path "nested/bar.org")
(list (test-org-roam--abs-path "nested/bar.org")
(list "Nested Bar"))
(list (org-roam-test-abs-path "nested/foo.org")
(list (test-org-roam--abs-path "nested/foo.org")
(list "Nested Foo"))
(list (org-roam-test-abs-path "no-title.org") nil)
(list (org-roam-test-abs-path "web_ref.org") nil)
(list (org-roam-test-abs-path "unlinked.org")
(list (test-org-roam--abs-path "no-title.org")
(list "Headline title"))
(list (test-org-roam--abs-path "web_ref.org") nil)
(list (test-org-roam--abs-path "unlinked.org")
(list "Unlinked"))))
(expect (org-roam-db-query [:select * :from refs])
:to-have-same-items-as
(list (list "https://google.com/" (org-roam-test-abs-path "web_ref.org"))))
(list (list "https://google.com/" (test-org-roam--abs-path "web_ref.org") "website")))
;; Expect rebuilds to be really quick (nothing changed)
(expect (org-roam-db-build-cache)
:to-equal
(list :files 0 :links 0 :titles 0 :refs 0 :deleted 0))))
(list :files 0 :links 0 :tags 0 :titles 0 :refs 0 :deleted 0))))
(describe "org-roam-insert"
(xdescribe "org-roam-insert"
(before-each
(org-roam-test-init)
(org-roam-db--clear)
(org-roam-db-build-cache))
(test-org-roam--init))
(after-each
(test-org-roam--teardown))
(it "temp1 -> foo"
(let ((buf (org-roam-test-find-new-file "temp1.org")))
(let ((buf (test-org-roam--find-file "temp1.org")))
(with-current-buffer buf
(with-simulated-input
"Foo RET"
(org-roam-insert nil))))
(org-roam-insert))))
(expect (buffer-string) :to-match (regexp-quote "file:foo.org")))
(it "temp2 -> nested/foo"
(let ((buf (org-roam-test-find-new-file "temp2.org")))
(let ((buf (test-org-roam--find-file "temp2.org")))
(with-current-buffer buf
(with-simulated-input
"Nested SPC Foo RET"
(org-roam-insert nil))))
"(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 (org-roam-test-find-new-file "nested/temp3.org")))
(let ((buf (test-org-roam--find-file "nested/temp3.org")))
(with-current-buffer buf
(with-simulated-input
"Foo RET"
(org-roam-insert nil))))
(org-roam-insert))))
(expect (buffer-string) :to-match (regexp-quote "file:../foo.org")))
(it "a/b/temp4 -> nested/foo"
(let ((buf (org-roam-test-find-new-file "a/b/temp4.org")))
(let ((buf (test-org-roam--find-file "a/b/temp4.org")))
(with-current-buffer buf
(with-simulated-input
"Nested SPC Foo RET"
(org-roam-insert nil))))
"(nested) SPC Nested SPC Foo RET"
(org-roam-insert))))
(expect (buffer-string) :to-match (regexp-quote "file:../../nested/foo.org"))))
(describe "rename file updates cache"
(xdescribe "rename file updates cache"
(before-each
(org-roam-test-init)
(org-roam-db--clear)
(org-roam-db-build-cache))
(test-org-roam--init))
(after-each
(test-org-roam--teardown))
(it "foo -> new_foo"
(rename-file (org-roam-test-abs-path "foo.org")
(org-roam-test-abs-path "new_foo.org"))
(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)]
(org-roam-test-abs-path "foo.org"))) :to-be 0)
(test-org-roam--abs-path "foo.org"))) :to-be 0)
(expect (caar (org-roam-db-query [:select (funcall count)
:from refs
:where (= file $s1)]
(org-roam-test-abs-path "foo.org"))) :to-be 0)
(test-org-roam--abs-path "foo.org"))) :to-be 0)
(expect (caar (org-roam-db-query [:select (funcall count)
:from links
:where (= from $s1)]
(org-roam-test-abs-path "foo.org"))) :to-be 0)
(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)]
(org-roam-test-abs-path "new_foo.org"))
(test-org-roam--abs-path "new_foo.org"))
:to-have-same-items-as
(list (list (org-roam-test-abs-path "bar.org"))))
(list (list (test-org-roam--abs-path "bar.org"))))
(expect (org-roam-db-query [:select [from]
:from links
:where (= to $s1)]
(org-roam-test-abs-path "new_foo.org"))
(test-org-roam--abs-path "new_foo.org"))
:to-have-same-items-as
(list (list (org-roam-test-abs-path "nested/bar.org"))))
(list (list (test-org-roam--abs-path "nested/bar.org"))))
;; Links are updated
(expect (with-temp-buffer
(insert-file-contents (org-roam-test-abs-path "nested/bar.org"))
(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 (org-roam-test-abs-path "foo.org")
(org-roam-test-abs-path "foo with spaces.org"))
(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)]
(org-roam-test-abs-path "foo.org"))) :to-be 0)
(test-org-roam--abs-path "foo.org"))) :to-be 0)
(expect (caar (org-roam-db-query [:select (funcall count)
:from refs
:where (= file $s1)]
(org-roam-test-abs-path "foo.org"))) :to-be 0)
(test-org-roam--abs-path "foo.org"))) :to-be 0)
(expect (caar (org-roam-db-query [:select (funcall count)
:from links
:where (= from $s1)]
(org-roam-test-abs-path "foo.org"))) :to-be 0)
(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)]
(org-roam-test-abs-path "foo with spaces.org"))
(test-org-roam--abs-path "foo with spaces.org"))
:to-have-same-items-as
(list (list (org-roam-test-abs-path "bar.org"))))
(list (list (test-org-roam--abs-path "bar.org"))))
(expect (org-roam-db-query [:select [from]
:from links
:where (= to $s1)]
(org-roam-test-abs-path "foo with spaces.org"))
(test-org-roam--abs-path "foo with spaces.org"))
:to-have-same-items-as
(list (list (org-roam-test-abs-path "nested/bar.org"))))
(list (list (test-org-roam--abs-path "nested/bar.org"))))
;; Links are updated
(expect (with-temp-buffer
(insert-file-contents (org-roam-test-abs-path "nested/bar.org"))
(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 (org-roam-test-abs-path "no-title.org")
(org-roam-test-abs-path "meaningful-title.org"))
(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)]
(org-roam-test-abs-path "no-title.org"))) :to-be 0)
(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)]
(org-roam-test-abs-path "meaningful-title.org"))) :to-be 1)
(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 (org-roam-test-abs-path "meaningful-title.org"))
(insert-file-contents (test-org-roam--abs-path "meaningful-title.org"))
(buffer-string))
:to-match
(regexp-quote "[[file:meaningful-title.org][meaningful-title]]")))
@ -260,47 +418,47 @@
:where (= ref $s1)]
"https://google.com/")
:to-equal
(list (list (org-roam-test-abs-path "web_ref.org"))))
(rename-file (org-roam-test-abs-path "web_ref.org")
(org-roam-test-abs-path "hello.org"))
(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 (org-roam-test-abs-path "hello.org"))))
:to-equal (list (list (test-org-roam--abs-path "hello.org"))))
(expect (caar (org-roam-db-query
[:select [ref] :from refs
:where (= file $s1)]
(org-roam-test-abs-path "web_ref.org")))
(test-org-roam--abs-path "web_ref.org")))
:to-equal nil)))
(describe "delete file updates cache"
(xdescribe "delete file updates cache"
(before-each
(org-roam-test-init)
(org-roam-db--clear)
(org-roam-db-build-cache)
(sleep-for 1))
(test-org-roam--init))
(after-each
(test-org-roam--teardown))
(it "delete foo"
(delete-file (org-roam-test-abs-path "foo.org"))
(delete-file (test-org-roam--abs-path "foo.org"))
(expect (caar (org-roam-db-query [:select (funcall count)
:from titles
:where (= file $s1)]
(org-roam-test-abs-path "foo.org"))) :to-be 0)
(test-org-roam--abs-path "foo.org"))) :to-be 0)
(expect (caar (org-roam-db-query [:select (funcall count)
:from refs
:where (= file $s1)]
(org-roam-test-abs-path "foo.org"))) :to-be 0)
(test-org-roam--abs-path "foo.org"))) :to-be 0)
(expect (caar (org-roam-db-query [:select (funcall count)
:from links
:where (= from $s1)]
(org-roam-test-abs-path "foo.org"))) :to-be 0))
(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/" (org-roam-test-abs-path "web_ref.org"))))
(delete-file (org-roam-test-abs-path "web_ref.org"))
(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))))