(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 # 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) ## 1.2.3 (13-11-2020)

View File

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

View File

@ -1525,20 +1525,19 @@ specifying the outline-path to a heading:
#'org-roam-capture--get-point #'org-roam-capture--get-point
"* %?" "* %?"
:file-name "daily/%<%Y-%m-%d>" :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")) :olp ("Journal"))
("j" "journal" entry ("j" "journal" entry
#'org-roam-capture--get-point #'org-roam-capture--get-point
"* %?" "* %?"
:file-name "daily/%<%Y-%m-%d>" :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")))) :olp ("Lab notes"))))
@end lisp @end lisp
The template @code{l} will put its notes under the heading Lab notes, and the 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 template @code{j} will put its notes under the heading Journal.
@code{:olp}, make sure that the headings are present in @code{:head}.
@node Capturing and finding daily-notes @node Capturing and finding daily-notes
@section 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)) (org-capture-put :no-save t))
file-path)) 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 () (defun org-roam-capture--get-point ()
"Return exact point to file for org-capture-template. "Return exact point to file for org-capture-template.
The file to use is dependent on the context: 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))) (org-roam-capture--put prop val)))
(set-buffer (org-capture-target-buffer file-path)) (set-buffer (org-capture-target-buffer file-path))
(widen) (widen)
(if-let* ((olp (when (eq org-roam-capture--context 'dailies) (if-let* ((olp (--> (org-roam-capture--get :olp)
(--> (org-roam-capture--get :olp) (pcase it
(pcase it ((pred listp)
((pred stringp) it)
(list it)) (wrong-type
((pred listp) (signal 'wrong-type-argument
it) `((stringp listp)
(wrong-type ,wrong-type)))))))
(signal 'wrong-type-argument
`((stringp listp)
,wrong-type))))))))
(condition-case err (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) (goto-char marker)
(set-marker marker nil)) (set-marker marker nil))
(error (error
(when (org-roam-capture--get :new-file) (when (org-roam-capture--get :new-file)
(kill-buffer)) (kill-buffer))
(signal (car err) (cdr err)))) (signal (car err) (cdr err))))
(goto-char (point-min))))) (goto-char (point-max)))))
(defun org-roam-capture--convert-template (template) (defun org-roam-capture--convert-template (template)
"Convert TEMPLATE from Org-roam syntax to `org-capture-templates' syntax." "Convert TEMPLATE from Org-roam syntax to `org-capture-templates' syntax."