mirror of
https://github.com/org-roam/org-roam
synced 2025-08-01 12:17:21 -05:00
Compare commits
94 Commits
Author | SHA1 | Date | |
---|---|---|---|
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 |
2
.github/workflows/docs.yml
vendored
2
.github/workflows/docs.yml
vendored
@ -4,7 +4,7 @@ name: "Docs"
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
8
.github/workflows/test.yml
vendored
8
.github/workflows/test.yml
vendored
@ -28,7 +28,7 @@ on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@ -36,7 +36,11 @@ 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
|
||||
|
122
.github/workflows/tidy-issues.yml
vendored
Normal file
122
.github/workflows/tidy-issues.yml
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
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.
|
||||
|
||||
**To reopen:**
|
||||
- If still relevant, comment below or push new commits
|
||||
- Or create a new PR with updated changes
|
||||
|
||||
If this PR is not reopened in 2 weeks, it will be locked.
|
||||
|
||||
# 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'"
|
||||
|
||||
lock:
|
||||
runs-on: ubuntu-latest
|
||||
needs: stale
|
||||
# Only run lock job if NOT in dry run mode
|
||||
if: github.event.inputs.dry_run != 'true'
|
||||
steps:
|
||||
# Lock issues/PRs that have been closed for 2 weeks or more
|
||||
- name: Lock closed issues
|
||||
uses: dessant/lock-threads@v5
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-inactive-days: 14
|
||||
issue-lock-reason: 'resolved'
|
||||
process-only: 'issues'
|
||||
|
||||
- name: Lock closed PRs
|
||||
uses: dessant/lock-threads@v5
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
pr-inactive-days: 14
|
||||
pr-lock-reason: 'resolved'
|
||||
process-only: 'prs'
|
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
|
||||
|
@ -153,9 +153,8 @@ 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
|
||||
|
||||
@ -230,6 +229,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
|
||||
|
||||
|
160
doc/org-roam.org
160
doc/org-roam.org
@ -1,23 +1,23 @@
|
||||
#+title: Org-roam User Manual
|
||||
#+author: Jethro Kuan
|
||||
#+email: jethrokuan95@gmail.com
|
||||
#+date: 2020-2022
|
||||
#+date: 2020-2025
|
||||
#+language: en
|
||||
|
||||
#+texinfo_deffn: t
|
||||
#+texinfo_dir_category: Emacs
|
||||
#+texinfo_dir_title: Org-roam: (org-roam).
|
||||
#+texinfo_dir_desc: Roam Research for Emacs.
|
||||
#+subtitle: for version 2.2.1
|
||||
#+subtitle: for version 2.3.1
|
||||
|
||||
#+options: H:4 num:3 toc:nil creator:t ':t
|
||||
#+property: header-args :eval never
|
||||
#+texinfo: @noindent
|
||||
|
||||
This manual is for Org-roam version 2.2.1.
|
||||
This manual is for Org-roam version 2.3.1.
|
||||
|
||||
#+BEGIN_QUOTE
|
||||
Copyright (C) 2020-2022 Jethro Kuan <jethrokuan95@gmail.com>
|
||||
Copyright (C) 2020-2025 Jethro Kuan <jethrokuan95@gmail.com>
|
||||
|
||||
You can redistribute this document and/or modify it under the terms of the GNU
|
||||
General Public License as published by the Free Software Foundation, either
|
||||
@ -178,18 +178,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:
|
||||
@ -235,7 +224,6 @@ dependencies that it requires. These include:
|
||||
- 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,7 +375,7 @@ 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
|
||||
@ -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)))))
|
||||
@ -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
|
||||
@ -865,7 +791,7 @@ 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
|
||||
@ -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
|
||||
@ -1300,7 +1241,7 @@ There are variants of those commands for ~-yesterday~ and ~-tomorrow~:
|
||||
|
||||
- Function: ~org-roam-dailies-capture-yesterday~ n &optional goto
|
||||
|
||||
Create an entry in the daily note for yesteday.
|
||||
Create an entry in the daily note for yesterday.
|
||||
|
||||
With numeric argument ~n~, use the daily note ~n~ days in the past.
|
||||
|
||||
@ -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
|
||||
@ -1809,7 +1735,7 @@ 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-2025 Jethro Kuan <jethrokuan95@gmail.com>
|
||||
|
||||
You can redistribute this document and/or modify it under the terms
|
||||
of the GNU General Public License as published by the Free Software
|
||||
|
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.
|
||||
|
||||
|
@ -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.
|
||||
|
180
org-roam-db.el
180
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
|
||||
|
@ -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
|
||||
|
213
org-roam-node.el
213
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."
|
||||
@ -144,6 +175,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 +246,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 +264,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 +286,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 +339,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 +381,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 +450,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 +499,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 +517,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 +526,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 +577,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 +605,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-"
|
||||
@ -766,7 +827,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 +850,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 +900,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 +922,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 +983,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 +1027,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 +1067,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 +1093,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 +1129,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