(feat): capture: create OLP if does not exist (#1270)

Remove the requirement that the OLP already exists in the captured file.
Also, make OLP available beyond dailies functionality.
This commit is contained in:
Jethro Kuan
2020-11-13 16:29:00 +08:00
committed by GitHub
parent cc01cf346e
commit b1608bf869
4 changed files with 68 additions and 21 deletions

View File

@ -1,4 +1,12 @@
# Changelog
## 1.2.4 (TBD)
### Added
- [#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`.
### Changed
### Fixed
## 1.2.3 (13-11-2020)

View File

@ -1123,20 +1123,19 @@ specifying the outline-path to a heading:
#'org-roam-capture--get-point
"* %?"
:file-name "daily/%<%Y-%m-%d>"
:head "#+title: %<%Y-%m-%d>\n\n* Lab notes\n* Journal"
:head "#+title: %<%Y-%m-%d>\n"
:olp ("Journal"))
("j" "journal" entry
#'org-roam-capture--get-point
"* %?"
:file-name "daily/%<%Y-%m-%d>"
:head "#+title: %<%Y-%m-%d>\n\n* Lab notes\n* Journal"
:head "#+title: %<%Y-%m-%d>\n"
:olp ("Lab notes"))))
#+end_src
The template ~l~ will put its notes under the heading Lab notes, and the
template ~j~ will put its notes under the heading Journal. When you use
~:olp~, make sure that the headings are present in ~:head~.
template ~j~ will put its notes under the heading Journal.
** Capturing and finding daily-notes

View File

@ -1525,20 +1525,19 @@ specifying the outline-path to a heading:
#'org-roam-capture--get-point
"* %?"
:file-name "daily/%<%Y-%m-%d>"
:head "#+title: %<%Y-%m-%d>\n\n* Lab notes\n* Journal"
:head "#+title: %<%Y-%m-%d>\n"
:olp ("Journal"))
("j" "journal" entry
#'org-roam-capture--get-point
"* %?"
:file-name "daily/%<%Y-%m-%d>"
:head "#+title: %<%Y-%m-%d>\n\n* Lab notes\n* Journal"
:head "#+title: %<%Y-%m-%d>\n"
:olp ("Lab notes"))))
@end lisp
The template @code{l} will put its notes under the heading Lab notes, and the
template @code{j} will put its notes under the heading Journal. When you use
@code{:olp}, make sure that the headings are present in @code{:head}.
template @code{j} will put its notes under the heading Journal.
@node Capturing and finding daily-notes
@section Capturing and finding daily-notes

View File

@ -442,6 +442,50 @@ the file if the original value of :no-save is not t and
(org-capture-put :no-save t))
file-path))
(defun org-roam-capture-find-or-create-olp (olp)
"Return a marker pointing to the entry at OLP in the current buffer.
If OLP does not exist, create it. If anything goes wrong, throw
an error, and if you need to do something based on this error,
you can catch it with `condition-case'."
(let* ((level 1)
(lmin 1)
(lmax 1)
(start (point-min))
(end (point-max))
found flevel)
(unless (derived-mode-p 'org-mode)
(error "Buffer %s needs to be in Org mode" (current-buffer)))
(org-with-wide-buffer
(goto-char start)
(dolist (heading olp)
(let ((re (format org-complex-heading-regexp-format
(regexp-quote heading)))
(cnt 0))
(while (re-search-forward re end t)
(setq level (- (match-end 1) (match-beginning 1)))
(when (and (>= level lmin) (<= level lmax))
(setq found (match-beginning 0) flevel level cnt (1+ cnt))))
(when (> cnt 1)
(error "Heading not unique on level %d: %s" lmax heading))
(when (= cnt 0)
;; Create heading if it doesn't exist
(goto-char end)
(unless (bolp) (newline))
(org-insert-heading nil nil t)
(unless (= lmax 1) (org-do-demote))
(insert heading)
(setq end (point))
(goto-char start)
(while (re-search-forward re end t)
(setq level (- (match-end 1) (match-beginning 1)))
(when (and (>= level lmin) (<= level lmax))
(setq found (match-beginning 0) flevel level cnt (1+ cnt))))))
(goto-char found)
(setq lmin (1+ flevel) lmax (+ lmin (if org-odd-levels-only 1 0)))
(setq start found
end (save-excursion (org-end-of-subtree t t))))
(point-marker))))
(defun org-roam-capture--get-point ()
"Return exact point to file for org-capture-template.
The file to use is dependent on the context:
@ -485,26 +529,23 @@ This function is used solely in Org-roam's capture templates: see
(org-roam-capture--put prop val)))
(set-buffer (org-capture-target-buffer file-path))
(widen)
(if-let* ((olp (when (eq org-roam-capture--context 'dailies)
(--> (org-roam-capture--get :olp)
(if-let* ((olp (--> (org-roam-capture--get :olp)
(pcase it
((pred stringp)
(list it))
((pred listp)
it)
(wrong-type
(signal 'wrong-type-argument
`((stringp listp)
,wrong-type))))))))
,wrong-type)))))))
(condition-case err
(when-let ((marker (org-find-olp `(,file-path ,@olp))))
(when-let ((marker (org-roam-capture-find-or-create-olp olp)))
(goto-char marker)
(set-marker marker nil))
(error
(when (org-roam-capture--get :new-file)
(kill-buffer))
(signal (car err) (cdr err))))
(goto-char (point-min)))))
(goto-char (point-max)))))
(defun org-roam-capture--convert-template (template)
"Convert TEMPLATE from Org-roam syntax to `org-capture-templates' syntax."