mirror of
https://github.com/org-roam/org-roam
synced 2025-08-01 12:17:21 -05:00
(feat): Overhaul org-roam-dailies (#978)
Implement ideas from `org-journal` to `org-roam-dailies`. Update the doc.
This commit is contained in:
142
doc/org-roam.org
142
doc/org-roam.org
@ -123,7 +123,7 @@ A slip-box requires a method of quickly capturing ideas. These are called
|
||||
*fleeting notes*: they are simple reminders of information or ideas that will
|
||||
need to be processed later on, or trashed. This is typically accomplished using
|
||||
~org-capture~ (see info:org#capture), or using Org-roam's daily notes
|
||||
functionality (see [[*Daily Notes][Daily Notes]]). This provides a central inbox for collecting
|
||||
functionality (see [[*Daily-notes][Daily-notes]]). This provides a central inbox for collecting
|
||||
thoughts, to be processed later into permanent notes.
|
||||
|
||||
Permanent notes are further split into two categories: *literature notes* and
|
||||
@ -993,11 +993,13 @@ This protocol finds or creates a new note with a given ~roam_key~ (see [[*Anatom
|
||||
To use this, create the following [[https://en.wikipedia.org/wiki/Bookmarklet][bookmarklet]] in your browser:
|
||||
|
||||
#+BEGIN_SRC javascript
|
||||
javascript:location.href =
|
||||
'org-protocol://roam-ref?template=r&ref='
|
||||
+ encodeURIComponent(location.href)
|
||||
+ '&title='
|
||||
+ encodeURIComponent(document.title)
|
||||
javascript:location.href =
|
||||
'org-protocol://roam-ref?template=r&ref='
|
||||
+ encodeURIComponent(location.href)
|
||||
+ '&title='
|
||||
+ encodeURIComponent(document.title)
|
||||
+ '&body='
|
||||
+ encodeURIComponent(window.getSelection())
|
||||
#+END_SRC
|
||||
|
||||
or as a keybinding in ~qutebrowser~ in , using the ~config.py~ file (see
|
||||
@ -1011,7 +1013,122 @@ where ~template~ is the template key for a template in
|
||||
~org-roam-capture-ref-templates~ (see [[*The Templating System][The Templating System]]). These templates
|
||||
should contain a ~#+roam_key: ${ref}~ in it.
|
||||
|
||||
* TODO Daily Notes
|
||||
* Daily-notes
|
||||
|
||||
Org-roam provides journaling capabilities akin to
|
||||
[[#org-journal][Org-journal]] with ~org-roam-dailies~.
|
||||
|
||||
** Configuration
|
||||
|
||||
For ~org-roam-dailies~ to work, you need to define two variables:
|
||||
|
||||
- Variable: ~org-roam-dailies-directory~
|
||||
|
||||
Path to daily-notes.
|
||||
|
||||
- Variable: ~org-roam-dailies-capture-templates~
|
||||
|
||||
Capture templates for daily-notes in Org-roam.
|
||||
|
||||
Here is a sane default configuration:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq org-roam-dailies-directory "daily/")
|
||||
|
||||
(setq org-roam-dailies-capture-templates
|
||||
'(("d" "default" entry
|
||||
#'org-roam-capture--get-point
|
||||
"* %?"
|
||||
:file-name "daily/%<%Y-%m-%d>"
|
||||
:head "#+title: %<%Y-%m-%d>\n\n")))
|
||||
#+end_src
|
||||
|
||||
Make sure that ~org-roam-dailies-directory~ appears in ~:file-name~ for your
|
||||
notes to be recognized as daily-notes. You can have different templates
|
||||
placing their notes in different directories, but the one in
|
||||
~org-roam-dailies-directory~ will be considered as the main one in commands.
|
||||
|
||||
See [[*The Templating System][The Templating System]] for creating new
|
||||
templates. ~org-roam-dailies~ provides an extra ~:olp~ option which allows
|
||||
specifying the outline-path to a heading:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq org-roam-dailies-capture-templates
|
||||
'(("l" "lab" entry
|
||||
#'org-roam-capture--get-point
|
||||
"* %?"
|
||||
:file-name "daily/%<%Y-%m-%d>"
|
||||
:head "#+title: %<%Y-%m-%d>\n\n* Lab notes\n* Journal"
|
||||
: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"
|
||||
: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~.
|
||||
|
||||
** Capturing and finding daily-notes
|
||||
|
||||
- Function: ~org-roam-dailies-capture-today~ &optional goto
|
||||
|
||||
Create an entry in the daily note for today.
|
||||
|
||||
When ~goto~ is non-nil, go the note without creating an entry.
|
||||
|
||||
- Function: ~org-roam-dailies-find-today~
|
||||
|
||||
Find the daily note for today, creating it if necessary.
|
||||
|
||||
There are variants of those commands for ~-yesterday~ and ~-tomorrow~:
|
||||
|
||||
- Function: ~org-roam-dailies-capture-yesterday~ n &optional goto
|
||||
|
||||
Create an entry in the daily note for yesteday.
|
||||
|
||||
With numeric argument ~n~, use the daily note ~n~ days in the past.
|
||||
|
||||
- Function: ~org-roam-dailies-find-yesterday~
|
||||
|
||||
With numeric argument N, use the daily-note N days in the future.
|
||||
|
||||
There are also commands which allow you to use Emacs’s ~calendar~ to find the date
|
||||
|
||||
- Function: ~org-roam-dailies-capture-date~
|
||||
|
||||
Create an entry in the daily note for a date using the calendar.
|
||||
|
||||
Prefer past dates, unless ~prefer-future~ is non-nil.
|
||||
|
||||
With a 'C-u' prefix or when ~goto~ is non-nil, go the note without
|
||||
creating an entry.
|
||||
|
||||
- Function: ~org-roam-dailies-find-date~
|
||||
|
||||
Find the daily note for a date using the calendar, creating it if necessary.
|
||||
|
||||
Prefer past dates, unless ~prefer-future~ is non-nil.
|
||||
|
||||
** Navigation
|
||||
|
||||
You can navigate between daily-notes:
|
||||
|
||||
- Function: ~org-roam-dailies-find-directory~
|
||||
|
||||
Find and open ~org-roam-dailies-directory~.
|
||||
|
||||
- Function: ~org-roam-dailies-find-previous-note~
|
||||
|
||||
When in an daily-note, find the previous one.
|
||||
|
||||
- Function: ~org-roam-dailies-find-next-note~
|
||||
|
||||
When in an daily-note, find the next one.
|
||||
|
||||
* Diagnosing and Repairing Files
|
||||
|
||||
@ -1198,10 +1315,11 @@ that uses an external search engine and indexer.
|
||||
:CUSTOM_ID: org-journal
|
||||
:END:
|
||||
|
||||
[[https://github.com/bastibe/org-journal][Org-journal]] is a more
|
||||
powerful alternative to the simple function ~org-roam-dailies-today~. It
|
||||
provides better journaling capabilities, and a nice calendar interface
|
||||
to see all dated entries.
|
||||
[[https://github.com/bastibe/org-journal][Org-journal]] provides journaling
|
||||
capabilities to Org-mode. A lot of its functionalities have been incorporated
|
||||
into Org-roam under the name ~org-roam-dailies~. It remains a good tool if
|
||||
you want to isolate your verbose journal entries from the ideas you would
|
||||
write on a scratchpad.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package org-journal
|
||||
@ -1210,7 +1328,7 @@ to see all dated entries.
|
||||
:custom
|
||||
(org-journal-date-prefix "#+title: ")
|
||||
(org-journal-file-format "%Y-%m-%d.org")
|
||||
(org-journal-dir "/path/to/org-roam-files/")
|
||||
(org-journal-dir "/path/to/journal/files/")
|
||||
(org-journal-date-format "%A, %d %B %Y"))
|
||||
#+END_SRC
|
||||
|
||||
|
@ -78,7 +78,7 @@ General Public License for more details.
|
||||
* Graphing::
|
||||
* Org-roam Completion System::
|
||||
* Roam Protocol::
|
||||
* Daily Notes::
|
||||
* Daily-notes::
|
||||
* Diagnosing and Repairing Files::
|
||||
* Finding Unlinked References::
|
||||
* Performance Optimization::
|
||||
@ -129,6 +129,12 @@ Roam Protocol
|
||||
* The roam-file protocol::
|
||||
* The roam-ref protocol::
|
||||
|
||||
Daily-notes
|
||||
|
||||
* Configuration::
|
||||
* Capturing and finding daily-notes::
|
||||
* Navigation::
|
||||
|
||||
Performance Optimization
|
||||
|
||||
* Profiling Key Operations::
|
||||
@ -260,7 +266,7 @@ A slip-box requires a method of quickly capturing ideas. These are called
|
||||
@strong{fleeting notes}: they are simple reminders of information or ideas that will
|
||||
need to be processed later on, or trashed. This is typically accomplished using
|
||||
@code{org-capture} (see @ref{capture,,,org,}), or using Org-roam's daily notes
|
||||
functionality (see @ref{Daily Notes}). This provides a central inbox for collecting
|
||||
functionality (see @ref{Daily-notes}). This provides a central inbox for collecting
|
||||
thoughts, to be processed later into permanent notes.
|
||||
|
||||
Permanent notes are further split into two categories: @strong{literature notes} and
|
||||
@ -402,7 +408,7 @@ Where @code{/path/to/my/info/files} is the location where you keep info files. T
|
||||
@lisp
|
||||
(require 'info)
|
||||
(add-to-list 'Info-default-directory-list
|
||||
"/path/to/my/info/files")
|
||||
"/path/to/my/info/files")
|
||||
@end lisp
|
||||
|
||||
You can also use one of the default locations, such as:
|
||||
@ -1329,10 +1335,12 @@ To use this, create the following @uref{https://en.wikipedia.org/wiki/Bookmarkle
|
||||
|
||||
@example
|
||||
javascript:location.href =
|
||||
'org-protocol://roam-ref?template=r&ref='
|
||||
+ encodeURIComponent(location.href)
|
||||
+ '&title='
|
||||
+ encodeURIComponent(document.title)
|
||||
'org-protocol://roam-ref?template=r&ref='
|
||||
+ encodeURIComponent(location.href)
|
||||
+ '&title='
|
||||
+ encodeURIComponent(document.title)
|
||||
+ '&body='
|
||||
+ encodeURIComponent(window.getSelection())
|
||||
@end example
|
||||
|
||||
or as a keybinding in @code{qutebrowser} in , using the @code{config.py} file (see
|
||||
@ -1346,8 +1354,153 @@ where @code{template} is the template key for a template in
|
||||
@code{org-roam-capture-ref-templates} (see @ref{The Templating System}). These templates
|
||||
should contain a @code{#+roam_key: $@{ref@}} in it.
|
||||
|
||||
@node Daily Notes
|
||||
@chapter @strong{TODO} Daily Notes
|
||||
@node Daily-notes
|
||||
@chapter Daily-notes
|
||||
|
||||
Org-roam provides journaling capabilities akin to
|
||||
@ref{Org-journal} with @code{org-roam-dailies}.
|
||||
|
||||
@menu
|
||||
* Configuration::
|
||||
* Capturing and finding daily-notes::
|
||||
* Navigation::
|
||||
@end menu
|
||||
|
||||
@node Configuration
|
||||
@section Configuration
|
||||
|
||||
For @code{org-roam-dailies} to work, you need to define two variables:
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Variable: @code{org-roam-dailies-directory}
|
||||
|
||||
Path to daily-notes.
|
||||
|
||||
@item
|
||||
Variable: @code{org-roam-dailies-capture-templates}
|
||||
|
||||
Capture templates for daily-notes in Org-roam.
|
||||
@end itemize
|
||||
|
||||
Here is a sane default configuration:
|
||||
|
||||
@lisp
|
||||
(setq org-roam-dailies-directory "daily/")
|
||||
|
||||
(setq org-roam-dailies-capture-templates
|
||||
'(("d" "default" entry
|
||||
#'org-roam-capture--get-point
|
||||
"* %?"
|
||||
:file-name "daily/%<%Y-%m-%d>"
|
||||
:head "#+title: %<%Y-%m-%d>\n\n")))
|
||||
@end lisp
|
||||
|
||||
Make sure that @code{org-roam-dailies-directory} appears in @code{:file-name} for your
|
||||
notes to be recognized as daily-notes. You can have different templates
|
||||
placing their notes in different directories, but the one in
|
||||
@code{org-roam-dailies-directory} will be considered as the main one in commands.
|
||||
|
||||
See @ref{The Templating System} for creating new
|
||||
templates. @code{org-roam-dailies} provides an extra @code{:olp} option which allows
|
||||
specifying the outline-path to a heading:
|
||||
|
||||
@lisp
|
||||
(setq org-roam-dailies-capture-templates
|
||||
'(("l" "lab" entry
|
||||
#'org-roam-capture--get-point
|
||||
"* %?"
|
||||
:file-name "daily/%<%Y-%m-%d>"
|
||||
:head "#+title: %<%Y-%m-%d>\n\n* Lab notes\n* Journal"
|
||||
: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"
|
||||
: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}.
|
||||
|
||||
@node Capturing and finding daily-notes
|
||||
@section Capturing and finding daily-notes
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Function: @code{org-roam-dailies-capture-today} &optional goto
|
||||
|
||||
Create an entry in the daily note for today.
|
||||
|
||||
When @code{goto} is non-nil, go the note without creating an entry.
|
||||
|
||||
@item
|
||||
Function: @code{org-roam-dailies-find-today}
|
||||
|
||||
Find the daily note for today, creating it if necessary.
|
||||
@end itemize
|
||||
|
||||
There are variants of those commands for @code{-yesterday} and @code{-tomorrow}:
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Function: @code{org-roam-dailies-capture-yesterday} n &optional goto
|
||||
|
||||
Create an entry in the daily note for yesteday.
|
||||
|
||||
With numeric argument @code{n}, use the daily note @code{n} days in the past.
|
||||
|
||||
@item
|
||||
Function: @code{org-roam-dailies-find-yesterday}
|
||||
|
||||
With numeric argument N, use the daily-note N days in the future.
|
||||
@end itemize
|
||||
|
||||
There are also commands which allow you to use Emacs’s @code{calendar} to find the date
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Function: @code{org-roam-dailies-capture-date}
|
||||
|
||||
Create an entry in the daily note for a date using the calendar.
|
||||
|
||||
Prefer past dates, unless @code{prefer-future} is non-nil.
|
||||
|
||||
With a 'C-u' prefix or when @code{goto} is non-nil, go the note without
|
||||
creating an entry.
|
||||
|
||||
@item
|
||||
Function: @code{org-roam-dailies-find-date}
|
||||
|
||||
Find the daily note for a date using the calendar, creating it if necessary.
|
||||
|
||||
Prefer past dates, unless @code{prefer-future} is non-nil.
|
||||
@end itemize
|
||||
|
||||
@node Navigation
|
||||
@section Navigation
|
||||
|
||||
You can navigate between daily-notes:
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Function: @code{org-roam-dailies-find-directory}
|
||||
|
||||
Find and open @code{org-roam-dailies-directory}.
|
||||
|
||||
@item
|
||||
Function: @code{org-roam-dailies-find-previous-note}
|
||||
|
||||
When in an daily-note, find the previous one.
|
||||
|
||||
@item
|
||||
Function: @code{org-roam-dailies-find-next-note}
|
||||
|
||||
When in an daily-note, find the next one.
|
||||
@end itemize
|
||||
|
||||
@node Diagnosing and Repairing Files
|
||||
@chapter Diagnosing and Repairing Files
|
||||
@ -1567,10 +1720,11 @@ that uses an external search engine and indexer.
|
||||
@node Org-journal
|
||||
@subsection Org-journal
|
||||
|
||||
@uref{https://github.com/bastibe/org-journal, Org-journal} is a more
|
||||
powerful alternative to the simple function @code{org-roam-dailies-today}. It
|
||||
provides better journaling capabilities, and a nice calendar interface
|
||||
to see all dated entries.
|
||||
@uref{https://github.com/bastibe/org-journal, Org-journal} provides journaling
|
||||
capabilities to Org-mode. A lot of its functionalities have been incorporated
|
||||
into Org-roam under the name @code{org-roam-dailies}. It remains a good tool if
|
||||
you want to isolate your verbose journal entries from the ideas you would
|
||||
write on a scratchpad.
|
||||
|
||||
@lisp
|
||||
(use-package org-journal
|
||||
@ -1579,7 +1733,7 @@ to see all dated entries.
|
||||
:custom
|
||||
(org-journal-date-prefix "#+title: ")
|
||||
(org-journal-file-format "%Y-%m-%d.org")
|
||||
(org-journal-dir "/path/to/org-roam-files/")
|
||||
(org-journal-dir "/path/to/journal/files/")
|
||||
(org-journal-date-format "%A, %d %B %Y"))
|
||||
@end lisp
|
||||
|
||||
@ -1708,5 +1862,5 @@ call @code{ivy-immediate-done}, typically bound to @code{C-M-j}. Alternatively,
|
||||
Org-roam should provide a selectable ``[?] bar'' candidate at the top of the candidate list.
|
||||
@end table
|
||||
|
||||
Emacs 28.0.50 (Org mode 9.4)
|
||||
@bye
|
||||
Emacs 27.1.50 (Org mode 9.4)
|
||||
@bye
|
@ -41,6 +41,9 @@
|
||||
(defvar org-roam-directory)
|
||||
(defvar org-roam-mode)
|
||||
(defvar org-roam-title-to-slug-function)
|
||||
(defvar org-roam-dailies-directory)
|
||||
(defvar org-roam-dailies-capture--file-name-default)
|
||||
(defvar org-roam-dailies-capture--header-default)
|
||||
(declare-function org-roam--get-title-path-completions "org-roam")
|
||||
(declare-function org-roam--get-ref-path-completions "org-roam")
|
||||
(declare-function org-roam--file-path-from-id "org-roam")
|
||||
@ -49,6 +52,12 @@
|
||||
(declare-function org-roam-mode "org-roam")
|
||||
(declare-function org-roam-completion--completing-read "org-roam-completion")
|
||||
|
||||
(defvar org-roam-capture--file-name-default "%<%Y%m%d%H%M%S>-${slug}"
|
||||
"The default file-name format for Org-roam templates.")
|
||||
|
||||
(defvar org-roam-capture--header-default "#+title: ${title}\n"
|
||||
"The default header for Org-roam templates.")
|
||||
|
||||
(defvar org-roam-capture--file-path nil
|
||||
"The file path for the Org-roam capture.
|
||||
This variable is set during the Org-roam capture process.")
|
||||
@ -74,14 +83,14 @@ note with the given `ref'.")
|
||||
(defvar org-roam-capture-additional-template-props nil
|
||||
"Additional props to be added to the Org-roam template.")
|
||||
|
||||
(defconst org-roam-capture--template-keywords '(:file-name :head)
|
||||
(defconst org-roam-capture--template-keywords '(:file-name :head :olp)
|
||||
"Keywords used in `org-roam-capture-templates' specific to Org-roam.")
|
||||
|
||||
(defcustom org-roam-capture-templates
|
||||
'(("d" "default" plain (function org-roam-capture--get-point)
|
||||
`(("d" "default" plain (function org-roam-capture--get-point)
|
||||
"%?"
|
||||
:file-name "%<%Y%m%d%H%M%S>-${slug}"
|
||||
:head "#+title: ${title}\n"
|
||||
:file-name ,org-roam-capture--file-name-default
|
||||
:head ,org-roam-capture--header-default
|
||||
:unnarrowed t))
|
||||
"Capture templates for Org-roam.
|
||||
The Org-roam capture-templates builds on the default behaviours of
|
||||
@ -217,12 +226,18 @@ Template string :\n%v")
|
||||
((const :format "%v " :table-line-pos) (string))
|
||||
((const :format "%v " :kill-buffer) (const t))))))
|
||||
|
||||
(defvar org-roam-capture-ref--file-name-default "${slug}"
|
||||
"The default file-name for `org-roam-capture-ref-templates'.")
|
||||
|
||||
(defvar org-roam-capture-ref--header-default "#+title: ${title}\n#+roam_key: ${ref}"
|
||||
"The default header for `org-roam-capture-ref-templates'.")
|
||||
|
||||
(defcustom org-roam-capture-ref-templates
|
||||
'(("r" "ref" plain (function org-roam-capture--get-point)
|
||||
"%?"
|
||||
:file-name "${slug}"
|
||||
:head "#+title: ${title}\n#+roam_key: ${ref}\n"
|
||||
:unnarrowed t))
|
||||
`(("r" "ref" plain (function org-roam-capture--get-point)
|
||||
"%?"
|
||||
:file-name ,org-roam-capture-ref--file-name-default
|
||||
:head ,org-roam-capture--header-default
|
||||
:unnarrowed t))
|
||||
"The Org-roam templates used during a capture from the roam-ref protocol.
|
||||
Details on how to specify for the template is given in `org-roam-capture-templates'."
|
||||
:group 'org-roam
|
||||
@ -387,6 +402,18 @@ The file is saved if the original value of :no-save is not t and
|
||||
(with-current-buffer (org-capture-get :buffer)
|
||||
(save-buffer)))))
|
||||
|
||||
(defun org-roam-capture--expand-file-name (file-name)
|
||||
"Expand FILE-NAME for `org-roam-capture'.
|
||||
|
||||
Prepend `org-roam-dailies-directory' to the value of `:file' when
|
||||
capturing a daily-note."
|
||||
(when file-name
|
||||
(pcase org-roam-capture--context
|
||||
('dailies
|
||||
(concat org-roam-dailies-directory file-name))
|
||||
(_
|
||||
file-name))))
|
||||
|
||||
(defun org-roam-capture--new-file ()
|
||||
"Return the path to the new file during an Org-roam capture.
|
||||
|
||||
@ -408,26 +435,52 @@ aborted, we do the following:
|
||||
3. Add a function on `org-capture-before-finalize-hook' that saves
|
||||
the file if the original value of :no-save is not t and
|
||||
`org-note-abort' is not t."
|
||||
(let* ((name-templ (org-roam-capture--get :file-name))
|
||||
(let* ((name-templ (or (org-roam-capture--get :file-name)
|
||||
(pcase org-roam-capture--context
|
||||
('dailies
|
||||
(or (-some-> org-roam-dailies-directory
|
||||
(file-name-as-directory)
|
||||
(concat org-roam-dailies-capture--file-name-default))
|
||||
(user-error "`org-roam-dailies-directory' cannot be nil")))
|
||||
('ref
|
||||
org-roam-capture-ref--file-name-default)
|
||||
(_
|
||||
org-roam-capture--file-name-default))))
|
||||
(new-id (s-trim (org-roam-capture--fill-template
|
||||
name-templ)))
|
||||
(file-path (org-roam--file-path-from-id new-id))
|
||||
(roam-head (org-roam-capture--get :head))
|
||||
(roam-head (or (org-roam-capture--get :head)
|
||||
(pcase org-roam-capture--context
|
||||
('dailies
|
||||
org-roam-dailies-capture--header-default)
|
||||
('ref
|
||||
org-roam-capture-ref--header-default)
|
||||
(_
|
||||
org-roam-capture--header-default))))
|
||||
(org-template (org-capture-get :template))
|
||||
(roam-template (concat roam-head org-template)))
|
||||
(unless (file-exists-p file-path)
|
||||
(unless (or (file-exists-p file-path)
|
||||
(cl-some (lambda (buffer)
|
||||
(string= (buffer-file-name buffer)
|
||||
file-path))
|
||||
(buffer-list)))
|
||||
(make-directory (file-name-directory file-path) t)
|
||||
(org-roam-capture--put :orig-no-save (org-capture-get :no-save)
|
||||
:new-file t)
|
||||
(org-capture-put :template
|
||||
;; Fixes org-capture-place-plain-text throwing 'invalid search bound'
|
||||
;; when both :unnarowed t and "%?" is missing from the template string;
|
||||
;; may become unnecessary when the upstream bug is fixed
|
||||
(if (s-contains-p "%?" roam-template)
|
||||
roam-template
|
||||
(concat roam-template "%?"))
|
||||
:type 'plain
|
||||
:no-save t))
|
||||
(pcase org-roam-capture--context
|
||||
('dailies
|
||||
;; Populate the header of the daily file before capture to prevent it
|
||||
;; from appearing in the buffer-restriction
|
||||
(save-window-excursion
|
||||
(find-file file-path)
|
||||
(insert (substring (org-capture-fill-template (concat roam-head "*"))
|
||||
0 -2))
|
||||
(set-buffer-modified-p nil))
|
||||
(org-capture-put :template org-template))
|
||||
(_
|
||||
(org-capture-put :template roam-template
|
||||
:type 'plain)))
|
||||
(org-capture-put :no-save t))
|
||||
file-path))
|
||||
|
||||
(defun org-roam-capture--get-point ()
|
||||
@ -446,32 +499,53 @@ If there is no file with that ref, a file with that ref is created.
|
||||
|
||||
This function is used solely in Org-roam's capture templates: see
|
||||
`org-roam-capture-templates'."
|
||||
(let ((file-path (pcase org-roam-capture--context
|
||||
('capture
|
||||
(or (cdr (assoc 'file org-roam-capture--info))
|
||||
(org-roam-capture--new-file)))
|
||||
('title
|
||||
(org-roam-capture--new-file))
|
||||
('dailies
|
||||
(org-capture-put :default-time (cdr (assoc 'time org-roam-capture--info)))
|
||||
(org-roam-capture--new-file))
|
||||
('ref
|
||||
(let ((completions (org-roam--get-ref-path-completions))
|
||||
(ref (cdr (assoc 'ref org-roam-capture--info))))
|
||||
(if-let ((pl (cdr (assoc ref completions))))
|
||||
(plist-get pl :path)
|
||||
(org-roam-capture--new-file))))
|
||||
(_ (error "Invalid org-roam-capture-context")))))
|
||||
(let* ((file-path (pcase org-roam-capture--context
|
||||
('capture
|
||||
(or (cdr (assoc 'file org-roam-capture--info))
|
||||
(org-roam-capture--new-file)))
|
||||
('title
|
||||
(org-roam-capture--new-file))
|
||||
('dailies
|
||||
(org-capture-put :default-time (cdr (assoc 'time org-roam-capture--info)))
|
||||
(org-roam-capture--new-file))
|
||||
('ref
|
||||
(let ((completions (org-roam--get-ref-path-completions))
|
||||
(ref (cdr (assoc 'ref org-roam-capture--info))))
|
||||
(if-let ((pl (cdr (assoc ref completions))))
|
||||
(plist-get pl :path)
|
||||
(org-roam-capture--new-file))))
|
||||
(_ (error "Invalid org-roam-capture-context")))))
|
||||
(org-capture-put :template
|
||||
(org-roam-capture--fill-template (org-capture-get :template)))
|
||||
(org-roam-capture--put :file-path file-path)
|
||||
(org-roam-capture--fill-template (org-capture-get :template)))
|
||||
(org-roam-capture--put :file-path file-path
|
||||
:finalize (or (org-capture-get :finalize)
|
||||
(org-roam-capture--get :finalize)))
|
||||
(while org-roam-capture-additional-template-props
|
||||
(let ((prop (pop org-roam-capture-additional-template-props))
|
||||
(val (pop org-roam-capture-additional-template-props)))
|
||||
(org-roam-capture--put prop val)))
|
||||
(set-buffer (org-capture-target-buffer file-path))
|
||||
(widen)
|
||||
(goto-char (point-max))))
|
||||
(if-let* ((olp (when (eq org-roam-capture--context 'dailies)
|
||||
(--> (org-roam-capture--get :olp)
|
||||
(pcase it
|
||||
((pred stringp)
|
||||
(list it))
|
||||
((pred listp)
|
||||
it)
|
||||
(wrong-type
|
||||
(signal 'wrong-type-argument
|
||||
`((stringp listp)
|
||||
,wrong-type))))))))
|
||||
(condition-case err
|
||||
(when-let ((marker (org-find-olp `(,file-path ,@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)))))
|
||||
|
||||
(defun org-roam-capture--convert-template (template)
|
||||
"Convert TEMPLATE from Org-roam syntax to `org-capture-templates' syntax."
|
||||
|
@ -1,8 +1,10 @@
|
||||
;;; org-roam-dailies.el --- Daily notes for Org-roam -*- coding: utf-8; lexical-binding: t; -*-
|
||||
;;; org-roam-dailies.el --- Daily-notes for Org-roam -*- coding: utf-8; lexical-binding: t; -*-
|
||||
;;;
|
||||
;; Copyright © 2020 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: 1.2.2
|
||||
@ -27,7 +29,7 @@
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
;; This library provides functionality for creating daily notes. This is a
|
||||
;; This library provides functionality for creating daily-notes. This is a
|
||||
;; concept borrowed from Roam Research.
|
||||
;;
|
||||
;;; Code:
|
||||
@ -35,102 +37,336 @@
|
||||
(require 'org-capture)
|
||||
(require 'org-roam-capture)
|
||||
(require 'org-roam-macs)
|
||||
(require 'f)
|
||||
|
||||
;;;; Declarations
|
||||
(defvar org-roam-mode)
|
||||
(defvar org-roam-directory)
|
||||
(declare-function org-roam--org-file-p "org-roam")
|
||||
(declare-function org-roam--file-path-from-id "org-roam")
|
||||
(declare-function org-roam--find-file "org-roam")
|
||||
(declare-function org-roam-mode "org-roam")
|
||||
|
||||
(defvar org-roam-dailies-capture--file-name-default "%<%Y-%m-%d>"
|
||||
"The default file-name for `org-roam-dailies-capture-templates'.")
|
||||
|
||||
(defvar org-roam-dailies-capture--header-default "#+title: %<%Y-%m-%d>\n"
|
||||
"The default header for `org-roam-dailies-capture-templates'.")
|
||||
|
||||
;;;; Customizable variables
|
||||
(defcustom org-roam-dailies-directory "daily/"
|
||||
"Path to daily-notes."
|
||||
:group 'org-roam
|
||||
:type 'string)
|
||||
|
||||
(defcustom org-roam-dailies-find-file-hook nil
|
||||
"Hook that is run right after navigating to a daily-note."
|
||||
:group 'org-roam
|
||||
:type 'hook)
|
||||
|
||||
(defcustom org-roam-dailies-capture-templates
|
||||
'(("d" "daily" plain (function org-roam-capture--get-point)
|
||||
""
|
||||
:immediate-finish t
|
||||
:file-name "%<%Y-%m-%d>"
|
||||
:head "#+title: %<%Y-%m-%d>"))
|
||||
"Capture templates for daily notes in Org-roam."
|
||||
'(("d" "default" entry (function org-roam-capture--get-point)
|
||||
"* %?"
|
||||
:file-name "daily/%<%Y-%m-%d>"
|
||||
:head "#+title: %<%Y-%m-%d>\n"))
|
||||
"Capture templates for daily-notes in Org-roam."
|
||||
:group 'org-roam
|
||||
;; Adapted from `org-capture-templates'
|
||||
:type
|
||||
'(repeat
|
||||
(choice :value ("d" "daily" plain (function org-roam-capture--get-point)
|
||||
""
|
||||
:immediate-finish t
|
||||
:file-name "%<%Y-%m-%d>"
|
||||
:head "#+title: %<%Y-%m-%d>")
|
||||
(list :tag "Multikey description"
|
||||
(string :tag "Keys ")
|
||||
(string :tag "Description"))
|
||||
(list :tag "Template entry"
|
||||
(string :tag "Keys ")
|
||||
(string :tag "Description ")
|
||||
(const :format "" plain)
|
||||
(const :format "" (function org-roam-capture--get-point))
|
||||
(choice :tag "Template "
|
||||
(string :tag "String"
|
||||
:format "String:\n \
|
||||
(choice :value ("d" "default" plain (function org-roam-capture--get-point)
|
||||
"%?"
|
||||
:file-name "daily/%<%Y-%m-%d>"
|
||||
:head "#+title: %<%Y-%m-%d>\n"
|
||||
:unnarrowed t)
|
||||
(list :tag "Multikey description"
|
||||
(string :tag "Keys ")
|
||||
(string :tag "Description"))
|
||||
(list :tag "Template entry"
|
||||
(string :tag "Keys ")
|
||||
(string :tag "Description ")
|
||||
(choice :tag "Type "
|
||||
(const :tag "Plain" plain)
|
||||
(const :tag "Entry (for creating headlines)" entry))
|
||||
(const :format "" #'org-roam-capture--get-point)
|
||||
(choice :tag "Template "
|
||||
(string :tag "String"
|
||||
:format "String:\n \
|
||||
Template string :\n%v")
|
||||
(list :tag "File"
|
||||
(const :format "" file)
|
||||
(file :tag "Template file "))
|
||||
(list :tag "Function"
|
||||
(const :format "" function)
|
||||
(function :tag "Template function ")))
|
||||
(const :format "" :immediate-finish) (const :format "" t)
|
||||
(const :format "File name format :" :file-name)
|
||||
(string :format " %v" :value "#+title: ${title}\n")
|
||||
(const :format "Header format :" :head)
|
||||
(string :format "\n%v" :value "%<%Y%m%d%H%M%S>-${slug}")
|
||||
(plist :inline t
|
||||
:tag "Options"
|
||||
;; Give the most common options as checkboxes
|
||||
:options
|
||||
(((const :format "%v " :prepend) (const t))
|
||||
((const :format "%v " :jump-to-captured) (const t))
|
||||
((const :format "%v " :empty-lines) (const 1))
|
||||
((const :format "%v " :empty-lines-before) (const 1))
|
||||
((const :format "%v " :empty-lines-after) (const 1))
|
||||
((const :format "%v " :clock-in) (const t))
|
||||
((const :format "%v " :clock-keep) (const t))
|
||||
((const :format "%v " :clock-resume) (const t))
|
||||
((const :format "%v " :time-prompt) (const t))
|
||||
((const :format "%v " :tree-type) (const week))
|
||||
((const :format "%v " :table-line-pos) (string))
|
||||
((const :format "%v " :kill-buffer) (const t))
|
||||
((const :format "%v " :unnarrowed) (const t))))))))
|
||||
(list :tag "File"
|
||||
(const :format "" file)
|
||||
(file :tag "Template file "))
|
||||
(list :tag "Function"
|
||||
(const :format "" function)
|
||||
(function :tag "Template function ")))
|
||||
(const :format "File name format :" :file-name)
|
||||
(string :format " %v" :value "daily/%<%Y-%m-%d>")
|
||||
(const :format "Header format :" :head)
|
||||
(string :format " %v" :value "#+title: ${title}\n")
|
||||
(plist :inline t
|
||||
:tag "Options"
|
||||
;; Give the most common options as checkboxes
|
||||
:options
|
||||
(((const :tag "Outline path" :olp)
|
||||
(repeat :tag "Headings"
|
||||
(string :tag "Heading")))
|
||||
((const :format "%v " :unnarrowed) (const t))
|
||||
((const :format "%v " :prepend) (const t))
|
||||
((const :format "%v " :immediate-finish) (const t))
|
||||
((const :format "%v " :jump-to-captured) (const t))
|
||||
((const :format "%v " :empty-lines) (const 1))
|
||||
((const :format "%v " :empty-lines-before) (const 1))
|
||||
((const :format "%v " :empty-lines-after) (const 1))
|
||||
((const :format "%v " :clock-in) (const t))
|
||||
((const :format "%v " :clock-keep) (const t))
|
||||
((const :format "%v " :clock-resume) (const t))
|
||||
((const :format "%v " :time-prompt) (const t))
|
||||
((const :format "%v " :tree-type) (const week))
|
||||
((const :format "%v " :table-line-pos) (string))
|
||||
((const :format "%v " :kill-buffer) (const t))))))))
|
||||
|
||||
;; Declarations
|
||||
(defvar org-roam-mode)
|
||||
(declare-function org-roam--file-path-from-id "org-roam")
|
||||
(declare-function org-roam-mode "org-roam")
|
||||
;;;; Utilities
|
||||
(defun org-roam-dailies-directory--get-absolute-path ()
|
||||
"Get absolute path to `org-roam-dailies-directory'."
|
||||
(-> (concat
|
||||
(file-name-as-directory org-roam-directory)
|
||||
org-roam-dailies-directory)
|
||||
(file-truename)))
|
||||
|
||||
(defun org-roam-dailies--file-for-time (time)
|
||||
"Create and find file for TIME."
|
||||
(let ((org-roam-capture-templates org-roam-dailies-capture-templates)
|
||||
(defun org-roam-dailies-find-directory ()
|
||||
"Find and open `org-roam-dailies-directory'."
|
||||
(interactive)
|
||||
(org-roam--find-file (org-roam-dailies-directory--get-absolute-path)))
|
||||
|
||||
(defun org-roam-dailies--daily-note-p (&optional file)
|
||||
"Return t if FILE is an Org-roam daily-note, nil otherwise.
|
||||
|
||||
If FILE is not specified, use the current buffer's file-path."
|
||||
(when-let ((path (or file
|
||||
(-> (buffer-base-buffer)
|
||||
(buffer-file-name))))
|
||||
(directory (org-roam-dailies-directory--get-absolute-path)))
|
||||
(setq path (file-truename path))
|
||||
(save-match-data
|
||||
(and
|
||||
(org-roam--org-file-p path)
|
||||
(f-descendant-of-p path directory)))))
|
||||
|
||||
(defun org-roam-dailies--capture (time &optional goto)
|
||||
"Capture an entry in a daily-note for TIME, creating it if necessary.
|
||||
|
||||
When GOTO is non-nil, go the note without creating an entry."
|
||||
(unless org-roam-mode (org-roam-mode))
|
||||
(let ((org-roam-capture-templates (--> org-roam-dailies-capture-templates
|
||||
(if goto (list (car it)) it)))
|
||||
(org-roam-capture--info (list (cons 'time time)))
|
||||
(org-roam-capture--context 'dailies))
|
||||
(setq org-roam-capture-additional-template-props (list :finalize 'find-file))
|
||||
(org-roam-capture--capture)))
|
||||
(org-roam-capture--capture (when goto '(4)))))
|
||||
|
||||
(defun org-roam-dailies-today ()
|
||||
"Create and find the daily note for today."
|
||||
;;;; Commands
|
||||
;;; Today
|
||||
(defun org-roam-dailies-capture-today (&optional goto)
|
||||
"Create an entry in the daily-note for today.
|
||||
|
||||
When GOTO is non-nil, go the note without creating an entry."
|
||||
(interactive "P")
|
||||
(org-roam-dailies--capture (current-time) goto)
|
||||
(when goto
|
||||
(run-hooks 'org-roam-dailies-find-file-hook)
|
||||
(message "Showing daily-note for today")))
|
||||
|
||||
(defun org-roam-dailies-find-today ()
|
||||
"Find the daily-note for today, creating it if necessary."
|
||||
(interactive)
|
||||
(unless org-roam-mode (org-roam-mode))
|
||||
(org-roam-dailies--file-for-time (current-time)))
|
||||
(org-roam-dailies-capture-today t))
|
||||
|
||||
(defun org-roam-dailies-tomorrow (n)
|
||||
"Create and find the daily note for tomorrow.
|
||||
With numeric argument N, use N days in the future."
|
||||
;;; Tomorrow
|
||||
(defun org-roam-dailies-capture-tomorrow (n &optional goto)
|
||||
"Create an entry in the daily-note for tomorrow.
|
||||
|
||||
With numeric argument N, use the daily-note N days in the future.
|
||||
|
||||
With a `C-u' prefix or when GOTO is non-nil, go the note without
|
||||
creating an entry."
|
||||
(interactive "p")
|
||||
(unless org-roam-mode (org-roam-mode))
|
||||
(org-roam-dailies--file-for-time (time-add (* n 86400) (current-time))))
|
||||
(org-roam-dailies--capture (time-add (* n 86400) (current-time)) goto))
|
||||
|
||||
(defun org-roam-dailies-yesterday (n)
|
||||
"Create and find the file for yesterday.
|
||||
With numeric argument N, use N days in the past."
|
||||
(defun org-roam-dailies-find-tomorrow (n)
|
||||
"Find the daily-note for tomorrow, creating it if necessary.
|
||||
|
||||
With numeric argument N, use the daily-note N days in the
|
||||
future."
|
||||
(interactive "p")
|
||||
(unless org-roam-mode (org-roam-mode))
|
||||
(org-roam-dailies-tomorrow (- n)))
|
||||
(org-roam-dailies-capture-tomorrow n t))
|
||||
|
||||
(defun org-roam-dailies-date ()
|
||||
"Create the file for any date using the calendar interface."
|
||||
;;; Yesterday
|
||||
(defun org-roam-dailies-capture-yesterday (n &optional goto)
|
||||
"Create an entry in the daily-note for yesteday.
|
||||
|
||||
With numeric argument N, use the daily-note N days in the past.
|
||||
|
||||
When GOTO is non-nil, go the note without creating an entry."
|
||||
(interactive "p")
|
||||
(org-roam-dailies-capture-tomorrow (- n) goto))
|
||||
|
||||
(defun org-roam-dailies-find-yesterday (n)
|
||||
"Find the daily-note for yesterday, creating it if necessary.
|
||||
|
||||
With numeric argument N, use the daily-note N days in the
|
||||
future."
|
||||
(interactive "p")
|
||||
(org-roam-dailies-capture-tomorrow (- n) t))
|
||||
|
||||
;;; Calendar
|
||||
(defvar org-roam-dailies-calendar-hook (list 'org-roam-dailies-calendar-mark-entries)
|
||||
"Hooks to run when showing the `org-roam-dailies-calendar'.")
|
||||
|
||||
(defun org-roam-dailies-calendar--install-hook ()
|
||||
"Install Org-roam-dailies hooks to calendar."
|
||||
(add-hook 'calendar-today-visible-hook #'org-roam-dailies-calendar--run-hook)
|
||||
(add-hook 'calendar-today-invisible-hook #'org-roam-dailies-calendar--run-hook))
|
||||
|
||||
(defun org-roam-dailies-calendar--run-hook ()
|
||||
"Run Org-roam-dailies hooks to calendar."
|
||||
(run-hooks 'org-roam-dailies-calendar-hook)
|
||||
(remove-hook 'calendar-today-visible-hook #'org-roam-dailies-calendar--run-hook)
|
||||
(remove-hook 'calendar-today-invisible-hook #'org-roam-dailies-calendar--run-hook))
|
||||
|
||||
(defun org-roam-dailies-calendar--file-to-date (&optional file)
|
||||
"Convert FILE to date.
|
||||
|
||||
Return (MONTH DAY YEAR)."
|
||||
(let ((file (or file
|
||||
(-> (buffer-base-buffer)
|
||||
(buffer-file-name)))))
|
||||
(cl-destructuring-bind (_ _ _ d m y _ _ _)
|
||||
(-> file
|
||||
(file-name-nondirectory)
|
||||
(file-name-sans-extension)
|
||||
(org-parse-time-string))
|
||||
(list m d y))))
|
||||
|
||||
(defun org-roam-dailies-calendar--date-to-time (date)
|
||||
"Convert DATE as returned from the calendar (MONTH DAY YEAR) to a time."
|
||||
(encode-time 0 0 0 (nth 1 date) (nth 0 date) (nth 2 date)))
|
||||
|
||||
(defun org-roam-dailies-calendar-mark-entries ()
|
||||
"Mark days in the calendar for which a daily-note is present."
|
||||
(when (file-exists-p (org-roam-dailies-directory--get-absolute-path))
|
||||
(dolist (date (mapcar #'org-roam-dailies-calendar--file-to-date
|
||||
(org-roam-dailies--list-files)))
|
||||
(when (calendar-date-is-visible-p date)
|
||||
(calendar-mark-visible-date date 'org-roam-dailies-calendar-note)))))
|
||||
|
||||
;;; Date
|
||||
(defun org-roam-dailies-capture-date (&optional goto prefer-future)
|
||||
"Create an entry in the daily-note for a date using the calendar.
|
||||
|
||||
Prefer past dates, unless PREFER-FUTURE is non-nil.
|
||||
|
||||
With a `C-u' prefix or when GOTO is non-nil, go the note without
|
||||
creating an entry."
|
||||
(interactive "P")
|
||||
(org-roam-dailies-calendar--install-hook)
|
||||
(let* ((time-str (let ((org-read-date-prefer-future prefer-future))
|
||||
(org-read-date nil nil nil (if goto
|
||||
"Find daily-note: "
|
||||
"Capture to daily-note: "))))
|
||||
(time (org-read-date nil t time-str)))
|
||||
(org-roam-dailies--capture time goto)
|
||||
(when goto
|
||||
(run-hooks 'org-roam-dailies-find-file-hook)
|
||||
(message "Showing note for %s" time-str))))
|
||||
|
||||
(defun org-roam-dailies-find-date (prefer-future)
|
||||
"Find the daily-note for a date using the calendar, creating it if necessary.
|
||||
|
||||
Prefer past dates, unless PREFER-FUTURE is non-nil."
|
||||
(interactive)
|
||||
(let ((time (org-read-date nil 'to-time nil "Date: ")))
|
||||
(org-roam-dailies--file-for-time time)))
|
||||
(org-roam-dailies-capture-date t prefer-future))
|
||||
|
||||
;;; Navigation
|
||||
(defun org-roam-dailies--list-files (&rest extra-files)
|
||||
"List all files in `org-roam-dailies-directory'.
|
||||
|
||||
EXTRA-FILES can be used to append extra files to the list."
|
||||
(let ((dir (org-roam-dailies-directory--get-absolute-path)))
|
||||
(append (--remove (let ((file (file-name-nondirectory it)))
|
||||
(when (or (auto-save-file-name-p file)
|
||||
(backup-file-name-p file)
|
||||
(string-match "^\\." file))
|
||||
it))
|
||||
(directory-files-recursively dir ""))
|
||||
extra-files)))
|
||||
|
||||
(defun org-roam-dailies--find-next-note-path (&optional n file)
|
||||
"Find next daily-note from FILE.
|
||||
|
||||
With numeric argument N, find note N days in the future. If N is
|
||||
negative, find note N days in the past.
|
||||
|
||||
If FILE is not provided, use the file visited by the current
|
||||
buffer."
|
||||
(unless (org-roam-dailies--daily-note-p file)
|
||||
(user-error "Not in a daily-note"))
|
||||
(let ((n (or n 1))
|
||||
(file (or file
|
||||
(-> (buffer-base-buffer)
|
||||
(buffer-file-name)))))
|
||||
;; Ensure that the buffer is saved before moving
|
||||
(save-buffer file)
|
||||
(let* ((list (org-roam-dailies--list-files))
|
||||
(position
|
||||
(cl-position-if (lambda (candidate)
|
||||
(string= file candidate))
|
||||
list)))
|
||||
(pcase n
|
||||
((pred (natnump))
|
||||
(if (eq position (- (length list) 1))
|
||||
(user-error "Already at newest note")
|
||||
(message "Showing next daily-note")))
|
||||
((pred (integerp))
|
||||
(if (eq position 0)
|
||||
(user-error "Already at oldest note")
|
||||
(message "Showing previous daily-note"))))
|
||||
(nth (+ position n) list))))
|
||||
|
||||
(defun org-roam-dailies-find-next-note (&optional n)
|
||||
"Find next daily-note.
|
||||
|
||||
With numeric argument N, find note N days in the future. If N is
|
||||
negative, find note N days in the past."
|
||||
(interactive "p")
|
||||
(let* ((n (or n 1))
|
||||
(next (org-roam-dailies--find-next-note-path n)))
|
||||
(find-file next)
|
||||
(run-hooks 'org-roam-dailies-find-file-hook)))
|
||||
|
||||
(defun org-roam-dailies-find-previous-note (&optional n)
|
||||
"Find previous daily-note.
|
||||
|
||||
With numeric argument N, find note N days in the past. If N is
|
||||
negative, find note N days in the future."
|
||||
(interactive "p")
|
||||
(let ((n (if n (- n) -1)))
|
||||
(org-roam-dailies-find-next-note n)))
|
||||
|
||||
;;;; Bindings
|
||||
(defvar org-roam-dailies-map (make-sparse-keymap)
|
||||
"Keymap for `org-roam-dailies'.")
|
||||
|
||||
(define-prefix-command 'org-roam-dailies-map)
|
||||
|
||||
(define-key org-roam-dailies-map (kbd "d") #'org-roam-dailies-find-today)
|
||||
(define-key org-roam-dailies-map (kbd "y") #'org-roam-dailies-find-yesterday)
|
||||
(define-key org-roam-dailies-map (kbd "t") #'org-roam-dailies-find-tomorrow)
|
||||
(define-key org-roam-dailies-map (kbd "n") #'org-roam-dailies-capture-today)
|
||||
(define-key org-roam-dailies-map (kbd "f") #'org-roam-dailies-find-next-note)
|
||||
(define-key org-roam-dailies-map (kbd "b") #'org-roam-dailies-find-previous-note)
|
||||
(define-key org-roam-dailies-map (kbd "c") #'org-roam-dailies-find-date)
|
||||
(define-key org-roam-dailies-map (kbd "v") #'org-roam-dailies-capture-date)
|
||||
(define-key org-roam-dailies-map (kbd ".") #'org-roam-dailies-find-directory)
|
||||
|
||||
(provide 'org-roam-dailies)
|
||||
|
||||
|
@ -65,6 +65,11 @@ This face is used on the region target by `org-roam-insertion'
|
||||
during an `org-roam-capture'."
|
||||
:group 'org-roam-faces)
|
||||
|
||||
(defface org-roam-dailies-calendar-note
|
||||
'((t :inherit (org-roam-link) :underline nil))
|
||||
"Face for dates with a daily-note in the calendar"
|
||||
:group 'org-roam-faces)
|
||||
|
||||
;;; _
|
||||
|
||||
(provide 'org-roam-faces)
|
||||
|
15
org-roam.el
15
org-roam.el
@ -374,13 +374,14 @@ Like `file-name-extension', but does not strip version number."
|
||||
If FILE is not specified, use the current buffer's file-path."
|
||||
(when-let ((path (or file
|
||||
org-roam-file-name
|
||||
(buffer-file-name))))
|
||||
(save-match-data
|
||||
(and
|
||||
(org-roam--org-file-p path)
|
||||
(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))))))
|
||||
(-> (buffer-base-buffer)
|
||||
(buffer-file-name)))))
|
||||
(save-match-data
|
||||
(and
|
||||
(org-roam--org-file-p path)
|
||||
(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))))))
|
||||
|
||||
(defun org-roam--shell-command-files (cmd)
|
||||
"Run CMD in the shell and return a list of files. If no files are found, an empty list is returned."
|
||||
|
Reference in New Issue
Block a user