Compare commits

...

12 Commits

Author SHA1 Message Date
Jethro Kuan
b5acacac20 (feat!)capture: change id creation to headline on entry-type capture-templates 2022-01-20 15:46:42 -08:00
Jethro Kuan
445e3594b2 (fix)dailies: remove f require (#2057) 2022-01-20 15:14:24 -08:00
Jethro Kuan
6f5d65abd9 (breaking!)node: simplify default display-template (#2054)
Revert to a simplified `org-roam-node-display-template`, because on
non-vertical completion frameworks it looks and behaves strangely. To
restore the original default behaviour, set
`org-roam-node-display-template` in your Emacs configuration as such:

  (setq org-roam-node-display-template
        (concat "${title:*} "
                (propertize "${tags:10}" 'face 'org-tag)))
2022-01-20 11:19:41 -08:00
Jethro Kuan
817d8036fb (fix)capture: return id in setup-target-location (#2052)
Fixes #2051.
2022-01-19 18:57:07 -08:00
Jethro Kuan
c17310f0de (feat)org-roam-node-random: support filter-fn (#2050) 2022-01-19 14:23:57 -08:00
Jethro Kuan
bf3ebe2121 (feat)capture: create ID before capture process (#2049)
* (feat)capture: create ID before capture process

This allows the ID to be used as part of the capture template. Addresses #2048.

* update changelog
2022-01-19 13:41:20 -08:00
Jethro Kuan
47ad646d51 (docs)completions: document org-roam-node-display-template (#2047) 2022-01-18 15:56:47 -08:00
Groobles
6263c3a956 (minor)dailies: fixed some wording (#2045) 2022-01-17 18:19:39 -08:00
Jethro Kuan
69742c3d51 (feat)db: add customizability of extra element link parsing (#2042)
Adds two customizable variables: org-roam-db-extra-links-elements and
org-roam-db-extra-links-exclude-keys, which govern which elements are to
be considered for link parsing by Org-roam.

Also added sane defaults to org-roam-db-extra-links-exclude-keys.
2022-01-16 13:30:13 -08:00
Jethro Kuan
5b15159a2c docs: symlink resolution with find-file-visit-truename
<p dir="auto"><span class="issue-keyword tooltipped tooltipped-se" aria-label="This pull request closes issue #1869.">Closes</span> <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1004482400" data-permission-text="Title is private" data-url="https://github.com/org-roam/org-roam/issues/1869" data-hovercard-type="issue" data-hovercard-url="/org-roam/org-roam/issues/1869/hovercard" href="https://github.com/org-roam/org-roam/issues/1869">#1869</a></p>
2022-01-15 21:36:28 -08:00
Stefan Kangas
c0c240b975 (chore): Drop f.el and s.el dependency (#2025)
Drops the f.el and implicit s.el dependency.

Co-authored-by: Jethro Kuan <jethrokuan95@gmail.com>
2022-01-15 21:26:20 -08:00
Andreas Stuhlmüller
001de3a874 (fix): fix completions width for Helm users (#2040) 2022-01-15 18:24:52 -08:00
13 changed files with 374 additions and 134 deletions

View File

@@ -1,4 +1,26 @@
# Changelog
## TBD
### 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:
```emacs-lisp
(setq org-roam-node-display-template
(concat "${title:*} "
(propertize "${tags:10}" 'face 'org-tag)))
```
### Added
- [#2042](https://github.com/org-roam/org-roam/pull/2042) db: add `org-roam-db-extra-links-elements` and `org-roam-db-extra-links-exclude-keys` for fine-grained control over additional link parsing
- [#2049](https://github.com/org-roam/org-roam/pull/2049) capture: allow ID to be used as part of `org-roam-capture-templates`
- [#2050](https://github.com/org-roam/org-roam/pull/2050) core: add `FILTER-FN` to `org-roam-node-random`
### Removed
### Fixed
- [#2055](https://github.com/org-roam/org-roam/pull/2055) dailies: removed stray f require, which was causing require and compilation errors
- [#2056](https://github.com/org-roam/org-roam/pull/2056) capture: IDs are now created for entries in capture templates
### Changed
- [#2040](https://github.com/org-roam/org-roam/pull/2040) completions: fix completions display-width for Helm users
- [#2025](https://github.com/org-roam/org-roam/pull/2025) chore: removed the dependencies on f.el and s.el
## 2.2.0
### Added

View File

@@ -47,30 +47,6 @@ Stable](https://stable.melpa.org/) using `package.el`:
```
M-x package-install RET org-roam RET
```
Here's a very basic sample for configuration of `org-roam` using `use-package`:
```emacs-lisp
(use-package org-roam
:ensure t
:custom
(org-roam-directory (file-truename "/path/to/org-files/"))
:bind (("C-c n l" . org-roam-buffer-toggle)
("C-c n f" . org-roam-node-find)
("C-c n g" . org-roam-graph)
("C-c n i" . org-roam-node-insert)
("C-c n c" . org-roam-capture)
;; Dailies
("C-c n j" . org-roam-dailies-capture-today))
:config
(org-roam-db-autosync-mode)
;; If using org-roam-protocol
(require 'org-roam-protocol))
```
Note that the `file-truename` function is only necessary when you use symbolic
link to `org-roam-directory`. Org-roam won't automatically resolve symbolic link
to the directory.
</details>
### Using `straight.el`
@@ -198,6 +174,33 @@ Org-roam also comes with `.texi` files to integrate with Emacs' built-in Info
system. Read the manual to find more details for how to install them manually.
</details>
## Configuration
Here's a very basic sample for configuration of `org-roam` using `use-package`:
```emacs-lisp
(use-package org-roam
:ensure t
:custom
(org-roam-directory (file-truename "/path/to/org-files/"))
:bind (("C-c n l" . org-roam-buffer-toggle)
("C-c n f" . org-roam-node-find)
("C-c n g" . org-roam-graph)
("C-c n i" . org-roam-node-insert)
("C-c n c" . org-roam-capture)
;; Dailies
("C-c n j" . org-roam-dailies-capture-today))
:config
;; If you're using a vertical completion framework, you might want a more informative completion interface
(setq org-roam-node-display-template (concat "${title:*} " (propertize "${tags:10}" 'face 'org-tag)))
(org-roam-db-autosync-mode)
;; If using org-roam-protocol
(require 'org-roam-protocol))
```
Note that the `file-truename` function is only necessary when you use symbolic
link to `org-roam-directory`. Org-roam won't automatically resolve symbolic link
to the directory.
## Getting Started
[David Wilson](https://github.com/daviwil) of [System

View File

@@ -369,7 +369,12 @@ For this tutorial, create an empty directory, and set ~org-roam-directory~:
#+END_SRC
The ~file-truename~ function is only necessary when you use symbolic links
inside ~org-roam-directory~: Org-roam does not resolve symbolic links.
inside ~org-roam-directory~: Org-roam does not resolve symbolic links. One can
however instruct Emacs to always resolve symlinks, at a performance cost:
#+begin_src emacs-lisp
(setq find-file-visit-truename t)
#+end_src
Next, we setup Org-roam to run functions on file changes to maintain cache
consistency. This is achieved by running ~M-x org-roam-db-autosync-mode~. To
@@ -413,6 +418,54 @@ brought through the node creation process.
One can also conveniently insert links via the completion-at-point functions
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
~org-roam-node-display-template~.
- Variable: org-roam-node-display-template
Configures display formatting for Org-roam node.
Patterns of form "${field-name:length}" are interpolated based
on the current node.
Each "field-name" is replaced with the return value of each
corresponding accessor function for org-roam-node, e.g.
"${title}" will be interpolated by the result of
org-roam-node-title. You can also define custom accessors using
cl-defmethod. For example, you can define:
(cl-defmethod org-roam-node-my-title ((node org-roam-node))
(concat "My " (org-roam-node-title node)))
and then reference it here or in the capture templates as
"${my-title}".
"length" is an optional specifier and declares how many
characters can be used to display the value of the corresponding
field. If it's not specified, the field will be inserted as is,
i.e. it won't be aligned nor trimmed. If it's an integer, the
field will be aligned accordingly and all the exceeding
characters will be trimmed out. If it's "*", the field will use
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.
If you're using a vertical completion framework, such as Ivy and Selectrum,
Org-roam supports the generation of an aligned, tabular completion interface.
For example, to include a column for tags up to 10 character widths wide, one
can set ~org-roam-node-display-template~ as such:
#+begin_src emacs-lisp
(setq org-roam-node-display-template
(concat "${title:*} "
(propertize "${tags:10}" 'face 'org-tag)))
#+end_src
* Customizing Node Caching
** How to cache
@@ -485,6 +538,35 @@ all headlines with the ~ATTACH~ tag from the Org-roam database, one can set:
(not (member "ATTACH" (org-get-tags)))))
#+end_src
Org-roam relied on the obtained Org AST for the buffer to parse links. However,
links appearing in some places (e.g. within property drawers) are not considered
by the Org AST to be links. Therefore, Org-roam takes special care of
additionally trying to process these links. Use
~org-roam-db-extra-links-elements~ to specify which additional Org AST element
types to consider.
- Variable: org-roam-db-extra-links-elements
The list of Org element types to include for parsing by Org-roam.
By default, when parsing Org's AST, links within keywords and
property drawers are not parsed as links. Sometimes however, it
is desirable to parse and cache these links (e.g. hiding links in
a property drawer).
Additionally, one may want to ignore certain keys from being excluded within
property drawers. For example, we would not want ~ROAM_REFS~ links to be
self-referential. Hence, to exclude specific keys, we use
~org-roam-db-extra-links-exclude-keys~.
- Variable: org-roam-db-extra-links-exclude-keys
Keys to ignore when mapping over links.
The car of the association list is the Org element type (e.g. keyword). The
cdr is a list of case-insensitive strings to exclude from being treated as
links.
** When to cache
By default, Org-roam is eager in caching: each time an Org-roam file is modified

View File

@@ -110,6 +110,7 @@ Getting Started
* Links between Nodes::
* Setting up Org-roam::
* Creating and Linking Nodes::
* Customizing Node Completions::
Customizing Node Caching
@@ -586,6 +587,7 @@ your Emacs configuration folder like this:
* Links between Nodes::
* Setting up Org-roam::
* Creating and Linking Nodes::
* Customizing Node Completions::
@end menu
@node The Org-roam Node
@@ -652,7 +654,12 @@ For this tutorial, create an empty directory, and set @code{org-roam-directory}:
@end lisp
The @code{file-truename} function is only necessary when you use symbolic links
inside @code{org-roam-directory}: Org-roam does not resolve symbolic links.
inside @code{org-roam-directory}: Org-roam does not resolve symbolic links. One can
however instruct Emacs to always resolve symlinks, at a performance cost:
@lisp
(setq find-file-visit-truename t)
@end lisp
Next, we setup Org-roam to run functions on file changes to maintain cache
consistency. This is achieved by running @code{M-x org-roam-db-autosync-mode}. To
@@ -704,6 +711,56 @@ brought through the node creation process.
One can also conveniently insert links via the completion-at-point functions
Org-roam provides (see @ref{Completion}).
@node Customizing Node Completions
@section Customizing Node Completions
Node selection is achieved via the @code{completing-read} interface, typically
through `org-roam-node-read`. The presentation of these nodes are governed by
@code{org-roam-node-display-template}.
@defvar org-roam-node-display-template
Configures display formatting for Org-roam node.
Patterns of form ``$@{field-name:length@}'' are interpolated based
on the current node.
Each ``field-name'' is replaced with the return value of each
corresponding accessor function for org-roam-node, e.g.
``$@{title@}'' will be interpolated by the result of
org-roam-node-title. You can also define custom accessors using
cl-defmethod. For example, you can define:
(cl-defmethod org-roam-node-my-title ((node org-roam-node))
(concat ``My '' (org-roam-node-title node)))
and then reference it here or in the capture templates as
``$@{my-title@}''.
``length'' is an optional specifier and declares how many
characters can be used to display the value of the corresponding
field. If it's not specified, the field will be inserted as is,
i.e. it won't be aligned nor trimmed. If it's an integer, the
field will be aligned accordingly and all the exceeding
characters will be trimmed out. If it's ``*'', the field will use
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.
@end defvar
If you're using a vertical completion framework, such as Ivy and Selectrum,
Org-roam supports the generation of an aligned, tabular completion interface.
For example, to include a column for tags up to 10 character widths wide, one
can set @code{org-roam-node-display-template} as such:
@lisp
(setq org-roam-node-display-template
(concat "$@{title:*@} "
(propertize "$@{tags:10@}" 'face 'org-tag)))
@end lisp
@node Customizing Node Caching
@chapter Customizing Node Caching
@@ -786,6 +843,37 @@ all headlines with the @code{ATTACH} tag from the Org-roam database, one can set
(not (member "ATTACH" (org-get-tags)))))
@end example
Org-roam relied on the obtained Org AST for the buffer to parse links. However,
links appearing in some places (e.g. within property drawers) are not considered
by the Org AST to be links. Therefore, Org-roam takes special care of
additionally trying to process these links. Use
@code{org-roam-db-extra-links-elements} to specify which additional Org AST element
types to consider.
@defvar org-roam-db-extra-links-elements
The list of Org element types to include for parsing by Org-roam.
By default, when parsing Org's AST, links within keywords and
property drawers are not parsed as links. Sometimes however, it
is desirable to parse and cache these links (e.g. hiding links in
a property drawer).
@end defvar
Additionally, one may want to ignore certain keys from being excluded within
property drawers. For example, we would not want @code{ROAM_REFS} links to be
self-referential. Hence, to exclude specific keys, we use
@code{org-roam-db-extra-links-exclude-keys}.
@defvar org-roam-db-extra-links-exclude-keys
Keys to ignore when mapping over links.
The car of the association list is the Org element type (e.g. keyword). The
cdr is a list of case-insensitive strings to exclude from being treated as
links.
@end defvar
@node When to cache
@section When to cache

View File

@@ -8,7 +8,7 @@
;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience
;; Version: 2.2.0
;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (org-roam "2.1"))
;; Package-Requires: ((emacs "26.1") (dash "2.13") (org-roam "2.1"))
;; This file is NOT part of GNU Emacs.
@@ -34,10 +34,9 @@
;; each file named after certain date and stored in `org-roam-dailies-directory'.
;;
;; One can use dailies for various purposes, e.g. journaling, fleeting notes,
;; scratch notes and whatever else you can came up with.
;; scratch notes or whatever else you can think of.
;;
;;; Code:
(require 'f)
(require 'dash)
(require 'org-roam)
@@ -269,7 +268,7 @@ If FILE is not specified, use the current buffer's file-path."
(save-match-data
(and
(org-roam-file-p path)
(f-descendant-of-p path directory)))))
(org-roam-descendant-of-p path directory)))))
;;;###autoload
(defun org-roam-dailies-find-directory ()
@@ -318,11 +317,12 @@ In this case, interactive selection will be bypassed."
(when goto (run-hooks 'org-roam-dailies-find-file-hook)))
(add-hook 'org-roam-capture-preface-hook #'org-roam-dailies--override-capture-time-h)
(defun org-roam-dailies--override-capture-time-h ()
"Override the `:default-time' with the time from `:override-default-time'."
(prog1 nil
(when (org-roam-capture--get :override-default-time)
(org-capture-put :default-time (org-roam-capture--get :override-default-time)))))
(when (org-roam-capture--get :override-default-time)
(org-capture-put :default-time (org-roam-capture--get :override-default-time)))
nil)
;;; Bindings
(defvar org-roam-dailies-map (make-sparse-keymap)

View File

@@ -266,7 +266,7 @@ Handles both Org-roam nodes, and string nodes (e.g. urls)."
(org-roam-quote-string
(pcase org-roam-graph-shorten-titles
(`truncate (truncate-string-to-width title org-roam-graph-max-title-length nil nil "..."))
(`wrap (s-word-wrap org-roam-graph-max-title-length title))
(`wrap (org-roam-word-wrap org-roam-graph-max-title-length title))
(_ title)))))
(setq node-id (org-roam-node-id node)
node-properties `(("label" . ,shortened-title)

View File

@@ -6,7 +6,7 @@
;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience
;; Version: 2.2.0
;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (org "9.4") (emacsql "3.0.0") (emacsql-sqlite "1.0.0") (magit-section "3.0.0"))
;; 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"))
;; This file is NOT part of GNU Emacs.
@@ -407,6 +407,8 @@ TEMPLATES is a list of org-roam templates."
(mapcar (lambda (template)
(org-roam-capture--convert-template template props))
(or templates org-roam-capture-templates)))
(_ (setf (org-roam-node-id node) (or (org-roam-node-id node)
(org-id-new))))
(org-roam-capture--node node)
(org-roam-capture--info info))
(when (and (not keys)
@@ -464,22 +466,21 @@ processing by `org-capture'.
Note: During the capture process this function is run by
`org-capture-set-target-location', as a (function ...) based
capture target."
(let ((id (cond ((run-hook-with-args-until-success 'org-roam-capture-preface-hook))
(t (org-roam-capture--setup-target-location)))))
(org-roam-capture--adjust-point-for-capture-type)
(let ((template (org-capture-get :template)))
(when (stringp template)
(org-capture-put
:template
(org-roam-capture--fill-template template))))
(org-roam-capture--put :id id)
(org-roam-capture--put :finalize (or (org-capture-get :finalize)
(org-roam-capture--get :finalize)))))
(if-let ((id (run-hook-with-args-until-success 'org-roam-capture-preface-hook)))
(org-roam-capture--put :id id)
(org-roam-capture--setup-target-location))
(let ((template (org-capture-get :template)))
(when (stringp template)
(org-capture-put
:template
(org-roam-capture--fill-template template))))
(org-roam-capture--put :finalize (or (org-capture-get :finalize)
(org-roam-capture--get :finalize))))
(defun org-roam-capture--setup-target-location ()
"Initialize the buffer, and goto the location of the new capture.
Return the ID of the location."
(let (p new-file-p)
"Initialize the buffer, and goto the location of the new capture."
(let ((target-entry-p t)
p new-file-p id)
(pcase (org-roam-capture--get-target)
(`(file ,path)
(setq path (org-roam-capture--target-truepath path)
@@ -487,7 +488,8 @@ Return the ID of the location."
(when new-file-p (org-roam-capture--put :new-file path))
(set-buffer (org-capture-target-buffer path))
(widen)
(setq p (goto-char (point-min))))
(setq p (goto-char (point-min))
target-entry-p nil))
(`(file+olp ,path ,olp)
(setq path (org-roam-capture--target-truepath path)
new-file-p (org-roam-capture--new-file-p path))
@@ -505,7 +507,8 @@ Return the ID of the location."
(org-roam-capture--put :new-file path)
(insert (org-roam-capture--fill-template head t)))
(widen)
(setq p (goto-char (point-min))))
(setq p (goto-char (point-min))
target-entry-p nil))
(`(file+head+olp ,path ,head ,olp)
(setq path (org-roam-capture--target-truepath path)
new-file-p (org-roam-capture--new-file-p path))
@@ -567,17 +570,45 @@ Return the ID of the location."
(user-error "No node with title or id \"%s\"" title-or-id))))
(set-buffer (org-capture-target-buffer (org-roam-node-file node)))
(goto-char (org-roam-node-point node))
(setq p (org-roam-node-point node)))))
(setq p (org-roam-node-point node)
target-entry-p (and (derived-mode-p 'org-mode) (org-at-heading-p))))))
;; Setup `org-id' for the current capture target and return it back to the
;; caller.
(save-excursion
(goto-char p)
(when-let* ((node org-roam-capture--node)
(id (org-roam-node-id node)))
(org-entry-put p "ID" id))
(prog1
(org-id-get-create)
(run-hooks 'org-roam-capture-new-node-hook)))))
;; Unless it's an entry type, then we want to create an ID for the entry instead
(pcase (org-capture-get :type)
('entry
(advice-add #'org-capture-place-entry :after #'org-roam-capture--create-id-for-entry)
(org-roam-capture--put :new-node-p t)
(setq id (org-roam-node-id org-roam-capture--node)))
(_
(save-excursion
(goto-char p)
(unless (org-entry-get p "ID")
(org-roam-capture--put :new-node-p t))
(setq id (or (org-entry-get p "ID")
(org-roam-node-id org-roam-capture--node)))
(setf (org-roam-node-id org-roam-capture--node) id)
(org-entry-put p "ID" id))))
(org-roam-capture--put :id id)
(org-roam-capture--put :target-entry-p target-entry-p)
(advice-add #'org-capture-place-template :before #'org-roam-capture--set-target-entry-p-a)
(advice-add #'org-capture-place-template :after #'org-roam-capture-run-new-node-hook-a)))
(defun org-roam-capture--set-target-entry-p-a (_)
"Correct `:target-entry-p' in Org-capture template based on `:target.'"
(org-capture-put :target-entry-p (org-roam-capture--get :target-entry-p))
(advice-remove #'org-capture-place-template #'org-roam-capture--set-target-entry-p-a))
(defun org-roam-capture-run-new-node-hook-a (_)
"Advice to run after the Org-capture template is placed."
(when (org-roam-capture--get :new-node-p)
(run-hooks 'org-roam-capture-new-node-hook))
(advice-remove #'org-capture-place-template #'org-roam-capture--place-template-a))
(defun org-roam-capture--create-id-for-entry ()
"Create the ID for the new entry."
(org-entry-put (point) "ID" (org-roam-capture--get :id))
(advice-remove #'org-capture-place-entry #'org-roam-capture--create-id-for-entry))
(defun org-roam-capture--get-target ()
"Get the current capture :target for the capture template in use."
@@ -590,9 +621,9 @@ PATH is a string that can optionally contain templated text in
it."
(or (org-roam-node-file org-roam-capture--node)
(thread-first path
(org-roam-capture--fill-template t)
(string-trim)
(expand-file-name org-roam-directory))))
(org-roam-capture--fill-template t)
(string-trim)
(expand-file-name org-roam-directory))))
(defun org-roam-capture--new-file-p (path)
"Return t if PATH is for a new file with no visiting buffer."
@@ -646,37 +677,6 @@ you can catch it with `condition-case'."
end (save-excursion (org-end-of-subtree t t))))
(point-marker))))
(defun org-roam-capture--adjust-point-for-capture-type (&optional pos)
"Reposition the point for template insertion dependently on the capture type.
Return the newly adjusted position of `point'.
POS is the current position of point (an integer) inside the
currently active capture buffer, where the adjustment should
start to begin from. If it's nil, then it will default to
the current value of `point'."
(or pos (setq pos (point)))
(goto-char pos)
(let ((location-type (if (= pos 1) 'beginning-of-file 'heading-at-point)))
(and (eq location-type 'heading-at-point)
(cl-assert (org-at-heading-p)))
(pcase (org-capture-get :type)
(`plain
(cl-case location-type
(beginning-of-file
(if (org-capture-get :prepend)
(let ((el (org-element-at-point)))
(while (and (not (eobp))
(memq (org-element-type el)
'(drawer property-drawer keyword comment comment-block horizontal-rule)))
(goto-char (org-element-property :end el))
(setq el (org-element-at-point))))
(goto-char (org-entry-end-position))))
(heading-at-point
(if (org-capture-get :prepend)
(org-end-of-meta-data t)
(goto-char (org-entry-end-position))))))))
(point))
;;;; Finalizers
(add-hook 'org-capture-prepare-finalize-hook #'org-roam-capture--install-finalize-h)
(defun org-roam-capture--install-finalize-h ()

View File

@@ -6,7 +6,7 @@
;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience
;; Version: 2.2.0
;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (org "9.4") (emacsql "3.0.0") (emacsql-sqlite "1.0.0") (magit-section "3.0.0"))
;; 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"))
;; This file is NOT part of GNU Emacs.
@@ -98,6 +98,32 @@ slow."
:type 'boolean
:group 'org-roam)
(defcustom org-roam-db-extra-links-elements '(node-property keyword)
"The list of Org element types to include for parsing by Org-roam.
By default, when parsing Org's AST, links within keywords and
property drawers are not parsed as links. Sometimes however, it
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)))
(defcustom org-roam-db-extra-links-exclude-keys '((node-property . ("ROAM_REFS"))
(keyword . ("transclude")))
"Keys to ignore when mapping over links.
The car of the association list is the Org element type (e.g.
keyword). The cdr is a list of case-insensitive strings to
exclude from being treated as links.
For example, we use this to prevent self-referential links in
ROAM_REFS."
:package-version '(org-roam . "2.2.0")
:group 'org-roam
:type '(alist))
;;; Variables
(defconst org-roam-db-version 18)
@@ -353,15 +379,12 @@ If UPDATE-P is non-nil, first remove the file in the database."
;; Links correctly recognized by Org Mode
((eq type 'link)
(setq link element))
;; Prevent self-referencing links in ROAM_REFS
((and (eq type 'node-property)
(org-roam-string-equal (org-element-property :key element) "ROAM_REFS"))
nil)
;; Links in property drawers and lines starting with #+. Recall that, as for Org Mode v9.4.4, the
;; org-element-type of links within properties drawers is "node-property" and for lines starting with
;; #+ is "keyword".
((and (or (eq type 'node-property)
(eq type 'keyword))
((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)

View File

@@ -6,7 +6,7 @@
;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience
;; Version: 2.2.0
;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (org "9.4") (emacsql "3.0.0") (emacsql-sqlite "1.0.0") (magit-section "3.0.0"))
;; 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"))
;; This file is NOT part of GNU Emacs.

View File

@@ -6,7 +6,7 @@
;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience
;; Version: 2.2.0
;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (org "9.4") (emacsql "3.0.0") (emacsql-sqlite "1.0.0") (magit-section "3.0.0"))
;; 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"))
;; This file is NOT part of GNU Emacs.
@@ -643,7 +643,7 @@ References from FILE are excluded."
col (string-to-number (match-string 3 line))
match (match-string 4 line))
(when (and match
(not (f-equal-p (org-roam-node-file node) f))
(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)

View File

@@ -36,8 +36,7 @@
;;; Options
;;;; Completing-read
(defcustom org-roam-node-display-template
(concat "${title:*} " (propertize "${tags:10}" 'face 'org-tag))
(defcustom org-roam-node-display-template "${title}"
"Configures display formatting for Org-roam node.
Patterns of form \"${field-name:length}\" are interpolated based
on the current node.
@@ -477,16 +476,16 @@ The TEMPLATES, if provided, override the list of capture templates (see
:props '(:finalize find-file)))))
;;;###autoload
(defun org-roam-node-random (&optional other-window)
(defun org-roam-node-random (filter-fn &optional other-window)
"Find and open a random Org-roam node.
With prefix argument OTHER-WINDOW, visit the node in another
window instead."
window instead.
FILTER-FN is a function to filter out nodes: it takes an `org-roam-node',
and when nil is returned the node will be filtered out."
(interactive current-prefix-arg)
(let ((random-row (seq-random-elt (org-roam-db-query [:select [id file pos] :from nodes]))))
(org-roam-node-visit (org-roam-node-create :id (nth 0 random-row)
:file (nth 1 random-row)
:point (nth 2 random-row))
other-window)))
(org-roam-node-visit
(cdr (seq-random-elt (org-roam-node-read--completions filter-fn)))
other-window))
;;;; Completing-read interface
(defun org-roam-node-read (&optional initial-input filter-fn sort-fn require-match prompt)
@@ -498,17 +497,7 @@ SORT-FN is a function to sort nodes. See `org-roam-node-read-sort-by-file-mtime'
for an example sort function.
If REQUIRE-MATCH, the minibuffer prompt will require a match.
PROMPT is a string to show at the beginning of the mini-buffer, defaulting to \"Node: \""
(let* ((nodes (org-roam-node-read--completions))
(nodes (if filter-fn
(cl-remove-if-not
(lambda (n) (funcall filter-fn (cdr n)))
nodes)
nodes))
(sort-fn (or sort-fn
(when org-roam-node-default-sort
(intern (concat "org-roam-node-read-sort-by-"
(symbol-name org-roam-node-default-sort))))))
(_ (when sort-fn (setq nodes (seq-sort sort-fn nodes))))
(let* ((nodes (org-roam-node-read--completions filter-fn sort-fn))
(prompt (or prompt "Node: "))
(node (completing-read
prompt
@@ -529,15 +518,31 @@ 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-node-read--completions ()
(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
is the `org-roam-node'.
FILTER-FN is a function to filter out nodes: it takes an `org-roam-node',
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))
(nodes (org-roam-node-list)))
(mapcar (lambda (node)
(org-roam-node-read--to-candidate node template)) nodes)))
(let* ((template (org-roam-node--process-display-format org-roam-node-display-template))
(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)))
nodes)
nodes))
(sort-fn (or sort-fn
(when org-roam-node-default-sort
(intern (concat "org-roam-node-read-sort-by-"
(symbol-name org-roam-node-default-sort))))))
(nodes (if sort-fn (seq-sort sort-fn nodes)
nodes)))
nodes))
(defun org-roam-node-read--to-candidate (node template)
"Return a minibuffer completion candidate given NODE.
@@ -545,7 +550,8 @@ TEMPLATE is the processed template used to format the entry."
(let ((candidate-main (org-roam-node--format-entry
template
node
(1- (frame-width)))))
(1- (if (bufferp (current-buffer))
(window-width) (frame-width))))))
(cons (propertize candidate-main 'node node) node)))
(defun org-roam-node--format-entry (template node &optional width)

View File

@@ -52,6 +52,16 @@
(org-roam-replace-string "\\" "\\\\")
(org-roam-replace-string "\"" "\\\"")))
(defun org-roam-word-wrap (len s)
"If S is longer than LEN, wrap the words with newlines."
(declare (side-effect-free t))
(save-match-data
(with-temp-buffer
(insert s)
(let ((fill-column len))
(fill-region (point-min) (point-max)))
(buffer-substring (point-min) (point-max)))))
(defun org-roam-string-equal (s1 s2)
"Return t if S1 and S2 are equal.
Like `string-equal', but case-insensitive."
@@ -99,6 +109,12 @@ SPEC is a list, as per `dolist'."
`(dolist ,spec ,@body)))
;;; 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))
(string-prefix-p (expand-file-name b)
(expand-file-name a))))
(defmacro org-roam-with-file (file keep-buf-p &rest body)
"Execute BODY within FILE.
If FILE is nil, execute BODY in the current buffer.

View File

@@ -6,7 +6,7 @@
;; URL: https://github.com/org-roam/org-roam
;; Keywords: org-mode, roam, convenience
;; Version: 2.2.0
;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (org "9.4") (emacsql "3.0.0") (emacsql-sqlite "1.0.0") (magit-section "3.0.0"))
;; 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"))
;; This file is NOT part of GNU Emacs.
@@ -71,7 +71,6 @@
;; majority of them can be found at https://github.com/org-roam and MELPA.
;;
;;; Code:
(require 'f)
(require 'dash)
(require 'rx)
@@ -195,7 +194,7 @@ FILE is an Org-roam file if:
(member ext org-roam-file-extensions)
(not (and org-roam-file-exclude-regexp
(string-match-p org-roam-file-exclude-regexp path)))
(f-descendant-of-p path (expand-file-name org-roam-directory))))))
(org-roam-descendant-of-p path (expand-file-name org-roam-directory))))))
(defun org-roam-list-files ()
"Return a list of all Org-roam files under `org-roam-directory'.
@@ -260,7 +259,8 @@ If no files are found, an empty list is returned."
(shell-command-to-string it)
(ansi-color-filter-apply it)
(split-string it "\n")
(seq-filter #'s-present? it)))
(seq-filter (lambda (s)
(or (null s) (string= "" s))) it)))
(defun org-roam--list-files-search-globs (exts)
"Given EXTS, return a list of search globs.