Skip to content

Commit

Permalink
(feat) represent note as a struct
Browse files Browse the repository at this point in the history
Fixes #33
  • Loading branch information
d12frosted committed Jan 12, 2021
1 parent 5a9ab8e commit e38a135
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 92 deletions.
19 changes: 9 additions & 10 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ taking. It started as an effort of organising my [[https://github.com/d12frosted
:ID: 26af31d5-4fd4-40bb-9058-8543e7359c53
:END:

A note is represented as a property list with the following properties:
A note is represented as a =vulpea-note= structure with the following
slots/fields:

- =:path= - absolute path to the note (even if the note is actually a heading);
- =:title= - title of the note (it might be an alias);
- =:tags= - tags extracted using =org-roam-tag-sources=;
- =:level= - level of the note inside =:path=, with =0= being a file-level note
- =vulpea-note-path= - absolute path to the note (even if the note is actually a heading);
- =vulpea-note-title= - title of the note (it might be an alias);
- =vulpea-note-tags= - tags extracted using =org-roam-tag-sources=;
- =vulpea-note-level= - level of the note inside =:path=, with =0= being a file-level note
and other numbers being a header;
- =:id= - =ID= property of note (file-level or heading level).
- =vulpea-note-id= - =ID= property of note (file-level or heading level).

If =ID= is not present in the note structure, this note is treated as
non-existent. For example, see =vulpea-select=.
Expand All @@ -36,15 +37,13 @@ non-existent. For example, see =vulpea-select=.
:ID: 4aa43ec9-b576-4adc-b4a7-b01958ec2e15
:END:

Please note, that each note (!) must contain an =ID= for Vulpea to be
Please note, that each =vulpea-note= (!) must contain an =ID= for Vulpea to be
operational. One of the ways to always ensure existence of =ID= is to use the
following code:

#+begin_src emacs-lisp
(defun +org-auto-id-add-to-headlines-in-file ()
"Add ID property to the current file and all its headlines.

Only missing properties are added."
"Add ID property to the current file and all its headlines."
(when (and (or (eq major-mode 'org-mode)
(eq major-mode 'org-journal-mode))
(eq buffer-read-only nil))
Expand Down
78 changes: 43 additions & 35 deletions test/vulpea-db-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
;;; Code:

(require 'vulpea-test-utils)
(require 'vulpea-utils)
(require 'vulpea-db)

(describe "vulpea-db-search-by-title"
Expand All @@ -37,36 +38,40 @@
(expect (vulpea-db-search-by-title "Alias of the note with alias")
:to-equal
(list
(list :path (expand-file-name "note-with-alias.org" org-roam-directory)
:title "Alias of the note with alias"
:tags nil
:level 0
:id "72522ed2-9991-482e-a365-01155c172aa5"))))
(make-vulpea-note
:path (expand-file-name "note-with-alias.org" org-roam-directory)
:title "Alias of the note with alias"
:tags nil
:level 0
:id "72522ed2-9991-482e-a365-01155c172aa5"))))

(it "finds multiple notes sharing the same title"
(expect (vulpea-db-search-by-title "Duplicating Term")
:to-have-same-items-as
(list
(list :path (expand-file-name "same-name-1.org" org-roam-directory)
:title "Duplicating Term"
:tags nil
:level 0
:id "ff01962f-47c2-4a32-9bf4-990e41090a9b")
(list :path (expand-file-name "same-name-2.org" org-roam-directory)
:title "Duplicating Term"
:tags nil
:level 0
:id "68f11246-91e1-4d48-b3c6-801a2ef0160b"))))
(make-vulpea-note
:path (expand-file-name "same-name-1.org" org-roam-directory)
:title "Duplicating Term"
:tags nil
:level 0
:id "ff01962f-47c2-4a32-9bf4-990e41090a9b")
(make-vulpea-note
:path (expand-file-name "same-name-2.org" org-roam-directory)
:title "Duplicating Term"
:tags nil
:level 0
:id "68f11246-91e1-4d48-b3c6-801a2ef0160b"))))

(it "returns all information about the note"
(expect (vulpea-db-search-by-title "Reference")
:to-equal
(list
(list :path (expand-file-name "reference.org" org-roam-directory)
:title "Reference"
:tags '("tag1" "tag2")
:level 0
:id "5093fc4e-8c63-4e60-a1da-83fc7ecd5db7"))))
(make-vulpea-note
:path (expand-file-name "reference.org" org-roam-directory)
:title "Reference"
:tags '("tag1" "tag2")
:level 0
:id "5093fc4e-8c63-4e60-a1da-83fc7ecd5db7"))))

(it "should use case sensitive search"
(expect (vulpea-db-search-by-title "reference")
Expand All @@ -86,29 +91,32 @@
(it "returns note by file id"
(expect (vulpea-db-get-by-id "72522ed2-9991-482e-a365-01155c172aa5")
:to-equal
(list :path (expand-file-name "note-with-alias.org" org-roam-directory)
:title "Note with an alias"
:tags nil
:level 0
:id "72522ed2-9991-482e-a365-01155c172aa5")))
(make-vulpea-note
:path (expand-file-name "note-with-alias.org" org-roam-directory)
:title "Note with an alias"
:tags nil
:level 0
:id "72522ed2-9991-482e-a365-01155c172aa5")))

(it "returns note by sub-heading id"
(expect (vulpea-db-get-by-id "b77a4837-71d6-495e-98f1-b576464aacc1")
:to-equal
(list :path (expand-file-name "big-note.org" org-roam-directory)
:title "Big note sub-heading"
:tags nil
:level 1
:id "b77a4837-71d6-495e-98f1-b576464aacc1")))
(make-vulpea-note
:path (expand-file-name "big-note.org" org-roam-directory)
:title "Big note sub-heading"
:tags nil
:level 1
:id "b77a4837-71d6-495e-98f1-b576464aacc1")))

(it "returns note by sub0sub-heading id"
(expect (vulpea-db-get-by-id "cfc39858-351d-4f1e-8f98-10d16d71f49e")
:to-equal
(list :path (expand-file-name "big-note.org" org-roam-directory)
:title "Big note sub-sub-heading"
:tags nil
:level 2
:id "cfc39858-351d-4f1e-8f98-10d16d71f49e"))))
(make-vulpea-note
:path (expand-file-name "big-note.org" org-roam-directory)
:title "Big note sub-sub-heading"
:tags nil
:level 2
:id "cfc39858-351d-4f1e-8f98-10d16d71f49e"))))

(describe "vulpea-db-get-file-by-id"
(before-all
Expand Down
27 changes: 15 additions & 12 deletions test/vulpea-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,21 @@
:and-return-value "(tag1,tag2) Reference")
(expect (vulpea-select "Note")
:to-equal
(list :path (expand-file-name "reference.org" org-roam-directory)
:title "Reference"
:tags '("tag1" "tag2")
:level 0
:id "5093fc4e-8c63-4e60-a1da-83fc7ecd5db7")))
(make-vulpea-note
:path (expand-file-name "reference.org" org-roam-directory)
:title "Reference"
:tags '("tag1" "tag2")
:level 0
:id "5093fc4e-8c63-4e60-a1da-83fc7ecd5db7")))

(it "returns only title for non-existent note"
(spy-on 'org-roam-completion--completing-read
:and-return-value "Future")
(expect (vulpea-select "Note")
:to-equal
(list :title "Future"
:level 0)))
(make-vulpea-note
:title "Future"
:level 0)))

(it "calls FILTER-FN on each item"
(spy-on 'org-roam-completion--completing-read
Expand Down Expand Up @@ -90,11 +92,12 @@
(org-roam-db-build-cache)
(expect (vulpea-db-get-by-id generated-id)
:to-equal
(list :path (expand-file-name "prefix-slarina.org" org-roam-directory)
:title "Slarina"
:tags nil
:level 0
:id generated-id))))
(make-vulpea-note
:path (expand-file-name "prefix-slarina.org" org-roam-directory)
:title "Slarina"
:tags nil
:level 0
:id generated-id))))

(provide 'vulpea-test)
;;; vulpea-test.el ends here
44 changes: 20 additions & 24 deletions vulpea-db.el
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,9 @@

;;;###autoload
(defun vulpea-db-search-by-title (title)
"Return a list of notes with TITLE.
"Return a list of `vulpea-note' that has TITLE.
Does not support headings in the note.
Each note is represented as a property list of the following
form: (:path :title :tags :level :id)."
Does not support headings in the note."
(let ((files
(seq-map
#'car
Expand All @@ -46,25 +43,23 @@ form: (:path :title :tags :level :id)."
title))))
(seq-map
(lambda (file)
(list :path file
:title title
:tags (vulpea-utils-with-file file
(org-roam--extract-tags file))
:level 0
:id (vulpea-db-get-id-by-file file)))
(make-vulpea-note
:path file
:title title
:tags (vulpea-utils-with-file file
(org-roam--extract-tags file))
:level 0
:id (vulpea-db-get-id-by-file file)))
files)))

;;
;; Exchanging ID to X

;;;###autoload
(defun vulpea-db-get-by-id (id)
"Find a note by ID.
Supports headings in the note.
"Find a `vulpea-note' by ID.
Note is represented as a property list of the following
form: (:path :title :tags :level :id)."
Supports headings in the note."
(when-let*
((fls
(org-roam-db-query
Expand All @@ -80,16 +75,17 @@ form: (:path :title :tags :level :id)."
(vulpea-utils-with-file file
(goto-char (cdr (org-id-find-id-in-file id file)))
(org-entry-get (point) "ITEM")))))
(list :path file
:title title
:tags (vulpea-utils-with-file file
(org-roam--extract-tags file))
:level level
:id id)))
(make-vulpea-note
:path file
:title title
:tags (vulpea-utils-with-file file
(org-roam--extract-tags file))
:level level
:id id)))

;;;###autoload
(defun vulpea-db-get-file-by-id (id)
"Get file of note with ID.
"Get file of `vulpea-note' with ID.
Supports headings in the note."
(caar
Expand All @@ -104,7 +100,7 @@ Supports headings in the note."

;;;###autoload
(defun vulpea-db-get-id-by-file (file)
"Get ID of note represented by FILE.
"Get ID of `vulpea-note' represented by FILE.
If the FILE is relative, it is considered to be relative to
`org-roam-directory'."
Expand Down
2 changes: 1 addition & 1 deletion vulpea-meta.el
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ which case VALUE is added at the end of the meta."
((and (stringp value)
(string-match-p vulpea-meta--uuid-regexp value))
(if-let* ((note (vulpea-db-get-by-id value))
(title (plist-get note :title)))
(title (vulpea-note-title note)))
(org-link-make-string (concat "id:" value) title)
(user-error "Note with id \"%s\" does not exist" value)))
((stringp value)
Expand Down
8 changes: 8 additions & 0 deletions vulpea-utils.el
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@
;;
;;; Code:

;;;###autoload
(cl-defstruct vulpea-note
id
title
path
tags
level)

;;;###autoload
(defmacro vulpea-utils-with-file (file &rest body)
"Execute BODY in `org-mode' FILE."
Expand Down
25 changes: 15 additions & 10 deletions vulpea.el
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
;;; Code:

(require 'org-roam)
(require 'vulpea-utils)
(require 'vulpea-meta)
(require 'vulpea-db)

Expand All @@ -34,8 +35,8 @@
filter-fn)
"Select a note.
Returns a property list representing selected note or its subset
without ID if selected note does not exist.
Returns a selected `vulpea-note'. If `vulpea-note-id' is nil, it
means that user selected non-existing note.
PROMPT is a message to present.
Expand All @@ -59,10 +60,13 @@ which takes as its argument an alist of path-completions. See
:initial-input initial-prompt))
(res (cdr (assoc title-with-tags completions))))
(if res
(plist-put res :id
(vulpea-db-get-id-by-file (plist-get res :path)))
(list :title title-with-tags
:level 0))))
(progn
(setf (vulpea-note-id res)
(vulpea-db-get-id-by-file (vulpea-note-path res)))
res)
(make-vulpea-note
:title title-with-tags
:level 0))))

(defun vulpea--get-title-path-completions ()
"Return an alist for completion.
Expand All @@ -85,10 +89,11 @@ contains all the funny stuff."
(dolist (row rows completions)
(pcase-let ((`(,file-path ,title ,tags) row))
(let ((k (org-roam--prepend-tag-string title tags))
(v (list :path file-path
:title title
:tags tags
:level 0)))
(v (make-vulpea-note
:path file-path
:title title
:tags tags
:level 0)))
(push (cons k v) completions))))))

(defun vulpea-create (title template)
Expand Down

0 comments on commit e38a135

Please sign in to comment.