summaryrefslogtreecommitdiff
path: root/org-gnosis.el
diff options
context:
space:
mode:
authorThanos Apollo <[email protected]>2024-11-21 05:19:20 +0200
committerThanos Apollo <[email protected]>2024-11-21 05:19:20 +0200
commit7198e1370f0434e68b5f35242ec92b3b0534a0ad (patch)
tree3693faa7129b286774c5b66e80639a11f1fb7e22 /org-gnosis.el
parentbb781d674f3628587978751247dd44a9b0651026 (diff)
[feature] Add journaling & Refactor finding nodes
Diffstat (limited to 'org-gnosis.el')
-rw-r--r--org-gnosis.el166
1 files changed, 126 insertions, 40 deletions
diff --git a/org-gnosis.el b/org-gnosis.el
index 6afab9a..a7177c9 100644
--- a/org-gnosis.el
+++ b/org-gnosis.el
@@ -41,6 +41,11 @@
:type 'directory
:group 'org-gnosis)
+(defcustom org-gnosis-journal-dir "~/Notes/journal"
+ "Gnosis journal directory."
+ :type 'directory
+ :group 'org-gnosis)
+
(defcustom org-gnosis-show-tags nil
"Display tags with `org-gnosis-find'."
:type 'boolean
@@ -207,14 +212,25 @@ INITIAL-TAGS: Initial set of tags to inherit."
Removes all contents of FILE in database, adding them anew."
(let* ((file (or file (file-name-nondirectory (buffer-file-name))))
- (nodes (org-gnosis-select 'id 'nodes `(= file ,file) t)))
- (if (null nodes)
- (org-gnosis--update-file file)
- (emacsql-with-transaction org-gnosis-db
+ (journal-p (file-in-directory-p file org-gnosis-journal-dir))
+ (nodes (if journal-p
+ (org-gnosis-select 'id 'journal `(= file ,file) t)
+ (org-gnosis-select 'id 'nodes `(= file ,file) t))))
+ (emacsql-with-transaction org-gnosis-db
;; Delete all nodes of file in db
(cl-loop for node in nodes
- do (org-gnosis--delete 'nodes `(= id ,node)))
- (org-gnosis--update-file file)))))
+ do (if journal-p
+ (org-gnosis--delete 'journal `(= id ,node))
+ (org-gnosis--delete 'nodes `(= id ,node))))
+ (if journal-p
+ (org-gnosis-journal--update-file file)
+ (org-gnosis--update-file file)))))
+
+(defun org-gnosis--is-journal-entry-p (file)
+ "Check if FILE is a journal entry."
+ (let ((file-dir (file-name-directory (expand-file-name file)))
+ (expanded-dir (file-name-as-directory (expand-file-name org-gnosis-journal-dir))))
+ (string-equal file-dir expanded-dir)))
(defun org-gnosis--update-file (file)
"Add contents of FILE to database."
@@ -244,16 +260,41 @@ Removes all contents of FILE in database, adding them anew."
;; (org-gnosis--insert-into 'links `([,id ]))
)))))
-(defun org-gnosis-db-sync ()
- "Sync `org-gnosis-db'."
- (interactive)
- (org-gnosis-db-init)
+(defun org-gnosis-journal--update-file (file)
+ "Update database for journal FILE."
+ (let* ((data (org-gnosis-get-file-info file))
+ (file (plist-get data :file))
+ (tags (nth 1 (plist-get data :topic)))
+ (date (org-gnosis-adjust-title (nth 0 (plist-get data :topic))))
+ (hash (nth 2 (plist-get data :topic)))
+ (links (plist-get data :links)))
+ ;; Add journal
+ (emacsql-with-transaction org-gnosis-db
+ (org-gnosis--insert-into 'journal `([,hash ,file ,date ,tags])))))
+
+(defun org-gnosis-db-sync--journal ()
+ "Sync journal entries in databse."
+ (cl-loop for file in (cl-remove-if-not (lambda (file)
+ (and (string-match-p "^[0-9]"
+ (file-name-nondirectory file))
+ (not (file-directory-p file))))
+ (directory-files org-gnosis-journal-dir t nil t))
+ do (org-gnosis-journal--update-file file)))
+
+(defun org-gnosis-db-sync (&optional arg)
+ "Sync `org-gnosis-db'.
+
+If called with ARG do not initialize the database."
+ (interactive "P")
+ (unless arg
+ (org-gnosis-db-init))
(let ((files (cl-remove-if-not (lambda (file)
(and (string-match-p "^[0-9]" (file-name-nondirectory file))
(not (file-directory-p file))))
(directory-files org-gnosis-dir t nil t))))
(cl-loop for file in files
- do (org-gnosis--update-file file))))
+ do (org-gnosis--update-file file)))
+ (org-gnosis-db-sync--journal))
(defun org-gnosis-find--tag-with-tag-prop (lst)
"Combine each sublist of strings in LST into a single string."
@@ -270,52 +311,97 @@ Removes all contents of FILE in database, adding them anew."
title)))
lst))
-(defun org-gnosis--create-file (title)
- "Create node & file for TITLE."
- (let ((file-name (replace-regexp-in-string "#" ""
- (replace-regexp-in-string " " "-" title))))
- (find-file
- (expand-file-name
- (format "%s--%s.org" (format-time-string "%Y%m%d%H%M%S") file-name)
- org-gnosis-dir))
- (insert (format "#+title: %s" title))
- (org-mode)
- (org-gnosis-mode)
- (org-id-get-create)
- file-name))
-
-(defun org-gnosis-find--with-tags ()
- "Select gnosis node with tags."
+(defun org-gnosis--create-file (title &optional file extras)
+ "Create node & FILE for TITLE."
+ (let* ((file-name (replace-regexp-in-string "#" "" ;; hashtags are used for tags
+ (replace-regexp-in-string " " "-" title)))
+ (file (or file (expand-file-name
+ (format "%s--%s.org" (format-time-string "%Y%m%d%H%M%S") file-name)
+ org-gnosis-dir))))
+ (find-file file)
+ (unless (file-exists-p file)
+ (insert (format "#+title: %s\n#+filetags:\n" title))
+ (org-id-get-create)
+ (and extras (insert extras))
+ (org-mode)
+ (org-gnosis-mode)
+ file-name)))
+
+(defun org-gnosis-find--with-tags (&optional prompt entries)
+ "Select gnosis node with tags from ENTRIES.
+
+PROMPT: Prompt message."
(replace-regexp-in-string " #[^[:space:]]+" ""
- (completing-read "Select gnosis node: "
+ (completing-read (or prompt "Select gnosis node: ")
(org-gnosis-find--tag-with-tag-prop
- (org-gnosis-select '[title tags] 'nodes)))))
+ (or entries (org-gnosis-select '[title tags] 'nodes))))))
-(defun org-gnosis-find ()
+(defun org-gnosis--find (prompt entries-with-tags entries)
+ "PROMPT user to select from ENTRIES.
+
+If `org-gnosis-show-tags' is non-nil, ENTRIES-WITH-TAGS will be used
+instead."
+ (let* ((entry (if org-gnosis-show-tags
+ (org-gnosis-find--with-tags prompt entries-with-tags)
+ (completing-read prompt entries))))
+ entry))
+
+(defun org-gnosis-find (&optional title file id directory)
"Select gnosis node."
(interactive)
- (let* ((title (if org-gnosis-show-tags
- (org-gnosis-find--with-tags)
- (completing-read "Select gnosis node: "
- (org-gnosis-select 'title 'nodes))))
- (file (caar (org-gnosis-select 'file 'nodes `(= title ,title))))
- (id (caar (org-gnosis-select 'id 'nodes `(= title ,title)))))
+ (let* ((title (or title (if org-gnosis-show-tags
+ (org-gnosis-find--with-tags)
+ (completing-read "Select gnosis node: "
+ (org-gnosis-select 'title 'nodes)))))
+ (file (or file (caar (org-gnosis-select 'file 'nodes `(= title ,title)))))
+ (id (or id (caar (or id (org-gnosis-select 'id 'nodes `(= title ,title))))))
+ (directory (or directory org-gnosis-dir)))
(cond ((null file)
(org-gnosis--create-file title))
- ((file-exists-p (expand-file-name file org-gnosis-dir))
+ ((file-exists-p (expand-file-name file directory))
(find-file
- (expand-file-name file org-gnosis-dir))
+ (expand-file-name file directory))
(ignore-errors (org-id-goto id))
(org-gnosis-mode 1)))))
(defun org-gnosis-insert ()
"Insert gnosis node."
(interactive)
- (let* ((node (completing-read "Select gnosis node: "
- (org-gnosis-select 'title 'nodes '1=1 t)))
+ (let* ((node (org-gnosis--find "Select gnosis node: "
+ (org-gnosis-select '[title tags] 'nodes '1=1)
+ (org-gnosis-select 'title 'nodes '1=1)))
(id (concat "id:" (car (org-gnosis-select 'id 'nodes `(= ,node title) '1=1)))))
(org-insert-link nil id node)))
+(defun org-gnosis-journal-find (&optional date)
+ "Find journal entry for DATE."
+ (interactive)
+ (let* ((prompt "Select journal entry")
+ (date (or date (org-gnosis--find
+ prompt
+ (org-gnosis-select '[date tags] 'journal)
+ (org-gnosis-select 'date 'journal))))
+ (id (car (org-gnosis-select 'id 'journal `(= date ,date) t)))
+ (file (car (org-gnosis-select 'file 'journal `(= date ,date) t))))
+ (org-gnosis-find date file id org-gnosis-journal-dir)))
+
+(defun org-gnosis-journal-insert ()
+ "Insert journal entry."
+ (interactive)
+ (let* ((node (org-gnosis--find "Select journal entry: "
+ (org-gnosis-select '[date tags] 'journal '1=1)
+ (org-gnosis-select 'date 'journal '1=1)))
+ (id (concat "id:" (car (org-gnosis-select 'id 'nodes `(= ,node title) '1=1)))))
+ (org-insert-link nil id node)))
+
+(defun org-gnosis-journal (&optional template)
+ "Start journaling for current date."
+ (interactive)
+ (let* ((date (format-time-string "%Y-%m-%d"))
+ (file (format "%s.org" date)))
+ (org-gnosis--create-file date (expand-file-name file org-gnosis-journal-dir)
+ (or template org-gnosis-journal-template))))
+
(define-minor-mode org-gnosis-mode
"Org gnosis mode."
:lighter " org-gnosis"