mirror of
https://github.com/org-roam/org-roam
synced 2025-08-03 12:27:23 -05:00
Compare commits
103 Commits
Author | SHA1 | Date | |
---|---|---|---|
c1ab5ea693 | |||
bd5aec066b | |||
a53ccbf485 | |||
07135ad2e4 | |||
3f3bb79554 | |||
a6d210b80a | |||
fc8638759b | |||
1958e035fc | |||
1ea7e3077c | |||
7ce95a286b | |||
c172951345 | |||
0786f73669 | |||
df4e903208 | |||
d099204129 | |||
031ee63bee | |||
fed577f805 | |||
2ff616fbd8 | |||
046822b512 | |||
cce9591c1c | |||
db4170a459 | |||
0037daaf3e | |||
888b5d1a67 | |||
ed272eaf56 | |||
551ff3b17e | |||
719594dfc7 | |||
b4b8d8c0ee | |||
0d51698839 | |||
7dc76b708b | |||
f3db974bcc | |||
bb08be4740 | |||
2490afe110 | |||
40b6c10d8a | |||
425d53d56d | |||
64e302c126 | |||
cad3518788 | |||
2a630476b3 | |||
9fd7c87b5b | |||
0b9fcbc97b | |||
e415610b05 | |||
3e186a8552 | |||
0b2218706d | |||
84334b7e16 | |||
3c52d581ae | |||
fdd834d9bf | |||
8e6938a39d | |||
a753ec097d | |||
43a5362ada | |||
a432539121 | |||
1ce760ccc7 | |||
76df9d1f3c | |||
74d714f789 | |||
6644cb27a9 | |||
94b826d759 | |||
edccf9be84 | |||
aa64cc9596 | |||
e93c77f6a5 | |||
2d1c5d78e8 | |||
f8b40a3109 | |||
7fdc7150cc | |||
8667e44187 | |||
2e94f55cc5 | |||
5c06471c3a | |||
b5436f3410 | |||
f7dc81e494 | |||
e73807efe1 | |||
1981dc3617 | |||
7d2f511251 | |||
74422df546 | |||
938c602faa | |||
45a6863e07 | |||
cdad2ee7f6 | |||
256fe73e7a | |||
f9228ce319 | |||
25c476791e | |||
78ee5c6814 | |||
3add6748ae | |||
e418037991 | |||
05f67901c6 | |||
c2e852e102 | |||
4e6f934690 | |||
d95d25615e | |||
7f453f3fff | |||
e435581215 | |||
917a325dd9 | |||
c386761914 | |||
171a8db32f | |||
bbac208fda | |||
fcefc1b1b4 | |||
0cd9b9e6d3 | |||
83a0b3d464 | |||
ed7d4f0a2e | |||
32557afdbf | |||
f144941dfb | |||
01843a6486 | |||
1f51ec91d5 | |||
2657f0b444 | |||
455f139d3e | |||
b2d9543fa2 | |||
c0871c42be | |||
007e76725c | |||
5483e65d5a | |||
b63ff2a7bb | |||
e8b4822a85 |
33
.github/workflows/docs.yml
vendored
33
.github/workflows/docs.yml
vendored
@ -1,31 +1,28 @@
|
||||
---
|
||||
# * docs.yml --- Build the documentation and publish to Github Pages
|
||||
|
||||
name: "Docs"
|
||||
name: Docs
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: true
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install deps
|
||||
run: |
|
||||
sudo apt-get install texinfo
|
||||
- name: Install deps
|
||||
run: sudo apt install texinfo
|
||||
|
||||
- name: Build docs
|
||||
continue-on-error: false
|
||||
run: make html
|
||||
- name: Build docs
|
||||
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
|
||||
- name: Deploy 🚀
|
||||
uses: JamesIves/github-pages-deploy-action@releases/v4
|
||||
with:
|
||||
token: ${{ secrets.ACCESS_TOKEN }}
|
||||
branch: gh-pages # The branch the action should deploy to.
|
||||
folder: doc
|
||||
clean: true
|
||||
|
43
.github/workflows/test.yml
vendored
43
.github/workflows/test.yml
vendored
@ -1,7 +1,4 @@
|
||||
# * test.yml --- Test Emacs packages using makem.sh on GitHub Actions
|
||||
|
||||
# https://github.com/alphapapa/makem.sh
|
||||
|
||||
---
|
||||
# Based on Steve Purcell's examples at
|
||||
# <https://github.com/purcell/setup-emacs/blob/master/.github/workflows/test.yml>,
|
||||
# <https://github.com/purcell/package-lint/blob/master/.github/workflows/test.yml>.
|
||||
@ -23,12 +20,12 @@
|
||||
|
||||
# * Code:
|
||||
|
||||
name: "CI"
|
||||
name: CI
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@ -36,17 +33,21 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
emacs_version:
|
||||
- 27.1
|
||||
# REVIEW: we do not yet have the bootstrapping in place to test
|
||||
# versions of emacs without built-in sqlite (pre 29.1)
|
||||
# - 27.2
|
||||
# - 28.2
|
||||
- 29.4
|
||||
- snapshot
|
||||
steps:
|
||||
- uses: purcell/setup-emacs@master
|
||||
with:
|
||||
version: ${{ matrix.emacs_version }}
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install Eldev
|
||||
run: curl -fsSL https://raw.github.com/org-roam/org-roam/master/github-eldev | sh
|
||||
uses: emacs-eldev/setup-eldev@v1
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install dependencies
|
||||
run: make prepare
|
||||
@ -56,6 +57,28 @@ jobs:
|
||||
|
||||
- name: Test
|
||||
run: make test
|
||||
|
||||
docs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install deps
|
||||
run: sudo apt install texinfo
|
||||
|
||||
- name: Build docs
|
||||
run: make html
|
||||
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Docs
|
||||
if-no-files-found: error
|
||||
# TODO: optimize images
|
||||
path: |
|
||||
doc/
|
||||
!doc/images/
|
||||
|
||||
# Local Variables:
|
||||
# eval: (outline-minor-mode)
|
||||
# End:
|
||||
|
93
.github/workflows/tidy-issues.yml
vendored
Normal file
93
.github/workflows/tidy-issues.yml
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
name: 'Manage stale/dormant issues and PRs'
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 1 * * *' # Daily at 1 AM UTC
|
||||
workflow_dispatch: # Allow this to be run manually
|
||||
inputs:
|
||||
dry_run:
|
||||
description: 'Dry run: Show what would happen without making changes'
|
||||
required: false
|
||||
default: 'false'
|
||||
type: boolean
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Handle stale issues/PRs
|
||||
- name: Mark/close stale issues and PRs
|
||||
uses: actions/stale@v9
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Dry run setting
|
||||
debug-only: ${{ github.event.inputs.dry_run == 'true' }}
|
||||
|
||||
# Messages
|
||||
stale-issue-message: |
|
||||
📅 **Stale Issue Notice**
|
||||
|
||||
This issue has been automatically marked as stale because it has not had recent activity for **6 months**.
|
||||
|
||||
**⏰ This issue will be closed in 2 weeks** if no further activity occurs.
|
||||
|
||||
**To keep this issue open:**
|
||||
- Comment on this issue
|
||||
- Reference it in a commit or PR
|
||||
- Add new information or updates
|
||||
|
||||
Thank you for your contributions to org-roam! 🙏
|
||||
|
||||
close-issue-message: |
|
||||
🔒 **Issue Automatically Closed**
|
||||
|
||||
This issue was automatically closed due to **6 months of inactivity** followed by 2 weeks notice.
|
||||
|
||||
**To reopen:**
|
||||
- If still relevant, comment below and we'll reopen
|
||||
- Or create a new issue with updated information
|
||||
|
||||
If this issue is not reopened in 2 weeks, it will be locked.
|
||||
|
||||
This helps keep our issue tracker focused and manageable.
|
||||
|
||||
stale-pr-message: |
|
||||
📅 **Stale Pull Request Notice**
|
||||
|
||||
This pull request has been automatically marked as stale because it has not had recent activity for **6 months**.
|
||||
|
||||
**⏰ This PR will be closed in 2 weeks** if no further activity occurs.
|
||||
|
||||
**To keep this PR open:**
|
||||
- Push new commits
|
||||
- Comment with updates
|
||||
- Rebase on latest main branch
|
||||
|
||||
Thank you for your contributions to org-roam! 🙏
|
||||
|
||||
close-pr-message: |
|
||||
🔒 **Pull Request Automatically Closed**
|
||||
|
||||
This pull request was automatically closed due to **6 months of inactivity** followed by 2 weeks notice.
|
||||
|
||||
# Timing (6 months + 2 weeks)
|
||||
days-before-stale: 182 # ~6 months
|
||||
days-before-close: 14 # 2 weeks notice
|
||||
|
||||
# Performance
|
||||
operations-per-run: 1000
|
||||
|
||||
# Show dry run summary
|
||||
- name: Dry run summary
|
||||
if: github.event.inputs.dry_run == 'true'
|
||||
run: |
|
||||
echo "🧪 DRY RUN COMPLETED"
|
||||
echo "This was a dry run - no actual changes were made."
|
||||
echo "Check the action logs above to see what would have happened."
|
||||
echo ""
|
||||
echo "To run for real:"
|
||||
echo "1. Go to Actions tab"
|
||||
echo "2. Click 'Run workflow'"
|
||||
echo "3. Leave 'Dry run mode' unchecked"
|
||||
echo "4. Click 'Run workflow'"
|
119
CHANGELOG.md
119
CHANGELOG.md
@ -1,5 +1,92 @@
|
||||
# Changelog
|
||||
## 2.2.2
|
||||
|
||||
## 2.3.1 (2025-06-26)
|
||||
|
||||
* (fix): Use correct type specifications to suppress warnings by @okomestudio in https://github.com/org-roam/org-roam/pull/2522
|
||||
* perf: suppress extra org features in the temp buffer by @dustinfarris in https://github.com/org-roam/org-roam/pull/2524
|
||||
|
||||
## 2.3.0 (2025-05-24)
|
||||
|
||||
* (perf)node-read: filter before map to candidate by @russmatney in https://github.com/org-roam/org-roam/pull/2168
|
||||
* (chore): remove extraneous changelog line by @jethrokuan in https://github.com/org-roam/org-roam/pull/2172
|
||||
* (fix)org-roam-file-p: don't exclude org-roam-directory by @toregilhk in https://github.com/org-roam/org-roam/pull/2178
|
||||
* (chore) fix version numbers by @jethrokuan in https://github.com/org-roam/org-roam/pull/2182
|
||||
* (fix) org-roam-file-p handle opening a buffer with no path by @jethrokuan in https://github.com/org-roam/org-roam/pull/2185
|
||||
* (fix)db: update atime on file access by @jethrokuan in https://github.com/org-roam/org-roam/pull/2174
|
||||
* Fix org-roam-extract-subtree by @ralfdoering in https://github.com/org-roam/org-roam/pull/2191
|
||||
* (node): fix org-roam-node-at-point check by @jethrokuan in https://github.com/org-roam/org-roam/pull/2195
|
||||
* (chore): reapply #2178 by @jethrokuan in https://github.com/org-roam/org-roam/pull/2197
|
||||
* Solved issue #2192 (Respect blank lines in capture templates) by @alopezrivera in https://github.com/org-roam/org-roam/pull/2203
|
||||
* (chore)ci: /s/master/main by @jethrokuan in https://github.com/org-roam/org-roam/pull/2204
|
||||
* support custom minibuffer matching function by @cuttlefisch in https://github.com/org-roam/org-roam/pull/2177
|
||||
* (db)fix: org-roam-db-connector group by @jethrokuan in https://github.com/org-roam/org-roam/pull/2209
|
||||
* ensure unique candidates in `org-roam-ref-find` by @bdarcus in https://github.com/org-roam/org-roam/pull/2208
|
||||
* (db)fix: FOREIGN KEY error in narrowed buffer by @psii in https://github.com/org-roam/org-roam/pull/2215
|
||||
* (feat): org-roam-property-* code duplication removed (#2217) by @clanghans in https://github.com/org-roam/org-roam/pull/2218
|
||||
* (db)fix: file modification detection failing in some edge cases by @kisaragi-hiu in https://github.com/org-roam/org-roam/pull/2221
|
||||
* (fix): autoload org-roam-list-files by @jethrokuan in https://github.com/org-roam/org-roam/pull/2226
|
||||
* (fix): links not displayed properly in org-roam-buffer by @ntharim in https://github.com/org-roam/org-roam/pull/2236
|
||||
* (fix): remove use of deprecated org-font-lock-ensure by @jethrokuan in https://github.com/org-roam/org-roam/pull/2238
|
||||
* was missing the FULL parameter to `org-end-of-meta-data` - fixes #2242 by @jmay in https://github.com/org-roam/org-roam/pull/2246
|
||||
* (Docs): Fixed typos in the docs by @hnvy in https://github.com/org-roam/org-roam/pull/2256
|
||||
* Fix space chars in roam refs by @hwiorn in https://github.com/org-roam/org-roam/pull/2285
|
||||
* org-roam-tag-add: use tags separator as crm-separator by @Hugo-Heagren in https://github.com/org-roam/org-roam/pull/2282
|
||||
* Support multi-line org titles by @FelixBrendel in https://github.com/org-roam/org-roam/pull/2264
|
||||
* (Docs): orgmode.org/elpa has been shut down by @aviad in https://github.com/org-roam/org-roam/pull/2258
|
||||
* Minor typo in the commented text of the definition of `org-roam-refile` by @apc in https://github.com/org-roam/org-roam/pull/2263
|
||||
* fix outline of link in properties by @bhuztez in https://github.com/org-roam/org-roam/pull/2230
|
||||
* (fix): update `org-roam-unlinked-references-section` check by @Elilif in https://github.com/org-roam/org-roam/pull/2254
|
||||
* Add support for filtering backlinks. by @swflint in https://github.com/org-roam/org-roam/pull/2247
|
||||
* (docs): update documentation on database-connectors by @jethrokuan in https://github.com/org-roam/org-roam/pull/2298
|
||||
* (db): default to sqlite-builtin when possible by @jethrokuan in https://github.com/org-roam/org-roam/pull/2299
|
||||
* don't complete org-roam nodes in source blocks by @ParetoOptimalDev in https://github.com/org-roam/org-roam/pull/2292
|
||||
* (core): add org-roam-node-category by @jethrokuan in https://github.com/org-roam/org-roam/pull/2300
|
||||
* add discoverability support for age encrypted org files by @anticomputer in https://github.com/org-roam/org-roam/pull/2302
|
||||
* (minor): fix lints on main by @jethrokuan in https://github.com/org-roam/org-roam/pull/2320
|
||||
* utils: descendant-of-p: Defend against nils by @qzdl in https://github.com/org-roam/org-roam/pull/2319
|
||||
* Add customisable function for prompting when adding refs by @Hugo-Heagren in https://github.com/org-roam/org-roam/pull/2317
|
||||
* Fix org-fold-core-style in org-roam-buffer by @hwiorn in https://github.com/org-roam/org-roam/pull/2325
|
||||
* depend on snapshot of emacsql by @jethrokuan in https://github.com/org-roam/org-roam/pull/2327
|
||||
* (node): org-roam-node-at-point: don't error in non-org buffers by @Hugo-Heagren in https://github.com/org-roam/org-roam/pull/2329
|
||||
* (node) add optional NOCASE parameter to org-roam-node-from-title-or-alias by @nuthub in https://github.com/org-roam/org-roam/pull/2403
|
||||
* (docs): update org-protocol instructions by @benthamite in https://github.com/org-roam/org-roam/pull/2401
|
||||
* Fix some typos by @feltcat in https://github.com/org-roam/org-roam/pull/2430
|
||||
* (docs): fix name of my-org-roam-show-backlink-p by @Delapouite in https://github.com/org-roam/org-roam/pull/2447
|
||||
* Link Martin Edström's knowledge base by @meedstrom in https://github.com/org-roam/org-roam/pull/2394
|
||||
* Update org-roam.org by @marcosbodio in https://github.com/org-roam/org-roam/pull/2441
|
||||
* (chore): fix indent blocking ci lint execution by @Delapouite in https://github.com/org-roam/org-roam/pull/2448
|
||||
* Fix Issue #2410 - Unlinked References doesnt work if the org-roam-directory has a space in it. by @vikram-mandyam in https://github.com/org-roam/org-roam/pull/2411
|
||||
* (test): add "org-roam--list-files-search-globs" by @Delapouite in https://github.com/org-roam/org-roam/pull/2449
|
||||
* Backlink heading by @toregilhk in https://github.com/org-roam/org-roam/pull/2333
|
||||
* (test): add org-roam-id-find by @Delapouite in https://github.com/org-roam/org-roam/pull/2450
|
||||
* (test): add org-roam-id-at-point by @Delapouite in https://github.com/org-roam/org-roam/pull/2451
|
||||
* (test): add org-roam--buffer-promoteable-p by @Delapouite in https://github.com/org-roam/org-roam/pull/2452
|
||||
* (test): add org-roam--get-titles by @Delapouite in https://github.com/org-roam/org-roam/pull/2453
|
||||
* (test): add org-roam-node-from-{id|title-or-alias} by @Delapouite in https://github.com/org-roam/org-roam/pull/2454
|
||||
* (test): add org-roam-alias-{add|remove} by @Delapouite in https://github.com/org-roam/org-roam/pull/2455
|
||||
* (docs): add missing versions dates and obsolete notice by @Delapouite in https://github.com/org-roam/org-roam/pull/2456
|
||||
* (docs): explain org-roam-file-exclude-regexp by @adamoudad in https://github.com/org-roam/org-roam/pull/2458
|
||||
* (test): add org-roam-demote-entire-buffer by @Delapouite in https://github.com/org-roam/org-roam/pull/2459
|
||||
* (test): add org-roam-file-p by @Delapouite in https://github.com/org-roam/org-roam/pull/2460
|
||||
* (test): add org-roam-buffer-p by @Delapouite in https://github.com/org-roam/org-roam/pull/2461
|
||||
* (fix): remove dead-code about org-roam-shield feature by @Delapouite in https://github.com/org-roam/org-roam/pull/2462
|
||||
* (test): add org-roam-db--file-hash by @Delapouite in https://github.com/org-roam/org-roam/pull/2464
|
||||
* (test): add org-roam-db-get-{scheduled|deadline}-time by @Delapouite in https://github.com/org-roam/org-roam/pull/2465
|
||||
* Doc formatting: 2 fixes by @kevinrineer in https://github.com/org-roam/org-roam/pull/2475
|
||||
* Take org-roam-node as argument to #'org-roam-refile by @pestctrl in https://github.com/org-roam/org-roam/pull/2388
|
||||
* Compatibility with latest org-id version: advise org-id-find rather than overwriting id link by @ricklupton in https://github.com/org-roam/org-roam/pull/2432
|
||||
* Depend on emacsql 4.0.0 by @bcc32 in https://github.com/org-roam/org-roam/pull/2466
|
||||
* Use regexp match to replace hard-coded path equal test by @manphiz in https://github.com/org-roam/org-roam/pull/2497
|
||||
* Align sqlite integration with emacsql 4.0 by @dustinfarris in https://github.com/org-roam/org-roam/pull/2503
|
||||
* fix #2425 Prevent data loss when user has called org-roam-extract-subtree on folded org headline by @akashpal-21 in https://github.com/org-roam/org-roam/pull/2444
|
||||
* Rely on emacsql-sqlite-open to pick the best available back-end by @tarsius in https://github.com/org-roam/org-roam/pull/2486
|
||||
* Set org-roam-directory to a non-existent path to ensure robust test by @manphiz in https://github.com/org-roam/org-roam/pull/2499
|
||||
* (perf): Deprecate link :outline properties by @meedstrom in https://github.com/org-roam/org-roam/pull/2509
|
||||
* Bump DB version to avoid error by @meedstrom in https://github.com/org-roam/org-roam/pull/2514
|
||||
|
||||
|
||||
## 2.2.2 (2022-04-25)
|
||||
|
||||
### Breaking
|
||||
### Added
|
||||
- [#2138](https://github.com/org-roam/org-roam/pull/2138) export: add new module
|
||||
@ -18,7 +105,8 @@
|
||||
### Changed
|
||||
- [#2160](https://github.com/org-roam/org-roam/pull/2160) core: ignore files in `org-attach-id-dir` by default
|
||||
|
||||
## 2.2.1
|
||||
## 2.2.1 (2022-03-15)
|
||||
|
||||
### Breaking
|
||||
- [#2054](https://github.com/org-roam/org-roam/pull/2054) node: simplify default `org-roam-node-display-template`.
|
||||
This was done so completions work fine by default on all completion systems. To restore the tabular vertical completion interface, set this in your configuration:
|
||||
@ -52,7 +140,8 @@
|
||||
- [#2109](https://github.com/org-roam/org-roam/pull/2109) capture: `org-roam-node-insert` places cursor after inserted link where appropriate
|
||||
- [#2123](https://github.com/org-roam/org-roam/pull/2123), [#2124](https://github.com/org-roam/org-roam/pull/2124) buffer: `org-roam-mode-section-functions` renamed to `org-roam-mode-sections`, supports passing args into the section-rendering function
|
||||
|
||||
## 2.2.0
|
||||
## 2.2.0 (2022-01-14)
|
||||
|
||||
### Added
|
||||
- [#1806](https://github.com/org-roam/org-roam/pull/1806), [#2017](https://github.com/org-roam/org-roam/pull/2017) db: support caching and usage of Org 9.5's in-built citations
|
||||
- [#1963](https://github.com/org-roam/org-roam/pull/1963) db: cache file title into files table
|
||||
@ -83,7 +172,8 @@
|
||||
- [#2016](https://github.com/org-roam/org-roam/pull/2016) db: fix node caching being affected by agenda variables
|
||||
- [#2033](https://github.com/org-roam/org-roam/pull/2023) db: respect local variables during db parsing
|
||||
|
||||
## 2.1.0
|
||||
## 2.1.0 (2021-08-20)
|
||||
|
||||
### Added
|
||||
- [#1693](https://github.com/org-roam/org-roam/pull/1693) added `filter-fn` and `templates` parameter to `org-roam-capture`, `org-roam-node-find`, and `org-roam-node-insert`
|
||||
- [#1709](https://github.com/org-roam/org-roam/pull/1709) added ability to specify default value in org-roam capture templates
|
||||
@ -113,7 +203,10 @@
|
||||
- [#1713](https://github.com/org-roam/org-roam/pull/1713) capture: check for file-existence before template insertion
|
||||
- [#1725](https://github.com/org-roam/org-roam/pull/1725) db: always compute hash of encrypted file to prevent re-processing of encrypted files
|
||||
|
||||
## 2.0.0
|
||||
## 2.0.0 (2021-07-17)
|
||||
|
||||
A few symbols have been marked as obsolete. Have a look at the content of [org-roam-compat.el](https://github.com/org-roam/org-roam/blob/f819720c510185af713522c592833ec9f2934251/org-roam-compat.el#L159)
|
||||
|
||||
### Added
|
||||
- [#1396](https://github.com/org-roam/org-roam/pull/1396) add option to choose between prepending, appending, and omitting `roam_tags` in file completion
|
||||
- [#1270](https://github.com/org-roam/org-roam/pull/1270) capture: create OLP if it does not exist. Removes need for OLP setup in `:head`.
|
||||
@ -140,7 +233,7 @@
|
||||
- [#1409](https://github.com/org-roam/org-roam/issues/1398) prevent inclusion of non-org-roam files in `org-roam-dailies--list-files`
|
||||
- [#1542](https://github.com/org-roam/org-roam/issues/1542) fix files not excluded when `org-roam-list-files-commands` is nil
|
||||
|
||||
## 1.2.3 (13-11-2020)
|
||||
## 1.2.3 (2020-11-13)
|
||||
|
||||
Primarily a stabilization and bug-fix release.
|
||||
|
||||
@ -171,7 +264,7 @@ Org-roam-dailies has also been revamped to include new features, see [this video
|
||||
- [#1233](https://github.com/org-roam/org-roam/issues/1233) fixes bug where descriptive file links become plain links during update for relative paths
|
||||
- [#1252](https://github.com/org-roam/org-roam/issues/1252) respect original link type during automatic replacement
|
||||
|
||||
## 1.2.2 (06-10-2020)
|
||||
## 1.2.2 (2020-10-06)
|
||||
|
||||
In this release we support fuzzy links of the form `[[roam:Title]]`, `[[roam:*Headline]]` and `[[roam:Title*Headline]]`. Completion for these fuzzy links is supported via `completion-at-point`.
|
||||
|
||||
@ -209,7 +302,7 @@ This change requires you to set `org-roam-directory` to the resolved path of a f
|
||||
- [#1057](https://github.com/org-roam/org-roam/pull/1057) Improve performance of database builds by preventing generation of LaTeX and image previews.
|
||||
- [#1103](https://github.com/org-roam/org-roam/pull/1103) Fix long build-times for Windows on files with URL links
|
||||
|
||||
## 1.2.1 (27-07-2020)
|
||||
## 1.2.1 (2020-07-27)
|
||||
|
||||
This release consisted of a big deal of refactoring and bug fixes. Notably, we fixed several catastrophic failures on db builds with bad setups (#854), and modularized tag and title extractions.
|
||||
|
||||
@ -242,7 +335,7 @@ We also added some new features that had been a long time coming:
|
||||
- [#894](https://github.com/org-roam/org-roam/pull/894) Perform link fixes on all Org-roam files
|
||||
- [#952](https://github.com/org-roam/org-roam/pull/952) Cache `${foo}` template variables so they do not need to be re-entered twice
|
||||
|
||||
## 1.2.0 (12-06-2020)
|
||||
## 1.2.0 (2020-06-12)
|
||||
|
||||
In this release, we improved the linking process by achieving feature parity between links to files and links to headlines. Before, we used the `file:foo::*bar` format to link to the headline `bar` in file `foo`, but this was prone to breakage upon renaming the file or modifying the headline. This is not the case anymore. Now, we use `org-id` to create IDs for those headlines, which are then stored in our database to compute the relationships and jump around. Note that this will work even if you’re not using `org-id` in your global configuration for Org-mode.
|
||||
|
||||
@ -270,7 +363,7 @@ We also add `org-roam-unlinked-references`, which naively finds text that could
|
||||
- [#759](https://github.com/org-roam/org-roam/pull/759), [#760](https://github.com/org-roam/org-roam/pull/760) Tags are only added to the tags table if there are actually tags present
|
||||
- [#700](https://github.com/org-roam/org-roam/pull/700), [#733](https://github.com/org-roam/org-roam/pull/733) Allow symlinks within the `org-roam` directory
|
||||
|
||||
## 1.1.1 (18-05-2020)
|
||||
## 1.1.1 (2020-05-18)
|
||||
|
||||
In this release, we added two new features:
|
||||
|
||||
@ -310,7 +403,7 @@ As usual, this release comes with a multitude of bug-fixes and refactorings.
|
||||
- [#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)
|
||||
## 1.1.0 (2020-04-21)
|
||||
|
||||
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:
|
||||
|
||||
@ -348,7 +441,7 @@ In the coming months, you can expect work on bigger projects (e.g. revamping the
|
||||
- [#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)
|
||||
## 1.0.0 (2020-03-23)
|
||||
|
||||
Org-roam is now on MELPA! We have squashed most of the bugs, and Org-roam has
|
||||
been stable for the most part.
|
||||
@ -367,7 +460,7 @@ been stable for the most part.
|
||||
- [#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)
|
||||
## 1.0.0-rc1 (2020-03-06)
|
||||
|
||||
This is a pre-release before the push to MELPA. It contains large
|
||||
internal changes, with little user-facing changes. Most notably, the
|
||||
|
16
Makefile
16
Makefile
@ -1,6 +1,7 @@
|
||||
.PHONY: clean
|
||||
clean:
|
||||
eldev clean all
|
||||
$(MAKE) -C doc clean
|
||||
|
||||
.PHONY: prepare
|
||||
prepare:
|
||||
@ -14,16 +15,17 @@ lint:
|
||||
test:
|
||||
eldev -C --unstable -T test
|
||||
|
||||
.PHONY: docs
|
||||
docs:
|
||||
make -C doc all
|
||||
$(MAKE) -C doc
|
||||
|
||||
.PHONY: html
|
||||
html:
|
||||
make -C doc html-dir
|
||||
$(MAKE) -C doc html
|
||||
|
||||
.PHONY: install
|
||||
install: install-docs
|
||||
|
||||
install-docs: docs
|
||||
make -C doc install-docs
|
||||
|
||||
install-info: info
|
||||
make -C doc install-info
|
||||
.PHONY: install-docs
|
||||
install-docs:
|
||||
$(MAKE) -C doc install
|
||||
|
@ -151,13 +151,9 @@ In both of the cases you will need to ensure that you have all the required
|
||||
dependencies. These include:
|
||||
|
||||
- dash
|
||||
- f
|
||||
- s
|
||||
- org (9.4 is the minimal required version!)
|
||||
- org (9.6 is the minimum required version!)
|
||||
- emacsql
|
||||
- emacsql-sqlite
|
||||
- magit-section
|
||||
- filenotify-recursive
|
||||
|
||||
After installing the package, you will need to properly setup `load-path` to the
|
||||
package:
|
||||
@ -230,6 +226,7 @@ it has not already been addressed on [GitHub][issues] or on
|
||||
([Source](https://github.com/jethrokuan/braindump/tree/master/org))
|
||||
- [Alexey Shmalko](https://www.alexeyshmalko.com/)
|
||||
- [Sidharth Arya](https://sidhartharya.github.io/braindump/index.html)
|
||||
- [Martin Edström](https://edstrom.dev/)
|
||||
|
||||
## Contributing
|
||||
|
||||
|
107
default.mk
107
default.mk
@ -1,107 +0,0 @@
|
||||
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.el
|
||||
ELS += org-roam-capture.el
|
||||
ELS += org-roam-compat.el
|
||||
ELS += org-roam-db.el
|
||||
ELS += org-roam-mode.el
|
||||
ELS += org-roam-node.el
|
||||
ELS += org-roam-utils.el
|
||||
ELS += extensions/org-roam-dailies.el
|
||||
ELS += extensions/org-roam-graph.el
|
||||
ELS += extensions/org-roam-overlay.el
|
||||
ELS += extensions/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
|
@ -1,37 +0,0 @@
|
||||
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@tquelch.com>
|
165
doc/Makefile
165
doc/Makefile
@ -1,127 +1,94 @@
|
||||
-include ../config.mk
|
||||
include ../default.mk
|
||||
|
||||
###################################################################
|
||||
MANUAL_HTML_ARGS = --css-ref assets/page.css
|
||||
## User options ######################################################
|
||||
#
|
||||
# You can override these settings in "config.mk" or on the command
|
||||
# line.
|
||||
|
||||
.PHONY: texi install clean AUTHORS.md stats
|
||||
sharedir ?= $(HOME)/.local/share
|
||||
infodir ?= $(sharedir)/info
|
||||
|
||||
all: info
|
||||
EMACS ?= emacs
|
||||
BATCH = $(EMACS) -Q --batch
|
||||
|
||||
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
|
||||
|
||||
INFOPAGES = $(addsuffix .info,$(PACKAGES))
|
||||
HTMLFILES = $(addsuffix .html,$(PACKAGES))
|
||||
|
||||
## Versions ##########################################################
|
||||
|
||||
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
|
||||
|
||||
######################################################################
|
||||
|
||||
.PHONY: default
|
||||
default: info
|
||||
|
||||
## Build #############################################################
|
||||
|
||||
info: $(INFOPAGES) dir
|
||||
html: $(HTMLFILES)
|
||||
pdf: $(PDFFILES)
|
||||
epub: $(EPUBFILES)
|
||||
.PHONY: info
|
||||
info: dir
|
||||
|
||||
dir: $(INFOPAGES)
|
||||
@printf "Generating dir\n"
|
||||
@echo $^ | xargs -n 1 $(INSTALL_INFO) --dir=$@
|
||||
|
||||
%.info: %.texi
|
||||
@printf "Generating $@\n"
|
||||
@$(MAKEINFO) --no-split $< -o $@
|
||||
|
||||
dir: org-roam.info
|
||||
@printf "Generating dir\n"
|
||||
@echo $^ | xargs -n 1 $(INSTALL_INFO) --dir=$@
|
||||
.PHONY: html
|
||||
html: $(HTMLFILES)
|
||||
mv $(PKG).html manual.html
|
||||
|
||||
%.html: %.texi
|
||||
@printf "Generating $@\n"
|
||||
@$(MAKEINFO) --html --no-split $(MANUAL_HTML_ARGS) $<
|
||||
|
||||
html-dir:
|
||||
@$(MAKEINFO) --html --no-split $(MANUAL_HTML_ARGS) org-roam.texi
|
||||
mv org-roam.html manual.html
|
||||
|
||||
%.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~
|
||||
# NOTE: %.org is not a prerequisite since package archives can’t generate texi
|
||||
# from org. texi is generated on org save and committed to repo
|
||||
%.texi:
|
||||
@echo "Generating $@"
|
||||
@$(BATCH) $*.org $(ORG_EVAL)
|
||||
|
||||
stats:
|
||||
@printf "Generating statistics\n"
|
||||
@gitstats -c style=/assets/stats.css -c max_authors=999 $(TOP) $(statsdir)
|
||||
## Install ###########################################################
|
||||
|
||||
authors: AUTHORS.md
|
||||
.PHONY: install
|
||||
install: install-info
|
||||
|
||||
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"
|
||||
.PHONY: install-info
|
||||
install-info: info
|
||||
install -p -m 755 -d $(DESTDIR)$(infodir)
|
||||
install -p -m 644 $(INFOPAGES) $(DESTDIR)$(infodir)
|
||||
|
||||
# Templates ##########################################################
|
||||
## Clean #############################################################
|
||||
|
||||
define AUTHORS_HEADER
|
||||
Authors
|
||||
=======
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@echo "Cleaning doc/*..."
|
||||
@rm -rf dir $(INFOPAGES) $(HTMLFILES)
|
||||
|
||||
The following people have contributed to Org-Roam.
|
||||
## Release management ################################################
|
||||
|
||||
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
|
||||
# Run VERSION=N make -C doc release-texi to explicitly set version when releasing
|
||||
.PHONY: release-texi
|
||||
release-texi:
|
||||
VERSION=$(VERSION) $(MAKE) -B $(PKG).texi
|
||||
|
238
doc/org-roam.org
238
doc/org-roam.org
@ -1,23 +1,25 @@
|
||||
#+title: Org-roam User Manual
|
||||
#+author: Jethro Kuan
|
||||
#+email: jethrokuan95@gmail.com
|
||||
#+date: 2020-2022
|
||||
#+date: 2020-{{{year}}}
|
||||
#+language: en
|
||||
|
||||
#+texinfo_deffn: t
|
||||
#+texinfo_dir_category: Emacs
|
||||
#+texinfo_dir_title: Org-roam: (org-roam).
|
||||
#+texinfo_dir_name: Org-roam: (org-roam).
|
||||
#+texinfo_dir_desc: Roam Research for Emacs.
|
||||
#+subtitle: for version 2.2.1
|
||||
#+subtitle: for {{{version}}}
|
||||
|
||||
#+options: H:4 num:3 toc:nil creator:t ':t
|
||||
#+property: header-args :eval never
|
||||
#+macro: version (eval (concat "version " (or (getenv "VERSION") (if-let* ((tag (ignore-errors (car (process-lines "git" "describe" "--tags" "--dirty=-devel" "--abbrev=0"))))) (replace-regexp-in-string "^v" "" tag) "<unknown>"))))
|
||||
#+macro: year (eval (format-time-string "%Y"))
|
||||
#+texinfo: @noindent
|
||||
|
||||
This manual is for Org-roam version 2.2.1.
|
||||
This manual is for Org-roam {{{version}}}.
|
||||
|
||||
#+BEGIN_QUOTE
|
||||
Copyright (C) 2020-2022 Jethro Kuan <jethrokuan95@gmail.com>
|
||||
Copyright (C) 2020-{{{year}}} Jethro Kuan <jethrokuan95@gmail.com> and the
|
||||
Org-roam contributors
|
||||
|
||||
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
|
||||
@ -178,18 +180,7 @@ archives to =package-archives=:
|
||||
#+END_SRC
|
||||
|
||||
Org-roam also depends on a recent version of Org, which can be obtained in Org's
|
||||
package repository (see info:org#Installation). To use Org's ELPA archive:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(add-to-list 'package-archives '("org" . "https://orgmode.org/elpa/") t)
|
||||
#+END_SRC
|
||||
|
||||
Once you have added your preferred archive, you need to update the
|
||||
local package list using:
|
||||
|
||||
#+BEGIN_EXAMPLE
|
||||
M-x package-refresh-contents RET
|
||||
#+END_EXAMPLE
|
||||
package repository (see info:org#Installation).
|
||||
|
||||
Once you have done that, you can install Org-roam and its dependencies
|
||||
using:
|
||||
@ -231,11 +222,8 @@ You now have Org-roam installed. However, you don't necessarily have the
|
||||
dependencies that it requires. These include:
|
||||
|
||||
- dash
|
||||
- f
|
||||
- s
|
||||
- org
|
||||
- emacsql
|
||||
- emacsql-sqlite
|
||||
- magit-section
|
||||
|
||||
You can install this manually as well, or get the latest version from MELPA. You
|
||||
@ -279,40 +267,6 @@ file:
|
||||
install-info /path/to/my/info/files/org-roam.info /path/to/my/info/files/dir
|
||||
#+end_src
|
||||
|
||||
** Installation Troubleshooting
|
||||
*** C Compiler
|
||||
Org-roam relies on an Emacs package called ~emacsql~ and ~emacsql-sqlite~ to
|
||||
work with the ~sqlite~ database. Both of them should be installed automatically
|
||||
in your Emacs environment as a prerequisite for Org-roam when you install it.
|
||||
|
||||
~emacsql-sqlite~ requires a C compiler (e.g. ~gcc~ or ~clang~) to be present in
|
||||
your computer. How to install a C compiler depends on the OS that you use.
|
||||
|
||||
**** C Compiler for Windows
|
||||
|
||||
One of the easiest ways to install a C compiler in Windows is to use [[https://www.msys2.org/][MSYS2]] as at the time of this writing:
|
||||
|
||||
1. Download and use the installer in the official MSYS2 website
|
||||
2. Run MSYS2 and in its terminal, type the following and answer "Y" to
|
||||
proceed -- this will install ~gcc~ in your PC:
|
||||
|
||||
#+BEGIN_SRC bash
|
||||
pacman -S gcc
|
||||
#+END_SRC
|
||||
|
||||
4. On Windows, add ~C:\msys64\usr\bin~ (command =where gcc= in MSYS2 terminal
|
||||
can tell you the correct path) to ~PATH~ in your environmental variables
|
||||
|
||||
5. Launch Emacs and call ~M-x org-roam-db-autosync-mode~ (launch Emacs after
|
||||
defining the path, so that Emacs can recognize it)
|
||||
|
||||
This will automatically start compiling ~emacsql-sqlite~; you should see a
|
||||
message in minibuffer. It may take a while until compilation completes. Once
|
||||
complete, you should see a new file ~emacsql-sqlite.exe~ created in a subfolder
|
||||
named ~sqlite~ under ~emacsql-sqlite~ installation folder. It's typically in
|
||||
your Emacs configuration folder like this:
|
||||
~/.config/emacs/elpa/emacsql-sqlite-20190727.1710/sqlite~
|
||||
|
||||
* Getting Started
|
||||
** The Org-roam Node
|
||||
|
||||
@ -421,10 +375,10 @@ Org-roam provides (see [[*Completion][Completion]]).
|
||||
** Customizing Node Completions
|
||||
|
||||
Node selection is achieved via the ~completing-read~ interface, typically
|
||||
through `org-roam-node-read`. The presentation of these nodes are governed by
|
||||
through ~org-roam-node-read~. The presentation of these nodes are governed by
|
||||
~org-roam-node-display-template~.
|
||||
|
||||
- Variable: org-roam-node-display-template
|
||||
- Variable: org-roam-node-display-template ::
|
||||
|
||||
Configures display formatting for Org-roam node.
|
||||
|
||||
@ -468,49 +422,8 @@ can set ~org-roam-node-display-template~ as such:
|
||||
|
||||
* Customizing Node Caching
|
||||
** How to cache
|
||||
|
||||
Org-roam uses a sqlite database to perform caching, but there are multiple Emacs
|
||||
libraries that can be used. The default used by Org-roam is ~emacs-sqlite~.
|
||||
Below the pros and cons of each package is used:
|
||||
|
||||
[[https://github.com/skeeto/emacsql][**emacs-sqlite**]]
|
||||
|
||||
The default option used by Org-roam. This library is the most mature and
|
||||
well-supported and is imported by default in Org-roam.
|
||||
|
||||
One downside of using ~emacs-sqlite~ is that using it requires compilation and
|
||||
can cause issues in some environments (especially Windows). If you have issues
|
||||
producing the customized binary required by ~emacs-sqlite~, consider using
|
||||
~emacs-sqlite3~.
|
||||
|
||||
[[https://github.com/cireu/emacsql-sqlite3][**emacs-sqlite3**]]
|
||||
|
||||
~emacs-sqlite3~ uses the official sqlite3 binary that can be obtained from your
|
||||
system's package manager. This is useful if you have issues producing the
|
||||
~sqlite3~ binary required by the other packages. However, it is not recommended
|
||||
because it has some compatibility issues with Emacs, but should work for most
|
||||
regular cases. See [[https://nullprogram.com/blog/2014/02/06/][Chris Wellon's blog post]] for more information.
|
||||
|
||||
To use ~emacsql-sqlite3~, ensure that the package is installed, and set:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq org-roam-database-connector 'sqlite3)
|
||||
#+end_src
|
||||
|
||||
[[https://github.com/emacscollective/emacsql-libsqlite3/][**emacsql-libsqlite3**]]
|
||||
|
||||
~emacs-libsqlite3~ is a relatively young package which uses an Emacs module that
|
||||
exposes parts of the SQLite C API to Emacs Lisp, instead of using subprocess as
|
||||
~emacsql-sqlite~ does. It is expected to be a more performant drop-in
|
||||
replacement for ~emacs-sqlite~.
|
||||
|
||||
At the moment it is experimental and does not work well with the SQL query load
|
||||
required by Org-roam, but you may still try it by ensuring the package is
|
||||
installed and setting:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq org-roam-database-connector 'libsqlite3)
|
||||
#+end_src
|
||||
Org-roam uses a SQLite database to perform caching. This integration is
|
||||
managed by the [[https://github.com/magit/emacsql][emacsql]] library. It should "just work".
|
||||
|
||||
** What to cache
|
||||
|
||||
@ -532,7 +445,7 @@ property to a non-nil value. For example:
|
||||
One can also set ~org-roam-db-node-include-function~. For example, to exclude
|
||||
all headlines with the ~ATTACH~ tag from the Org-roam database, one can set:
|
||||
|
||||
#+begin_src org
|
||||
#+begin_src emacs-lisp
|
||||
(setq org-roam-db-node-include-function
|
||||
(lambda ()
|
||||
(not (member "ATTACH" (org-get-tags)))))
|
||||
@ -545,7 +458,7 @@ additionally trying to process these links. Use
|
||||
~org-roam-db-extra-links-elements~ to specify which additional Org AST element
|
||||
types to consider.
|
||||
|
||||
- Variable: org-roam-db-extra-links-elements
|
||||
- Variable: org-roam-db-extra-links-elements ::
|
||||
|
||||
The list of Org element types to include for parsing by Org-roam.
|
||||
|
||||
@ -559,7 +472,7 @@ property drawers. For example, we would not want ~ROAM_REFS~ links to be
|
||||
self-referential. Hence, to exclude specific keys, we use
|
||||
~org-roam-db-extra-links-exclude-keys~.
|
||||
|
||||
- Variable: org-roam-db-extra-links-exclude-keys
|
||||
- Variable: org-roam-db-extra-links-exclude-keys ::
|
||||
|
||||
Keys to ignore when mapping over links.
|
||||
|
||||
@ -578,7 +491,7 @@ However, depending on how large your Org files are, database updating can be a
|
||||
slow operation. You can disable the automatic updating of the database by
|
||||
setting ~org-roam-db-update-on-save~ to ~nil~.
|
||||
|
||||
- Variable: org-roam-db-update-on-save
|
||||
- Variable: org-roam-db-update-on-save ::
|
||||
|
||||
If t, update the Org-roam database upon saving the file. Disable this if your
|
||||
files are large and updating the database is slow.
|
||||
@ -600,14 +513,14 @@ two main commands to use here:
|
||||
To bring up a buffer that tracks the current node at point, call ~M-x
|
||||
org-roam-buffer-toggle~.
|
||||
|
||||
- Function: org-roam-buffer-toggle
|
||||
- Function: org-roam-buffer-toggle ::
|
||||
|
||||
Toggle display of the ~org-roam-buffer~.
|
||||
|
||||
To bring up a buffer that's dedicated for a specific node, call ~M-x
|
||||
org-roam-buffer-display-dedicated~.
|
||||
|
||||
- Function: org-roam-buffer-display-dedicated
|
||||
- Function: org-roam-buffer-display-dedicated ::
|
||||
|
||||
Launch node dedicated Org-roam buffer without visiting the node itself.
|
||||
|
||||
@ -633,7 +546,7 @@ There are currently 3 provided widget types:
|
||||
- Unlinked references :: View nodes that contain text that match the nodes
|
||||
title/alias but are not linked
|
||||
|
||||
To configure what sections are displayed in the buffer, set ~org-roam-mode-sections.
|
||||
To configure what sections are displayed in the buffer, set ~org-roam-mode-sections~.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq org-roam-mode-sections
|
||||
@ -655,6 +568,19 @@ rendering reference links), set ~org-roam-mode-sections~ as follows:
|
||||
org-roam-reflinks-section))
|
||||
#+end_src
|
||||
|
||||
The backlinks section ~org-roam-backlinks-section~ also supports a
|
||||
predicate to filter backlinks, ~:show-backlink-p~. This can be used
|
||||
as follows:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun my-org-roam-show-backlink-p (backlink)
|
||||
(not (member "daily" (org-roam-node-tags (org-roam-backlink-source-node backlink)))))
|
||||
|
||||
(setq org-roam-mode-sections
|
||||
'((org-roam-backlinks-section :unique t :show-backlink-p my-org-roam-show-backlink-p)
|
||||
org-roam-reflinks-section))
|
||||
#+end_src
|
||||
|
||||
** Configuring the Org-roam buffer display
|
||||
|
||||
Org-roam does not control how the pop-up buffer is displayed: this is left to
|
||||
@ -723,12 +649,12 @@ To assign an alias to a node, add the "ROAM_ALIASES" property to the node:
|
||||
|
||||
Alternatively, Org-roam provides some functions to add or remove aliases.
|
||||
|
||||
- Function: org-roam-alias-add alias
|
||||
- Function: org-roam-alias-add alias ::
|
||||
|
||||
Add ALIAS to the node at point. When called interactively, prompt for the
|
||||
alias to add.
|
||||
|
||||
- Function: org-roam-alias-remove
|
||||
- Function: org-roam-alias-remove ::
|
||||
|
||||
Remove an alias from the node at point.
|
||||
|
||||
@ -770,12 +696,12 @@ key and a URL at the same time.
|
||||
|
||||
Org-roam also provides some functions to add or remove refs.
|
||||
|
||||
- Function: org-roam-ref-add ref
|
||||
- Function: org-roam-ref-add ref ::
|
||||
|
||||
Add REF to the node at point. When called interactively, prompt for the
|
||||
ref to add.
|
||||
|
||||
- Function: org-roam-ref-remove
|
||||
- Function: org-roam-ref-remove ::
|
||||
|
||||
Remove a ref from the node at point.
|
||||
|
||||
@ -865,14 +791,14 @@ Similarly, the completion candidates are the titles and aliases for all Org-roam
|
||||
nodes, and upon choosing a candidate a ~roam:Title~ link will be inserted
|
||||
linking to the node of choice.
|
||||
|
||||
This is disable by default. To enable it, set ~org-roam-completion-everywhere~
|
||||
This is disabled by default. To enable it, set ~org-roam-completion-everywhere~
|
||||
to ~t~:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq org-roam-completion-everywhere t)
|
||||
#+end_src
|
||||
|
||||
- Variable: org-roam-completion-everywhere
|
||||
- Variable: org-roam-completion-everywhere ::
|
||||
|
||||
When non-nil, provide link completion matching outside of Org links.
|
||||
|
||||
@ -1053,7 +979,7 @@ For Mac OS, we need to create our own application.
|
||||
on open location this_URL
|
||||
set EC to "/usr/local/bin/emacsclient --no-wait "
|
||||
set filePath to quoted form of this_URL
|
||||
do shell script EC & filePath
|
||||
do shell script EC & filePath & " &> /dev/null &"
|
||||
tell application "Emacs" to activate
|
||||
end open location
|
||||
#+end_src
|
||||
@ -1098,6 +1024,21 @@ defaults write com.apple.LaunchServices/com.apple.launchservices.secure LSHandle
|
||||
|
||||
Then restart your computer.
|
||||
|
||||
If you're using the [[https://formulae.brew.sh/formula/emacs][Emacs Homebrew formula]], you may need one of the following additional configurations:
|
||||
|
||||
a) Add option `-c` to `emacsclient` in the script, and start emacs from command line with `emacs --daemon`
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
on open location this_URL
|
||||
set EC to "/usr/local/bin/emacsclient -c --no-wait "
|
||||
set filePath to quoted form of this_URL
|
||||
do shell script EC & filePath & " &> /dev/null &"
|
||||
tell application "Emacs" to activate
|
||||
end open location
|
||||
#+end_src
|
||||
|
||||
b) Add `(server-start)` in .emacs (in this case you do not need option `-c` for `emacsclient` in the script, and you do not need to start emacs with `emacs --daemon`
|
||||
|
||||
***** Testing org-protocol
|
||||
|
||||
To test that you have the handler setup and registered properly from the command
|
||||
@ -1188,7 +1129,7 @@ generating images using [[https://graphviz.org/][Graphviz]]. The graph can also
|
||||
|
||||
The entry point to graph creation is ~org-roam-graph~.
|
||||
|
||||
- Function: org-roam-graph & optional arg node
|
||||
- Function: org-roam-graph & optional arg node ::
|
||||
|
||||
Build and display a graph for NODE.
|
||||
ARG may be any of the following values:
|
||||
@ -1197,7 +1138,7 @@ ARG may be any of the following values:
|
||||
- ~integer~ an integer argument ~N~ will show the graph for the connected
|
||||
components to node up to ~N~ steps away.
|
||||
|
||||
- User Option: org-roam-graph-executable
|
||||
- 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.
|
||||
@ -1205,7 +1146,7 @@ ARG may be any of the following values:
|
||||
You may also choose to use ~neato~ in place of ~dot~, which generates a more
|
||||
compact graph layout.
|
||||
|
||||
- User Option: org-roam-graph-viewer
|
||||
- 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:
|
||||
@ -1231,22 +1172,22 @@ 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-filetype
|
||||
- User Option: org-roam-graph-filetype ::
|
||||
|
||||
The file type to generate for graphs. This defaults to ~"svg"~.
|
||||
|
||||
- User Option: org-roam-graph-extra-config
|
||||
- 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
|
||||
- User Option: org-roam-graph-node-extra-config ::
|
||||
|
||||
An alist of options to style the nodes.
|
||||
The car of the alist node type such as ~"id"~, or ~"http"~. The cdr of the
|
||||
list is another alist of Graphviz node options (the "N" attributes).
|
||||
|
||||
- User Option: org-roam-graph-edge-extra-config
|
||||
- User Option: org-roam-graph-edge-extra-config ::
|
||||
|
||||
Extra options for edges in the graphviz output (The "E" attributes).
|
||||
Example: ~'(("dir" . "back"))~
|
||||
@ -1260,11 +1201,11 @@ Org-journal with ~org-roam-dailies~.
|
||||
|
||||
For ~org-roam-dailies~ to work, you need to define two variables:
|
||||
|
||||
- Variable: ~org-roam-dailies-directory~
|
||||
- Variable: org-roam-dailies-directory ::
|
||||
|
||||
Path to daily-notes. This path is relative to ~org-roam-directory~.
|
||||
|
||||
- Variable: ~org-roam-dailies-capture-templates~
|
||||
- Variable: org-roam-dailies-capture-templates ::
|
||||
|
||||
Capture templates for daily-notes in Org-roam.
|
||||
|
||||
@ -1286,31 +1227,31 @@ See [[*The Templating System][The Templating System]] for creating new templates
|
||||
|
||||
~org-roam-dailies~ provides these interactive functions:
|
||||
|
||||
- Function: ~org-roam-dailies-capture-today~ &optional goto
|
||||
- Function: org-roam-dailies-capture-today &optional goto ::
|
||||
|
||||
Create an entry in the daily note for today.
|
||||
|
||||
When ~goto~ is non-nil, go to the note without creating an entry.
|
||||
|
||||
- Function: ~org-roam-dailies-goto-today~
|
||||
- Function: org-roam-dailies-goto-today ::
|
||||
|
||||
Find the daily note for today, creating it if necessary.
|
||||
|
||||
There are variants of those commands for ~-yesterday~ and ~-tomorrow~:
|
||||
|
||||
- Function: ~org-roam-dailies-capture-yesterday~ n &optional goto
|
||||
- Function: org-roam-dailies-capture-yesterday n &optional goto ::
|
||||
|
||||
Create an entry in the daily note for yesteday.
|
||||
Create an entry in the daily note for yesterday.
|
||||
|
||||
With numeric argument ~n~, use the daily note ~n~ days in the past.
|
||||
|
||||
- Function: ~org-roam-dailies-goto-yesterday~
|
||||
- Function: org-roam-dailies-goto-yesterday ::
|
||||
|
||||
With numeric argument N, use the daily-note N days in the future.
|
||||
|
||||
There are also commands which allow you to use Emacs’s ~calendar~ to find the date
|
||||
|
||||
- Function: ~org-roam-dailies-capture-date~
|
||||
- Function: org-roam-dailies-capture-date ::
|
||||
|
||||
Create an entry in the daily note for a date using the calendar.
|
||||
|
||||
@ -1319,21 +1260,21 @@ There are also commands which allow you to use Emacs’s ~calendar~ to find the
|
||||
With a 'C-u' prefix or when ~goto~ is non-nil, go the note without
|
||||
creating an entry.
|
||||
|
||||
- Function: ~org-roam-dailies-goto-date~
|
||||
- Function: org-roam-dailies-goto-date ::
|
||||
|
||||
Find the daily note for a date using the calendar, creating it if necessary.
|
||||
|
||||
Prefer past dates, unless ~prefer-future~ is non-nil.
|
||||
|
||||
- Function: ~org-roam-dailies-find-directory~
|
||||
- Function: org-roam-dailies-find-directory ::
|
||||
|
||||
Find and open ~org-roam-dailies-directory~.
|
||||
|
||||
- Function: ~org-roam-dailies-goto-previous-note~
|
||||
- Function: org-roam-dailies-goto-previous-note ::
|
||||
|
||||
When in an daily-note, find the previous one.
|
||||
|
||||
- Function: ~org-roam-dailies-goto-next-note~
|
||||
- Function: org-roam-dailies-goto-next-note ::
|
||||
|
||||
When in an daily-note, find the next one.
|
||||
** org-roam-export
|
||||
@ -1649,21 +1590,6 @@ to the publishing directory. Example code follows:
|
||||
(kill-buffer (file-name-nondirectory svg))
|
||||
(setq my-publish-time 0)))))
|
||||
#+end_src
|
||||
** I'm seeing this "Selecting deleted buffer" error. What do I do?
|
||||
|
||||
The "selecting deleted buffer" error usually occurs when you don't have a
|
||||
working ~emacsql-sqlite~ executable. Org-roam relies on this executable to
|
||||
function properly, and doesn't catch this error. This issue is most commonly
|
||||
seen on Windows setups. You can browse through the various GitHub issues posted
|
||||
about this [[https://github.com/org-roam/org-roam/issues?q=is%3Aissue+selecting+deleted][here]].
|
||||
|
||||
To fix this, you can try the following:
|
||||
|
||||
1. If on Windows, try replacing your system binary with [[https://github.com/nobiot/emacsql-sqlite.exe][this one]] that has been proven
|
||||
to work
|
||||
2. Use the ~emacsql-sqlite3~ option rather than compiling your own emacsql
|
||||
binary (see [[*How to cache][How to cache]]).
|
||||
|
||||
* Developer's Guide to Org-roam
|
||||
** Org-roam's Design Principle
|
||||
|
||||
@ -1702,7 +1628,7 @@ queries on their Org files.
|
||||
** Building Extensions and Advanced Customization of Org-roam
|
||||
|
||||
Because Org-roam's core functionality is small, it is possible and sometimes
|
||||
desirable to build extensions on top of it. These extensions may one or more of
|
||||
desirable to build extensions on top of it. These extensions may use one or more of
|
||||
the following functionalities:
|
||||
|
||||
- Access to Org-roam's database
|
||||
@ -1738,13 +1664,12 @@ that extensions/customizations are robust to change, extensions should only use
|
||||
The node interface is cleanly defined using ~cl-defstruct~. The primary
|
||||
method to access nodes is ~org-roam-node-at-point~ and ~org-roam-node-read~:
|
||||
|
||||
- Function: org-roam-node-at-point &optional assert
|
||||
- Function: org-roam-node-at-point &optional assert ::
|
||||
|
||||
Return the node at point. If ASSERT, throw an error if there is no node at
|
||||
point.
|
||||
|
||||
- Function: org-roam-node-read &optional initial-input filter-fn sort-fn
|
||||
require-match
|
||||
- Function: org-roam-node-read &optional initial-input filter-fn sort-fn require-match ::
|
||||
|
||||
Read and return an `org-roam-node'.
|
||||
INITIAL-INPUT is the initial minibuffer prompt value. FILTER-FN
|
||||
@ -1779,7 +1704,7 @@ Org-roam applies some patching over Org's capture system to smooth out the user
|
||||
experience, and sometimes it is desirable to use Org-roam's capturing system
|
||||
instead. The exposed function to be used in extensions is ~org-roam-capture-~:
|
||||
|
||||
- Function: org-roam-capture- &key goto keys node info props templates
|
||||
- Function: org-roam-capture- &key goto keys node info props templates ::
|
||||
|
||||
Main entry point.
|
||||
GOTO and KEYS correspond to `org-capture' arguments.
|
||||
@ -1809,7 +1734,8 @@ When GOTO is non-nil, go the note without creating an entry."
|
||||
:END:
|
||||
|
||||
#+BEGIN_QUOTE
|
||||
Copyright (C) 2020-2022 Jethro Kuan <jethrokuan95@gmail.com>
|
||||
Copyright (C) 2020-{{{year}}} Jethro Kuan <jethrokuan95@gmail.com> and the
|
||||
Org-roam contributors
|
||||
|
||||
You can redistribute this document and/or modify it under the terms
|
||||
of the GNU General Public License as published by the Free Software
|
||||
@ -1870,9 +1796,9 @@ an Org file code block (like =#+BEGIN_SRC emacs-lisp=).
|
||||
|
||||
# Local Variables:
|
||||
# eval: (require 'ol-info)
|
||||
# eval: (require 'ox-texinfo+ nil t)
|
||||
# eval: (auto-fill-mode +1)
|
||||
# after-save-hook: (lambda nil (progn (require 'ox-texinfo nil t) (org-texinfo-export-to-info)))
|
||||
# after-save-hook: org-texinfo-export-to-info
|
||||
# indent-tabs-mode: nil
|
||||
# org-src-preserve-indentation: nil
|
||||
# org-list-allow-alphabetical: t
|
||||
# End:
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,13 +1,13 @@
|
||||
;;; org-roam-dailies.el --- Daily-notes for Org-roam -*- coding: utf-8; lexical-binding: t; -*-
|
||||
;;;
|
||||
;; Copyright © 2020-2022 Jethro Kuan <jethrokuan95@gmail.com>
|
||||
;; Copyright © 2020-2025 Jethro Kuan <jethrokuan95@gmail.com>
|
||||
;; Copyright © 2020 Leo Vivier <leo.vivier+dev@gmail.com>
|
||||
|
||||
;; Author: Jethro Kuan <jethrokuan95@gmail.com>
|
||||
;; Leo Vivier <leo.vivier+dev@gmail.com>
|
||||
;; URL: https://github.com/org-roam/org-roam
|
||||
;; Keywords: org-mode, roam, convenience
|
||||
;; Version: 2.2.1
|
||||
;; Version: 2.3.1
|
||||
;; Package-Requires: ((emacs "26.1") (dash "2.13") (org-roam "2.1"))
|
||||
|
||||
;; This file is NOT part of GNU Emacs.
|
||||
|
@ -1,12 +1,12 @@
|
||||
;;; org-roam-export.el --- Org-roam org-export tweaks -*- coding: utf-8; lexical-binding: t; -*-
|
||||
|
||||
;; Copyright © 2020-2022 Jethro Kuan <jethrokuan95@gmail.com>
|
||||
;; Copyright © 2020-2025 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: 2.2.1
|
||||
;; Package-Requires: ((emacs "26.1") (org "9.4") (org-roam "2.1"))
|
||||
;; Version: 2.3.1
|
||||
;; Package-Requires: ((emacs "26.1") (org "9.6") (org-roam "2.1"))
|
||||
|
||||
;; This file is NOT part of GNU Emacs.
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
;;; org-roam-graph.el --- Basic graphing functionality for Org-roam -*- coding: utf-8; lexical-binding: t; -*-
|
||||
|
||||
;; Copyright © 2020-2022 Jethro Kuan <jethrokuan95@gmail.com>
|
||||
;; Copyright © 2020-2025 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: 2.2.1
|
||||
;; Package-Requires: ((emacs "26.1") (org "9.4") (org-roam "2.1"))
|
||||
;; Version: 2.3.1
|
||||
;; Package-Requires: ((emacs "26.1") (org "9.6") (org-roam "2.1"))
|
||||
|
||||
;; This file is NOT part of GNU Emacs.
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
;;; org-roam-overlay.el --- Link overlay for [id:] links to Org-roam nodes -*- coding: utf-8; lexical-binding: t; -*-
|
||||
|
||||
;; Copyright © 2020-2022 Jethro Kuan <jethrokuan95@gmail.com>
|
||||
;; Copyright © 2020-2025 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: 2.2.1
|
||||
;; Package-Requires: ((emacs "26.1") (org "9.4") (org-roam "2.1"))
|
||||
;; Version: 2.3.1
|
||||
;; Package-Requires: ((emacs "26.1") (org "9.6") (org-roam "2.1"))
|
||||
|
||||
;; This file is NOT part of GNU Emacs.
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
;;; org-roam-protocol.el --- Protocol handler for roam:// links -*- coding: utf-8; lexical-binding: t; -*-
|
||||
|
||||
;; Copyright © 2020-2022 Jethro Kuan <jethrokuan95@gmail.com>
|
||||
;; Copyright © 2020-2025 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: 2.2.1
|
||||
;; Package-Requires: ((emacs "26.1") (org "9.4") (org-roam "2.1"))
|
||||
;; Version: 2.3.1
|
||||
;; Package-Requires: ((emacs "26.1") (org "9.6") (org-roam "2.1"))
|
||||
|
||||
;; This file is NOT part of GNU Emacs.
|
||||
|
||||
|
11
github-eldev
11
github-eldev
@ -1,11 +0,0 @@
|
||||
#! /bin/sh
|
||||
set -e
|
||||
|
||||
ELDEV_BIN_DIR=~/.local/bin
|
||||
|
||||
# `$GITHUB_PATH' is a magic file which contents is translated to environment variable `$PATH'.
|
||||
echo "$ELDEV_BIN_DIR" >> $GITHUB_PATH
|
||||
|
||||
mkdir -p $ELDEV_BIN_DIR
|
||||
curl -fsSL https://raw.githubusercontent.com/doublep/eldev/f111d19cda305e5e8fcb70a5675b87173041cb68/bin/eldev > $ELDEV_BIN_DIR/eldev
|
||||
chmod a+x $ELDEV_BIN_DIR/eldev
|
@ -1,12 +1,12 @@
|
||||
;;; org-roam-capture.el --- Capture functionality -*- coding: utf-8; lexical-binding: t; -*-
|
||||
|
||||
;; Copyright © 2020-2022 Jethro Kuan <jethrokuan95@gmail.com>
|
||||
;; Copyright © 2020-2025 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: 2.2.1
|
||||
;; Package-Requires: ((emacs "26.1") (dash "2.13") (org "9.4") (emacsql "3.0.0") (emacsql-sqlite "1.0.0") (magit-section "3.0.0"))
|
||||
;; Version: 2.3.1
|
||||
;; Package-Requires: ((emacs "26.1") (dash "2.13") (org "9.6") (emacsql "4.1.0") (magit-section "3.0.0"))
|
||||
|
||||
;; This file is NOT part of GNU Emacs.
|
||||
|
||||
@ -707,8 +707,6 @@ the current value of `point'."
|
||||
|
||||
(defun org-roam-capture--finalize ()
|
||||
"Finalize the `org-roam-capture' process."
|
||||
(when-let ((region (org-roam-capture--get :region)))
|
||||
(org-roam-unshield-region (car region) (cdr region)))
|
||||
(if org-note-abort
|
||||
(when-let ((new-file (org-roam-capture--get :new-file))
|
||||
(_ (yes-or-no-p "Delete file for aborted capture?")))
|
||||
@ -740,7 +738,6 @@ This function is to be called in the Org-capture finalization process."
|
||||
(buf (marker-buffer mkr)))
|
||||
(with-current-buffer buf
|
||||
(when-let ((region (org-roam-capture--get :region)))
|
||||
(org-roam-unshield-region (car region) (cdr region))
|
||||
(delete-region (car region) (cdr region))
|
||||
(set-marker (car region) nil)
|
||||
(set-marker (cdr region) nil))
|
||||
@ -788,7 +785,7 @@ When ENSURE-NEWLINE, always ensure there's a newline behind."
|
||||
;; template does not start with any whitespace, and only ends with a single newline
|
||||
;;
|
||||
;; Instead, we restore the whitespace in the original template.
|
||||
(setq template (replace-regexp-in-string "\n$" "" (org-capture-fill-template template)))
|
||||
(setq template (replace-regexp-in-string "[\n]*\\'" "" (org-capture-fill-template template)))
|
||||
(when (and ensure-newline
|
||||
(string-equal template-whitespace-content ""))
|
||||
(setq template-whitespace-content "\n"))
|
||||
|
@ -1,11 +1,11 @@
|
||||
;;; org-roam-compat.el --- Backward compatibility code -*- coding: utf-8; lexical-binding: t; -*-
|
||||
|
||||
;; Copyright © 2020-2022 Jethro Kuan <jethrokuan95@gmail.com>
|
||||
;; Copyright © 2020-2025 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: 2.2.1
|
||||
;; Version: 2.3.1
|
||||
;; Package-Requires: ((emacs "26.1"))
|
||||
|
||||
;; This file is NOT part of GNU Emacs.
|
||||
|
193
org-roam-db.el
193
org-roam-db.el
@ -1,12 +1,12 @@
|
||||
;;; org-roam-db.el --- Org-roam database API -*- coding: utf-8; lexical-binding: t; -*-
|
||||
|
||||
;; Copyright © 2020-2022 Jethro Kuan <jethrokuan95@gmail.com>
|
||||
;; Copyright © 2020-2025 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: 2.2.1
|
||||
;; Package-Requires: ((emacs "26.1") (dash "2.13") (org "9.4") (emacsql "3.0.0") (emacsql-sqlite "1.0.0") (magit-section "3.0.0"))
|
||||
;; Version: 2.3.1
|
||||
;; Package-Requires: ((emacs "26.1") (dash "2.13") (org "9.6") (emacsql "4.1.0") (magit-section "3.0.0"))
|
||||
|
||||
;; This file is NOT part of GNU Emacs.
|
||||
|
||||
@ -31,41 +31,11 @@
|
||||
;;
|
||||
;;; Code:
|
||||
(require 'org-roam)
|
||||
(require 'url-parse)
|
||||
(require 'ol)
|
||||
(defvar org-outline-path-cache)
|
||||
|
||||
;;; Options
|
||||
(defcustom org-roam-database-connector 'sqlite
|
||||
"The database connector used by Org-roam.
|
||||
This must be set before `org-roam' is loaded. To use an alternative
|
||||
connector you must install the respective package explicitly.
|
||||
The default is `sqlite', which uses the `emacsql-sqlite' library
|
||||
that is being maintained in the same repository as `emacsql'
|
||||
itself.
|
||||
If you are using Emacs 29, then the recommended connector is
|
||||
`sqlite-builtin', which uses the new builtin support for SQLite.
|
||||
You need to install the `emacsql-sqlite-builtin' package to use
|
||||
this connector.
|
||||
If you are using an older Emacs release, then the recommended
|
||||
connector is `sqlite-module', which uses the module provided by
|
||||
the `sqlite3' package. This is very similar to the previous
|
||||
connector and the built-in support in Emacs 29 derives from this
|
||||
module. You need to install the `emacsql-sqlite-module' package
|
||||
to use this connector.
|
||||
For the time being `libsqlite3' is still supported. Do not use
|
||||
this, it is an older version of the `sqlite-module' connector
|
||||
from before the connector and the package were renamed.
|
||||
For the time being `sqlite3' is also supported. Do not use this.
|
||||
This uses the third-party `emacsql-sqlite3' package, which uses
|
||||
the official `sqlite3' cli tool, which is not intended
|
||||
to be used like this. See https://nullprogram.com/blog/2014/02/06/."
|
||||
:package-version '(forge . "0.3.0")
|
||||
:group 'forge
|
||||
:type '(choice (const sqlite)
|
||||
(const sqlite-builtin)
|
||||
(const sqlite-module)
|
||||
(const :tag "libsqlite3 (OBSOLETE)" libsqlite3)
|
||||
(const :tag "sqlite3 (BROKEN)" sqlite3)))
|
||||
|
||||
(defcustom org-roam-db-location (locate-user-emacs-file "org-roam.db")
|
||||
"The path to file where the Org-roam database is stored.
|
||||
|
||||
@ -119,8 +89,9 @@ is desirable to parse and cache these links (e.g. hiding links in
|
||||
a property drawer)."
|
||||
:package-version '(org-roam . "2.2.0")
|
||||
:group 'org-roam
|
||||
:type '(set (const :tag "keywords" keyword)
|
||||
(const :tag "property drawers" node-property)))
|
||||
:type '(set
|
||||
(const :tag "keywords" keyword)
|
||||
(const :tag "property drawers" node-property)))
|
||||
|
||||
(defcustom org-roam-db-extra-links-exclude-keys '((node-property . ("ROAM_REFS"))
|
||||
(keyword . ("transclude")))
|
||||
@ -137,7 +108,7 @@ ROAM_REFS."
|
||||
:type '(alist))
|
||||
|
||||
;;; Variables
|
||||
(defconst org-roam-db-version 18)
|
||||
(defconst org-roam-db-version 20)
|
||||
|
||||
(defvar org-roam-db--connection (make-hash-table :test #'equal)
|
||||
"Database connection to Org-roam database.")
|
||||
@ -148,36 +119,6 @@ ROAM_REFS."
|
||||
(gethash (expand-file-name (file-name-as-directory org-roam-directory))
|
||||
org-roam-db--connection))
|
||||
|
||||
(declare-function emacsql-sqlite "ext:emacsql-sqlite")
|
||||
(declare-function emacsql-sqlite3 "ext:emacsql-sqlite3")
|
||||
(declare-function emacsql-libsqlite3 "ext:emacsql-libsqlite3")
|
||||
(declare-function emacsql-sqlite-builtin "ext:emacsql-sqlite-builtin")
|
||||
(declare-function emacsql-sqlite-module "ext:emacsql-sqlite-module")
|
||||
|
||||
(defun org-roam-db--conn-fn ()
|
||||
"Return the function for creating the database connection."
|
||||
(cl-case org-roam-database-connector
|
||||
(sqlite
|
||||
(progn
|
||||
(require 'emacsql-sqlite)
|
||||
#'emacsql-sqlite))
|
||||
(sqlite-builtin
|
||||
(progn
|
||||
(require 'emacsql-sqlite-builtin)
|
||||
#'emacsql-sqlite-builtin))
|
||||
(sqlite-module
|
||||
(progn
|
||||
(require 'emacsql-sqlite-module)
|
||||
#'emacsql-sqlite-module))
|
||||
(libsqlite3
|
||||
(progn
|
||||
(require 'emacsql-libsqlite3)
|
||||
#'emacsql-libsqlite3))
|
||||
(sqlite3
|
||||
(progn
|
||||
(require 'emacsql-sqlite3)
|
||||
#'emacsql-sqlite3))))
|
||||
|
||||
(defun org-roam-db ()
|
||||
"Entrypoint to the Org-roam sqlite database.
|
||||
Initializes and stores the database, and the database connection.
|
||||
@ -186,11 +127,7 @@ Performs a database upgrade when required."
|
||||
(emacsql-live-p (org-roam-db--get-connection)))
|
||||
(let ((init-db (not (file-exists-p org-roam-db-location))))
|
||||
(make-directory (file-name-directory org-roam-db-location) t)
|
||||
(let ((conn (funcall (org-roam-db--conn-fn) org-roam-db-location)))
|
||||
(emacsql conn [:pragma (= foreign_keys ON)])
|
||||
(when-let* ((process (emacsql-process conn))
|
||||
(_ (processp process)))
|
||||
(set-process-query-on-exit-flag process nil))
|
||||
(let ((conn (emacsql-sqlite-open org-roam-db-location)))
|
||||
(puthash (expand-file-name (file-name-as-directory org-roam-directory))
|
||||
conn
|
||||
org-roam-db--connection)
|
||||
@ -202,7 +139,7 @@ Performs a database upgrade when required."
|
||||
((> version org-roam-db-version)
|
||||
(emacsql-close conn)
|
||||
(user-error
|
||||
"The Org-roam database was created with a newer Org-roam version. "
|
||||
"The Org-roam database was created with a newer Org-roam version. %s"
|
||||
"You need to update the Org-roam package"))
|
||||
((< version org-roam-db-version)
|
||||
(emacsql-close conn)
|
||||
@ -344,20 +281,21 @@ If FILE is nil, clear the current buffer."
|
||||
If there is no title, return the file name relative to
|
||||
`org-roam-directory'."
|
||||
(org-link-display-format
|
||||
(or (cadr (assoc "TITLE" (org-collect-keywords '("title"))))
|
||||
(or (string-join (cdr (assoc "TITLE" (org-collect-keywords '("title")))) " ")
|
||||
(file-name-sans-extension (file-relative-name
|
||||
(buffer-file-name (buffer-base-buffer))
|
||||
org-roam-directory)))))
|
||||
|
||||
(defun org-roam-db-insert-file ()
|
||||
(defun org-roam-db-insert-file (&optional hash)
|
||||
"Update the files table for the current buffer.
|
||||
If UPDATE-P is non-nil, first remove the file in the database."
|
||||
If UPDATE-P is non-nil, first remove the file in the database.
|
||||
If HASH is non-nil, use that as the file's hash without recalculating it."
|
||||
(let* ((file (buffer-file-name))
|
||||
(file-title (org-roam-db--file-title))
|
||||
(attr (file-attributes file))
|
||||
(atime (file-attribute-access-time attr))
|
||||
(mtime (file-attribute-modification-time attr))
|
||||
(hash (org-roam-db--file-hash)))
|
||||
(hash (or hash (org-roam-db--file-hash file))))
|
||||
(org-roam-db-query
|
||||
[:insert :into files
|
||||
:values $v1]
|
||||
@ -366,12 +304,12 @@ If UPDATE-P is non-nil, first remove the file in the database."
|
||||
(defun org-roam-db-get-scheduled-time ()
|
||||
"Return the scheduled time at point in ISO8601 format."
|
||||
(when-let ((time (org-get-scheduled-time (point))))
|
||||
(org-format-time-string "%FT%T%z" time)))
|
||||
(format-time-string "%FT%T" time)))
|
||||
|
||||
(defun org-roam-db-get-deadline-time ()
|
||||
"Return the deadline time at point in ISO8601 format."
|
||||
(when-let ((time (org-get-deadline-time (point))))
|
||||
(org-format-time-string "%FT%T%z" time)))
|
||||
(format-time-string "%FT%T" time)))
|
||||
|
||||
(defun org-roam-db-node-p ()
|
||||
"Return t if headline at point is an Org-roam node, else return nil."
|
||||
@ -381,12 +319,13 @@ If UPDATE-P is non-nil, first remove the file in the database."
|
||||
|
||||
(defun org-roam-db-map-nodes (fns)
|
||||
"Run FNS over all nodes in the current buffer."
|
||||
(org-map-region
|
||||
(lambda ()
|
||||
(when (org-roam-db-node-p)
|
||||
(dolist (fn fns)
|
||||
(funcall fn))))
|
||||
(point-min) (point-max)))
|
||||
(org-with-wide-buffer
|
||||
(org-map-region
|
||||
(lambda ()
|
||||
(when (org-roam-db-node-p)
|
||||
(dolist (fn fns)
|
||||
(funcall fn))))
|
||||
(point-min) (point-max))))
|
||||
|
||||
(defun org-roam-db-map-links (fns)
|
||||
"Run FNS over all links in the current buffer."
|
||||
@ -395,9 +334,10 @@ If UPDATE-P is non-nil, first remove the file in the database."
|
||||
;; `re-search-forward' let the cursor one character after the link, we need to go backward one char to
|
||||
;; make the point be on the link.
|
||||
(backward-char)
|
||||
(let* ((element (org-element-context))
|
||||
(let* ((begin (match-beginning 0))
|
||||
(element (org-element-context))
|
||||
(type (org-element-type element))
|
||||
link bounds)
|
||||
link)
|
||||
(cond
|
||||
;; Links correctly recognized by Org Mode
|
||||
((eq type 'link)
|
||||
@ -408,14 +348,9 @@ If UPDATE-P is non-nil, first remove the file in the database."
|
||||
((and (member type org-roam-db-extra-links-elements)
|
||||
(not (member-ignore-case (org-element-property :key element)
|
||||
(cdr (assoc type org-roam-db-extra-links-exclude-keys))))
|
||||
(setq bounds (org-in-regexp org-link-any-re))
|
||||
(setq link (buffer-substring-no-properties
|
||||
(car bounds)
|
||||
(cdr bounds))))
|
||||
(with-temp-buffer
|
||||
(delay-mode-hooks (org-mode))
|
||||
(insert link)
|
||||
(setq link (org-element-context)))))
|
||||
(setq link (save-excursion
|
||||
(goto-char begin)
|
||||
(save-match-data (org-element-link-parser)))))))
|
||||
(when link
|
||||
(dolist (fn fns)
|
||||
(funcall fn link)))))))
|
||||
@ -539,9 +474,14 @@ INFO is the org-element parsed buffer."
|
||||
(;; https://google.com, cite:citeKey
|
||||
;; Note: we use string-match here because it matches any link: e.g. [[cite:abc][abc]]
|
||||
;; But this form of matching is loose, and can accept invalid links e.g. [[cite:abc]
|
||||
(string-match org-link-plain-re ref)
|
||||
(let ((link-type (match-string 1 ref))
|
||||
(path (match-string 2 ref)))
|
||||
(string-match org-link-any-re (org-link-encode ref '(#x20)))
|
||||
(setq ref (org-link-encode ref '(#x20)))
|
||||
(let ((ref-url (url-generic-parse-url (or (match-string 2 ref) (match-string 0 ref))))
|
||||
(link-type ()) ;; clear url-type for backward compatible.
|
||||
(path ()))
|
||||
(setq link-type (url-type ref-url))
|
||||
(setf (url-type ref-url) nil)
|
||||
(setq path (org-link-decode (url-recreate-url ref-url)))
|
||||
(if (and (boundp 'org-ref-cite-types)
|
||||
(or (assoc link-type org-ref-cite-types)
|
||||
(member link-type org-ref-cite-types)))
|
||||
@ -560,12 +500,18 @@ INFO is the org-element parsed buffer."
|
||||
"Insert link data for LINK at current point into the Org-roam cache."
|
||||
(save-excursion
|
||||
(goto-char (org-element-property :begin link))
|
||||
(let ((type (org-element-property :type link))
|
||||
(path (org-element-property :path link))
|
||||
(source (org-roam-id-at-point))
|
||||
(properties (list :outline (ignore-errors
|
||||
;; This can error if link is not under any headline
|
||||
(org-get-outline-path 'with-self 'use-cache)))))
|
||||
(let* ((type (org-element-property :type link))
|
||||
(path (org-element-property :path link))
|
||||
(option (and (string-match "::\\(.*\\)\\'" path)
|
||||
(match-string 1 path)))
|
||||
(path (if (not option) path
|
||||
(substring path 0 (match-beginning 0))))
|
||||
(source (org-roam-id-at-point))
|
||||
(properties (list :outline (ignore-errors
|
||||
;; This can error if link is not under any headline
|
||||
(org-get-outline-path 'with-self 'use-cache))))
|
||||
(properties (if option (plist-put properties :search-option option)
|
||||
properties)))
|
||||
;; For Org-ref links, we need to split the path into the cite keys
|
||||
(when (and source path)
|
||||
(if (and (boundp 'org-ref-cite-types)
|
||||
@ -605,19 +551,12 @@ INFO is the org-element parsed buffer."
|
||||
(puthash (car row) (cadr row) ht))
|
||||
ht))
|
||||
|
||||
(defun org-roam-db--file-hash (&optional file-path)
|
||||
"Compute the hash of FILE-PATH, a file or current buffer."
|
||||
;; If it is a GPG encrypted file, we always want to compute the hash
|
||||
;; for the GPG encrypted file (undecrypted)
|
||||
(when (and (not file-path) (equal "gpg" (file-name-extension (buffer-file-name))))
|
||||
(setq file-path (buffer-file-name)))
|
||||
(if file-path
|
||||
(with-temp-buffer
|
||||
(set-buffer-multibyte nil)
|
||||
(insert-file-contents-literally file-path)
|
||||
(secure-hash 'sha1 (current-buffer)))
|
||||
(org-with-wide-buffer
|
||||
(secure-hash 'sha1 (current-buffer)))))
|
||||
(defun org-roam-db--file-hash (file-path)
|
||||
"Compute the hash of FILE-PATH."
|
||||
(with-temp-buffer
|
||||
(set-buffer-multibyte nil)
|
||||
(insert-file-contents-literally file-path)
|
||||
(secure-hash 'sha1 (current-buffer))))
|
||||
|
||||
;;;; Synchronization
|
||||
(defun org-roam-db-update-file (&optional file-path no-require)
|
||||
@ -642,9 +581,10 @@ in `org-roam-db-sync'."
|
||||
(emacsql-with-transaction (org-roam-db)
|
||||
(org-with-wide-buffer
|
||||
(org-set-regexps-and-options 'tags-only)
|
||||
(org-refresh-category-properties)
|
||||
;; Org doesn't use this anymore, so we probably should stop too.
|
||||
;; (org-refresh-category-properties)
|
||||
(org-roam-db-clear-file)
|
||||
(org-roam-db-insert-file)
|
||||
(org-roam-db-insert-file content-hash)
|
||||
(org-roam-db-insert-file-node)
|
||||
(setq org-outline-path-cache nil)
|
||||
(org-roam-db-map-nodes
|
||||
@ -715,12 +655,14 @@ database, see `org-roam-db-sync' command."
|
||||
(add-hook 'kill-emacs-hook #'org-roam-db--close-all)
|
||||
(advice-add #'rename-file :after #'org-roam-db-autosync--rename-file-a)
|
||||
(advice-add #'delete-file :before #'org-roam-db-autosync--delete-file-a)
|
||||
(advice-add #'vc-delete-file :around #'org-roam-db-autosync--vc-delete-file-a)
|
||||
(org-roam-db-sync))
|
||||
(t
|
||||
(remove-hook 'find-file-hook #'org-roam-db-autosync--setup-file-h)
|
||||
(remove-hook 'kill-emacs-hook #'org-roam-db--close-all)
|
||||
(advice-remove #'rename-file #'org-roam-db-autosync--rename-file-a)
|
||||
(advice-remove #'delete-file #'org-roam-db-autosync--delete-file-a)
|
||||
(advice-remove #'vc-delete-file #'org-roam-db-autosync--vc-delete-file-a)
|
||||
(org-roam-db--close-all)
|
||||
;; Disable local hooks for all org-roam buffers
|
||||
(dolist (buf (org-roam-buffer-list))
|
||||
@ -748,6 +690,17 @@ FILE is removed from the database."
|
||||
(org-roam-file-p file))
|
||||
(org-roam-db-clear-file (expand-file-name file))))
|
||||
|
||||
(defun org-roam-db-autosync--vc-delete-file-a (fun file)
|
||||
"Maintain cache consistency on file deletion by FUN.
|
||||
FILE is removed from the database."
|
||||
(let ((org-roam-file-p (and (not (auto-save-file-name-p file))
|
||||
(not (backup-file-name-p file))
|
||||
(org-roam-file-p file))))
|
||||
(apply fun `(,file))
|
||||
(when (and org-roam-file-p
|
||||
(not (file-exists-p file)))
|
||||
(org-roam-db-clear-file (expand-file-name file)))))
|
||||
|
||||
(defun org-roam-db-autosync--rename-file-a (old-file new-file-or-dir &rest _args)
|
||||
"Maintain cache consistency of file rename.
|
||||
OLD-FILE is cleared from the database, and NEW-FILE-OR-DIR is added."
|
||||
|
@ -1,12 +1,12 @@
|
||||
;;; org-roam-id.el --- ID-related utilities for Org-roam -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright © 2020-2022 Jethro Kuan <jethrokuan95@gmail.com>
|
||||
;; Copyright © 2020-2025 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: 2.2.1
|
||||
;; Package-Requires: ((emacs "26.1") (dash "2.13") (org "9.4") (magit-section "3.0.0"))
|
||||
;; Version: 2.3.1
|
||||
;; Package-Requires: ((emacs "26.1") (dash "2.13") (org "9.6") (magit-section "3.0.0"))
|
||||
|
||||
;; This file is NOT part of GNU Emacs.
|
||||
|
||||
@ -55,40 +55,17 @@ With optional argument MARKERP, return the position as a new marker."
|
||||
(let ((node (org-roam-populate (org-roam-node-create :id id))))
|
||||
(when-let ((file (org-roam-node-file node)))
|
||||
(if markerp
|
||||
(unwind-protect
|
||||
(let ((buffer (or (find-buffer-visiting file)
|
||||
(find-file-noselect file))))
|
||||
(with-current-buffer buffer
|
||||
(move-marker (make-marker) (org-roam-node-point node) buffer))))
|
||||
(let ((buffer (or (find-buffer-visiting file)
|
||||
(find-file-noselect file))))
|
||||
(with-current-buffer buffer
|
||||
(move-marker (make-marker) (org-roam-node-point node) buffer)))
|
||||
(cons (org-roam-node-file node)
|
||||
(org-roam-node-point node))))))
|
||||
|
||||
(defun org-roam-id-open (id _)
|
||||
"Go to the entry with id ID.
|
||||
Like `org-id-open', but additionally uses the Org-roam database."
|
||||
(org-mark-ring-push)
|
||||
(let ((m (or (org-roam-id-find id 'marker)
|
||||
(org-id-find id 'marker)))
|
||||
cmd)
|
||||
(unless m
|
||||
(error "Cannot find entry with ID \"%s\"" id))
|
||||
;; Use a buffer-switching command in analogy to finding files
|
||||
(setq cmd
|
||||
(or
|
||||
(cdr
|
||||
(assq
|
||||
(cdr (assq 'file org-link-frame-setup))
|
||||
'((find-file . switch-to-buffer)
|
||||
(find-file-other-window . switch-to-buffer-other-window)
|
||||
(find-file-other-frame . switch-to-buffer-other-frame))))
|
||||
'switch-to-buffer-other-window))
|
||||
(if (not (equal (current-buffer) (marker-buffer m)))
|
||||
(funcall cmd (marker-buffer m)))
|
||||
(goto-char m)
|
||||
(move-marker m nil)
|
||||
(org-show-context)))
|
||||
(defalias 'org-roam-id-open 'org-id-open
|
||||
"Obsolete alias - use `org-id-open' directly.")
|
||||
|
||||
(org-link-set-parameters "id" :follow #'org-roam-id-open)
|
||||
(advice-add 'org-id-find :before-until #'org-roam-id-find)
|
||||
|
||||
;;;###autoload
|
||||
(defun org-roam-update-org-id-locations (&rest directories)
|
||||
|
@ -1,12 +1,12 @@
|
||||
;;; org-roam-log.el --- Integrations with Org-log -*- coding: utf-8; lexical-binding: t; -*-
|
||||
|
||||
;; Copyright © 2022-2022 Jethro Kuan <jethrokuan95@gmail.com>
|
||||
;; Copyright © 2022-2025 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: 2.2.1
|
||||
;; Package-Requires: ((emacs "26.1") (dash "2.13") (org "9.4") (emacsql "3.0.0") (emacsql-sqlite "1.0.0") (magit-section "3.0.0"))
|
||||
;; Version: 2.3.1
|
||||
;; Package-Requires: ((emacs "26.1") (dash "2.13") (org "9.6") (emacsql "4.1.0") (magit-section "3.0.0"))
|
||||
|
||||
;; This file is NOT part of GNU Emacs.
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
;;; org-roam-migrate.el --- Migration utilities from v1 to v2 -*- coding: utf-8; lexical-binding: t; -*-
|
||||
|
||||
;; Copyright © 2020-2022 Jethro Kuan <jethrokuan95@gmail.com>
|
||||
;; Copyright © 2020-2025 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: 2.2.1
|
||||
;; Package-Requires: ((emacs "26.1") (dash "2.13") (org "9.4") (emacsql "3.0.0") (emacsql-sqlite "1.0.0") (magit-section "3.0.0"))
|
||||
;; Version: 2.3.1
|
||||
;; Package-Requires: ((emacs "26.1") (dash "2.13") (org "9.6") (emacsql "4.1.0") (magit-section "3.0.0"))
|
||||
|
||||
;; This file is NOT part of GNU Emacs.
|
||||
|
||||
|
131
org-roam-mode.el
131
org-roam-mode.el
@ -1,12 +1,12 @@
|
||||
;;; org-roam-mode.el --- Major mode for special Org-roam buffers -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright © 2020-2022 Jethro Kuan <jethrokuan95@gmail.com>
|
||||
;; Copyright © 2020-2025 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: 2.2.1
|
||||
;; Package-Requires: ((emacs "26.1") (dash "2.13") (org "9.4") (emacsql "3.0.0") (emacsql-sqlite "1.0.0") (magit-section "3.0.0"))
|
||||
;; Version: 2.3.1
|
||||
;; Package-Requires: ((emacs "26.1") (dash "2.13") (org "9.6") (emacsql "4.1.0") (magit-section "3.0.0"))
|
||||
|
||||
;; This file is NOT part of GNU Emacs.
|
||||
|
||||
@ -42,8 +42,8 @@
|
||||
(defcustom org-roam-mode-sections (list #'org-roam-backlinks-section
|
||||
#'org-roam-reflinks-section)
|
||||
"A list of sections for the `org-roam-mode' based buffers.
|
||||
Each section is a function that is passed the an `org-roam-node'
|
||||
for which the section will be constructed for as the first
|
||||
Each section is a function that is passed the `org-roam-node'
|
||||
for which the section will be constructed as the first
|
||||
argument. Normally this node is `org-roam-buffer-current-node'.
|
||||
The function may also accept other optional arguments. Each item
|
||||
in the list is either:
|
||||
@ -319,7 +319,7 @@ To toggle its display use `org-roam-buffer-toggle' command.")
|
||||
|
||||
(define-inline org-roam-buffer--visibility ()
|
||||
"Return the current visibility state of the persistent `org-roam-buffer'.
|
||||
Valid states are 'visible, 'exists and 'none."
|
||||
Valid states are `visible', `exists' and `none'."
|
||||
(declare (side-effect-free t))
|
||||
(inline-quote
|
||||
(cond
|
||||
@ -339,7 +339,7 @@ Has no effect when there's no `org-roam-node-at-point'."
|
||||
(add-hook 'kill-buffer-hook #'org-roam-buffer--persistent-cleanup-h nil t)))))
|
||||
|
||||
(defun org-roam-buffer--persistent-cleanup-h ()
|
||||
"Clean-up global state thats dedicated for the persistent `org-roam-buffer'."
|
||||
"Clean-up global state that's dedicated for the persistent `org-roam-buffer'."
|
||||
(setq-default org-roam-buffer-current-node nil
|
||||
org-roam-buffer-current-directory nil))
|
||||
|
||||
@ -441,7 +441,7 @@ In interactive calls OTHER-WINDOW is set with
|
||||
(with-current-buffer buf
|
||||
(widen)
|
||||
(goto-char point))
|
||||
(when (org-invisible-p) (org-show-context))
|
||||
(when (org-invisible-p) (org-fold-show-context))
|
||||
buf))
|
||||
|
||||
(defun org-roam-preview-default-function ()
|
||||
@ -514,19 +514,28 @@ Sorts by title."
|
||||
(string< (org-roam-node-title (org-roam-backlink-source-node a))
|
||||
(org-roam-node-title (org-roam-backlink-source-node b))))
|
||||
|
||||
(cl-defun org-roam-backlinks-section (node &key (unique nil))
|
||||
(cl-defun org-roam-backlinks-section (node &key (unique nil) (show-backlink-p nil)
|
||||
(section-heading "Backlinks:"))
|
||||
"The backlinks section for NODE.
|
||||
|
||||
When UNIQUE is nil, show all positions where references are found.
|
||||
When UNIQUE is t, limit to unique sources."
|
||||
When UNIQUE is t, limit to unique sources.
|
||||
|
||||
When SHOW-BACKLINK-P is not null, only show backlinks for which
|
||||
this predicate is not nil.
|
||||
|
||||
SECTION-HEADING is the string used as a heading for the backlink section."
|
||||
(when-let ((backlinks (seq-sort #'org-roam-backlinks-sort (org-roam-backlinks-get node :unique unique))))
|
||||
(magit-insert-section (org-roam-backlinks)
|
||||
(magit-insert-heading "Backlinks:")
|
||||
(magit-insert-heading section-heading)
|
||||
(dolist (backlink backlinks)
|
||||
(org-roam-node-insert-section
|
||||
:source-node (org-roam-backlink-source-node backlink)
|
||||
:point (org-roam-backlink-point backlink)
|
||||
:properties (org-roam-backlink-properties backlink)))
|
||||
(when (or (null show-backlink-p)
|
||||
(and (not (null show-backlink-p))
|
||||
(funcall show-backlink-p backlink)))
|
||||
(org-roam-node-insert-section
|
||||
:source-node (org-roam-backlink-source-node backlink)
|
||||
:point (org-roam-backlink-point backlink)
|
||||
:properties (org-roam-backlink-properties backlink))))
|
||||
(insert ?\n))))
|
||||
|
||||
;;;; Reflinks
|
||||
@ -621,7 +630,7 @@ instead."
|
||||
(forward-line (1- row)))
|
||||
(when col
|
||||
(forward-char (1- col))))
|
||||
(when (org-invisible-p) (org-show-context))
|
||||
(when (org-invisible-p) (org-fold-show-context))
|
||||
buf))
|
||||
|
||||
;;;; Unlinked references
|
||||
@ -649,49 +658,69 @@ This is the ROW within FILE."
|
||||
(end-of-line)
|
||||
(point)))))
|
||||
|
||||
(defun org-roam-unlinked-references--rg-command (titles temp-file)
|
||||
"Return the ripgrep command searching for TITLES using TEMP-FILE for pattern.
|
||||
This avoids shell escaping issues by writing the pattern to a file instead
|
||||
of passing it directly through the shell command line."
|
||||
;; Write pattern to temp file to avoid shell escaping issues with quotes,
|
||||
;; spaces, and other special characters in titles
|
||||
(with-temp-file temp-file
|
||||
(insert "\\[([^[]]++|(?R))*\\]"
|
||||
(mapconcat (lambda (title)
|
||||
;; Use regexp-quote instead of shell-quote-argument
|
||||
;; since we're writing a regex pattern, not a shell argument
|
||||
(format "|(\\b%s\\b)" (regexp-quote title)))
|
||||
titles "")))
|
||||
|
||||
(concat "rg --follow --only-matching --vimgrep --pcre2 --ignore-case "
|
||||
(mapconcat (lambda (glob) (concat "--glob " glob))
|
||||
(org-roam--list-files-search-globs org-roam-file-extensions)
|
||||
" ")
|
||||
" --file " (shell-quote-argument temp-file) " "
|
||||
(shell-quote-argument (expand-file-name org-roam-directory))))
|
||||
|
||||
(defun org-roam-unlinked-references-section (node)
|
||||
"The unlinked references section for NODE.
|
||||
References from FILE are excluded."
|
||||
(when (and (executable-find "rg")
|
||||
(org-roam-node-title node)
|
||||
(not (string-match "PCRE2 is not available"
|
||||
(shell-command-to-string "rg --pcre2-version"))))
|
||||
(let* ((titles (cons (org-roam-node-title node)
|
||||
(org-roam-node-aliases node)))
|
||||
(rg-command (concat "rg -L -o --vimgrep -P -i "
|
||||
(mapconcat (lambda (glob) (concat "-g " glob))
|
||||
(org-roam--list-files-search-globs org-roam-file-extensions)
|
||||
" ")
|
||||
(format " '\\[([^[]]++|(?R))*\\]%s' "
|
||||
(mapconcat (lambda (title)
|
||||
(format "|(\\b%s\\b)" (shell-quote-argument title)))
|
||||
titles ""))
|
||||
org-roam-directory))
|
||||
(results (split-string (shell-command-to-string rg-command) "\n"))
|
||||
f row col match)
|
||||
(magit-insert-section (unlinked-references)
|
||||
(magit-insert-heading "Unlinked References:")
|
||||
(dolist (line results)
|
||||
(save-match-data
|
||||
(when (string-match org-roam-unlinked-references-result-re line)
|
||||
(setq f (match-string 1 line)
|
||||
row (string-to-number (match-string 2 line))
|
||||
col (string-to-number (match-string 3 line))
|
||||
match (match-string 4 line))
|
||||
(when (and match
|
||||
(not (file-equal-p (org-roam-node-file node) f))
|
||||
(member (downcase match) (mapcar #'downcase titles)))
|
||||
(magit-insert-section section (org-roam-grep-section)
|
||||
(oset section file f)
|
||||
(oset section row row)
|
||||
(oset section col col)
|
||||
(insert (propertize (format "%s:%s:%s"
|
||||
(truncate-string-to-width (file-name-base f) 15 nil nil t)
|
||||
row col) 'font-lock-face 'org-roam-dim)
|
||||
" "
|
||||
(org-roam-fontify-like-in-org-mode
|
||||
(org-roam-unlinked-references-preview-line f row))
|
||||
"\n"))))))
|
||||
(insert ?\n)))))
|
||||
;; Create temp file for the regex pattern
|
||||
(temp-file (make-temp-file "org-roam-rg-pattern-"))
|
||||
(rg-command (org-roam-unlinked-references--rg-command titles temp-file)))
|
||||
;; Use unwind-protect to ensure temp file cleanup even if errors occur
|
||||
(unwind-protect
|
||||
(let* ((results (split-string (shell-command-to-string rg-command) "\n"))
|
||||
f row col match)
|
||||
(magit-insert-section (unlinked-references)
|
||||
(magit-insert-heading "Unlinked References:")
|
||||
(dolist (line results)
|
||||
(save-match-data
|
||||
(when (string-match org-roam-unlinked-references-result-re line)
|
||||
(setq f (match-string 1 line)
|
||||
row (string-to-number (match-string 2 line))
|
||||
col (string-to-number (match-string 3 line))
|
||||
match (match-string 4 line))
|
||||
(when (and match
|
||||
(not (file-equal-p (org-roam-node-file node) f))
|
||||
(member (downcase match) (mapcar #'downcase titles)))
|
||||
(magit-insert-section section (org-roam-grep-section)
|
||||
(oset section file f)
|
||||
(oset section row row)
|
||||
(oset section col col)
|
||||
(insert (propertize (format "%s:%s:%s"
|
||||
(truncate-string-to-width (file-name-base f) 15 nil nil t)
|
||||
row col) 'font-lock-face 'org-roam-dim)
|
||||
" "
|
||||
(org-roam-fontify-like-in-org-mode
|
||||
(org-roam-unlinked-references-preview-line f row))
|
||||
"\n"))))))
|
||||
(insert ?\n)))
|
||||
;; Clean up temp file - this runs even if an error occurs above
|
||||
(delete-file temp-file)))))
|
||||
|
||||
(provide 'org-roam-mode)
|
||||
;;; org-roam-mode.el ends here
|
||||
|
228
org-roam-node.el
228
org-roam-node.el
@ -1,12 +1,12 @@
|
||||
;;; org-roam-node.el --- Interfacing and interacting with nodes -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright © 2020-2022 Jethro Kuan <jethrokuan95@gmail.com>
|
||||
;; Copyright © 2020-2025 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: 2.2.1
|
||||
;; Package-Requires: ((emacs "26.1") (dash "2.13") (org "9.4") (magit-section "3.0.0"))
|
||||
;; Version: 2.3.1
|
||||
;; Package-Requires: ((emacs "26.1") (dash "2.13") (org "9.6") (magit-section "3.0.0"))
|
||||
|
||||
;; This file is NOT part of GNU Emacs.
|
||||
|
||||
@ -32,12 +32,23 @@
|
||||
;; interactively.
|
||||
;;
|
||||
;;; Code:
|
||||
(require 'crm)
|
||||
(require 'org-roam)
|
||||
|
||||
;;; Options
|
||||
;;;; Completing-read
|
||||
(defcustom org-roam-node-display-template "${title}"
|
||||
"Configures display formatting for Org-roam node.
|
||||
|
||||
If it is a function, it will be called to format a node.
|
||||
Its result is expected to be a string (potentially with
|
||||
embedded properties).
|
||||
|
||||
If it is a string and it will be used as described in org-roam
|
||||
(see org-roam-node-display-template)
|
||||
|
||||
When it is a string, the following processing is done:
|
||||
|
||||
Patterns of form \"${field-name:length}\" are interpolated based
|
||||
on the current node.
|
||||
|
||||
@ -63,9 +74,23 @@ as many characters as possible and will be aligned accordingly.
|
||||
|
||||
A closure can also be assigned to this variable in which case the
|
||||
closure is evaluated and the return value is used as the
|
||||
template. The closure must evaluate to a valid template string."
|
||||
template. The closure must evaluate to a valid template string.
|
||||
|
||||
When org-roam-node-display-template is a function, the function is
|
||||
expected to return a string, potentially propertized. For example, the
|
||||
following function shows the title and base filename of the node:
|
||||
|
||||
\(defun my--org-roam-format (node)
|
||||
\"formats the node\"
|
||||
(format \"%-40s %s\"
|
||||
(if (org-roam-node-title node)
|
||||
(propertize (org-roam-node-title node) 'face 'org-todo)
|
||||
\"\")
|
||||
(file-name-nondirectory (org-roam-node-file node))))
|
||||
|
||||
\q(setq org-roam-node-display-template 'my--org-roam-format)"
|
||||
:group 'org-roam
|
||||
:type '(string function))
|
||||
:type '(choice string function))
|
||||
|
||||
(defcustom org-roam-node-annotation-function #'org-roam-node-read--annotation
|
||||
"This function used to attach annotations for `org-roam-node-read'.
|
||||
@ -89,7 +114,7 @@ argument, an `org-roam-node', and return a string.
|
||||
If a string is provided, it is a template string expanded by
|
||||
`org-roam-node--format-entry'."
|
||||
:group 'org-roam
|
||||
:type '(string function))
|
||||
:type '(choice string function))
|
||||
|
||||
(defcustom org-roam-node-template-prefixes
|
||||
'(("tags" . "#")
|
||||
@ -112,6 +137,12 @@ It takes a single argument REF, which is a propertized string."
|
||||
:group 'org-roam
|
||||
:type '(function))
|
||||
|
||||
(defcustom org-roam-ref-prompt-function nil
|
||||
"Function to prompt for ref strings in `org-roam-ref-add'.
|
||||
Should take no arguments, prompt the user, and return a string."
|
||||
:group 'org-roam
|
||||
:type 'function)
|
||||
|
||||
;;;; Completion-at-point
|
||||
(defcustom org-roam-completion-everywhere nil
|
||||
"When non-nil, provide link completion matching outside of Org links."
|
||||
@ -136,6 +167,10 @@ This path is relative to `org-roam-directory'."
|
||||
:group 'org-roam
|
||||
:type 'string)
|
||||
|
||||
(defvar org-roam-link-type "roam"
|
||||
"Link type for org-roam nodes.
|
||||
Replaced by `id' automatically when `org-roam-link-auto-replace' is non-nil.")
|
||||
|
||||
(defvar org-roam-node-history nil
|
||||
"Minibuffer history of nodes.")
|
||||
|
||||
@ -144,6 +179,11 @@ This path is relative to `org-roam-directory'."
|
||||
|
||||
;;; Definition
|
||||
(cl-defstruct (org-roam-node (:constructor org-roam-node-create)
|
||||
(:constructor org-roam-node-create-from-db
|
||||
(title aliases ; 2
|
||||
id file file-title level todo ; 5
|
||||
point priority scheduled deadline properties ;;5
|
||||
olp file-atime file-mtime tags refs)) ;;5
|
||||
(:copier nil))
|
||||
"A heading or top level file with an assigned ID property."
|
||||
file file-title file-hash file-atime file-mtime
|
||||
@ -210,6 +250,10 @@ This path is relative to `org-roam-directory'."
|
||||
(_
|
||||
(org-roam-node-title node))))
|
||||
|
||||
(cl-defmethod org-roam-node-category ((node org-roam-node))
|
||||
"Return the category for NODE."
|
||||
(cdr (assoc-string "CATEGORY" (org-roam-node-properties node))))
|
||||
|
||||
;;; Nodes
|
||||
;;;; Getters
|
||||
(defun org-roam-node-at-point (&optional assert)
|
||||
@ -224,9 +268,12 @@ populated."
|
||||
(magit-section-up)
|
||||
(org-roam-node-at-point)))
|
||||
(t (org-with-wide-buffer
|
||||
(org-back-to-heading-or-point-min t)
|
||||
(while (and (not (org-roam-db-node-p))
|
||||
(not (bobp)))
|
||||
(while (not (or (org-roam-db-node-p)
|
||||
(bobp)
|
||||
(eq (funcall outline-level)
|
||||
(save-excursion
|
||||
(org-roam-up-heading-or-point-min)
|
||||
(funcall outline-level)))))
|
||||
(org-roam-up-heading-or-point-min))
|
||||
(when-let ((id (org-id-get)))
|
||||
(org-roam-populate
|
||||
@ -243,17 +290,21 @@ Return nil if a node with ID does not exist."
|
||||
id)) 0)
|
||||
(org-roam-populate (org-roam-node-create :id id))))
|
||||
|
||||
(defun org-roam-node-from-title-or-alias (s)
|
||||
(defun org-roam-node-from-title-or-alias (s &optional nocase)
|
||||
"Return an `org-roam-node' for the node with title or alias S.
|
||||
Return nil if the node does not exist.
|
||||
Throw an error if multiple choices exist."
|
||||
Throw an error if multiple choices exist.
|
||||
|
||||
If NOCASE is non-nil, the query is case insensitive. It is case sensitive otherwise."
|
||||
(let ((matches (seq-uniq
|
||||
(append
|
||||
(org-roam-db-query [:select [id] :from nodes
|
||||
:where (= title $s1)]
|
||||
(org-roam-db-query (vconcat [:select [id] :from nodes
|
||||
:where (= title $s1)]
|
||||
(if nocase [ :collate NOCASE ]))
|
||||
s)
|
||||
(org-roam-db-query [:select [node-id] :from aliases
|
||||
:where (= alias $s1)]
|
||||
(org-roam-db-query (vconcat [:select [node-id] :from aliases
|
||||
:where (= alias $s1)]
|
||||
(if nocase [ :collate NOCASE ]))
|
||||
s)))))
|
||||
(cond
|
||||
((seq-empty-p matches)
|
||||
@ -292,7 +343,8 @@ Return nil if there's no node with such REF."
|
||||
Uses the ID, and fetches remaining details from the database.
|
||||
This can be quite costly: avoid, unless dealing with very few
|
||||
nodes."
|
||||
(when-let ((node-info (car (org-roam-db-query [:select [file level pos todo priority
|
||||
(when-let ((node-info (car (org-roam-db-query [:select [
|
||||
file level pos todo priority
|
||||
scheduled deadline title properties olp]
|
||||
:from nodes
|
||||
:where (= id $s1)
|
||||
@ -333,23 +385,27 @@ nodes."
|
||||
(defun org-roam-node-list ()
|
||||
"Return all nodes stored in the database as a list of `org-roam-node's."
|
||||
(let ((rows (org-roam-db-query
|
||||
"SELECT
|
||||
"
|
||||
SELECT
|
||||
title,
|
||||
aliases,
|
||||
|
||||
id,
|
||||
file,
|
||||
filetitle,
|
||||
\"level\",
|
||||
todo,
|
||||
|
||||
pos,
|
||||
priority ,
|
||||
scheduled ,
|
||||
deadline ,
|
||||
title,
|
||||
properties ,
|
||||
|
||||
olp,
|
||||
atime,
|
||||
mtime,
|
||||
'(' || group_concat(tags, ' ') || ')' as tags,
|
||||
aliases,
|
||||
refs
|
||||
FROM
|
||||
(
|
||||
@ -398,41 +454,29 @@ FROM
|
||||
LEFT JOIN refs ON refs.node_id = nodes.id
|
||||
GROUP BY nodes.id, tags.tag, aliases.alias )
|
||||
GROUP BY id, tags )
|
||||
GROUP BY id")))
|
||||
(cl-loop for row in rows
|
||||
append (pcase-let* ((`(,id ,file ,file-title ,level ,todo ,pos ,priority ,scheduled ,deadline
|
||||
,title ,properties ,olp ,atime ,mtime ,tags ,aliases ,refs)
|
||||
row)
|
||||
(all-titles (cons title aliases)))
|
||||
(mapcar (lambda (temp-title)
|
||||
(org-roam-node-create :id id
|
||||
:file file
|
||||
:file-title file-title
|
||||
:file-atime atime
|
||||
:file-mtime mtime
|
||||
:level level
|
||||
:point pos
|
||||
:todo todo
|
||||
:priority priority
|
||||
:scheduled scheduled
|
||||
:deadline deadline
|
||||
:title temp-title
|
||||
:aliases aliases
|
||||
:properties properties
|
||||
:olp olp
|
||||
:tags tags
|
||||
:refs refs))
|
||||
all-titles)))))
|
||||
GROUP BY id
|
||||
")))
|
||||
(mapcan
|
||||
(lambda (row)
|
||||
(let (
|
||||
(all-titles (cons (car row) (nth 1 row)))
|
||||
)
|
||||
(mapcar (lambda (temp-title)
|
||||
(apply 'org-roam-node-create-from-db (cons temp-title (cdr row))))
|
||||
all-titles)
|
||||
))
|
||||
rows)
|
||||
)
|
||||
)
|
||||
|
||||
;;;; Finders
|
||||
(defun org-roam-node-marker (node)
|
||||
"Get the marker for NODE."
|
||||
(unwind-protect
|
||||
(let* ((file (org-roam-node-file node))
|
||||
(buffer (or (find-buffer-visiting file)
|
||||
(find-file-noselect file))))
|
||||
(with-current-buffer buffer
|
||||
(move-marker (make-marker) (org-roam-node-point node) buffer)))))
|
||||
(let* ((file (org-roam-node-file node))
|
||||
(buffer (or (find-buffer-visiting file)
|
||||
(find-file-noselect file))))
|
||||
(with-current-buffer buffer
|
||||
(move-marker (make-marker) (org-roam-node-point node) buffer))))
|
||||
|
||||
(defun org-roam-node-open (node &optional cmd force)
|
||||
"Go to the node NODE.
|
||||
@ -459,7 +503,7 @@ NODE, unless FORCE is non-nil."
|
||||
(org-roam-id-at-point))))
|
||||
(goto-char m))
|
||||
(move-marker m nil))
|
||||
(org-show-context))
|
||||
(org-fold-show-context))
|
||||
|
||||
(defun org-roam-node-visit (node &optional other-window force)
|
||||
"From the current buffer, visit NODE. Return the visited buffer.
|
||||
@ -477,7 +521,7 @@ interactive calls FORCE always set to t."
|
||||
force))
|
||||
|
||||
;;;###autoload
|
||||
(cl-defun org-roam-node-find (&optional other-window initial-input filter-fn &key templates)
|
||||
(cl-defun org-roam-node-find (&optional other-window initial-input filter-fn pred &key templates)
|
||||
"Find and open an Org-roam node by its title or alias.
|
||||
INITIAL-INPUT is the initial input for the prompt.
|
||||
FILTER-FN is a function to filter out nodes: it takes an `org-roam-node',
|
||||
@ -486,7 +530,7 @@ If OTHER-WINDOW, visit the NODE in another window.
|
||||
The TEMPLATES, if provided, override the list of capture templates (see
|
||||
`org-roam-capture-'.)"
|
||||
(interactive current-prefix-arg)
|
||||
(let ((node (org-roam-node-read initial-input filter-fn)))
|
||||
(let ((node (org-roam-node-read initial-input filter-fn pred)))
|
||||
(if (org-roam-node-file node)
|
||||
(org-roam-node-visit node other-window)
|
||||
(org-roam-capture-
|
||||
@ -537,6 +581,25 @@ PROMPT is a string to show at the beginning of the mini-buffer, defaulting to \"
|
||||
(or (cdr (assoc node nodes))
|
||||
(org-roam-node-create :title node))))
|
||||
|
||||
(defun org-roam--format-nodes-using-template (nodes)
|
||||
"Formats NODES using org-roam template features.
|
||||
Uses org-roam--node-display-template."
|
||||
(let (
|
||||
(wTemplate (org-roam-node--process-display-format org-roam-node-display-template))
|
||||
)
|
||||
(mapcar (lambda (node)
|
||||
(org-roam-node-read--to-candidate node wTemplate)) nodes))
|
||||
)
|
||||
|
||||
(defun org-roam--format-nodes-using-function (nodes)
|
||||
"Formats NODES using the function org-roam-node-display-template."
|
||||
(mapcar (lambda (node)
|
||||
(cons
|
||||
(propertize (funcall org-roam-node-display-template node) 'node node)
|
||||
node))
|
||||
nodes)
|
||||
)
|
||||
|
||||
(defun org-roam-node-read--completions (&optional filter-fn sort-fn)
|
||||
"Return an alist for node completion.
|
||||
The car is the displayed title or alias for the node, and the cdr
|
||||
@ -546,15 +609,17 @@ and when nil is returned the node will be filtered out.
|
||||
SORT-FN is a function to sort nodes. See `org-roam-node-read-sort-by-file-mtime'
|
||||
for an example sort function.
|
||||
The displayed title is formatted according to `org-roam-node-display-template'."
|
||||
(let* ((template (org-roam-node--process-display-format org-roam-node-display-template))
|
||||
(let* (
|
||||
(nodes (org-roam-node-list))
|
||||
(nodes (mapcar (lambda (node)
|
||||
(org-roam-node-read--to-candidate node template)) nodes))
|
||||
(nodes (if filter-fn
|
||||
(cl-remove-if-not
|
||||
(lambda (n) (funcall filter-fn (cdr n)))
|
||||
(lambda (n) (funcall filter-fn n))
|
||||
nodes)
|
||||
nodes))
|
||||
(nodes (if (functionp org-roam-node-display-template)
|
||||
(org-roam--format-nodes-using-function nodes)
|
||||
(org-roam--format-nodes-using-template nodes)))
|
||||
|
||||
(sort-fn (or sort-fn
|
||||
(when org-roam-node-default-sort
|
||||
(intern (concat "org-roam-node-read-sort-by-"
|
||||
@ -707,7 +772,7 @@ The INFO, if provided, is passed to the underlying `org-roam-capture-'."
|
||||
(deactivate-mark)))
|
||||
|
||||
;;;;; [roam:] link
|
||||
(org-link-set-parameters "roam" :follow #'org-roam-link-follow-link)
|
||||
(org-link-set-parameters org-roam-link-type :follow #'org-roam-link-follow-link)
|
||||
(defun org-roam-link-follow-link (title-or-alias)
|
||||
"Navigate \"roam:\" link to find and open the node with TITLE-OR-ALIAS.
|
||||
Assumes that the cursor was put where the link is."
|
||||
@ -736,7 +801,7 @@ Assumes that the cursor was put where the link is."
|
||||
node)
|
||||
(goto-char (org-element-property :begin link))
|
||||
(when (and (org-in-regexp org-link-any-re 1)
|
||||
(string-equal type "roam")
|
||||
(string-equal type org-roam-link-type)
|
||||
(setq node (save-match-data (org-roam-node-from-title-or-alias path))))
|
||||
(replace-match (org-link-make-string
|
||||
(concat "id:" (org-roam-node-id node))
|
||||
@ -745,9 +810,10 @@ Assumes that the cursor was put where the link is."
|
||||
(defun org-roam-link-replace-all ()
|
||||
"Replace all \"roam:\" links in buffer with \"id:\" links."
|
||||
(interactive)
|
||||
(org-with-point-at 1
|
||||
(while (re-search-forward org-link-bracket-re nil t)
|
||||
(org-roam-link-replace-at-point))))
|
||||
(let ((org-roam-link-prefix (concat "[[" org-roam-link-type ":")))
|
||||
(org-with-point-at 1
|
||||
(while (re-search-forward org-roam-link-prefix nil t)
|
||||
(org-roam-link-replace-at-point)))))
|
||||
|
||||
(add-hook 'org-roam-find-file-hook #'org-roam--replace-roam-links-on-save-h)
|
||||
(defun org-roam--replace-roam-links-on-save-h ()
|
||||
@ -766,7 +832,8 @@ We use this as a substitute for `org-link-bracket-re', because
|
||||
"Complete \"roam:\" link at point to an existing Org-roam node."
|
||||
(let (roam-p start end)
|
||||
(when (org-in-regexp org-roam-bracket-completion-re 1)
|
||||
(setq roam-p (not (string-blank-p (match-string 1)))
|
||||
(setq roam-p (not (or (org-in-src-block-p)
|
||||
(string-blank-p (match-string 1))))
|
||||
start (match-beginning 2)
|
||||
end (match-end 2))
|
||||
(list start end
|
||||
@ -788,6 +855,7 @@ outside of the bracket syntax for links (i.e. \"[[roam:|]]\"),
|
||||
hence \"everywhere\"."
|
||||
(when (and org-roam-completion-everywhere
|
||||
(thing-at-point 'word)
|
||||
(not (org-in-src-block-p))
|
||||
(not (save-match-data (org-in-regexp org-link-any-re))))
|
||||
(let ((bounds (bounds-of-thing-at-point 'word)))
|
||||
(list (car bounds) (cdr bounds)
|
||||
@ -837,7 +905,7 @@ Any top level properties drawers are incorporated into the new heading."
|
||||
(org-with-wide-buffer
|
||||
(org-map-region (lambda ()
|
||||
(if (= (org-current-level) 1)
|
||||
(incf h1-count)))
|
||||
(cl-incf h1-count)))
|
||||
(point-min) (point-max))
|
||||
h1-count)))
|
||||
|
||||
@ -859,22 +927,24 @@ node."
|
||||
(org-with-point-at 1
|
||||
(let ((title (nth 4 (org-heading-components)))
|
||||
(tags (org-get-tags)))
|
||||
(org-fold-show-all)
|
||||
(kill-whole-line)
|
||||
(org-roam-end-of-meta-data)
|
||||
(org-roam-end-of-meta-data t)
|
||||
(insert "#+title: " title "\n")
|
||||
(when tags (org-roam-tag-add tags))
|
||||
(org-map-region #'org-promote (point-min) (point-max))
|
||||
(org-roam-db-update-file))))
|
||||
|
||||
;;;###autoload
|
||||
(defun org-roam-refile ()
|
||||
"Refile node at point to an Org-roam node.
|
||||
(defun org-roam-refile (node)
|
||||
"Refile node at point to an org-roam NODE.
|
||||
|
||||
If region is active, then use it instead of the node at point."
|
||||
(interactive)
|
||||
(interactive
|
||||
(list (org-roam-node-read nil nil nil 'require-match)))
|
||||
(let* ((regionp (org-region-active-p))
|
||||
(region-start (and regionp (region-beginning)))
|
||||
(region-end (and regionp (region-end)))
|
||||
(node (org-roam-node-read nil nil nil 'require-match))
|
||||
(file (org-roam-node-file node))
|
||||
(nbuf (or (find-buffer-visiting file)
|
||||
(find-file-noselect file)))
|
||||
@ -918,7 +988,7 @@ If region is active, then use it instead of the node at point."
|
||||
(if (buffer-file-name)
|
||||
(delete-file (buffer-file-name)))
|
||||
(set-buffer-modified-p nil)
|
||||
;; In this was done during capture, abort the capture process.
|
||||
;; If this was done during capture, abort the capture process.
|
||||
(when (and org-capture-mode
|
||||
(buffer-base-buffer (current-buffer)))
|
||||
(org-capture-kill))
|
||||
@ -962,6 +1032,7 @@ If region is active, then use it instead of the node at point."
|
||||
(with-current-buffer (find-file-noselect file-path)
|
||||
(org-paste-subtree)
|
||||
(while (> (org-current-level) 1) (org-promote-subtree))
|
||||
(save-buffer)
|
||||
(org-roam-promote-entire-buffer)
|
||||
(save-buffer)))))
|
||||
|
||||
@ -1001,8 +1072,10 @@ The car is the ref, and the cdr is the corresponding node for the ref."
|
||||
:file file
|
||||
:point pos
|
||||
:title title)))
|
||||
(cons (propertize ref 'node node 'type type)
|
||||
node)))))
|
||||
(cons
|
||||
(concat (propertize ref 'node node 'type type)
|
||||
(propertize id 'invisible t))
|
||||
node)))))
|
||||
|
||||
(defun org-roam-ref-read--annotation (ref)
|
||||
"Return the annotation for REF, which assumed to be a propertized string."
|
||||
@ -1025,11 +1098,15 @@ and when nil is returned the node will be filtered out."
|
||||
;;;; Editing
|
||||
(defun org-roam-ref-add (ref)
|
||||
"Add REF to the node at point."
|
||||
(interactive "sRef: ")
|
||||
(interactive `(,(if org-roam-ref-prompt-function
|
||||
(funcall org-roam-ref-prompt-function)
|
||||
(read-string "Ref: "))))
|
||||
(let ((node (org-roam-node-at-point 'assert)))
|
||||
(save-excursion
|
||||
(goto-char (org-roam-node-point node))
|
||||
(org-roam-property-add "ROAM_REFS" ref))))
|
||||
(org-roam-property-add "ROAM_REFS" (if (member " " (string-to-list ref))
|
||||
(concat "\"" ref "\"")
|
||||
ref)))))
|
||||
|
||||
(defun org-roam-ref-remove (&optional ref)
|
||||
"Remove a REF from the node at point."
|
||||
@ -1057,7 +1134,8 @@ and when nil is returned the node will be filtered out."
|
||||
(defun org-roam-tag-add (tags)
|
||||
"Add TAGS to the node at point."
|
||||
(interactive
|
||||
(list (completing-read-multiple "Tag: " (org-roam-tag-completions))))
|
||||
(list (let ((crm-separator "[ ]*:[ ]*"))
|
||||
(completing-read-multiple "Tag: " (org-roam-tag-completions)))))
|
||||
(let ((node (org-roam-node-at-point 'assert)))
|
||||
(save-excursion
|
||||
(goto-char (org-roam-node-point node))
|
||||
|
@ -1,12 +1,12 @@
|
||||
;;; org-roam-utils.el --- Utilities for Org-roam -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright © 2020-2022 Jethro Kuan <jethrokuan95@gmail.com>
|
||||
;; Copyright © 2020-2025 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: 2.2.1
|
||||
;; Package-Requires: ((emacs "26.1") (dash "2.13") (org "9.4"))
|
||||
;; Version: 2.3.1
|
||||
;; Package-Requires: ((emacs "26.1") (dash "2.13") (org "9.6"))
|
||||
|
||||
;; This file is NOT part of GNU Emacs.
|
||||
|
||||
@ -72,11 +72,10 @@ Like `string-equal', but case-insensitive."
|
||||
(defun org-roam-whitespace-content (s)
|
||||
"Return the whitespace content at the end of S."
|
||||
(with-temp-buffer
|
||||
(let ((c 0))
|
||||
(insert s)
|
||||
(skip-chars-backward " \t\n")
|
||||
(buffer-substring-no-properties
|
||||
(point) (point-max)))))
|
||||
(insert s)
|
||||
(skip-chars-backward " \t\n")
|
||||
(buffer-substring-no-properties
|
||||
(point) (point-max))))
|
||||
|
||||
(defun org-roam-strip-comments (s)
|
||||
"Strip Org comments from string S."
|
||||
@ -85,7 +84,8 @@ Like `string-equal', but case-insensitive."
|
||||
(goto-char (point-min))
|
||||
(while (not (eobp))
|
||||
(if (org-at-comment-p)
|
||||
(delete-region (point-at-bol) (progn (forward-line) (point)))
|
||||
(delete-region (line-beginning-position)
|
||||
(progn (forward-line) (point)))
|
||||
(forward-line)))
|
||||
(buffer-string)))
|
||||
|
||||
@ -120,7 +120,7 @@ SPEC is a list, as per `dolist'."
|
||||
;;; File utilities
|
||||
(defun org-roam-descendant-of-p (a b)
|
||||
"Return t if A is descendant of B."
|
||||
(unless (equal (file-truename a) (file-truename b))
|
||||
(unless (and a b (equal (file-truename a) (file-truename b)))
|
||||
(string-prefix-p (replace-regexp-in-string "^\\([A-Za-z]\\):" 'downcase (expand-file-name b) t t)
|
||||
(replace-regexp-in-string "^\\([A-Za-z]\\):" 'downcase (expand-file-name a) t t))))
|
||||
|
||||
@ -163,7 +163,8 @@ If FILE, set `default-directory' to FILE's directory and insert its contents."
|
||||
(let ((current-org-roam-directory (make-symbol "current-org-roam-directory")))
|
||||
`(let ((,current-org-roam-directory org-roam-directory))
|
||||
(with-temp-buffer
|
||||
(let ((org-roam-directory ,current-org-roam-directory))
|
||||
(let ((org-roam-directory ,current-org-roam-directory)
|
||||
(org-inhibit-startup t))
|
||||
(delay-mode-hooks (org-mode))
|
||||
(when ,file
|
||||
(insert-file-contents ,file)
|
||||
@ -229,36 +230,10 @@ Like `org-fontify-like-in-org-mode', but supports `org-ref'."
|
||||
(insert s)
|
||||
(let ((org-ref-buffer-hacked t))
|
||||
(org-mode)
|
||||
(org-font-lock-ensure)
|
||||
(setq-local org-fold-core-style 'overlays)
|
||||
(font-lock-ensure)
|
||||
(buffer-string))))
|
||||
|
||||
;;;; Shielding regions
|
||||
(defface org-roam-shielded
|
||||
'((t :inherit (warning)))
|
||||
"Face for regions that are shielded (marked as read-only).
|
||||
This face is used on the region target by org-roam-insertion
|
||||
during an `org-roam-capture'."
|
||||
:group 'org-roam-faces)
|
||||
|
||||
(defun org-roam-shield-region (beg end)
|
||||
"Shield region against modifications.
|
||||
BEG and END are markers for the beginning and end regions.
|
||||
REGION must be a cons-cell containing the marker to the region
|
||||
beginning and maximum values."
|
||||
(add-text-properties beg end
|
||||
'(font-lock-face org-roam-shielded
|
||||
read-only t)
|
||||
(marker-buffer beg)))
|
||||
|
||||
(defun org-roam-unshield-region (beg end)
|
||||
"Unshield the shielded REGION.
|
||||
BEG and END are markers for the beginning and end regions."
|
||||
(let ((inhibit-read-only t))
|
||||
(remove-text-properties beg end
|
||||
'(font-lock-face org-roam-shielded
|
||||
read-only t)
|
||||
(marker-buffer beg))))
|
||||
|
||||
;;; Org-mode utilities
|
||||
;;;; Motions
|
||||
(defun org-roam-up-heading-or-point-min ()
|
||||
@ -364,26 +339,14 @@ If the property is already set, it's value is replaced."
|
||||
(defun org-roam-add-property (val prop)
|
||||
"Add VAL value to PROP property for the node at point.
|
||||
Both, VAL and PROP are strings."
|
||||
(let* ((p (org-entry-get (point) prop))
|
||||
(lst (when p (split-string-and-unquote p)))
|
||||
(lst (if (memq val lst) lst (cons val lst)))
|
||||
(lst (seq-uniq lst)))
|
||||
(org-set-property prop (combine-and-quote-strings lst))
|
||||
val))
|
||||
(org-roam-property-add prop val))
|
||||
|
||||
(defun org-roam-remove-property (prop &optional val)
|
||||
"Remove VAL value from PROP property for the node at point.
|
||||
Both VAL and PROP are strings.
|
||||
|
||||
If VAL is not specified, user is prompted to select a value."
|
||||
(let* ((p (org-entry-get (point) prop))
|
||||
(lst (when p (split-string-and-unquote p)))
|
||||
(prop-to-remove (or val (completing-read "Remove: " lst)))
|
||||
(lst (delete prop-to-remove lst)))
|
||||
(if lst
|
||||
(org-set-property prop (combine-and-quote-strings lst))
|
||||
(org-delete-property prop))
|
||||
prop-to-remove))
|
||||
(org-roam-property-remove prop val))
|
||||
|
||||
(defun org-roam-property-add (prop val)
|
||||
"Add VAL value to PROP property for the node at point.
|
||||
@ -487,8 +450,10 @@ See <https://github.com/raxod502/straight.el/issues/520>."
|
||||
(quit "N/A"))))
|
||||
(insert (format "- Org: %s\n" (org-version nil 'full)))
|
||||
(insert (format "- Org-roam: %s" (org-roam-version)))
|
||||
(insert (format "- sqlite-connector: %s" org-roam-database-connector))))
|
||||
|
||||
(insert (format "- sqlite-connector: %s"
|
||||
(if-let ((conn (org-roam-db--get-connection)))
|
||||
(eieio-object-class conn)
|
||||
"not connected")))))
|
||||
|
||||
(provide 'org-roam-utils)
|
||||
;;; org-roam-utils.el ends here
|
||||
|
113
org-roam.el
113
org-roam.el
@ -1,12 +1,12 @@
|
||||
;;; org-roam.el --- A database abstraction layer for Org-mode -*- coding: utf-8; lexical-binding: t; -*-
|
||||
|
||||
;; Copyright © 2020-2022 Jethro Kuan <jethrokuan95@gmail.com>
|
||||
;; Copyright © 2020-2025 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: 2.2.1
|
||||
;; Package-Requires: ((emacs "26.1") (dash "2.13") (org "9.4") (emacsql "3.0.0") (emacsql-sqlite "1.0.0") (magit-section "3.0.0"))
|
||||
;; Version: 2.3.1
|
||||
;; Package-Requires: ((emacs "26.1") (dash "2.13") (org "9.6") (emacsql "4.1.0") (magit-section "3.0.0"))
|
||||
|
||||
;; This file is NOT part of GNU Emacs.
|
||||
|
||||
@ -80,6 +80,9 @@
|
||||
(require 'magit-section)
|
||||
|
||||
(require 'emacsql)
|
||||
;; REVIEW: is this require needed?
|
||||
;; emacsql-sqlite provides a common interface to an emacsql SQLite backend (e.g. emacs-sqlite-builtin)
|
||||
;; not to be confused with a backend itself named emacsql-sqlite that existed in emacsql < 4.0.
|
||||
(require 'emacsql-sqlite)
|
||||
|
||||
(require 'org)
|
||||
@ -138,7 +141,7 @@ responsibility to ensure that."
|
||||
:group 'org-roam)
|
||||
|
||||
(defcustom org-roam-file-exclude-regexp (list org-attach-id-dir)
|
||||
"Files matching this regular expression are excluded from the Org-roam."
|
||||
"Files matching this regular expression or list of regular expressions are excluded from the Org-roam."
|
||||
:type '(choice
|
||||
(repeat
|
||||
(string :tag "Regular expression matching files to ignore"))
|
||||
@ -152,36 +155,46 @@ responsibility to ensure that."
|
||||
'(find fd fdfind rg))
|
||||
"Commands that will be used to find Org-roam files.
|
||||
|
||||
It should be a list of symbols or cons cells representing any of the following
|
||||
supported file search methods.
|
||||
It should be a list of symbols or cons cells representing any of
|
||||
the following supported file search methods.
|
||||
|
||||
The commands will be tried in order until an executable for a command is found.
|
||||
The Elisp implementation is used if no command in the list is found.
|
||||
The commands will be tried in order until an executable for a
|
||||
command is found. The Elisp implementation is used if no command
|
||||
in the list is found.
|
||||
|
||||
`find'
|
||||
|
||||
Use find as the file search method.
|
||||
Example command:
|
||||
find /path/to/dir -type f \( -name \"*.org\" -o -name \"*.org.gpg\" \)
|
||||
find /path/to/dir -type f \
|
||||
\( -name \"*.org\" -o -name \"*.org.gpg\" -name \"*.org.age\" \)
|
||||
|
||||
`fd'
|
||||
|
||||
Use fd as the file search method.
|
||||
Example command: fd /path/to/dir/ --type file -e \".org\" -e \".org.gpg\"
|
||||
Example command:
|
||||
fd /path/to/dir/ --type file -e \".org\" -e \".org.gpg\" -e \".org.age\"
|
||||
|
||||
`fdfind'
|
||||
|
||||
Same as `fd'. It's an alias that used in some OSes (e.g. Debian, Ubuntu)
|
||||
|
||||
`rg'
|
||||
Use ripgrep as the file search method.
|
||||
Example command: rg /path/to/dir/ --files -g \"*.org\" -g \"*.org.gpg\"
|
||||
|
||||
By default, `executable-find' will be used to look up the path to the
|
||||
executable. If a custom path is required, it can be specified together with the
|
||||
method symbol as a cons cell. For example: '(find (rg . \"/path/to/rg\"))."
|
||||
:type '(set (const :tag "find" find)
|
||||
(const :tag "fd" fd)
|
||||
(const :tag "fdfind" fdfind)
|
||||
(const :tag "rg" rg)
|
||||
(const :tag "elisp" nil)))
|
||||
Use ripgrep as the file search method.
|
||||
Example command:
|
||||
rg /path/to/dir/ --files -g \"*.org\" -g \"*.org.gpg\" -g \"*.org.age\"
|
||||
|
||||
By default, `executable-find' will be used to look up the path to
|
||||
the executable. If a custom path is required, it can be specified
|
||||
together with the method symbol as a cons cell. For example:
|
||||
\\='(find (rg . \"/path/to/rg\"))."
|
||||
:type '(set
|
||||
(const :tag "find" find)
|
||||
(const :tag "fd" fd)
|
||||
(const :tag "fdfind" fdfind)
|
||||
(const :tag "rg" rg)
|
||||
(const :tag "elisp" nil)))
|
||||
|
||||
;;; Library
|
||||
(defun org-roam-file-p (&optional file)
|
||||
@ -192,30 +205,34 @@ FILE is an Org-roam file if:
|
||||
- It's located somewhere under `org-roam-directory'
|
||||
- It has a matching file extension (`org-roam-file-extensions')
|
||||
- It doesn't match excluded regexp (`org-roam-file-exclude-regexp')"
|
||||
(let* ((path (or file (buffer-file-name (buffer-base-buffer))))
|
||||
(ext (when path (org-roam--file-name-extension path)))
|
||||
(ext (if (string= ext "gpg")
|
||||
(org-roam--file-name-extension (file-name-sans-extension path))
|
||||
ext))
|
||||
(org-roam-dir-p (org-roam-descendant-of-p path org-roam-directory))
|
||||
(valid-file-ext-p (member ext org-roam-file-extensions))
|
||||
(match-exclude-regexp-p
|
||||
(cond
|
||||
((not org-roam-file-exclude-regexp) nil)
|
||||
((stringp org-roam-file-exclude-regexp)
|
||||
(string-match-p org-roam-file-exclude-regexp path))
|
||||
((listp org-roam-file-exclude-regexp)
|
||||
(let (is-match)
|
||||
(dolist (exclude-re org-roam-file-exclude-regexp)
|
||||
(setq is-match (or is-match (string-match-p exclude-re path))))
|
||||
is-match)))))
|
||||
(save-match-data
|
||||
(and
|
||||
path
|
||||
org-roam-dir-p
|
||||
valid-file-ext-p
|
||||
(not match-exclude-regexp-p)))))
|
||||
(when (or file (buffer-file-name (buffer-base-buffer)))
|
||||
(let* ((path (or file (buffer-file-name (buffer-base-buffer))))
|
||||
(relative-path (file-relative-name path org-roam-directory))
|
||||
(ext (org-roam--file-name-extension path))
|
||||
(ext (if (or (string= ext "gpg")
|
||||
(string= ext "age"))
|
||||
(org-roam--file-name-extension (file-name-sans-extension path))
|
||||
ext))
|
||||
(org-roam-dir-p (org-roam-descendant-of-p path org-roam-directory))
|
||||
(valid-file-ext-p (member ext org-roam-file-extensions))
|
||||
(match-exclude-regexp-p
|
||||
(cond
|
||||
((not org-roam-file-exclude-regexp) nil)
|
||||
((stringp org-roam-file-exclude-regexp)
|
||||
(string-match-p org-roam-file-exclude-regexp relative-path))
|
||||
((listp org-roam-file-exclude-regexp)
|
||||
(let (is-match)
|
||||
(dolist (exclude-re org-roam-file-exclude-regexp)
|
||||
(setq is-match (or is-match (string-match-p exclude-re relative-path))))
|
||||
is-match)))))
|
||||
(save-match-data
|
||||
(and
|
||||
path
|
||||
org-roam-dir-p
|
||||
valid-file-ext-p
|
||||
(not match-exclude-regexp-p))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun org-roam-list-files ()
|
||||
"Return a list of all Org-roam files under `org-roam-directory'.
|
||||
See `org-roam-file-p' for how each file is determined to be as
|
||||
@ -287,7 +304,8 @@ If no files are found, an empty list is returned."
|
||||
E.g. (\".org\") => (\"*.org\" \"*.org.gpg\")"
|
||||
(cl-loop for e in exts
|
||||
append (list (format "\"*.%s\"" e)
|
||||
(format "\"*.%s.gpg\"" e))))
|
||||
(format "\"*.%s.gpg\"" e)
|
||||
(format "\"*.%s.age\"" e))))
|
||||
|
||||
(defun org-roam--list-files-find (executable dir)
|
||||
"Return all Org-roam files under DIR, using \"find\", provided as EXECUTABLE."
|
||||
@ -308,8 +326,9 @@ E.g. (\".org\") => (\"*.org\" \"*.org.gpg\")"
|
||||
(defun org-roam--list-files-rg (executable dir)
|
||||
"Return all Org-roam files under DIR, using \"rg\", provided as EXECUTABLE."
|
||||
(let* ((globs (org-roam--list-files-search-globs org-roam-file-extensions))
|
||||
(command (string-join `(,executable "-L" ,dir "--files"
|
||||
,@(mapcar (lambda (glob) (concat "-g " glob)) globs)) " ")))
|
||||
(command (string-join `(
|
||||
,executable "-L" ,dir "--files"
|
||||
,@(mapcar (lambda (glob) (concat "-g " glob)) globs)) " ")))
|
||||
(org-roam--shell-command-files command)))
|
||||
|
||||
(declare-function org-roam--directory-files-recursively "org-roam-compat")
|
||||
@ -318,7 +337,7 @@ E.g. (\".org\") => (\"*.org\" \"*.org.gpg\")"
|
||||
"Return all Org-roam files under DIR, using Elisp based implementation."
|
||||
(let ((regex (concat "\\.\\(?:"(mapconcat
|
||||
#'regexp-quote org-roam-file-extensions
|
||||
"\\|" )"\\)\\(?:\\.gpg\\)?\\'"))
|
||||
"\\|" )"\\)\\(?:\\.gpg\\|\\.age\\)?\\'"))
|
||||
result)
|
||||
(dolist (file (org-roam--directory-files-recursively dir regex nil nil t) result)
|
||||
(when (and (file-readable-p file)
|
||||
|
8
tests/roam-files/demoteable.org
Normal file
8
tests/roam-files/demoteable.org
Normal file
@ -0,0 +1,8 @@
|
||||
:PROPERTIES:
|
||||
:ID: 97bf31cf-dfee-45d8-87a5-2ae0dabc4734
|
||||
:END:
|
||||
#+title: Demoteable
|
||||
|
||||
* Demoteable h1
|
||||
|
||||
** Demoteable child
|
19
tests/roam-files/family.org
Normal file
19
tests/roam-files/family.org
Normal file
@ -0,0 +1,19 @@
|
||||
:PROPERTIES:
|
||||
:ID: 998b2341-b7fe-434d-848c-5282c0727870
|
||||
:END:
|
||||
#+title: Family
|
||||
|
||||
* Grand-Parent
|
||||
:PROPERTIES:
|
||||
:ID: 77a90980-1994-464e-901f-7e3d3df07fd3
|
||||
:END:
|
||||
|
||||
** Parent
|
||||
:PROPERTIES:
|
||||
:ID: 0fa5bb3e-3d8c-4966-8bc9-78d32e505d69
|
||||
:END:
|
||||
|
||||
*** Child
|
||||
:PROPERTIES:
|
||||
:ID: 5fb4fdc5-b6d2-4f75-8d54-e60053e467ec
|
||||
:END:
|
3
tests/roam-files/promoteable.org
Normal file
3
tests/roam-files/promoteable.org
Normal file
@ -0,0 +1,3 @@
|
||||
* Promoteable h1
|
||||
|
||||
** Promoteable child
|
7
tests/roam-files/ref_with_space.org
Normal file
7
tests/roam-files/ref_with_space.org
Normal file
@ -0,0 +1,7 @@
|
||||
:PROPERTIES:
|
||||
:ROAM_REFS: "http://site.net/docs/01. introduction - hello world.html"
|
||||
:ID: 5b9a7400-f59c-4ef9-acbb-045b69af98f1
|
||||
:END:
|
||||
#+title: ref with space
|
||||
* Note
|
||||
hello
|
5
tests/roam-files/with-alias.org
Normal file
5
tests/roam-files/with-alias.org
Normal file
@ -0,0 +1,5 @@
|
||||
:PROPERTIES:
|
||||
:ID: 57ff3ce7-5bda-4825-8fca-c09f523e87ba
|
||||
:ROAM_ALIASES: Batman
|
||||
:END:
|
||||
#+title: Bruce Wayne
|
16
tests/roam-files/with-times.org
Normal file
16
tests/roam-files/with-times.org
Normal file
@ -0,0 +1,16 @@
|
||||
:PROPERTIES:
|
||||
:ID: 9a20ca6c-5555-41c9-a039-ac38bf59c7a9
|
||||
:END:
|
||||
#+title: With Times
|
||||
|
||||
* Scheduled heading
|
||||
SCHEDULED: <2024-07-16 Tue>
|
||||
:PROPERTIES:
|
||||
:ID: a523c198-4cb4-44d2-909c-a0e3258089cd
|
||||
:END:
|
||||
|
||||
* Deadline heading
|
||||
DEADLINE: <2024-07-17 Tue>
|
||||
:PROPERTIES:
|
||||
:ID: 3ab84701-d1c1-463f-b5c6-715e6ff5a0bf
|
||||
:END:
|
@ -48,9 +48,16 @@
|
||||
(org-roam-capture--fill-template "foo\n\t\n")
|
||||
:to-equal "foo\n\t\n"))
|
||||
|
||||
(it "fills template without deleting newlines in its body"
|
||||
(expect
|
||||
(org-roam-capture--fill-template "foo\n\n\nbar\n\n")
|
||||
:to-equal "foo\n\n\nbar\n\n"))
|
||||
|
||||
(it "expands templates when it's a function"
|
||||
(expect
|
||||
(org-roam-capture--fill-template (lambda () "foo"))
|
||||
:to-equal "foo")))
|
||||
|
||||
(provide 'test-org-roam-capture)
|
||||
|
||||
;;; test-org-roam-capture.el ends here
|
||||
|
120
tests/test-org-roam-db.el
Normal file
120
tests/test-org-roam-db.el
Normal file
@ -0,0 +1,120 @@
|
||||
;;; test-org-roam-db.el --- Tests for Org-roam -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2020 Jethro Kuan
|
||||
|
||||
;; Author: Jethro Kuan <jethrokuan95@gmail.com>
|
||||
;; Package-Requires: ((buttercup))
|
||||
|
||||
;; 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 of the License, 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
(require 'buttercup)
|
||||
(require 'org-roam)
|
||||
|
||||
(defvar root-directory default-directory)
|
||||
|
||||
(describe "org-roam-db-get-scheduled-time"
|
||||
(before-all
|
||||
(setq org-roam-directory (expand-file-name "tests/roam-files")
|
||||
org-roam-db-location (expand-file-name "org-roam.db" temporary-file-directory)
|
||||
org-roam-file-extensions '("org")
|
||||
org-roam-file-exclude-regexp nil)
|
||||
(org-roam-db-sync))
|
||||
|
||||
(after-all
|
||||
(org-roam-db--close)
|
||||
(delete-file org-roam-db-location)
|
||||
(cd root-directory))
|
||||
|
||||
(it "should get scheduled time for current heading node"
|
||||
(org-roam-id-open "a523c198-4cb4-44d2-909c-a0e3258089cd" nil)
|
||||
(expect (org-roam-db-get-scheduled-time) :to-equal "2024-07-16T00:00:00")))
|
||||
|
||||
(describe "org-roam-db-get-deadline-time"
|
||||
(before-all
|
||||
(setq org-roam-directory (expand-file-name "tests/roam-files")
|
||||
org-roam-db-location (expand-file-name "org-roam.db" temporary-file-directory)
|
||||
org-roam-file-extensions '("org")
|
||||
org-roam-file-exclude-regexp nil)
|
||||
(org-roam-db-sync))
|
||||
|
||||
(after-all
|
||||
(org-roam-db--close)
|
||||
(delete-file org-roam-db-location)
|
||||
(cd root-directory))
|
||||
|
||||
(it "should get deadline time for current heading node"
|
||||
(org-roam-id-open "3ab84701-d1c1-463f-b5c6-715e6ff5a0bf" nil)
|
||||
(expect (org-roam-db-get-deadline-time) :to-equal "2024-07-17T00:00:00")))
|
||||
|
||||
(describe "org-roam-db--file-hash"
|
||||
(it "computes the SHA1 of file"
|
||||
(expect (org-roam-db--file-hash "tests/roam-files/family.org")
|
||||
:to-equal
|
||||
"c4ebf8918c1533df72e4d182cbf1bbd90f776b3b")))
|
||||
|
||||
(describe "org-roam-db-sync"
|
||||
(before-all
|
||||
(setq org-roam-directory (expand-file-name "tests/roam-files")
|
||||
org-roam-db-location (expand-file-name "org-roam.db" temporary-file-directory)
|
||||
org-roam-file-extensions '("org")
|
||||
org-roam-file-exclude-regexp nil)
|
||||
(org-roam-db-sync))
|
||||
|
||||
(after-all
|
||||
(org-roam-db--close)
|
||||
(delete-file org-roam-db-location))
|
||||
|
||||
(it "has the correct number of files"
|
||||
(expect (caar (org-roam-db-query [:select (funcall count) :from files]))
|
||||
:to-equal
|
||||
9))
|
||||
|
||||
(it "has the correct number of nodes"
|
||||
(expect (caar (org-roam-db-query [:select (funcall count) :from nodes]))
|
||||
:to-equal
|
||||
12))
|
||||
|
||||
(it "has the correct number of links"
|
||||
(expect (caar (org-roam-db-query [:select (funcall count) :from links]))
|
||||
:to-equal
|
||||
1))
|
||||
|
||||
(it "respects ROAM_EXCLUDE"
|
||||
;; The excluded node has ID "53fadc75-f48e-461e-be06-44a1e88b2abe"
|
||||
(expect (mapcar #'car (org-roam-db-query [:select id :from nodes]))
|
||||
:to-have-same-items-as
|
||||
'("884b2341-b7fe-434d-848c-5282c0727861"
|
||||
"440795d0-70c1-4165-993d-aebd5eef7a24"
|
||||
"5b9a7400-f59c-4ef9-acbb-045b69af98f1"
|
||||
"0fa5bb3e-3d8c-4966-8bc9-78d32e505d69"
|
||||
"5fb4fdc5-b6d2-4f75-8d54-e60053e467ec"
|
||||
"77a90980-1994-464e-901f-7e3d3df07fd3"
|
||||
"57ff3ce7-5bda-4825-8fca-c09f523e87ba"
|
||||
"998b2341-b7fe-434d-848c-5282c0727870"
|
||||
"a523c198-4cb4-44d2-909c-a0e3258089cd"
|
||||
"3ab84701-d1c1-463f-b5c6-715e6ff5a0bf"
|
||||
"9a20ca6c-5555-41c9-a039-ac38bf59c7a9"
|
||||
"97bf31cf-dfee-45d8-87a5-2ae0dabc4734")))
|
||||
|
||||
(it "reads ref in quotes correctly"
|
||||
(expect (mapcar #'car (org-roam-db-query [:select [ref] :from refs]))
|
||||
:to-have-same-items-as
|
||||
'("//site.net/docs/01. introduction - hello world.html"))))
|
||||
|
||||
(provide 'test-org-roam-db)
|
||||
|
||||
;;; test-org-roam-db.el ends here
|
79
tests/test-org-roam-id.el
Normal file
79
tests/test-org-roam-id.el
Normal file
@ -0,0 +1,79 @@
|
||||
;;; test-org-roam-id.el --- Tests for Org-roam -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2020 Jethro Kuan
|
||||
|
||||
;; Author: Jethro Kuan <jethrokuan95@gmail.com>
|
||||
;; Package-Requires: ((buttercup))
|
||||
|
||||
;; 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 of the License, 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
(require 'buttercup)
|
||||
(require 'org-roam)
|
||||
|
||||
(defvar root-directory default-directory)
|
||||
|
||||
(describe "org-roam-id-at-point"
|
||||
(before-all
|
||||
(setq org-roam-directory (expand-file-name "tests/roam-files")
|
||||
org-roam-db-location (expand-file-name "org-roam.db" temporary-file-directory)
|
||||
org-roam-file-extensions '("org")
|
||||
org-roam-file-exclude-regexp nil)
|
||||
(org-roam-db-sync))
|
||||
|
||||
(after-all
|
||||
(org-roam-db--close)
|
||||
(delete-file org-roam-db-location)
|
||||
(cd root-directory))
|
||||
|
||||
(it "returns the correct node ids"
|
||||
(find-file "tests/roam-files/family.org" nil)
|
||||
(expect (org-roam-id-at-point) :to-equal "998b2341-b7fe-434d-848c-5282c0727870")
|
||||
|
||||
(search-forward "Grand")
|
||||
(expect (org-roam-id-at-point) :to-equal "77a90980-1994-464e-901f-7e3d3df07fd3")
|
||||
|
||||
(search-forward "Child")
|
||||
(expect (org-roam-id-at-point) :to-equal "5fb4fdc5-b6d2-4f75-8d54-e60053e467ec")))
|
||||
|
||||
(describe "org-roam-id-find"
|
||||
(before-all
|
||||
(setq org-roam-directory (expand-file-name "tests/roam-files")
|
||||
org-roam-db-location (expand-file-name "org-roam.db" temporary-file-directory)
|
||||
org-roam-file-extensions '("org")
|
||||
org-roam-file-exclude-regexp nil)
|
||||
(org-roam-db-sync))
|
||||
|
||||
(after-all
|
||||
(org-roam-db--close)
|
||||
(delete-file org-roam-db-location))
|
||||
|
||||
(it "finds nothing for non-existing node"
|
||||
(expect (org-roam-id-find "non-existing") :to-equal nil))
|
||||
|
||||
(it "finds the correct file node"
|
||||
(let ((location (org-roam-id-find "884b2341-b7fe-434d-848c-5282c0727861")))
|
||||
(expect (car location) :to-match ".*/tests/roam-files/foo.org")
|
||||
(expect (cdr location) :to-equal 1)))
|
||||
|
||||
(it "finds the correct heading node"
|
||||
(let ((location (org-roam-id-find "0fa5bb3e-3d8c-4966-8bc9-78d32e505d69")))
|
||||
(expect (car location) :to-match ".*/tests/roam-files/family.org")
|
||||
(expect (cdr location) :to-equal 156))))
|
||||
|
||||
(provide 'test-org-roam-id)
|
||||
|
||||
;;; test-org-roam-id.el ends here
|
39
tests/test-org-roam-mode.el
Normal file
39
tests/test-org-roam-mode.el
Normal file
@ -0,0 +1,39 @@
|
||||
;;; test-org-roam-mode.el --- Tests for Org-roam -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2020 Jethro Kuan
|
||||
|
||||
;; Author: Jethro Kuan <jethrokuan95@gmail.com>
|
||||
;; Package-Requires: ((buttercup))
|
||||
|
||||
;; 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 of the License, 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
(require 'buttercup)
|
||||
(require 'org-roam)
|
||||
|
||||
(describe "org-roam-unlinked-references--rg-command"
|
||||
(before-each
|
||||
;; the space in the directory is on purpose
|
||||
(setq org-roam-directory "/tmp/org roam"))
|
||||
|
||||
(it "returns the correct rg command for unlinked references"
|
||||
(expect (org-roam-unlinked-references--rg-command '("foo" "bar") "/tmp/regex")
|
||||
:to-equal
|
||||
"rg --follow --only-matching --vimgrep --pcre2 --ignore-case --glob \"*.org\" --glob \"*.org.gpg\" --glob \"*.org.age\" --file /tmp/regex /tmp/org\\ roam")))
|
||||
|
||||
(provide 'test-org-roam-mode)
|
||||
|
||||
;;; test-org-roam-mode.el ends here
|
164
tests/test-org-roam-node.el
Normal file
164
tests/test-org-roam-node.el
Normal file
@ -0,0 +1,164 @@
|
||||
;;; test-org-roam-node.el --- Tests for Org-roam -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2020 Jethro Kuan
|
||||
|
||||
;; Author: Jethro Kuan <jethrokuan95@gmail.com>
|
||||
;; Package-Requires: ((buttercup))
|
||||
|
||||
;; 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 of the License, 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
(require 'buttercup)
|
||||
(require 'org-roam)
|
||||
|
||||
(defvar root-directory default-directory)
|
||||
|
||||
(describe "org-roam-node-from-id"
|
||||
(before-all
|
||||
(setq org-roam-directory (expand-file-name "tests/roam-files")
|
||||
org-roam-db-location (expand-file-name "org-roam.db" temporary-file-directory)
|
||||
org-roam-file-extensions '("org")
|
||||
org-roam-file-exclude-regexp nil)
|
||||
(org-roam-db-sync))
|
||||
|
||||
(after-all
|
||||
(org-roam-db--close)
|
||||
(delete-file org-roam-db-location))
|
||||
|
||||
(it "returns nil for unknown id"
|
||||
(expect (org-roam-node-from-id "non-existing") :to-equal nil))
|
||||
|
||||
(it "returns correct node from id"
|
||||
(let ((node (org-roam-node-from-id "884b2341-b7fe-434d-848c-5282c0727861")))
|
||||
(expect (org-roam-node-title node) :to-equal "Foo"))))
|
||||
|
||||
(describe "org-roam-node-from-title-or-alias"
|
||||
(before-all
|
||||
(setq org-roam-directory (expand-file-name "tests/roam-files")
|
||||
org-roam-db-location (expand-file-name "org-roam.db" temporary-file-directory)
|
||||
org-roam-file-extensions '("org")
|
||||
org-roam-file-exclude-regexp nil)
|
||||
(org-roam-db-sync))
|
||||
|
||||
(after-all
|
||||
(org-roam-db--close)
|
||||
(delete-file org-roam-db-location))
|
||||
|
||||
(it "returns nil for unknown title"
|
||||
(expect (org-roam-node-from-title-or-alias "non-existing") :to-equal nil))
|
||||
|
||||
(it "returns correct node from title"
|
||||
(let ((node (org-roam-node-from-title-or-alias "Foo")))
|
||||
(expect (org-roam-node-title node) :to-equal "Foo")))
|
||||
|
||||
(it "returns correct node from alias"
|
||||
(let ((node (org-roam-node-from-title-or-alias "Batman")))
|
||||
(expect (org-roam-node-title node) :to-equal "Bruce Wayne")))
|
||||
|
||||
(it "returns correct node from alias with nocase"
|
||||
(let ((node (org-roam-node-from-title-or-alias "batman" t)))
|
||||
(expect (org-roam-node-title node) :to-equal "Bruce Wayne"))))
|
||||
|
||||
(describe "org-roam-demote-entire-buffer"
|
||||
(after-each
|
||||
(cd root-directory))
|
||||
|
||||
(it "demotes an entire org buffer"
|
||||
(find-file "tests/roam-files/demoteable.org" nil)
|
||||
(org-roam-demote-entire-buffer)
|
||||
(expect (buffer-substring-no-properties (point) (point-max))
|
||||
:to-equal "* Demoteable\n:PROPERTIES:\n:ID: 97bf31cf-dfee-45d8-87a5-2ae0dabc4734\n:END:\n\n** Demoteable h1\n\n*** Demoteable child\n")))
|
||||
|
||||
(describe "org-roam--h1-count"
|
||||
(after-each
|
||||
(cd root-directory))
|
||||
|
||||
(it "returns the correct number of level-1 headings"
|
||||
(find-file "tests/roam-files/foo.org" nil)
|
||||
(expect (org-roam--h1-count) :to-equal 0)
|
||||
|
||||
(cd root-directory)
|
||||
|
||||
(find-file "tests/roam-files/family.org" nil)
|
||||
(expect (org-roam--h1-count) :to-equal 1)))
|
||||
|
||||
(describe "org-roam--buffer-promoteable-p"
|
||||
(after-each
|
||||
(cd root-directory))
|
||||
|
||||
(it "should check if buffer is promoteable"
|
||||
(find-file "tests/roam-files/foo.org" nil)
|
||||
(expect (org-roam--buffer-promoteable-p) :to-equal nil)
|
||||
|
||||
(cd root-directory)
|
||||
|
||||
(find-file "tests/roam-files/family.org" nil)
|
||||
(expect (org-roam--buffer-promoteable-p) :to-equal nil)
|
||||
|
||||
(cd root-directory)
|
||||
|
||||
(find-file "tests/roam-files/promoteable.org" nil)
|
||||
(expect (org-roam--buffer-promoteable-p) :to-equal t)))
|
||||
|
||||
(describe "org-roam--get-titles"
|
||||
(before-all
|
||||
(setq org-roam-directory (expand-file-name "tests/roam-files")
|
||||
org-roam-db-location (expand-file-name "org-roam.db" temporary-file-directory)
|
||||
org-roam-file-extensions '("org")
|
||||
org-roam-file-exclude-regexp nil)
|
||||
(org-roam-db-sync))
|
||||
|
||||
(after-all
|
||||
(org-roam-db--close)
|
||||
(delete-file org-roam-db-location))
|
||||
|
||||
(it "returns the list of titles and aliases"
|
||||
(expect (org-roam--get-titles)
|
||||
:to-have-same-items-as
|
||||
`("Bar" "Batman" "Bruce Wayne" "Child" "Deadline heading" "Demoteable" "Family"
|
||||
"Foo" "Grand-Parent" "Parent" "ref with space" "Scheduled heading" "With Times"))))
|
||||
|
||||
|
||||
(describe "org-roam-alias"
|
||||
(before-all
|
||||
(setq org-roam-directory (expand-file-name "tests/roam-files")
|
||||
org-roam-db-location (expand-file-name "org-roam.db" temporary-file-directory)
|
||||
org-roam-file-extensions '("org")
|
||||
org-roam-file-exclude-regexp nil)
|
||||
(org-roam-db-sync))
|
||||
|
||||
(after-all
|
||||
(org-roam-db--close)
|
||||
(delete-file org-roam-db-location)
|
||||
(cd root-directory))
|
||||
|
||||
(it "adds an alias to a node"
|
||||
(cd root-directory)
|
||||
(find-file "tests/roam-files/foo.org" nil)
|
||||
(org-roam-alias-add "qux")
|
||||
(expect (buffer-substring-no-properties (point) (point-max))
|
||||
:to-equal ":PROPERTIES:\n:ID: 884b2341-b7fe-434d-848c-5282c0727861\n:ROAM_ALIASES: qux\n:END:\n#+title: Foo\n"))
|
||||
|
||||
(it "removes an alias from a node"
|
||||
(cd root-directory)
|
||||
(find-file "tests/roam-files/with-alias.org" nil)
|
||||
(org-roam-alias-remove "Batman")
|
||||
(expect (buffer-substring-no-properties (point) (point-max))
|
||||
:to-equal ":PROPERTIES:\n:ID: 57ff3ce7-5bda-4825-8fca-c09f523e87ba\n:END:\n#+title: Bruce Wayne\n")))
|
||||
|
||||
(provide 'test-org-roam-node)
|
||||
|
||||
;;; test-org-roam-node.el ends here
|
@ -36,4 +36,29 @@
|
||||
(org-roam-whitespace-content "foo\n\t\n")
|
||||
:to-equal "\n\t\n")))
|
||||
|
||||
(describe "org-roam-db--file-title"
|
||||
(it "supports normal titles"
|
||||
(expect
|
||||
(with-temp-buffer
|
||||
(insert "#+title:normal title")
|
||||
(org-roam-db--file-title))
|
||||
:to-equal "normal title"))
|
||||
(it "supports multi-line titles"
|
||||
(expect
|
||||
(with-temp-buffer
|
||||
(insert "#+title: title:\n#+title: separated by newline")
|
||||
(org-roam-db--file-title))
|
||||
:to-equal "title: separated by newline"))
|
||||
(it "supports file-name based titles"
|
||||
(progn
|
||||
(setq org-roam-directory temporary-file-directory
|
||||
org-roam-db-location (expand-file-name "org-roam.db" temporary-file-directory)
|
||||
org-roam-file-extensions '("org"))
|
||||
(with-temp-buffer
|
||||
(write-file (expand-file-name "test file.org" org-roam-directory))
|
||||
(org-roam-db--file-title)))
|
||||
:to-equal "test file"))
|
||||
|
||||
(provide 'test-org-roam-utils)
|
||||
|
||||
;;; test-org-roam-utils.el ends here
|
||||
|
@ -24,6 +24,28 @@
|
||||
(require 'buttercup)
|
||||
(require 'org-roam)
|
||||
|
||||
(defvar root-directory default-directory)
|
||||
|
||||
(describe "org-roam-file-p"
|
||||
(it "checks if given file respects criteria"
|
||||
(setq org-roam-directory "/non-existent")
|
||||
(expect (org-roam-file-p "tests/roam-files/family.org") :to-equal nil)
|
||||
|
||||
(setq org-roam-directory (expand-file-name "tests/roam-files"))
|
||||
(expect (org-roam-file-p "tests/roam-files/family.org") :to-equal t)
|
||||
(expect (org-roam-file-p "tests/roam-files/markdown.md") :to-equal nil)
|
||||
|
||||
(setq org-roam-file-exclude-regexp (regexp-quote "family.org"))
|
||||
(expect (org-roam-file-p "tests/roam-files/family.org") :to-equal nil)))
|
||||
|
||||
(describe "org-roam-buffer-p"
|
||||
(it "checks if current buffer respects criteria"
|
||||
(setq org-roam-directory (expand-file-name "tests/roam-files")
|
||||
org-roam-file-exclude-regexp nil)
|
||||
(find-file "tests/roam-files/family.org" nil)
|
||||
(expect (org-roam-buffer-p) :to-equal t)
|
||||
(cd root-directory)))
|
||||
|
||||
(describe "org-roam-list-files"
|
||||
(before-each
|
||||
(setq org-roam-directory (expand-file-name "tests/roam-files")
|
||||
@ -31,52 +53,29 @@
|
||||
org-roam-file-extensions '("org")
|
||||
org-roam-file-exclude-regexp nil))
|
||||
|
||||
(after-all
|
||||
(org-roam-db--close)
|
||||
(delete-file org-roam-db-location))
|
||||
|
||||
(it "gets files correctly"
|
||||
(expect (length (org-roam-list-files))
|
||||
:to-equal 3))
|
||||
(expect (length (org-roam-list-files)) :to-equal 9))
|
||||
|
||||
(it "respects org-roam-file-extensions"
|
||||
(setq org-roam-file-extensions '("md"))
|
||||
(expect (length (org-roam-list-files)) :to-equal 1)
|
||||
(setq org-roam-file-extensions '("org" "md"))
|
||||
(expect (length (org-roam-list-files)) :to-equal 4))
|
||||
(expect (length (org-roam-list-files)) :to-equal 10))
|
||||
|
||||
(it "respects org-roam-file-exclude-regexp"
|
||||
(setq org-roam-file-exclude-regexp (regexp-quote "foo.org"))
|
||||
(expect (length (org-roam-list-files)) :to-equal 2)))
|
||||
(expect (length (org-roam-list-files)) :to-equal 8)))
|
||||
|
||||
(describe "org-roam-db-sync"
|
||||
(before-all
|
||||
(setq org-roam-directory (expand-file-name "tests/roam-files")
|
||||
org-roam-db-location (expand-file-name "org-roam.db" temporary-file-directory)
|
||||
org-roam-file-extensions '("org")
|
||||
org-roam-file-exclude-regexp nil)
|
||||
(org-roam-db-sync))
|
||||
(describe "org-roam--list-files-search-globs"
|
||||
|
||||
(after-all
|
||||
(org-roam-db--close)
|
||||
(delete-file org-roam-db-location))
|
||||
|
||||
(it "has the correct number of files"
|
||||
(expect (caar (org-roam-db-query [:select (funcall count) :from files]))
|
||||
:to-equal
|
||||
3))
|
||||
|
||||
(it "has the correct number of nodes"
|
||||
(expect (caar (org-roam-db-query [:select (funcall count) :from nodes]))
|
||||
:to-equal
|
||||
2))
|
||||
|
||||
(it "has the correct number of links"
|
||||
(expect (caar (org-roam-db-query [:select (funcall count) :from links]))
|
||||
:to-equal
|
||||
1))
|
||||
|
||||
(it "respects ROAM_EXCLUDE"
|
||||
;; The excluded node has ID "53fadc75-f48e-461e-be06-44a1e88b2abe"
|
||||
(expect (mapcar #'car (org-roam-db-query [:select id :from nodes]))
|
||||
(it "returns the correct list of globs"
|
||||
(expect (org-roam--list-files-search-globs org-roam-file-extensions)
|
||||
:to-have-same-items-as
|
||||
'("884b2341-b7fe-434d-848c-5282c0727861" "440795d0-70c1-4165-993d-aebd5eef7a24"))))
|
||||
'("\"*.org\"" "\"*.org.gpg\"" "\"*.org.age\""))))
|
||||
|
||||
(provide 'test-org-roam)
|
||||
|
||||
|
Reference in New Issue
Block a user