From 60f4476b54c165669b86031a278859ef44106b49 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Sat, 20 Jul 2024 06:48:06 +0300 Subject: faces: Fix typos --- gnosis.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 8291a1b..27cc001 100644 --- a/gnosis.el +++ b/gnosis.el @@ -190,12 +190,13 @@ Seperate the question/stem from options." (defcustom gnosis-center-content-p t "Non-nil means center content." :type 'boolean - :group 'gosis) + :group 'gnosis) (defcustom gnosis-apply-highlighting-p t "Non-nil means apply syntax highlighting." :type 'boolean - :group 'gosis) + :group 'gnosis) + (defvar gnosis-due-notes-total nil "Total due notes.") -- cgit v1.2.3 From a494aa67f527e9f3f8fbd7064ebe0f5601af45df Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Sat, 20 Jul 2024 06:48:49 +0300 Subject: new custom: Add gnosis-new-notes-limit * Limit number of new notes for a session. --- gnosis.el | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 27cc001..52fc45b 100644 --- a/gnosis.el +++ b/gnosis.el @@ -197,6 +197,11 @@ Seperate the question/stem from options." :type 'boolean :group 'gnosis) +(defcustom gnosis-new-notes-limit nil + "Total new notes limit." + :type '(choice (const :tag "None" nil) + (integer :tag "Number")) + :group 'gnosis) (defvar gnosis-due-notes-total nil "Total due notes.") -- cgit v1.2.3 From bd403d64412301323f7ebe610773382fbdadb9c2 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Sat, 20 Jul 2024 06:50:04 +0300 Subject: review: Add gnosis-get-new-notes. * Get new notes for review. --- gnosis.el | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 52fc45b..0e3ca1d 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1379,6 +1379,10 @@ well." (cl-loop for note in notes when (gnosis-review-is-due-p note) collect note))) +(defun gnosis-get-new-notes (notes) + "Get new notes from NOTES." + (cl-assert (listp notes) nil "Notes must be a list.") + (cl-intersection notes (gnosis-select 'id 'review-log '(= n 0) t))) (defun gnosis-review-get-due-tags () "Return a list of due note tags." -- cgit v1.2.3 From 6d305eb08092d155d3e00a61122732586e3030a6 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Sat, 20 Jul 2024 06:50:48 +0300 Subject: review: Add new review type: All notes of deck * Add option to review/cram all notes of deck. --- gnosis.el | 2 ++ 1 file changed, 2 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 0e3ca1d..dfbf265 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1711,6 +1711,7 @@ NOTES: List of note ids" (interactive) ;; Refresh modeline (setq gnosis-due-notes-total (length (gnosis-review-get-due-notes))) + ;; Select review type (let ((review-type (gnosis-completing-read "Review: " '("Due notes" "Due notes of deck" "Due notes of specified tag(s)" @@ -1719,6 +1720,7 @@ NOTES: List of note ids" ("Due notes" (gnosis-review-session (gnosis-collect-note-ids :due t))) ("Due notes of deck" (gnosis-review-session (gnosis-collect-note-ids :due t :deck (gnosis--get-deck-id)))) ("Due notes of specified tag(s)" (gnosis-review-session (gnosis-collect-note-ids :due t :tags t))) + ("All notes of deck" (gnosis-review-session (gnosis-collect-note-ids :deck (gnosis--get-deck-id)))) ("All notes of tag(s)" (gnosis-review-session (gnosis-collect-note-ids :tags t)))))) -- cgit v1.2.3 From d34c22f1781676018d575e6274e7975c2d986e94 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Sat, 20 Jul 2024 06:51:48 +0300 Subject: [Refactor] gnosis-review-get-due-notes: Adjust for new notes limit. * Use gnosis-new-notes-limit to calculate new notes for review. --- gnosis.el | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index dfbf265..e3577bc 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1375,10 +1375,14 @@ well." (defun gnosis-review-get-due-notes () "Return a list due notes id for current date." - (let ((notes (gnosis-select 'id 'notes '1=1 t))) - (cl-loop for note in notes - when (gnosis-review-is-due-p note) - collect note))) + (let* ((old-notes (cl-loop for note in (gnosis-select 'id 'review-log '(> n 0) t) + when (gnosis-review-is-due-p note) + collect note)) + (new-notes (cl-loop for note in (gnosis-select 'id 'review-log '(= n 0) t) + when (gnosis-review-is-due-p note) + collect note))) + (append (cl-subseq new-notes 0 gnosis-new-notes-limit) old-notes))) + (defun gnosis-get-new-notes (notes) "Get new notes from NOTES." (cl-assert (listp notes) nil "Notes must be a list.") -- cgit v1.2.3 From 102fe7c385677b8dec8ff0eb736e2130f16fd89c Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Sat, 20 Jul 2024 06:53:02 +0300 Subject: New variable: gnosis-review-notes: Hold value of notes for review. * Collection of note ids for review. --- gnosis.el | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index e3577bc..dd81ab0 100644 --- a/gnosis.el +++ b/gnosis.el @@ -206,6 +206,9 @@ Seperate the question/stem from options." (defvar gnosis-due-notes-total nil "Total due notes.") +(defvar gnosis-review-notes nil + "Review notes.") + ;;; Faces (defgroup gnosis-faces nil @@ -1702,6 +1705,7 @@ NOTES: List of note ids" (if (null notes) (message "No notes for review.") (when (y-or-n-p (format "You have %s total notes for review, start session?" (length notes))) + (setf gnosis-review-notes notes) (catch 'stop-loop (cl-loop for note in notes do (let ((success (gnosis-review-note note))) -- cgit v1.2.3 From 3df9bb0824627f10c60b6b24edad39411c36e505 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Sat, 20 Jul 2024 16:57:02 +0300 Subject: Remove gnosis-get-new-notes * Unused func --- gnosis.el | 5 ----- 1 file changed, 5 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index dd81ab0..5c3537e 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1386,11 +1386,6 @@ well." collect note))) (append (cl-subseq new-notes 0 gnosis-new-notes-limit) old-notes))) -(defun gnosis-get-new-notes (notes) - "Get new notes from NOTES." - (cl-assert (listp notes) nil "Notes must be a list.") - (cl-intersection notes (gnosis-select 'id 'review-log '(= n 0) t))) - (defun gnosis-review-get-due-tags () "Return a list of due note tags." (let ((due-notes (gnosis-review-get-due-notes))) -- cgit v1.2.3 From f08c93426342365bb21ed88c64a18099b95a44fa Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Sat, 20 Jul 2024 16:57:46 +0300 Subject: db: Update to version 3 * Add activity-log, keep track of total notes reviewed per date. --- gnosis.el | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 5c3537e..d98af59 100644 --- a/gnosis.el +++ b/gnosis.el @@ -139,7 +139,7 @@ a string describing the action." (defvar gnosis-dashboard-note-ids nil "Store note ids for dashboard.") -(defconst gnosis-db-version 2 +(defconst gnosis-db-version 3 "Gnosis database version.") (defvar gnosis-note-types '("MCQ" "Cloze" "Basic" "Double" "y-or-n") @@ -2042,6 +2042,9 @@ to improve readability." (:foreign-key [id] :references notes [id] :on-delete :cascade))) +(defvar gnosis-db-schema-activity-log '([(date text :not-null) + (note-num integer :not-null)])) + (defvar gnosis-db-schema-extras '([(id integer :primary-key :not-null) (extra-notes string) ;; Despite the name 'images', this @@ -2255,7 +2258,7 @@ DASHBOARD-TYPE: either 'Notes' or 'Decks' to display the respective dashboard." (defun gnosis-db-init () "Create gnosis essential directories & database." (let ((gnosis-curr-version (caar (emacsql gnosis-db (format "PRAGMA user_version"))))) - (unless (length= (emacsql gnosis-db [:select name :from sqlite-master :where (= type table)]) 6) + (unless (length= (emacsql gnosis-db [:select name :from sqlite-master :where (= type table)]) 7) ;; Enable foreign keys (emacsql gnosis-db "PRAGMA foreign_keys = ON") ;; Gnosis version @@ -2269,14 +2272,21 @@ DASHBOARD-TYPE: either 'Notes' or 'Decks' to display the respective dashboard." ;; Create review-log table (gnosis--create-table 'review-log gnosis-db-schema-review-log) ;; Create extras table - (gnosis--create-table 'extras gnosis-db-schema-extras)) + (gnosis--create-table 'extras gnosis-db-schema-extras) + ;; Create activity-log table + (gnosis--create-table 'activity-log gnosis-db-schema-activity-log)) ;; Update database schema for version - (cond ((= gnosis-curr-version 1) ;; Update to version 2 + (cond ((= gnosis-curr-version 1) ;; Update from version 1 to version 3 (emacsql gnosis-db [:alter-table decks :add failure-factor]) (emacsql gnosis-db [:alter-table decks :add ef-increase]) (emacsql gnosis-db [:alter-table decks :add ef-decrease]) (emacsql gnosis-db [:alter-table decks :add ef-threshold]) (emacsql gnosis-db [:alter-table decks :add initial-interval]) + (emacsql gnosis-db (format "PRAGMA user_version = %s" gnosis-db-version)) + (gnosis--create-table 'activity-log gnosis-db-schema-activity-log)) + ;; Update from version 2 to 3 + ((= gnosis-curr-version 2) + (gnosis--create-table 'activity-log gnosis-db-schema-activity-log) (emacsql gnosis-db (format "PRAGMA user_version = %s" gnosis-db-version)))))) (gnosis-db-init) -- cgit v1.2.3 From 07015f7b67243009dfc317548c14e8bcf48eb548 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Sat, 20 Jul 2024 16:58:44 +0300 Subject: review: Update activity log for every note review. * New function: gnosis-get-date-total-notes. * Return total notes reviewed for date. * New function: Add gnosis-review-increment-log. * Update total notes reviewed for current date. --- gnosis.el | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index d98af59..6ff4bf0 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1566,18 +1566,29 @@ If user-input is equal to CLOZE, return t." (gnosis-display-next-review id success) success)) -(defun gnosis-review-note (id) - "Start review for note with value of id ID, if note is unsuspended." +(defun gnosis-review-increment-activity-log (&optional date) + "Increament activity log for DATE by one." + (let* ((current-value (gnosis-get-date-total-notes)) + (new-value (cl-incf current-value)) + (date (or date (gnosis-algorithm-date)))) + (gnosis-update 'activity-log `(= note-num ,new-value) `(= date ',date)))) + +(defun gnosis-review-note (id &optional date) + "Start review for note with value of id ID, if note is unsuspended. + +DATE: Date to log the note review on the activity-log." (when (gnosis-suspended-p id) (message "Suspended note with id: %s" id) (sit-for 0.3)) ;; this should only occur in testing/dev cases (let* ((type (gnosis-get 'type 'notes `(= id ,id))) - (func-name (intern (format "gnosis-review-%s" (downcase type))))) + (func-name (intern (format "gnosis-review-%s" (downcase type)))) + (date (or date (gnosis-algorithm-date)))) (if (fboundp func-name) (progn (pop-to-buffer-same-window (get-buffer-create "*gnosis*")) (gnosis-mode) - (funcall func-name id)) + (funcall func-name id) + (gnosis-review-increment-activity-log date)) (error "Malformed note type: '%s'" type)))) @@ -1696,14 +1707,15 @@ To customize the keybindings, adjust `gnosis-review-keybindings'." "Start review session for NOTES. NOTES: List of note ids" - (let ((note-count 0)) + (let ((note-count 0) + (date (gnosis-algorithm-date))) (if (null notes) (message "No notes for review.") (when (y-or-n-p (format "You have %s total notes for review, start session?" (length notes))) (setf gnosis-review-notes notes) (catch 'stop-loop (cl-loop for note in notes - do (let ((success (gnosis-review-note note))) + do (let ((success (gnosis-review-note note date))) (cl-incf note-count) (gnosis-review-actions success note note-count)) finally (gnosis-review-commit note-count))))))) @@ -1962,6 +1974,18 @@ SUSPEND: Suspend note, 0 for unsuspend, 1 for suspend" (let ((deck-id (gnosis-get 'deck-id 'notes `(= id ,id)))) (gnosis-get-deck-initial-interval deck-id))) +(defun gnosis-get-date-total-notes (&optional date) + "Return total notes reviewed for DATE. + +Defaults to current date." + (cl-assert (listp date) nil "Date must be a list.") + (let* ((date (or date (gnosis-algorithm-date))) + (note-num (car (gnosis-select 'note-num 'activity-log `(= date ',date) t)))) + (or note-num + (progn + (gnosis--insert-into 'activity-log `([,date 0])) + 0)))) + (cl-defun gnosis-export-note (id &optional (export-for-deck nil)) "Export fields for note with value of id ID. -- cgit v1.2.3 From 56d9ecb057327d43372c48dc5cffbd77ae0c79b1 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Sat, 20 Jul 2024 17:57:13 +0300 Subject: db: Add gnosis-table-exists * Check if a table exists before creating/deleting it. --- gnosis.el | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 6ff4bf0..1c3881d 100644 --- a/gnosis.el +++ b/gnosis.el @@ -287,13 +287,21 @@ Optional argument FLATTEN, when non-nil, flattens the result." "Select VALUE from TABLE for note ID." (gnosis-select value table `(= id ,id) t)) +(defun gnosis-table-exists-p (table) + "Check if TABLE exists." + (let ((tables (mapcar (lambda (str) (replace-regexp-in-string "_" "-" (symbol-name str))) + (cdr (gnosis-select 'name 'sqlite-master '(= type table) t))))) + (member (symbol-name table) tables))) + (cl-defun gnosis--create-table (table &optional values) "Create TABLE for VALUES." - (emacsql gnosis-db `[:create-table ,table ,values])) + (unless (gnosis-table-exists-p table) + (emacsql gnosis-db `[:create-table ,table ,values]))) (cl-defun gnosis--drop-table (table) "Drop TABLE from `gnosis-db'." - (emacsql gnosis-db `[:drop-table ,table])) + (when (gnosis-table-exists-p table) + (emacsql gnosis-db `[:drop-table ,table]))) (cl-defun gnosis--insert-into (table values) "Insert VALUES to TABLE." -- cgit v1.2.3 From edcd36b912009573307446b5ce97b77fff955fff Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Sun, 21 Jul 2024 16:01:49 +0300 Subject: [fix] gnosis-review: Encapsulate update of db. * All updates of the db should be done within gnosis-review--update. --- gnosis.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 1c3881d..bee4d15 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1450,6 +1450,8 @@ Returns a list of the form ((yyyy mm dd) (ef-increase ef-decrease ef-total))." SUCCESS is a boolean value, t for success, nil for failure." (let ((ef (cadr (gnosis-review-algorithm id success))) (next-rev (car (gnosis-review-algorithm id success)))) + ;; Update activity-log + (gnosis-review-increment-activity-log) ;; Update review-log (gnosis-update 'review-log `(= last-rev ',(gnosis-algorithm-date)) `(= id ,id)) (gnosis-update 'review-log `(= next-rev ',next-rev) `(= id ,id)) @@ -1595,8 +1597,7 @@ DATE: Date to log the note review on the activity-log." (progn (pop-to-buffer-same-window (get-buffer-create "*gnosis*")) (gnosis-mode) - (funcall func-name id) - (gnosis-review-increment-activity-log date)) + (funcall func-name id)) (error "Malformed note type: '%s'" type)))) -- cgit v1.2.3 From 00adb72afc14021909ecad668fbba892ebf5e03a Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Sun, 21 Jul 2024 16:03:19 +0300 Subject: review: Get unsuspended due notes directly with emacsql * Improve performance. --- gnosis.el | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index bee4d15..81907a4 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1386,11 +1386,15 @@ well." (defun gnosis-review-get-due-notes () "Return a list due notes id for current date." - (let* ((old-notes (cl-loop for note in (gnosis-select 'id 'review-log '(> n 0) t) + (let* ((old-notes (cl-loop for note in (gnosis-select 'id 'review-log '(and (> n 0) + (= suspend 0)) + t) when (gnosis-review-is-due-p note) collect note)) - (new-notes (cl-loop for note in (gnosis-select 'id 'review-log '(= n 0) t) - when (gnosis-review-is-due-p note) + (new-notes (cl-loop for note in (gnosis-select 'id 'review-log '(and (= n 0) + (= suspend 0)) + t) + when (gnosis-review-is-due-today-p note) collect note))) (append (cl-subseq new-notes 0 gnosis-new-notes-limit) old-notes))) -- cgit v1.2.3 From 9bf0e241f0862526583262a1f2671b0524a8508d Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Mon, 22 Jul 2024 09:32:06 +0300 Subject: gnosis: Use gnosis-dashboard as a separated module. --- gnosis.el | 218 ++++++++++---------------------------------------------------- 1 file changed, 35 insertions(+), 183 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 81907a4..5e42d99 100644 --- a/gnosis.el +++ b/gnosis.el @@ -45,6 +45,7 @@ (require 'gnosis-algorithm) (require 'gnosis-string-edit) +(require 'gnosis-dashboard) (require 'animate) @@ -136,9 +137,6 @@ a string describing the action." (defvar gnosis-testing nil "When t, warn user he is in a testing environment.") -(defvar gnosis-dashboard-note-ids nil - "Store note ids for dashboard.") - (defconst gnosis-db-version 3 "Gnosis database version.") @@ -1366,6 +1364,40 @@ provided, use it as the default value." (setf gnosis-previous-note-tags tags) (if (equal tags '("")) '("untagged") tags))) +;; Collecting note ids + +;; TODO: Rewrite. Tags should be an input of strings, interactive +;; handling should be done by "helper" funcs +(cl-defun gnosis-collect-note-ids (&key (tags nil) (due nil) (deck nil) (query nil)) + "Return list of note ids based on TAGS, DUE, DECKS, QUERY. + +TAGS: boolean value, t to specify tags. +DUE: boolean value, t to specify due notes. +DECK: Integer, specify deck id. +QUERY: String value," + (cl-assert (and (booleanp due) (booleanp tags) (or (numberp deck) (null deck)) (or (stringp query) (null query))) + nil "Incorrect value passed to `gnosis-collect-note-ids'") + (cond ((and (null tags) (null due) (null deck) (null query)) + (gnosis-select 'id 'notes '1=1 t)) + ;; All due notes + ((and (null tags) due (null deck)) + (gnosis-review-get-due-notes)) + ;; All notes for tags + ((and tags (null due) (null deck)) + (gnosis-select-by-tag (gnosis-tag-prompt))) + ;; All due notes for tags + ((and tags due (null deck)) + (gnosis-select-by-tag (gnosis-tag-prompt) t)) + ;; All notes for deck + ((and (null tags) (null due) deck) + (gnosis-get-deck-notes deck nil)) + ;; All due notes for deck + ((and (null tags) deck due) + (gnosis-get-deck-notes deck t)) + ;; Query + ((and (null tags) (null due) (null deck) query) + (gnosis-search-note query)))) + ;; Review ;;;;;;;;;; (defun gnosis-review-is-due-p (note-id) @@ -2112,186 +2144,6 @@ Return note ids for notes that match QUERY." words)))) (gnosis-select 'id 'notes clause t))) -;; Dashboard - -(defun gnosis-dashboard-output-note (id) - "Output contents for note with ID, formatted for gnosis dashboard." - (cl-loop for item in (append (gnosis-select '[main options answer tags type] 'notes `(= id ,id) t) - (gnosis-select 'suspend 'review-log `(= id ,id) t)) - if (listp item) - collect (mapconcat #'identity item ",") - else - collect (replace-regexp-in-string "\n" " " (format "%s" item)))) - -;; TODO: Rewrite. Tags should be an input of strings, interactive -;; handling should be done by "helper" funcs -(cl-defun gnosis-collect-note-ids (&key (tags nil) (due nil) (deck nil) (query nil)) - "Return list of note ids based on TAGS, DUE, DECKS, QUERY. - -TAGS: boolean value, t to specify tags. -DUE: boolean value, t to specify due notes. -DECK: Integer, specify deck id. -QUERY: String value," - (cl-assert (and (booleanp due) (booleanp tags) (or (numberp deck) (null deck)) (or (stringp query) (null query))) - nil "Incorrect value passed to `gnosis-collect-note-ids'") - (cond ((and (null tags) (null due) (null deck) (null query)) - (gnosis-select 'id 'notes '1=1 t)) - ;; All due notes - ((and (null tags) due (null deck)) - (gnosis-review-get-due-notes)) - ;; All notes for tags - ((and tags (null due) (null deck)) - (gnosis-select-by-tag (gnosis-tag-prompt))) - ;; All due notes for tags - ((and tags due (null deck)) - (gnosis-select-by-tag (gnosis-tag-prompt) t)) - ;; All notes for deck - ((and (null tags) (null due) deck) - (gnosis-get-deck-notes deck nil)) - ;; All due notes for deck - ((and (null tags) deck due) - (gnosis-get-deck-notes deck t)) - ;; Query - ((and (null tags) (null due) (null deck) query) - (gnosis-search-note query)))) - -(defun gnosis-dashboard-output-notes (note-ids) - "Return NOTE-IDS contents on gnosis dashboard." - (cl-assert (listp note-ids) t "`note-ids' must be a list of note ids.") - (pop-to-buffer "*gnosis-dashboard*") - (gnosis-dashboard-mode) - (setf tabulated-list-format `[("Main" ,(/ (window-width) 4) t) - ("Options" ,(/ (window-width) 6) t) - ("Answer" ,(/ (window-width) 6) t) - ("Tags" ,(/ (window-width) 5) t) - ("Type" ,(/ (window-width) 10) T) - ("Suspend" ,(/ (window-width) 6) t)] - tabulated-list-entries (cl-loop for id in note-ids - for output = (gnosis-dashboard-output-note id) - when output - collect (list (number-to-string id) (vconcat output))) - gnosis-dashboard-note-ids note-ids) - (tabulated-list-init-header) - ;; Keybindings, for editing, suspending, deleting notes. - ;; We use `local-set-key' to bind keys to the buffer to avoid - ;; conflicts when using the dashboard for displaying either notes - ;; or decks. - (local-set-key (kbd "e") #'gnosis-dashboard-edit-note) - (local-set-key (kbd "s") #'(lambda () (interactive) - (gnosis-suspend-note (string-to-number (tabulated-list-get-id))) - (gnosis-dashboard-output-notes gnosis-dashboard-note-ids) - (revert-buffer t t t))) - (local-set-key (kbd "a") #'gnosis-add-note) - (local-set-key (kbd "r") #'gnosis-dashboard) - (local-set-key (kbd "d") #'(lambda () (interactive) - (gnosis-delete-note (string-to-number (tabulated-list-get-id))) - (gnosis-dashboard-output-notes gnosis-dashboard-note-ids) - (revert-buffer t t t))) - (local-unset-key (kbd "RET"))) - -(defun gnosis-dashboard-deck-note-count (id) - "Return total note count for deck with ID." - (let ((note-count (caar (emacsql gnosis-db (format "SELECT COUNT(*) FROM notes WHERE deck_id=%s" id))))) - (when (gnosis-select 'id 'decks `(= id ,id)) - (list (number-to-string note-count))))) - -(defun gnosis-dashboard-output-deck (id) - "Output contents from deck with ID, formatted for gnosis dashboard." - (cl-loop for item in (append (gnosis-select - '[name failure-factor ef-increase ef-decrease ef-threshold initial-interval] - 'decks `(= id ,id) t) - (mapcar 'string-to-number (gnosis-dashboard-deck-note-count id))) - when (listp item) - do (cl-remove-if (lambda (x) (and (vectorp x) (zerop (length x)))) item) - collect (format "%s" item))) - -(defun gnosis-dashboard-output-decks () - "Return deck contents for gnosis dashboard." - (pop-to-buffer "*gnosis-dashboard*") - (gnosis-dashboard-mode) - (setq tabulated-list-format [("Name" 15 t) - ("failure-factor" 15 t) - ("ef-increase" 15 t) - ("ef-decrease" 15 t) - ("ef-threshold" 15 t) - ("Initial Interval" 20 t) - ("Total Notes" 10 t)]) - (tabulated-list-init-header) - (setq tabulated-list-entries - (cl-loop for id in (gnosis-select 'id 'decks '1=1 t) - for output = (gnosis-dashboard-output-deck id) - when output - collect (list (number-to-string id) (vconcat output)))) - (local-set-key (kbd "e") #'gnosis-dashboard-edit-deck) - (local-set-key (kbd "a") #'(lambda () "Add deck & refresh" (interactive) - (gnosis-add-deck (read-string "Deck name: ")) - (gnosis-dashboard-output-decks) - (revert-buffer t t t))) - (local-set-key (kbd "s") #'(lambda () "Suspend notes" (interactive) - (gnosis-suspend-deck - (string-to-number (tabulated-list-get-id))) - (gnosis-dashboard-output-decks) - (revert-buffer t t t))) - (local-set-key (kbd "d") #'(lambda () "Delete deck" (interactive) - (gnosis-delete-deck (string-to-number (tabulated-list-get-id))) - (gnosis-dashboard-output-decks) - (revert-buffer t t t))) - (local-set-key (kbd "RET") #'(lambda () "View notes of deck" (interactive) - (gnosis-dashboard "notes" - (gnosis-collect-note-ids - :deck (string-to-number (tabulated-list-get-id))))))) - -(defun gnosis-dashboard-edit-note (&optional dashboard) - "Get note id from tabulated list and edit it. - -DASHBOARD: Dashboard to return to after editing." - (interactive) - (let ((id (tabulated-list-get-id)) - (dashboard (or dashboard "notes"))) - (gnosis-edit-note (string-to-number id) nil dashboard) - (message "Editing note with id: %s" id))) - -(defun gnosis-dashboard-edit-deck () - "Get deck id from tabulated list and edit it." - (interactive) - (let ((id (tabulated-list-get-id))) - (gnosis-edit-deck (string-to-number id)))) - -(defvar-keymap gnosis-dashboard-mode-map - :doc "gnosis-dashboard keymap" - "q" #'quit-window) - -(define-derived-mode gnosis-dashboard-mode tabulated-list-mode "Gnosis Dashboard" - "Major mode for displaying Gnosis dashboard." - :keymap gnosis-dashboard-mode-map - (setq tabulated-list-padding 2 - tabulated-list-sort-key nil)) - -;;;###autoload -(cl-defun gnosis-dashboard (&optional dashboard-type (note-ids nil)) - "Display gnosis dashboard. - -NOTE-IDS: List of note ids to display on dashboard. When nil, prompt -for dashboard type. - -DASHBOARD-TYPE: either 'Notes' or 'Decks' to display the respective dashboard." - (interactive) - (let ((dashboard-type (or dashboard-type - (cadr (read-multiple-choice - "Display dashboard for:" - '((?n "notes") - (?d "decks") - (?t "tags") - (?s "search"))))))) - (if note-ids (gnosis-dashboard-output-notes note-ids) - (pcase dashboard-type - ("notes" (gnosis-dashboard-output-notes (gnosis-collect-note-ids))) - ("decks" (gnosis-dashboard-output-decks)) - ("tags" (gnosis-dashboard-output-notes (gnosis-collect-note-ids :tags t))) - ("search" (gnosis-dashboard-output-notes - (gnosis-collect-note-ids :query (read-string "Search for note: ")))))) - (tabulated-list-print t))) - (defun gnosis-db-init () "Create gnosis essential directories & database." (let ((gnosis-curr-version (caar (emacsql gnosis-db (format "PRAGMA user_version"))))) -- cgit v1.2.3 From 58b0ece3a027969a097ea7bd6381429e9ad361b9 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 23 Jul 2024 18:38:07 +0300 Subject: review: Add threshold and use c-fails to calc next interv. * Use threshold to reset next interval to 0. When c-fails >= threshold set next interval to 0. --- gnosis.el | 2 ++ 1 file changed, 2 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 5e42d99..e3dad4b 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1470,6 +1470,8 @@ Returns a list of the form ((yyyy mm dd) (ef-increase ef-decrease ef-total))." :ef (nth 2 ef) ;; total ef is used for next interval :success success :successful-reviews t-success + :c-fails c-fails + :threshold 3 ;;TODO: Create a gnosis-interval-thershold :failure-factor ff :initial-interval (gnosis-get-note-initial-interval id)) (gnosis-algorithm-next-ef :ef ef -- cgit v1.2.3 From d3ec1ab2ca0c3bec8a14626968a50b58a6dac0d9 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 23 Jul 2024 18:39:36 +0300 Subject: db: Rewrite schema for activity-log * Rename note-num -> reviewed-total * Add reviewed-new: Hold value of new notes reviewed for date entry. --- gnosis.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index e3dad4b..ed45621 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2114,7 +2114,8 @@ to improve readability." :on-delete :cascade))) (defvar gnosis-db-schema-activity-log '([(date text :not-null) - (note-num integer :not-null)])) + (reviewed-total integer :not-null) + (reviewed-new integer :not-null)])) (defvar gnosis-db-schema-extras '([(id integer :primary-key :not-null) (extra-notes string) -- cgit v1.2.3 From b0eafe453cab365d1d3d5d534289eba9bfd2b46c Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 23 Jul 2024 18:41:16 +0300 Subject: Rewrite review-increment-activity-log * Adjust for adding new notes on reviewed-new column * Use new variable names * Rewrite more cleanly. --- gnosis.el | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index ed45621..1435a3b 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1614,12 +1614,17 @@ If user-input is equal to CLOZE, return t." (gnosis-display-next-review id success) success)) -(defun gnosis-review-increment-activity-log (&optional date) - "Increament activity log for DATE by one." - (let* ((current-value (gnosis-get-date-total-notes)) - (new-value (cl-incf current-value)) +(defun gnosis-review-increment-activity-log (new? &optional date) + "Increament activity log for DATE by one. + +If NEW? is non-nil, increment new notes log by 1." + (let* ((current-total-value (gnosis-get-date-total-notes)) + (inc-total (cl-incf current-total-value)) + (current-new-value (gnosis-get-date-new-notes)) + (inc-new (cl-incf current-new-value)) (date (or date (gnosis-algorithm-date)))) - (gnosis-update 'activity-log `(= note-num ,new-value) `(= date ',date)))) + (gnosis-update 'activity-log `(= reviewed-total ,inc-total) `(= date ',date)) + (and new? (gnosis-update 'activity-log `(= reviewed-new ,inc-new) `(= date ',date))))) (defun gnosis-review-note (id &optional date) "Start review for note with value of id ID, if note is unsuspended. -- cgit v1.2.3 From 538a7d3a500a9a4757e44f086d225a289eb5537d Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 23 Jul 2024 18:42:28 +0300 Subject: New function: review-is-note-new-p * Check if note ID is a new note. --- gnosis.el | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 1435a3b..d3673bd 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1614,6 +1614,11 @@ If user-input is equal to CLOZE, return t." (gnosis-display-next-review id success) success)) +(defun gnosis-review-is-note-new-p (id) + "Return t if note with ID is new." + (let ((reviews (car (gnosis-select-id 'n 'review-log id)))) + (not (> reviews 0)))) + (defun gnosis-review-increment-activity-log (new? &optional date) "Increament activity log for DATE by one. -- cgit v1.2.3 From 5d74e3fa6f203477610d3f8d8b1838f4b3027ff9 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 23 Jul 2024 18:43:18 +0300 Subject: Review: Increment new note entries. * Use gnosis-review-is-note-new-p with gnosis-review-increment-activity-log to update activity-log properly for total notes & new notes. --- gnosis.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index d3673bd..1a425cc 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1489,7 +1489,7 @@ SUCCESS is a boolean value, t for success, nil for failure." (let ((ef (cadr (gnosis-review-algorithm id success))) (next-rev (car (gnosis-review-algorithm id success)))) ;; Update activity-log - (gnosis-review-increment-activity-log) + (gnosis-review-increment-activity-log (gnosis-review-is-note-new-p id)) ;; Update review-log (gnosis-update 'review-log `(= last-rev ',(gnosis-algorithm-date)) `(= id ,id)) (gnosis-update 'review-log `(= next-rev ',next-rev) `(= id ,id)) -- cgit v1.2.3 From 8d20fc3183ab2ce486d76df452144d3b1ea7edda Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 23 Jul 2024 18:44:59 +0300 Subject: New function: get-date-new-notes. * Get new notes for date. --- gnosis.el | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 1a425cc..bd27619 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2043,6 +2043,15 @@ Defaults to current date." (gnosis--insert-into 'activity-log `([,date 0])) 0)))) +(defun gnosis-get-date-new-notes (&optional date) + "Return total notes reviewed for DATE. + +Defaults to current date." + (cl-assert (listp date) nil "Date must be a list.") + (let* ((date (or date (gnosis-algorithm-date))) + (reviewed-new (or (car (gnosis-select 'reviewed-new 'activity-log `(= date ',date) t)) 0))) + reviewed-new)) + (cl-defun gnosis-export-note (id &optional (export-for-deck nil)) "Export fields for note with value of id ID. -- cgit v1.2.3 From 293684279e55c14bb9a819a40ecfaddec5febe72 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 23 Jul 2024 18:46:03 +0300 Subject: edit:(decks) Remove asserts for initial-interval length. * Initial interval can be more than 2 items. --- gnosis.el | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index bd27619..7f207f8 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1900,8 +1900,7 @@ INITIAL-INTERVAL: Initial interval for notes of deck" (gnosis-assert-int-or-nil ef-threshold "ef-threshold must be an integer") (gnosis-assert-number-or-nil ef-increase "ef-increase must be a number") (cl-assert (or (and (listp initial-interval) - (and (cl-every #'integerp initial-interval) - (length= initial-interval 2))) + (cl-every #'integerp initial-interval)) (null initial-interval)) nil "Initial-interval must be a list of 2 integers") (cl-loop for (field . value) in -- cgit v1.2.3 From e72d2dc67439d880d93739fe003d451c6c790ae3 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 23 Jul 2024 18:46:49 +0300 Subject: [fix] get-date-total-notes creation of new entries. * gnosis-get-date-total-notes should not create new entries unless it's for the current date. --- gnosis.el | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 7f207f8..f9a224a 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2033,13 +2033,18 @@ SUSPEND: Suspend note, 0 for unsuspend, 1 for suspend" (defun gnosis-get-date-total-notes (&optional date) "Return total notes reviewed for DATE. +If entry for DATE does not exist, it will be created. + Defaults to current date." (cl-assert (listp date) nil "Date must be a list.") (let* ((date (or date (gnosis-algorithm-date))) - (note-num (car (gnosis-select 'note-num 'activity-log `(= date ',date) t)))) - (or note-num + (reviewed-total (car (gnosis-select 'reviewed-total 'activity-log `(= date ',date) t))) + (reviewed-new (or (car (gnosis-select 'reviewed-new 'activity-log `(= date ',date) t)) 0))) + (or reviewed-total (progn - (gnosis--insert-into 'activity-log `([,date 0])) + ;; Using reviewed-new instead of hardcoding 0 just to not mess up tests. + (and (equal date (gnosis-algorithm-date)) + (gnosis--insert-into 'activity-log `([,date 0 ,reviewed-new]))) 0)))) (defun gnosis-get-date-new-notes (&optional date) -- cgit v1.2.3 From b167f66799e83b0be874599b0e9979de9db7232a Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 23 Jul 2024 18:47:57 +0300 Subject: db-init: Update docstring. --- gnosis.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index f9a224a..bbb1826 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2171,7 +2171,7 @@ Return note ids for notes that match QUERY." (gnosis-select 'id 'notes clause t))) (defun gnosis-db-init () - "Create gnosis essential directories & database." + "Create essential directories & database." (let ((gnosis-curr-version (caar (emacsql gnosis-db (format "PRAGMA user_version"))))) (unless (length= (emacsql gnosis-db [:select name :from sqlite-master :where (= type table)]) 7) ;; Enable foreign keys -- cgit v1.2.3 From 5ee7502983a4f8d93b0d4c13630580edb9f73177 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Fri, 26 Jul 2024 17:59:50 +0300 Subject: packaging: Add transient 0.7.2. * Require transient. --- gnosis-dashboard.el | 3 ++- gnosis.el | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis-dashboard.el b/gnosis-dashboard.el index 96d4ffe..c89fd20 100644 --- a/gnosis-dashboard.el +++ b/gnosis-dashboard.el @@ -7,7 +7,7 @@ ;; URL: https://git.thanosapollo.org/gnosis ;; Version: 0.0.1 -;; Package-Requires: ((emacs "27.2") (compat "29.1.4.2")) +;; Package-Requires: ((emacs "27.2") (compat "29.1.4.2") (transient "0.7.2")) ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -29,6 +29,7 @@ ;;; Code: (require 'cl-lib) (require 'calendar) +(require 'transient) (declare-function gnosis-select "gnosis.el") (declare-function gnosis-delete-note "gnosis.el") diff --git a/gnosis.el b/gnosis.el index bbb1826..ac4c0f5 100644 --- a/gnosis.el +++ b/gnosis.el @@ -7,7 +7,7 @@ ;; URL: https://thanosapollo.org/projects/gnosis ;; Version: 0.3.2 -;; Package-Requires: ((emacs "27.2") (emacsql "20240124") (compat "29.1.4.2")) +;; Package-Requires: ((emacs "27.2") (emacsql "20240124") (compat "29.1.4.2") (transient "0.7.2")) ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -- cgit v1.2.3 From 015f2b692f7b986e3cc287f38f44a7806e40faa1 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 31 Jul 2024 10:29:08 +0300 Subject: New custom: review-new-first * When non-nil review new notes first during a gnosis review session. --- gnosis.el | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index ac4c0f5..a5a3e46 100644 --- a/gnosis.el +++ b/gnosis.el @@ -201,6 +201,13 @@ Seperate the question/stem from options." (integer :tag "Number")) :group 'gnosis) +(defcustom gnosis-review-new-first t + "Review new notes first. + +When nil, review new notes last." + :type 'bolean + :group 'gnosis) + (defvar gnosis-due-notes-total nil "Total due notes.") @@ -795,9 +802,7 @@ SUSPEND: Integer value of 1 or 0, where 1 suspends the card IMAGE: Image to display during review. SECOND-IMAGE: Image to display after user-input. -NOTE: If a gnosis--insert-into fails, the whole transaction will be - (or at least it should). Else there will be an error for foreign key - constraint." +If a gnosis--insert-into fails, the whole transaction will be." (let* ((deck-id (gnosis--get-deck-id deck)) (initial-interval (gnosis-get-deck-initial-interval deck-id)) (note-id (gnosis-generate-id))) @@ -1428,7 +1433,9 @@ well." t) when (gnosis-review-is-due-today-p note) collect note))) - (append (cl-subseq new-notes 0 gnosis-new-notes-limit) old-notes))) + (if gnosis-review-new-first + (append (cl-subseq new-notes 0 gnosis-new-notes-limit) old-notes) + (append old-notes (cl-subseq new-notes 0 gnosis-new-notes-limit))))) (defun gnosis-review-get-due-tags () "Return a list of due note tags." -- cgit v1.2.3 From 8a097b768ed456226bdeffaccd7f189c772fa513 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 31 Jul 2024 18:57:10 +0300 Subject: review-session: Add option to repeat for due notes. * Add optional argument DUE. * When due is non-nil, repeat for due notes. --- gnosis.el | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index a5a3e46..6c62413 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1720,7 +1720,7 @@ the review session." (gnosis-review-result note success) (gnosis-review-commit note-count) ;; Break the loop of `gnosis-review-session' - (throw 'stop-loop t)) + (throw 'review-loop t)) (defun gnosis-review-action--suspend (success note note-count) "Suspend/Unsuspend NOTE. @@ -1767,7 +1767,7 @@ To customize the keybindings, adjust `gnosis-review-keybindings'." ("edit" (gnosis-review-action--edit success note note-count)) ("quit" (gnosis-review-action--quit success note note-count))))) -(defun gnosis-review-session (notes) +(defun gnosis-review-session (notes &optional due) "Start review session for NOTES. NOTES: List of note ids" @@ -1775,14 +1775,17 @@ NOTES: List of note ids" (date (gnosis-algorithm-date))) (if (null notes) (message "No notes for review.") - (when (y-or-n-p (format "You have %s total notes for review, start session?" (length notes))) - (setf gnosis-review-notes notes) - (catch 'stop-loop - (cl-loop for note in notes - do (let ((success (gnosis-review-note note date))) - (cl-incf note-count) - (gnosis-review-actions success note note-count)) - finally (gnosis-review-commit note-count))))))) + (setf gnosis-review-notes notes) + (catch 'review-loop + (cl-loop for note in notes + do (let ((success (gnosis-review-note note date))) + (cl-incf note-count) + (gnosis-review-actions success note note-count)) + finally (gnosis-review-commit note-count) + ;; TODO: Add optional arg to repeat for specific deck/tag + ;; Repeat until there are no due notes + (and due (gnosis-review-session (gnosis-collect-note-ids :due t) t)))) + (gnosis-dashboard)))) ;;;###autoload (defun gnosis-review () @@ -1796,8 +1799,9 @@ NOTES: List of note ids" "Due notes of specified tag(s)" "All notes of tag(s)")))) (pcase review-type - ("Due notes" (gnosis-review-session (gnosis-collect-note-ids :due t))) - ("Due notes of deck" (gnosis-review-session (gnosis-collect-note-ids :due t :deck (gnosis--get-deck-id)))) + ("Due notes" (gnosis-review-session (gnosis-collect-note-ids :due t) t)) + ("Due notes of deck" (gnosis-review-session + (gnosis-collect-note-ids :due t :deck (gnosis--get-deck-id)))) ("Due notes of specified tag(s)" (gnosis-review-session (gnosis-collect-note-ids :due t :tags t))) ("All notes of deck" (gnosis-review-session (gnosis-collect-note-ids :deck (gnosis--get-deck-id)))) ("All notes of tag(s)" (gnosis-review-session (gnosis-collect-note-ids :tags t)))))) -- cgit v1.2.3 From 20a75f9ccee189c83ee75032801c1bd0d16271b4 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Fri, 2 Aug 2024 17:17:14 +0300 Subject: Adjust review commit messages. * Use note-count as optional argument for review session to be used with recursion. --- gnosis.el | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 6c62413..22683fb 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1674,14 +1674,14 @@ DATE: Date to log the note review on the activity-log." ;; Reopen gnosis-db after pull (setf gnosis-db (emacsql-sqlite-open (expand-file-name "gnosis.db" dir))))) -(defun gnosis-review-commit (note-num) +(defun gnosis-review-commit (note-count) "Commit review session on git repository. This function initializes the `gnosis-dir' as a Git repository if it is not already one. It then adds the gnosis.db file to the repository and commits the changes with a message containing the reviewed number of notes. -NOTE-NUM: The number of notes reviewed in the session." +NOTE-COUNT: The number of notes reviewed in the session to be commited." (let ((git (executable-find "git")) (default-directory gnosis-dir)) (unless git @@ -1692,10 +1692,11 @@ NOTE-NUM: The number of notes reviewed in the session." (unless gnosis-testing (shell-command (format "%s %s %s" git "add" (shell-quote-argument "gnosis.db"))) (shell-command (format "%s %s %s" git "commit -m" - (shell-quote-argument (format "Total notes for session: %d" note-num))))) + (shell-quote-argument + (format "Reviewed %d notes." note-count))))) (when (and gnosis-vc-auto-push (not gnosis-testing)) (gnosis-vc-push)) - (message "Review session finished. %d notes reviewed." note-num))) + (message "Review session finished."))) (defun gnosis-review-action--edit (success note note-count) "Edit NOTE during review. @@ -1767,11 +1768,13 @@ To customize the keybindings, adjust `gnosis-review-keybindings'." ("edit" (gnosis-review-action--edit success note note-count)) ("quit" (gnosis-review-action--quit success note note-count))))) -(defun gnosis-review-session (notes &optional due) +(defun gnosis-review-session (notes &optional due note-count) "Start review session for NOTES. -NOTES: List of note ids" - (let ((note-count 0) +NOTES: List of note ids +DUE: If due is non-nil, session will loop for due notes. +NOTE-COUNT: Total notes to be commited for session." + (let ((note-count (or note-count 0)) (date (gnosis-algorithm-date))) (if (null notes) (message "No notes for review.") @@ -1781,11 +1784,12 @@ NOTES: List of note ids" do (let ((success (gnosis-review-note note date))) (cl-incf note-count) (gnosis-review-actions success note note-count)) - finally (gnosis-review-commit note-count) + finally ;; TODO: Add optional arg to repeat for specific deck/tag ;; Repeat until there are no due notes - (and due (gnosis-review-session (gnosis-collect-note-ids :due t) t)))) - (gnosis-dashboard)))) + (and due (gnosis-review-session (gnosis-collect-note-ids :due t) t note-count)))) + (gnosis-dashboard) + (gnosis-review-commit note-count)))) ;;;###autoload (defun gnosis-review () -- cgit v1.2.3 From ba119ccb4d4cf07dc30e4a99bc9bef1ded8827af Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Sat, 3 Aug 2024 19:26:51 +0300 Subject: New function: get-note-deck-name. --- gnosis.el | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 22683fb..6c9e88d 100644 --- a/gnosis.el +++ b/gnosis.el @@ -706,6 +706,11 @@ Set SPLIT to t to split all input given." "Return id for DECK name." (gnosis-get 'id 'decks `(= name ,deck))) +(defun gnosis-get-note-deck-name (id) + "Return deck name of note ID." + (let ((deck (gnosis-get 'deck-id 'notes `(= id ,id)))) + (gnosis--get-deck-name deck))) + (defun gnosis-get-deck--note (id &optional name) "Get deck id for note ID. -- cgit v1.2.3 From 06eafd6979c5fb91fa74686286556dce56fd4dd5 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 20:30:22 +0300 Subject: delete-note: Add verification optional arg * Optionally skip verification. --- gnosis.el | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 6c9e88d..90a2f3c 100644 --- a/gnosis.el +++ b/gnosis.el @@ -331,9 +331,11 @@ Example: "From TABLE use where to delete VALUE." (emacsql gnosis-db `[:delete :from ,table :where ,value])) -(defun gnosis-delete-note (id) - "Delete note with ID." - (when (y-or-n-p "Delete note?") +(defun gnosis-delete-note (id &optional verification) + "Delete note with ID. + +When VERIFICATION is non-nil, skip `y-or-n-p' prompt." + (when (or verification (y-or-n-p "Delete note?")) (emacsql-with-transaction gnosis-db (gnosis--delete 'notes `(= id ,id))))) (defun gnosis-delete-deck (&optional id) -- cgit v1.2.3 From 6d0852e3cfd9bec67536c6d2c502961f332ca5a4 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 20:33:24 +0300 Subject: fix indetation & style --- gnosis.el | 78 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 39 insertions(+), 39 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 90a2f3c..f513df1 100644 --- a/gnosis.el +++ b/gnosis.el @@ -398,22 +398,22 @@ Acts only when CENTER? is t." (let ((window-width (window-width)) (center? (or center? gnosis-center-content-p))) (if center? - (mapconcat - (lambda (line) - (let* ((text (string-trim line)) - (wrapped (with-temp-buffer - (insert text) - (fill-region (point-min) (point-max)) - (buffer-string))) - (lines (split-string wrapped "\n"))) - (mapconcat - (lambda (line) - (let ((padding (max (/ (- window-width (length line)) 2) 0))) - (concat (make-string padding ? ) line))) - lines - "\n"))) - (split-string input-string "\n") - "\n") + (mapconcat + (lambda (line) + (let* ((text (string-trim line)) + (wrapped (with-temp-buffer + (insert text) + (fill-region (point-min) (point-max)) + (buffer-string))) + (lines (split-string wrapped "\n"))) + (mapconcat + (lambda (line) + (let ((padding (max (/ (- window-width (length line)) 2) 0))) + (concat (make-string padding ? ) line))) + lines + "\n"))) + (split-string input-string "\n") + "\n") input-string))) (defun gnosis-apply-center-buffer-overlay (&optional point) @@ -566,7 +566,7 @@ When SUCCESS nil, display USER-INPUT as well" ;; Insert user wrong answer (when (not success) (insert "\n" - (propertize "Your answer:" 'face 'gnosis-face-directions) + (propertize "Your answer:" 'face 'gnosis-face-directions) " " (propertize user-input 'face 'gnosis-face-false)) (gnosis-center-current-line))) @@ -641,12 +641,12 @@ inserted in the buffer. Also see `gnosis-string-edit'." (gnosis-string-edit prompt string - (lambda (edited) - (setq string (substring-no-properties edited)) - (exit-recursive-edit)) - :abort-callback (lambda () - (exit-recursive-edit) - (error "Aborted edit"))) + (lambda (edited) + (setq string (substring-no-properties edited)) + (exit-recursive-edit)) + :abort-callback (lambda () + (exit-recursive-edit) + (error "Aborted edit"))) (recursive-edit) string) @@ -687,14 +687,14 @@ Set SPLIT to t to split all input given." (defun gnosis-add-deck (name) "Create deck with NAME." (interactive (list (read-string "Deck Name: "))) - (when gnosis-testing - (unless (y-or-n-p "You are using a testing environment! Continue?") - (error "Aborted"))) - (if (gnosis-get 'name 'decks `(= name ,name)) - (error "Deck `%s' already exists" name) - (let ((deck-id (gnosis-generate-id 5 t))) - (gnosis--insert-into 'decks `([,deck-id ,name nil nil nil nil nil])) - (message "Created deck '%s'" name)))) + (when gnosis-testing + (unless (y-or-n-p "You are using a testing environment! Continue?") + (error "Aborted"))) + (if (gnosis-get 'name 'decks `(= name ,name)) + (error "Deck `%s' already exists" name) + (let ((deck-id (gnosis-generate-id 5 t))) + (gnosis--insert-into 'decks `([,deck-id ,name])) + (message "Created deck '%s'" name)))) (defun gnosis--get-deck-name (&optional id) "Get deck name for ID, or prompt for deck name when ID is nil." @@ -1146,11 +1146,11 @@ TYPE: Type of gnosis note, must be one of `gnosis-note-types'" (defun gnosis-cloze-check (sentence clozes) "Check if CLOZES are found in SENTENCE." - (catch 'not-found - (dolist (cloze clozes) - (unless (string-match-p cloze sentence) - (throw 'not-found nil))) - t)) + (catch 'not-found + (dolist (cloze clozes) + (unless (string-match-p cloze sentence) + (throw 'not-found nil))) + t)) (defun gnosis-cloze-remove-tags (string) "Replace cloze tags and hints in STRING. @@ -1182,7 +1182,7 @@ Valid cloze formats include: (nreverse result-alist)))) (defun gnosis-cloze-extract-answers (nested-lst) - "Extract cloze answers for string clozes inside the NESTED-LST. + "Extract cloze answers for string clozes inside the NESTED-LST. This function should be used in combination with `gnosis-cloze-extract-answers'." (mapcar (lambda (lst) @@ -1251,11 +1251,11 @@ Optionally, add cusotm PROMPT." (let* ((prompt (or prompt "Select image: ")) (image (if (y-or-n-p "Add review image?") (gnosis-completing-read prompt - (cons nil (gnosis-directory-files gnosis-images-dir))) + (cons nil (gnosis-directory-files gnosis-images-dir))) nil)) (extra-image (if (y-or-n-p "Add post review image?") (gnosis-completing-read prompt - (cons nil (gnosis-directory-files gnosis-images-dir)))))) + (cons nil (gnosis-directory-files gnosis-images-dir)))))) (cons image extra-image)) nil)) -- cgit v1.2.3 From 05cfba7d4edfab7822a9cdd59cbfcd7d54fc1cd2 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 20:33:48 +0300 Subject: get-note-deck-name: Return nil if deck-id does not exist. * Return nil if neck does not exist. This is meant to make testing easier. --- gnosis.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index f513df1..bb91de3 100644 --- a/gnosis.el +++ b/gnosis.el @@ -711,7 +711,7 @@ Set SPLIT to t to split all input given." (defun gnosis-get-note-deck-name (id) "Return deck name of note ID." (let ((deck (gnosis-get 'deck-id 'notes `(= id ,id)))) - (gnosis--get-deck-name deck))) + (and deck (gnosis--get-deck-name deck)))) (defun gnosis-get-deck--note (id &optional name) "Get deck id for note ID. -- cgit v1.2.3 From dee5ed194c45de6a8c376c28f1b7728cbe1d0982 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 20:34:52 +0300 Subject: Remove get-deck-ff & get-note-ff. * ff usage is deprecated. --- gnosis.el | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index bb91de3..ab46e26 100644 --- a/gnosis.el +++ b/gnosis.el @@ -721,20 +721,6 @@ If NAME is t, return name of deck." (deck (gnosis-get 'deck-id 'notes id-clause))) (if name (gnosis--get-deck-name deck) deck))) -(defun gnosis-get-deck-ff (id) - "Return failure factor for deck of ID." - (let* ((id-clause `(= id ,id)) - (deck-ff (gnosis-get 'failure-factor 'decks id-clause))) - deck-ff)) - -(defun gnosis-get-note-ff (id) - "Return failure factor for note ID." - (let ((deck-ff (gnosis-get-deck-ff (gnosis-get-deck--note id))) - (note-ff (gnosis-get 'ff 'review `(= id ,id)))) - (if (and deck-ff (> deck-ff note-ff)) - deck-ff - note-ff))) - (cl-defun gnosis-suspend-note (id) "Suspend note with ID." (let ((suspended (= (gnosis-get 'suspend 'review-log `(= id ,id)) 1))) -- cgit v1.2.3 From 2a41bcba72847481584f118a9b1a4b1862d3bb31 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 20:36:10 +0300 Subject: suspend-note: Add verification optional arg. * Optionally, skin verification y-or-n-p promtp. --- gnosis.el | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index ab46e26..3e0049a 100644 --- a/gnosis.el +++ b/gnosis.el @@ -721,10 +721,13 @@ If NAME is t, return name of deck." (deck (gnosis-get 'deck-id 'notes id-clause))) (if name (gnosis--get-deck-name deck) deck))) -(cl-defun gnosis-suspend-note (id) - "Suspend note with ID." - (let ((suspended (= (gnosis-get 'suspend 'review-log `(= id ,id)) 1))) - (when (y-or-n-p (if suspended "Unsuspend note? " "Suspend note? ")) +(cl-defun gnosis-suspend-note (id &optional verification) + "Suspend note with ID. + +When VERIFICATION is non-nil, skips `y-or-n-p' prompt." + (let* ((suspended (= (gnosis-get 'suspend 'review-log `(= id ,id)) 1)) + (verification (or verification (y-or-n-p (if suspended "Unsuspend note? " "Suspend note? "))))) + (when verification (if suspended (gnosis-update 'review-log '(= suspend 0) `(= id ,id)) (gnosis-update 'review-log '(= suspend 1) `(= id ,id)))))) -- cgit v1.2.3 From 75e073baefb3b13337d91990762f1eeda66b89c2 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 20:39:19 +0300 Subject: New database: Add db-update-v3. * Storing of deck specific values now will be done using global variables, now in addition with tags. * Remove deprecated sm2 like nomeclature and use gnosis new variables. --- gnosis.el | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 3e0049a..b092be2 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2180,6 +2180,22 @@ Return note ids for notes that match QUERY." `(like main ,(format "%%%s%%" word))) words)))) (gnosis-select 'id 'notes clause t))) +(defun gnosis-db-update-v3 () + "Upgrade database to version 3." + (emacsql-with-transaction gnosis-db + (emacsql gnosis-db [:alter-table decks :drop-column failure-factor]) + (emacsql gnosis-db [:alter-table decks :drop-column ef-increase]) + (emacsql gnosis-db [:alter-table decks :drop-column ef-threshold]) + (emacsql gnosis-db [:alter-table decks :drop-column ef-decrease]) + (emacsql gnosis-db [:alter-table decks :drop-column initial-interval]) + ;; Review changes + (emacsql gnosis-db [:alter-table review :rename ef :to gnosis]) + (emacsql gnosis-db [:alter-table review :rename ff :to amnesia]) + (emacsql gnosis-db [:alter-table review :drop-column interval]) + ;; Add activity log + (gnosis--create-table 'activity-log gnosis-db-schema-activity-log) + ;; Update version + (emacsql gnosis-db (format "PRAGMA user_version = %s" gnosis-db-version)))) (defun gnosis-db-init () "Create essential directories & database." -- cgit v1.2.3 From 176404ccadce3dcce1e8f8c5b08449f558275865 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 20:40:44 +0300 Subject: db-init: Update to v3. --- gnosis.el | 47 +++++++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 28 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index b092be2..610e3a4 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2201,35 +2201,26 @@ Return note ids for notes that match QUERY." "Create essential directories & database." (let ((gnosis-curr-version (caar (emacsql gnosis-db (format "PRAGMA user_version"))))) (unless (length= (emacsql gnosis-db [:select name :from sqlite-master :where (= type table)]) 7) - ;; Enable foreign keys - (emacsql gnosis-db "PRAGMA foreign_keys = ON") - ;; Gnosis version - (emacsql gnosis-db (format "PRAGMA user_version = %s" gnosis-db-version)) - ;; Create decks table - (gnosis--create-table 'decks gnosis-db-schema-decks) - ;; Create notes table - (gnosis--create-table 'notes gnosis-db-schema-notes) - ;; Create review table - (gnosis--create-table 'review gnosis-db-schema-review) - ;; Create review-log table - (gnosis--create-table 'review-log gnosis-db-schema-review-log) - ;; Create extras table - (gnosis--create-table 'extras gnosis-db-schema-extras) - ;; Create activity-log table - (gnosis--create-table 'activity-log gnosis-db-schema-activity-log)) + (emacsql-with-transaction gnosis-db + ;; Enable foreign keys + (emacsql gnosis-db "PRAGMA foreign_keys = ON") + ;; Gnosis version + (emacsql gnosis-db (format "PRAGMA user_version = %s" gnosis-db-version)) + ;; Create decks table + (gnosis--create-table 'decks gnosis-db-schema-decks) + ;; Create notes table + (gnosis--create-table 'notes gnosis-db-schema-notes) + ;; Create review table + (gnosis--create-table 'review gnosis-db-schema-review) + ;; Create review-log table + (gnosis--create-table 'review-log gnosis-db-schema-review-log) + ;; Create extras table + (gnosis--create-table 'extras gnosis-db-schema-extras) + ;; Create activity-log table + (gnosis--create-table 'activity-log gnosis-db-schema-activity-log))) ;; Update database schema for version - (cond ((= gnosis-curr-version 1) ;; Update from version 1 to version 3 - (emacsql gnosis-db [:alter-table decks :add failure-factor]) - (emacsql gnosis-db [:alter-table decks :add ef-increase]) - (emacsql gnosis-db [:alter-table decks :add ef-decrease]) - (emacsql gnosis-db [:alter-table decks :add ef-threshold]) - (emacsql gnosis-db [:alter-table decks :add initial-interval]) - (emacsql gnosis-db (format "PRAGMA user_version = %s" gnosis-db-version)) - (gnosis--create-table 'activity-log gnosis-db-schema-activity-log)) - ;; Update from version 2 to 3 - ((= gnosis-curr-version 2) - (gnosis--create-table 'activity-log gnosis-db-schema-activity-log) - (emacsql gnosis-db (format "PRAGMA user_version = %s" gnosis-db-version)))))) + (cond ((<= gnosis-curr-version 2) + (gnosis-db-update-v3))))) (gnosis-db-init) -- cgit v1.2.3 From e1eec6efc7cb1b15a800dd0ad25e0f7df3a6eddc Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 20:41:08 +0300 Subject: db: Add v2 function. * Storing v2 update function for users that have not updated to v2. --- gnosis.el | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 610e3a4..1348123 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2180,6 +2180,19 @@ Return note ids for notes that match QUERY." `(like main ,(format "%%%s%%" word))) words)))) (gnosis-select 'id 'notes clause t))) +(defun gnosis-db-update-v2 () + "Update to first gnosis-db version." + (emacsql-with-transaction gnosis-db + (emacsql gnosis-db [:alter-table decks :add failure-factor]) + (emacsql gnosis-db [:alter-table decks :add ef-increase]) + (emacsql gnosis-db [:alter-table decks :add ef-decrease]) + (emacsql gnosis-db [:alter-table decks :add ef-threshold]) + (emacsql gnosis-db [:alter-table decks :add initial-interval]) + (emacsql gnosis-db (format "PRAGMA user_version = 2")) + (gnosis--create-table 'activity-log gnosis-db-schema-activity-log) + ;; Update to most recent gnosis db version. + (gnosis-db-update-v3))) + (defun gnosis-db-update-v3 () "Upgrade database to version 3." (emacsql-with-transaction gnosis-db -- cgit v1.2.3 From 920189bbf57de50feb568131df8440d38657a423 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 20:41:55 +0300 Subject: demo: style. --- gnosis.el | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 1348123..cc931b2 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2294,33 +2294,33 @@ If STRING-SECTION is nil, apply FACE to the entire STRING." (if (not (cl-some #'(lambda (x) (member "demo" x)) (gnosis-select 'name 'decks))) (progn (gnosis-add-deck deck-name) (gnosis-add-note--basic :deck deck-name - :question "Repetitio est mater memoriae" - :hint "Translate this Latin phrase to English." - :answer "Repetition is the mother of memory" - :extra "/Regular review/ at increasing intervals *reinforces* *memory* *retention*. Strengthening neural connections & making it easier to recall information long-term" + :question "Repetitio est mater memoriae" + :hint "Translate this Latin phrase to English." + :answer "Repetition is the mother of memory" + :extra "/Regular review/ at increasing intervals *reinforces* *memory* *retention*. Strengthening neural connections & making it easier to recall information long-term" + :tags note-tags) + (gnosis-add-note--mc-cloze :deck deck-name + :question "Consistency is _key_ to using gnosis effectively." + :options '("Consistency" "Procrastination" "Incosistency") + :answer "Consistency" + :extra "Avoid monotony, try to engage with the material actively, and stay _consistent_!" + :tags note-tags) + (gnosis-add-note--mcq :deck deck-name + :question "Which one is the capital of Greece?" + :choices '("Athens" "Sparta" "Rome" "Berlin") + :correct-answer 1 + :extra "Athens (Αθήνα) is the largest city of Greece & one of the world's oldest cities, with it's recorded history spanning over 3,500 years." :tags note-tags) - (gnosis-add-note--mc-cloze :deck deck-name - :question "Consistency is _key_ to using gnosis effectively." - :options '("Consistency" "Procrastination" "Incosistency") - :answer "Consistency" - :extra "Avoid monotony, try to engage with the material actively, and stay _consistent_!" - :tags note-tags) - (gnosis-add-note--mcq :deck deck-name - :question "Which one is the capital of Greece?" - :choices '("Athens" "Sparta" "Rome" "Berlin") - :correct-answer 1 - :extra "Athens (Αθήνα) is the largest city of Greece & one of the world's oldest cities, with it's recorded history spanning over 3,500 years." - :tags note-tags) - (gnosis-add-note--cloze :deck deck-name - :note "GNU Emacs is an extensible editor created by {{c1::Richard}} {{c1::Stallman}} in {{c2::1984::year}}" - :tags note-tags - :extra "Emacs was originally implemented in 1976 on the MIT AI Lab's Incompatible Timesharing System (ITS), as a collection of TECO macros. The name “Emacs” was originally chosen as an abbreviation of “Editor MACroS”. =This version of Emacs=, GNU Emacs, was originally *written in 1984*") - (gnosis-add-note--y-or-n :deck deck-name - :question "Is GNU Emacs the greatest program ever written?" - :hint "Duh" - :answer 121 - :extra "" - :tags note-tags)) + (gnosis-add-note--cloze :deck deck-name + :note "GNU Emacs is an extensible editor created by {{c1::Richard}} {{c1::Stallman}} in {{c2::1984::year}}" + :tags note-tags + :extra "Emacs was originally implemented in 1976 on the MIT AI Lab's Incompatible Timesharing System (ITS), as a collection of TECO macros. The name “Emacs” was originally chosen as an abbreviation of “Editor MACroS”. =This version of Emacs=, GNU Emacs, was originally *written in 1984*") + (gnosis-add-note--y-or-n :deck deck-name + :question "Is GNU Emacs the greatest program ever written?" + :hint "Duh" + :answer 121 + :extra "" + :tags note-tags)) (error "Demo deck already exists")))) ;; Gnosis mode ;; -- cgit v1.2.3 From 8473e27447ea28f6fd95069583cd8cecab966e62 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 20:42:33 +0300 Subject: Remove old comments & update indentation. --- gnosis.el | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index cc931b2..79dd73b 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2251,12 +2251,12 @@ If STRING-SECTION is nil, apply FACE to the entire STRING." (goto-char (point-min)) (animate-string string vpos hpos) (and face - (if string-section - (progn - (goto-char (point-min)) - (while (search-forward string-section nil t) - (add-text-properties (match-beginning 0) (match-end 0) `(face ,face)))) - (add-text-properties (line-beginning-position) (line-end-position) `(face ,face)))))) + (if string-section + (progn + (goto-char (point-min)) + (while (search-forward string-section nil t) + (add-text-properties (match-beginning 0) (match-end 0) `(face ,face)))) + (add-text-properties (line-beginning-position) (line-end-position) `(face ,face)))))) ;;;###autoload (defun gnosis-demo () @@ -2332,18 +2332,18 @@ If STRING-SECTION is nil, apply FACE to the entire STRING." :global t :group 'gnosis :lighter nil - (setq gnosis-due-notes-total (length (gnosis-review-get-due-notes))) - (if gnosis-modeline-mode - (progn - (add-to-list 'global-mode-string '(:eval - (format " G:%d" gnosis-due-notes-total))) - (force-mode-line-update)) - (setq global-mode-string - (seq-remove (lambda (item) - (and (listp item) (eq (car item) :eval) - (string-prefix-p " G:" (format "%s" (eval (cadr item)))))) - global-mode-string)) - (force-mode-line-update))) + (setq gnosis-due-notes-total (length (gnosis-review-get-due-notes))) + (if gnosis-modeline-mode + (progn + (add-to-list 'global-mode-string '(:eval + (format " G:%d" gnosis-due-notes-total))) + (force-mode-line-update)) + (setq global-mode-string + (seq-remove (lambda (item) + (and (listp item) (eq (car item) :eval) + (string-prefix-p " G:" (format "%s" (eval (cadr item)))))) + global-mode-string)) + (force-mode-line-update))) (define-derived-mode gnosis-mode special-mode "Gnosis" "Gnosis Mode." -- cgit v1.2.3 From 3435bd162059ebe8329a52dc6cf763a7fd81fcf1 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 20:43:03 +0300 Subject: search-note: Now searches for answer as well. --- gnosis.el | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 79dd73b..c68a4f3 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2176,10 +2176,15 @@ Return note ids for notes that match QUERY." (cl-assert (or (stringp query) (eq query nil))) (let* ((query (or query (read-string "Search for note: "))) (words (split-string query)) - (clause `(and ,@(mapcar (lambda (word) - `(like main ,(format "%%%s%%" word))) - words)))) - (gnosis-select 'id 'notes clause t))) + (clause-main `(and ,@(mapcar (lambda (word) + `(like main ,(format "%%%s%%" word))) + words))) + (clause-answer `(and ,@(mapcar (lambda (word) + `(like answer ,(format "%%%s%%" word))) + words)))) + (append (gnosis-select 'id 'notes clause-main t) + (gnosis-select 'id 'notes clause-answer t)))) + (defun gnosis-db-update-v2 () "Update to first gnosis-db version." (emacsql-with-transaction gnosis-db -- cgit v1.2.3 From b7ce3f2fb8a8d74478f076b0dac12a5e95c47932 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 20:43:24 +0300 Subject: schemas: Update all schemas to v3. --- gnosis.el | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index c68a4f3..b962b42 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2111,12 +2111,7 @@ to improve readability." ;;; Database Schemas (defvar gnosis-db-schema-decks '([(id integer :primary-key :autoincrement) - (name text :not-null) - (failure-factor float) - (ef-increase float) - (ef-decrease float) - (ef-threshold integer) - (initial-interval listp)])) + (name text :not-null)])) (defvar gnosis-db-schema-notes '([(id integer :primary-key :autoincrement) (type text :not-null) @@ -2129,19 +2124,18 @@ to improve readability." :on-delete :cascade))) (defvar gnosis-db-schema-review '([(id integer :primary-key :not-null) ;; note-id - (ef integer :not-null) ;; Easiness factor - (ff integer :not-null) ;; Forgetting factor - (interval integer :not-null)] ;; Initial Interval + (gnosis integer :not-null) + (amnesia integer :not-null)] (:foreign-key [id] :references notes [id] :on-delete :cascade))) (defvar gnosis-db-schema-review-log '([(id integer :primary-key :not-null) ;; note-id (last-rev integer :not-null) ;; Last review date (next-rev integer :not-null) ;; Next review date - (c-success integer :not-null) ;; number of consecutive successful reviews - (t-success integer :not-null) ;; Number of total successful reviews - (c-fails integer :not-null) ;; Number of consecutive failed reviewss - (t-fails integer :not-null) ;; Number of total failed reviews + (c-success integer :not-null) ;; Consecutive successful reviews + (t-success integer :not-null) ;; Total successful reviews + (c-fails integer :not-null) ;; Consecutive failed reviewss + (t-fails integer :not-null) ;; Total failed reviews (suspend integer :not-null) ;; Binary value, 1=suspended (n integer :not-null)] ;; Number of reviews (:foreign-key [id] :references notes [id] @@ -2153,13 +2147,6 @@ to improve readability." (defvar gnosis-db-schema-extras '([(id integer :primary-key :not-null) (extra-notes string) - ;; Despite the name 'images', this - ;; is a single string value. At - ;; first it was designed to hold a - ;; list of strings for image paths, - ;; but it was changed to just a - ;; string to hold a single image - ;; path. (images string) ;; Extra image path to show after review (extra-image string)] -- cgit v1.2.3 From d408048f64cde226c23397014fa114e9d7e5657c Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 20:43:46 +0300 Subject: export-note: Update to new gnosis variable values. --- gnosis.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index b962b42..3e27862 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2095,9 +2095,10 @@ The final exported note is indented using the `indent-region' function to improve readability." (let ((values (append (gnosis-select '[id main options answer tags] 'notes `(= id ,id) t) (gnosis-select '[extra-notes images extra-image] 'extras `(= id ,id) t) - (gnosis-select '[ef ff] 'review `(= id ,id) t) + (gnosis-select '[gnosis amnesia] 'review `(= id ,id) t) (gnosis-select 'suspend 'review-log `(= id ,id) t))) - (fields '(:id :main :options :answer :tags :extra-notes :image :second-image :ef :ff :suspend))) + (fields (list :id :main :options :answer :tags + :extra-notes :image :second-image :gnosis :amnesia :suspend))) (when export-for-deck (setf values (append (gnosis-select 'type 'notes `(= id ,id) t) (butlast (cdr values) 3))) -- cgit v1.2.3 From 0314d6af05bc1d9d2374ec71173ec7759ee954d5 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 20:44:07 +0300 Subject: Remove functions for recovering deprecated db variables. --- gnosis.el | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 3e27862..d104d1e 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2016,30 +2016,6 @@ SUSPEND: Suspend note, 0 for unsuspend, 1 for suspend" (gnosis-update 'notes `(= ,field ',value) `(= id ,id))) (t (gnosis-update 'notes `(= ,field ,value) `(= id ,id)))))) -(defun gnosis-get-ef-increase (id) - "Return ef-increase for note with value of id ID." - (let ((ef-increase (gnosis-get 'ef-increase 'decks `(= id ,(gnosis-get 'deck-id 'notes `(= id ,id)))))) - (or ef-increase gnosis-algorithm-ef-increase))) - -(defun gnosis-get-ef-decrease (id) - "Return ef-decrease for note with value of id ID." - (let ((ef-decrease (gnosis-get 'ef-decrease 'decks `(= id ,(gnosis-get 'deck-id 'notes `(= id ,id)))))) - (or ef-decrease gnosis-algorithm-ef-decrease))) - -(defun gnosis-get-ef-threshold (id) - "Return ef-threshold for note with value of id ID." - (let ((ef-threshold (gnosis-get 'ef-threshold 'decks `(= id ,(gnosis-get 'deck-id 'notes `(= id ,id)))))) - (or ef-threshold gnosis-algorithm-ef-threshold))) - -(defun gnosis-get-deck-initial-interval (id) - "Return initial-interval for notes of deck ID." - (let ((initial-interval (gnosis-get 'initial-interval 'decks `(= id ,id)))) - (or initial-interval gnosis-algorithm-interval))) - -(defun gnosis-get-note-initial-interval (id) - "Return initial-interval for note with ID." - (let ((deck-id (gnosis-get 'deck-id 'notes `(= id ,id)))) - (gnosis-get-deck-initial-interval deck-id))) (defun gnosis-get-date-total-notes (&optional date) "Return total notes reviewed for DATE. -- cgit v1.2.3 From cc2ec22d5a8d75568cffd0a8763f8fc19106e108 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 20:44:59 +0300 Subject: New variable: Add custom-values. * Specify review values specific for decks & tags. --- gnosis.el | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index d104d1e..3a021fe 100644 --- a/gnosis.el +++ b/gnosis.el @@ -214,6 +214,11 @@ When nil, review new notes last." (defvar gnosis-review-notes nil "Review notes.") +(defvar gnosis-custom-values + '((:deck "demo" (:proto (0 1 3) :anagnsois 3 :epignosis 0.5 :agnoia 0.3 :amnesia 0.5 :lethe 3)) + (:tag "demo" (:proto (1 2) :anagnosis 3 :epignosis 0.5 :agnoia 0.3 :amnesia 0.45 :lethe 3))) + "Custom review values for adjusting gnosis algorithm.") + ;;; Faces (defgroup gnosis-faces nil -- cgit v1.2.3 From 8a857c2e7b0935d5f6213525bef027a4ea097ef8 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 20:45:57 +0300 Subject: New function: get-tag-notes. * Return note-ids for TAG. --- gnosis.el | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 3a021fe..1496d1e 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1271,6 +1271,11 @@ If DUE, return only due notes." (if due (gnosis-review-is-due-p id) t)) collect id)) +(defun gnosis-get-tag-notes (tag) + "Return note ids for TAG." + (let ((notes (gnosis-select 'id 'notes `(like tags ',(format "%%\"%s\"%%" tag)) t))) + notes)) + (defun gnosis-suspended-p (id) "Return t if note with ID is suspended." (= (gnosis-get 'suspend 'review-log `(= id ,id)) 1)) -- cgit v1.2.3 From 44964c8cba68750e2f53d3d9d86a3506cfaed611 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 23:38:34 +0300 Subject: add-note-fields: Update new algorithm values. --- gnosis.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 1496d1e..2e0e508 100644 --- a/gnosis.el +++ b/gnosis.el @@ -805,12 +805,12 @@ SECOND-IMAGE: Image to display after user-input. If a gnosis--insert-into fails, the whole transaction will be." (let* ((deck-id (gnosis--get-deck-id deck)) - (initial-interval (gnosis-get-deck-initial-interval deck-id)) (note-id (gnosis-generate-id))) (emacsql-with-transaction gnosis-db ;; Refer to `gnosis-db-schema-SCHEMA' e.g `gnosis-db-schema-review-log' (gnosis--insert-into 'notes `([,note-id ,type ,main ,options ,answer ,tags ,deck-id])) - (gnosis--insert-into 'review `([,note-id ,gnosis-algorithm-ef ,gnosis-algorithm-ff ,initial-interval])) + (gnosis--insert-into 'review `([,note-id ,gnosis-algorithm-gnosis-value + ,gnosis-algorithm-amnesia-value])) (gnosis--insert-into 'review-log `([,note-id ,(gnosis-algorithm-date) ,(gnosis-algorithm-date) 0 0 0 0 ,suspend 0])) (gnosis--insert-into 'extras `([,note-id ,extra ,image ,second-image]))))) -- cgit v1.2.3 From 1e31ca88420f7039d8cbf3b728fce2416db1b5ea Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 23:39:20 +0300 Subject: select-by-tag: Add arg to filter for suspended --- gnosis.el | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 2e0e508..dcbdc68 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1258,16 +1258,17 @@ Optionally, add cusotm PROMPT." (cl-loop for tags in (gnosis-select 'tags 'notes '1=1 t) nconc tags into all-tags finally return (delete-dups all-tags))) - -(defun gnosis-select-by-tag (input-tags &optional due) +;; TODO: Rewrite this using `gnosis-get-tag-notes'. +(defun gnosis-select-by-tag (input-tags &optional due suspended-p) "Return note ID's for every note with INPUT-TAGS. -If DUE, return only due notes." +If DUE, return only due notes. +If SUSPENDED-P, return suspended notes as well." (cl-assert (listp input-tags) t "Input tags must be a list") (cl-assert (booleanp due) "Due value must be a boolean") (cl-loop for (id tags) in (gnosis-select '[id tags] 'notes) when (and (cl-every (lambda (tag) (member tag tags)) input-tags) - (not (gnosis-suspended-p id)) + (or (not suspended-p) (not (gnosis-suspended-p id))) (if due (gnosis-review-is-due-p id) t)) collect id)) -- cgit v1.2.3 From 3838eeee00e23b6ee246d554d3e541f4c6c84714 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 23:41:12 +0300 Subject: review-algorithm: Update to new algorithm. --- gnosis.el | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index dcbdc68..3909f70 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1466,13 +1466,13 @@ well." (max (gnosis-algorithm-date-diff last-rev rev-date) 1))) (defun gnosis-review-algorithm (id success) - "Return next review date & ef for note with value of id ID. + "Return next review date & gnosis for note with value of id ID. SUCCESS is a boolean value, t for success, nil for failure. Returns a list of the form ((yyyy mm dd) (ef-increase ef-decrease ef-total))." - (let ((ff (gnosis-get-note-ff id)) - (ef (gnosis-get 'ef 'review `(= id ,id))) + (let ((amnesia (gnosis-get-note-amnesia id)) + (gnosis (gnosis-get 'gnosis 'review `(= id ,id))) (t-success (gnosis-get 't-success 'review-log `(= id ,id))) ;; total successful reviews (c-success (gnosis-get 'c-success 'review-log `(= id ,id))) ;; consecutive successful reviews (c-fails (gnosis-get 'c-fails 'review-log `(= id ,id))) ;; consecutive failed reviews @@ -1480,21 +1480,24 @@ Returns a list of the form ((yyyy mm dd) (ef-increase ef-decrease ef-total))." ;; (review-num (gnosis-get 'n 'review-log `(= id ,id))) ;; total reviews ;; (last-interval (max (gnosis-review--get-offset id) 1)) (last-interval (gnosis-review-last-interval id))) ;; last interval - (list (gnosis-algorithm-next-interval :last-interval last-interval - :ef (nth 2 ef) ;; total ef is used for next interval - :success success - :successful-reviews t-success - :c-fails c-fails - :threshold 3 ;;TODO: Create a gnosis-interval-thershold - :failure-factor ff - :initial-interval (gnosis-get-note-initial-interval id)) - (gnosis-algorithm-next-ef :ef ef - :success success - :increase (gnosis-get-ef-increase id) - :decrease (gnosis-get-ef-decrease id) - :threshold (gnosis-get-ef-threshold id) - :c-successes c-success - :c-failures c-fails)))) + (list + (gnosis-algorithm-next-interval + :last-interval last-interval + :gnosis-synolon (nth 2 gnosis) + :success success + :successful-reviews t-success + :c-fails c-fails + :lethe (gnosis-get-note-lethe id) + :amnesia amnesia + :proto (gnosis-get-note-proto id)) + (gnosis-algorithm-next-gnosis + :gnosis gnosis + :success success + :epignosis (gnosis-get-note-epignosis id) + :agnoia (gnosis-get-note-agnoia id) + :anagnosis (gnosis-get-note-anagnosis id) + :c-successes c-success + :c-failures c-fails)))) (defun gnosis-review--update (id success) "Update review-log for note with value of id ID. -- cgit v1.2.3 From 01aace1dce44fe589ab895c41eb612a5d1140731 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 23:42:06 +0300 Subject: review--update: Update to new db values. --- gnosis.el | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 3909f70..d4d229d 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1503,7 +1503,7 @@ Returns a list of the form ((yyyy mm dd) (ef-increase ef-decrease ef-total))." "Update review-log for note with value of id ID. SUCCESS is a boolean value, t for success, nil for failure." - (let ((ef (cadr (gnosis-review-algorithm id success))) + (let ((gnosis (cadr (gnosis-review-algorithm id success))) (next-rev (car (gnosis-review-algorithm id success)))) ;; Update activity-log (gnosis-review-increment-activity-log (gnosis-review-is-note-new-p id)) @@ -1512,15 +1512,19 @@ SUCCESS is a boolean value, t for success, nil for failure." (gnosis-update 'review-log `(= next-rev ',next-rev) `(= id ,id)) (gnosis-update 'review-log `(= n (+ 1 ,(gnosis-get 'n 'review-log `(= id ,id)))) `(= id ,id)) ;; Update review - (gnosis-update 'review `(= ef ',ef) `(= id ,id)) + (gnosis-update 'review `(= gnosis ',gnosis) `(= id ,id)) (if success (progn (gnosis-update 'review-log - `(= c-success ,(1+ (gnosis-get 'c-success 'review-log `(= id ,id)))) `(= id ,id)) - (gnosis-update 'review-log `(= t-success ,(1+ (gnosis-get 't-success 'review-log `(= id ,id)))) + `(= c-success ,(1+ (gnosis-get 'c-success 'review-log `(= id ,id)))) + `(= id ,id)) + (gnosis-update 'review-log + `(= t-success ,(1+ (gnosis-get 't-success 'review-log `(= id ,id)))) `(= id ,id)) (gnosis-update 'review-log `(= c-fails 0) `(= id ,id))) - (gnosis-update 'review-log `(= c-fails ,(1+ (gnosis-get 'c-fails 'review-log `(= id ,id)))) `(= id ,id)) - (gnosis-update 'review-log `(= t-fails ,(1+ (gnosis-get 't-fails 'review-log `(= id ,id)))) `(= id ,id)) + (gnosis-update 'review-log + `(= c-fails ,(1+ (gnosis-get 'c-fails 'review-log `(= id ,id)))) `(= id ,id)) + (gnosis-update 'review-log + `(= t-fails ,(1+ (gnosis-get 't-fails 'review-log `(= id ,id)))) `(= id ,id)) (gnosis-update 'review-log `(= c-success 0) `(= id ,id))))) (defun gnosis-review-result (id success) -- cgit v1.2.3 From 23bb89e78c05a42926374e522a04e8bfbd0b69fc Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 23:43:01 +0300 Subject: review: style & remove unused arguments --- gnosis.el | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index d4d229d..a7921cb 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1600,11 +1600,13 @@ If user-input is equal to CLOZE, return t." ;; Correct answer -> reveal the current cloze (progn (cl-incf num) (gnosis-display-cloze-string main (nthcdr num clozes) - (nthcdr num hints) - (cl-subseq clozes 0 num) - nil)) + (nthcdr num hints) + (cl-subseq clozes 0 num) + nil)) ;; Incorrect answer - (gnosis-display-cloze-string main nil nil (cl-subseq clozes 0 num) (member cloze clozes)) + (gnosis-display-cloze-string main nil nil + (cl-subseq clozes 0 num) + (member cloze clozes)) (gnosis-display-cloze-user-answer (cdr input)) (setq success nil) (cl-return))) @@ -1652,7 +1654,7 @@ If NEW? is non-nil, increment new notes log by 1." (gnosis-update 'activity-log `(= reviewed-total ,inc-total) `(= date ',date)) (and new? (gnosis-update 'activity-log `(= reviewed-new ,inc-new) `(= date ',date))))) -(defun gnosis-review-note (id &optional date) +(defun gnosis-review-note (id) "Start review for note with value of id ID, if note is unsuspended. DATE: Date to log the note review on the activity-log." @@ -1660,8 +1662,7 @@ DATE: Date to log the note review on the activity-log." (message "Suspended note with id: %s" id) (sit-for 0.3)) ;; this should only occur in testing/dev cases (let* ((type (gnosis-get 'type 'notes `(= id ,id))) - (func-name (intern (format "gnosis-review-%s" (downcase type)))) - (date (or date (gnosis-algorithm-date)))) + (func-name (intern (format "gnosis-review-%s" (downcase type))))) (if (fboundp func-name) (progn (pop-to-buffer-same-window (get-buffer-create "*gnosis*")) -- cgit v1.2.3 From 6051ee407ce44df36b9b2d8c10f22298f7b35ddc Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 23:44:14 +0300 Subject: review: Remove note-count from commits. --- gnosis.el | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index a7921cb..5a25a2c 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1726,7 +1726,7 @@ NOTE-COUNT." (recursive-edit) (gnosis-review-actions success note note-count)) -(defun gnosis-review-action--quit (success note note-count) +(defun gnosis-review-action--quit (success note) "Quit review session. Update result for NOTE review with SUCCESS and commit session for NOTE-COUNT. @@ -1734,8 +1734,7 @@ Update result for NOTE review with SUCCESS and commit session for NOTE-COUNT. This function should be used with `gnosis-review-actions', to finish the review session." (gnosis-review-result note success) - (gnosis-review-commit note-count) - ;; Break the loop of `gnosis-review-session' + ;; Break the review loop of `gnosis-review-session' (throw 'review-loop t)) (defun gnosis-review-action--suspend (success note note-count) @@ -1781,7 +1780,7 @@ To customize the keybindings, adjust `gnosis-review-keybindings'." ("override" (gnosis-review-action--override success note note-count)) ("suspend" (gnosis-review-action--suspend success note note-count)) ("edit" (gnosis-review-action--edit success note note-count)) - ("quit" (gnosis-review-action--quit success note note-count))))) + ("quit" (gnosis-review-action--quit success note))))) (defun gnosis-review-session (notes &optional due note-count) "Start review session for NOTES. -- cgit v1.2.3 From d0c1f48a2d68b7021dfa9130445c0adb46051807 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 23:44:48 +0300 Subject: edit-note: Remove unused optional args. --- gnosis.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 5a25a2c..13aca46 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1722,7 +1722,7 @@ editing NOTE with it's new contents. After done editing, call `gnosis-review-actions' with SUCCESS NOTE NOTE-COUNT." (gnosis-edit-save-exit) - (gnosis-edit-note note t) + (gnosis-edit-note note) (recursive-edit) (gnosis-review-actions success note note-count)) @@ -1834,7 +1834,7 @@ NOTE-COUNT: Total notes to be commited for session." (put-text-property (match-beginning 0) (match-end 0) 'read-only t))) (goto-char (point-min))) -(cl-defun gnosis-edit-note (id &optional (recursive-edit nil) (dashboard "notes")) +(cl-defun gnosis-edit-note (id) "Edit the contents of a note with the given ID. This function creates an Emacs Lisp buffer named *gnosis-edit* on the -- cgit v1.2.3 From 0d1b86cce0ba070de8919695c2cb32c2b947c281 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 23:47:35 +0300 Subject: review-session: Remove deprecated date variable. --- gnosis.el | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 13aca46..bb07cd7 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1788,14 +1788,13 @@ To customize the keybindings, adjust `gnosis-review-keybindings'." NOTES: List of note ids DUE: If due is non-nil, session will loop for due notes. NOTE-COUNT: Total notes to be commited for session." - (let ((note-count (or note-count 0)) - (date (gnosis-algorithm-date))) + (let ((note-count (or note-count 0))) (if (null notes) (message "No notes for review.") (setf gnosis-review-notes notes) (catch 'review-loop (cl-loop for note in notes - do (let ((success (gnosis-review-note note date))) + do (let ((success (gnosis-review-note note))) (cl-incf note-count) (gnosis-review-actions success note note-count)) finally -- cgit v1.2.3 From 085a3aef8014fbd0a244380bcc12ba17546b8228 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 23:49:07 +0300 Subject: Remove deprecated deck edit. --- gnosis.el | 83 ++++++++++----------------------------------------------------- 1 file changed, 13 insertions(+), 70 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index bb07cd7..8c0762d 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1866,29 +1866,8 @@ changes." ;; Insert id & fields as read-only values (gnosis-edit-read-only-values (format ":id %s" id) ":main" ":options" ":answer" ":tags" ":extra-notes" ":image" ":second-image" - ":ef" ":ff" ":suspend") - (local-unset-key (kbd "C-c C-c")) - (local-set-key (kbd "C-c C-c") (lambda () (interactive) (if recursive-edit - (gnosis-edit-save-exit 'exit-recursive-edit) - (gnosis-edit-save-exit 'gnosis-dashboard dashboard - gnosis-dashboard-note-ids))))) - -(defun gnosis-edit-deck--export (id) - "Export deck with ID. - -WARNING: This export is only for editing said deck! - -Insert deck values: - `ef-increase', `ef-decrease', `ef-threshold', `failure-factor'" - (let ((name (gnosis-get 'name 'decks `(= id ,id))) - (ef-increase (gnosis-get 'ef-increase 'decks `(= id ,id))) - (ef-decrease (gnosis-get 'ef-decrease 'decks `(= id ,id))) - (ef-threshold (gnosis-get 'ef-threshold 'decks `(= id ,id))) - (failure-factor (gnosis-get 'failure-factor 'decks `(= id ,id))) - (initial-interval (gnosis-get 'initial-interval 'decks `(= id ,id)))) - (insert - (format "\n:id %s\n:name \"%s\"\n:ef-increase %s\n:ef-decrease %s\n:ef-threshold %s\n:failure-factor %s\n :initial-interval '%s" - id name ef-increase ef-decrease ef-threshold failure-factor initial-interval)))) + ":gnosis" ":amensia" ":suspend") + (local-set-key (kbd "C-c C-c") (lambda () (interactive) (gnosis-edit-note-save-exit)))) (defun gnosis-assert-int-or-nil (value description) "Assert that VALUE is an integer or nil. @@ -1915,59 +1894,23 @@ DESCRIPTION is a string that describes the value." (unless (or (null value) (numberp value)) (error "Invalid value: %s, %s" value description))) -(cl-defun gnosis-edit-update-deck (&key id name ef-increase ef-decrease ef-threshold failure-factor initial-interval) - "Update deck with id value of ID. - -NAME: Name of deck -EF-INCREASE: Easiness factor increase value -EF-DECREASE: Easiness factor decrease value -EF-THRESHOLD: Easiness factor threshold value -FAILURE-FACTOR: Failure factor value -INITIAL-INTERVAL: Initial interval for notes of deck" - (gnosis-assert-float-or-nil failure-factor "failure-factor must be a float less than 1" t) - (gnosis-assert-int-or-nil ef-threshold "ef-threshold must be an integer") - (gnosis-assert-number-or-nil ef-increase "ef-increase must be a number") - (cl-assert (or (and (listp initial-interval) - (cl-every #'integerp initial-interval)) - (null initial-interval)) - nil "Initial-interval must be a list of 2 integers") - (cl-loop for (field . value) in - `((ef-increase . ,ef-increase) - (ef-decrease . ,ef-decrease) - (ef-threshold . ,ef-threshold) - (failure-factor . ,failure-factor) - (initial-interval . ',initial-interval) - (name . ,name)) - when value - do (gnosis-update 'decks `(= ,field ,value) `(= id ,id)))) - -(defun gnosis-edit-deck (&optional id) - "Edit the contents of a deck with the given ID." - (interactive "P") - (let ((id (or id (gnosis--get-deck-id)))) - (pop-to-buffer-same-window (get-buffer-create "*gnosis-edit*")) - (gnosis-edit-mode) - (erase-buffer) - (insert ";;\n;; You are editing a gnosis deck.\n\n") - (insert "(gnosis-edit-update-deck ") - (gnosis-edit-deck--export id) - (insert ")") - (insert "\n\n;; After finishing editing, save changes with ` '\n;; Avoid exiting without saving.") - (indent-region (point-min) (point-max)) - (gnosis-edit-read-only-values (format ":id %s" id) ":name" ":ef-increase" - ":ef-decrease" ":ef-threshold" ":failure-factor") - (local-unset-key (kbd "C-c C-c")) - (local-set-key (kbd "C-c C-c") (lambda () (interactive) (gnosis-edit-save-exit 'gnosis-dashboard "decks"))))) - -(cl-defun gnosis-edit-save-exit (&optional exit-func &rest args) +(cl-defun gnosis-edit-save-exit () + "Save edits and exit using EXIT-FUNC, with ARGS." + (interactive) + (when (get-buffer "*gnosis-edit*") + (switch-to-buffer "*gnosis-edit*") + (eval-buffer) + (quit-window t) + (gnosis-dashboard-return))) + +(cl-defun gnosis-edit-note-save-exit () "Save edits and exit using EXIT-FUNC, with ARGS." (interactive) (when (get-buffer "*gnosis-edit*") (switch-to-buffer "*gnosis-edit*") (eval-buffer) (quit-window t) - (when exit-func - (apply exit-func args)))) + (exit-recursive-edit))) (defvar-keymap gnosis-edit-mode-map :doc "gnosis-edit keymap" -- cgit v1.2.3 From 53cb07663067ab28c8b210cd008b74de3ae01d94 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 23:50:14 +0300 Subject: edit-update-note: Update to new db variables. --- gnosis.el | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 8c0762d..a39d08b 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1922,8 +1922,8 @@ DESCRIPTION is a string that describes the value." :lighter " Gnosis Edit" :keymap gnosis-edit-mode-map) -(cl-defun gnosis-edit-update-note (&key id main options answer tags (extra-notes nil) (image nil) (second-image nil) - ef ff suspend) +(cl-defun gnosis-edit-update-note (&key id main options answer tags (extra-notes nil) (image nil) + (second-image nil) gnosis amnesia suspend) "Update note with id value of ID. ID: Note id @@ -1934,8 +1934,8 @@ TAGS: Tags for note, used to organize & differentiate between notes EXTRA-NOTES: Notes to display after user-input IMAGE: Image to display before user-input SECOND-IMAGE: Image to display after user-input -EF: Easiness factor value -FF: Failure factor value +GNOSIS: Gnosis score +AMNESIA: Amnesia value SUSPEND: Suspend note, 0 for unsuspend, 1 for suspend" (cl-assert (stringp main) nil "Main must be a string") (cl-assert (or (stringp image) (null image)) nil @@ -1945,14 +1945,15 @@ SUSPEND: Suspend note, 0 for unsuspend, 1 for suspend" (cl-assert (or (stringp extra-notes) (null extra-notes)) nil "Extra-notes must be a string, or nil") (cl-assert (listp tags) nil "Tags must be a list of strings") - (cl-assert (and (listp ef) (length= ef 3)) nil "ef must be a list of 3 floats") + (cl-assert (and (listp gnosis) (length= gnosis 3)) nil "gnosis must be a list of 3 floats") (cl-assert (or (stringp options) (listp options)) nil "Options must be a string, or a list for MCQ") (cl-assert (or (= suspend 0) (= suspend 1)) nil "Suspend must be either 0 or 1") (when (and (string= (gnosis-get-type id) "cloze") (not (stringp options))) (cl-assert (or (listp options) (stringp options)) nil "Options must be a list or a string.") (cl-assert (gnosis-cloze-check main answer) nil "Clozes are not part of the question (main).") - (cl-assert (>= (length answer) (length options)) nil "Hints (options) must be equal or less than clozes (answer).") + (cl-assert (>= (length answer) (length options)) nil + "Hints (options) must be equal or less than clozes (answer).") (cl-assert (cl-every (lambda (item) (or (null item) (stringp item))) options) nil "Hints (options) must be either nil or a string.")) ;; Construct the update clause for the emacsql update statement. (cl-loop for (field . value) in `((main . ,main) @@ -1962,13 +1963,13 @@ SUSPEND: Suspend note, 0 for unsuspend, 1 for suspend" (extra-notes . ,extra-notes) (images . ,image) (extra-image . ,second-image) - (ef . ',ef) - (ff . ,ff) + (gnosis . ',gnosis) + (amnesia . ,amnesia) (suspend . ,suspend)) when value do (cond ((memq field '(extra-notes images extra-image)) (gnosis-update 'extras `(= ,field ,value) `(= id ,id))) - ((memq field '(ef ff)) + ((memq field '(gnosis amnesia)) (gnosis-update 'review `(= ,field ,value) `(= id ,id))) ((eq field 'suspend) (gnosis-update 'review-log `(= ,field ,value) `(= id ,id))) -- cgit v1.2.3 From 37f8a26b38b7234f3aef5031662e1f6a2ab1af95 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 23:51:51 +0300 Subject: New function: get-custom-values: Return custom review values. * Returns custom values to adjust gnosis algorithm for each deck and tag --- gnosis.el | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index a39d08b..6c69b98 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1977,6 +1977,20 @@ SUSPEND: Suspend note, 0 for unsuspend, 1 for suspend" (gnosis-update 'notes `(= ,field ',value) `(= id ,id))) (t (gnosis-update 'notes `(= ,field ,value) `(= id ,id)))))) +(defun gnosis-get-custom-values (key search-value &optional values) + "Return SEARCH-VALUE for KEY from VALUES. + +VALUES: Defaults to `gnosis-custom-values'." + (cl-assert (or (eq key :deck) (eq key :tag)) nil "Key value must be either :tag or :deck") + (cl-assert (stringp search-value) nil "Search-value must be a string, the name of tag or deck.") + (let ((results) + (values (or values gnosis-custom-values))) + (dolist (rule values) + (when (and (plist-get rule key) + (equal (plist-get rule key) search-value)) + (setq results (append results (nth 2 rule))))) + results)) + (defun gnosis-get-date-total-notes (&optional date) "Return total notes reviewed for DATE. -- cgit v1.2.3 From 9ad5793b12a1195878113337c117461c929dcfb2 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 23:53:14 +0300 Subject: New function: get-custom-deck-value * Return custom deck value for deck, avoiding code repetition. --- gnosis.el | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 6c69b98..c7d02a5 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1991,6 +1991,10 @@ VALUES: Defaults to `gnosis-custom-values'." (setq results (append results (nth 2 rule))))) results)) +(defun gnosis-get-custom-deck-value (deck value &optional values) + "Return custom VALUE for note DECK." + (plist-get (gnosis-get-custom-values :deck deck values) value)) + (defun gnosis-get-date-total-notes (&optional date) "Return total notes reviewed for DATE. -- cgit v1.2.3 From 1c2b2c4e41005e126e81aa73018d00c8004133dc Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 23:53:45 +0300 Subject: New function: get-custom-tag-values * Return custom tag values. --- gnosis.el | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index c7d02a5..60b8ff2 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1995,6 +1995,15 @@ VALUES: Defaults to `gnosis-custom-values'." "Return custom VALUE for note DECK." (plist-get (gnosis-get-custom-values :deck deck values) value)) +(defun gnosis-get-custom-tag-values (id keyword &optional custom-tags custom-values) + "Return KEYWORD values for note ID." + (cl-assert (keywordp keyword) nil "keyword must be a keyword!") + (let ((tags (if id (gnosis-get 'tags 'notes `(= id ,id)) custom-tags))) + (cl-loop for tag in tags + ;; Only collect non-nil values + when (plist-get (gnosis-get-custom-values :tag tag custom-values) keyword) + collect (plist-get (gnosis-get-custom-values :tag tag custom-values) keyword)))) + (defun gnosis-get-date-total-notes (&optional date) "Return total notes reviewed for DATE. -- cgit v1.2.3 From 762cbc5d944ad3dc6528108fb1e9937f0b8f8c90 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 23:56:22 +0300 Subject: New function: get-note-tag-amnesia * Return the minimum note tag amnesia. --- gnosis.el | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 60b8ff2..b0a9714 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2004,6 +2004,19 @@ VALUES: Defaults to `gnosis-custom-values'." when (plist-get (gnosis-get-custom-values :tag tag custom-values) keyword) collect (plist-get (gnosis-get-custom-values :tag tag custom-values) keyword)))) +(defun gnosis-get-note-tag-amnesia (id &optional custom-tags custom-values) + "Return tag MINIMUM amnesia for note ID. + +The closer the amnesia value is to 0, the closer it is to total +amnesia i.e next interval to be 0. + +CUSTOM-TAGS: Specify tags for note id. +CUSTOM-VALUES: Specify values for tags." + (let ((amnesia-values (gnosis-get-custom-tag-values id :amnesia custom-tags custom-values))) + (if amnesia-values + (apply #'min amnesia-values) + gnosis-algorithm-amnesia-value))) + (defun gnosis-get-date-total-notes (&optional date) "Return total notes reviewed for DATE. -- cgit v1.2.3 From 1bb2e3bdc17dca1206910ca997a1650a731c1f7d Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 6 Aug 2024 23:57:48 +0300 Subject: New function: get-note-deck-amnesia * Return amnesia value for note's deck. --- gnosis.el | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index b0a9714..9ef0ab5 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2017,6 +2017,14 @@ CUSTOM-VALUES: Specify values for tags." (apply #'min amnesia-values) gnosis-algorithm-amnesia-value))) +(defun gnosis-get-note-deck-amnesia (id &optional custom-deck custom-values) + "Return tag amnesia for note ID. + +Optionally, use CUSTOM-DECK and CUSTOM-VALUES." + (let ((deck (or (gnosis-get-note-deck-name id) custom-deck ))) + (or (gnosis-get-custom-deck-value deck :amnesia custom-values) + gnosis-algorithm-amnesia-value))) + (defun gnosis-get-date-total-notes (&optional date) "Return total notes reviewed for DATE. -- cgit v1.2.3 From 833934440394d67aafcb7e98f79621838018368f Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 01:37:14 +0300 Subject: get-note-amnesia: Add optional arguments values for testing. --- gnosis.el | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 9ef0ab5..9b30f43 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2025,6 +2025,19 @@ Optionally, use CUSTOM-DECK and CUSTOM-VALUES." (or (gnosis-get-custom-deck-value deck :amnesia custom-values) gnosis-algorithm-amnesia-value))) +(defun gnosis-get-note-amnesia (id &optional custom-deck custom-tags custom-values ) + "Return amnesia value for note ID. + +Note amnesia should be hte MINIMUM value of deck's & tags' amnesia. + +CUSTOM-TAGS: Specify tags for note id. +CUSTOM-VALUES: Specify values for tags." + (let* ((deck-amnesia (gnosis-get-note-deck-amnesia id custom-deck custom-values)) + (tags-amnesia (gnosis-get-note-tag-amnesia id custom-tags custom-values)) + (note-amnesia (min deck-amnesia tags-amnesia))) + (if (>= note-amnesia 1) + (error "Amnesia value must be lower than 1") + note-amnesia))) (defun gnosis-get-date-total-notes (&optional date) "Return total notes reviewed for DATE. -- cgit v1.2.3 From e231678d3e4e46eb9babbc1d74f902eb32a4477d Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 01:38:08 +0300 Subject: New functions: get-note-epignosis. --- gnosis.el | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 9b30f43..905bc5e 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2039,6 +2039,30 @@ CUSTOM-VALUES: Specify values for tags." (error "Amnesia value must be lower than 1") note-amnesia))) +(defun gnosis-get-note-tag-epignosis (id &optional custom-tags custom-values) + "Return tag epignosis for note ID. + +CUSTOM-TAGS: Specify tags for note id. +CUSTOM-VALUES: Specify values for tags." + (let* ((epignosis-values (gnosis-get-custom-tag-values id :epignosis custom-tags custom-values))) + (if epignosis-values + (apply #'max epignosis-values) + gnosis-algorithm-epignosis-value))) + +(defun gnosis-get-note-deck-epignosis (id &optional custom-deck custom-values) + "Return deck epignosis for note ID." + (let ((deck (or (gnosis-get-note-deck-name id) custom-deck))) + (or (gnosis-get-custom-deck-value deck :epignosis custom-values) + gnosis-algorithm-epignosis-value))) + +(defun gnosis-get-note-epignosis (id &optional custom-deck custom-tags custom-values) + "Return epignosis value for note ID." + (let* ((deck-epignosis (gnosis-get-note-deck-epignosis id custom-deck custom-values)) + (tag-epignosis (gnosis-get-note-tag-epignosis id custom-tags custom-values)) + (note-epignosis (max deck-epignosis tag-epignosis))) + (if (>= note-epignosis 1) + (error "Epignosis value must be lower than 1") + note-epignosis))) (defun gnosis-get-date-total-notes (&optional date) "Return total notes reviewed for DATE. -- cgit v1.2.3 From a755a634eadea49829d4231d510ee8976d08f473 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 01:39:05 +0300 Subject: New functions: get-note-agnoia. --- gnosis.el | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 905bc5e..84f8164 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2063,6 +2063,28 @@ CUSTOM-VALUES: Specify values for tags." (if (>= note-epignosis 1) (error "Epignosis value must be lower than 1") note-epignosis))) + +(defun gnosis-get-note-tag-agnoia (id &optional custom-tags custom-values) + "Return agnoia value for note ID." + (let ((agnoia-values (gnosis-get-custom-tag-values id :agnoia custom-tags custom-values))) + (if agnoia-values + (apply #'max agnoia-values) + gnosis-algorithm-agnoia-value))) + +(defun gnosis-get-note-deck-agnoia (id &optional custom-deck custom-values) + "Return agnoia value for note ID." + (let ((deck (or (gnosis-get-note-deck-name id) custom-deck))) + (or (gnosis-get-custom-deck-value deck :agnoia custom-values) + gnosis-algorithm-agnoia-value))) + +(defun gnosis-get-note-agnoia (id &optional custom-deck custom-tags custom-values) + "Return agnoia value for note ID." + (let* ((deck-agnoia (gnosis-get-note-deck-agnoia id custom-deck custom-values)) + (tag-agnoia (gnosis-get-note-tag-agnoia id custom-tags custom-values)) + (max-agnoia (max deck-agnoia tag-agnoia))) + (if (>= max-agnoia 1) + (error "Agnoia value must be lower than 1") + max-agnoia))) (defun gnosis-get-date-total-notes (&optional date) "Return total notes reviewed for DATE. -- cgit v1.2.3 From 95fda0a8e3819f833334bbcfeda5fbe85be6dfe9 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 01:39:31 +0300 Subject: New function: proto-max-values. * To be used with get-note-proto, to return the max list of proto values. --- gnosis.el | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 84f8164..32d1438 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2085,6 +2085,17 @@ CUSTOM-VALUES: Specify values for tags." (if (>= max-agnoia 1) (error "Agnoia value must be lower than 1") max-agnoia))) + +(defun gnosis-proto-max-values (proto-values) + "Return max values from PROTO-VALUES." + (if (not (and (listp proto-values) (cl-every #'listp proto-values))) + proto-values + (let* ((max-len (apply #'max (mapcar #'length proto-values))) + (padded-lists (mapcar (lambda (lst) + (append lst (make-list (- max-len (length lst)) 0))) + proto-values))) + (apply #'cl-mapcar #'max padded-lists)))) + (defun gnosis-get-date-total-notes (&optional date) "Return total notes reviewed for DATE. -- cgit v1.2.3 From 0625ac6501884f6da8fa9fe7a55c006b328d3885 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 01:40:04 +0300 Subject: New function: get-note-proto. --- gnosis.el | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 32d1438..7e44dba 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2096,6 +2096,15 @@ CUSTOM-VALUES: Specify values for tags." proto-values))) (apply #'cl-mapcar #'max padded-lists)))) +(defun gnosis-get-note-proto (id &optional custom-tags custom-deck custom-values) + "Return tag proto values for note ID." + (let* ((deck (or custom-deck (gnosis-get-note-deck-name id))) + (tags (or custom-tags (gnosis-get 'tags 'notes `(= id ,id)))) + (proto-values (or (delq nil (append (gnosis-get-custom-tag-values nil :proto tags custom-values) + (list (gnosis-get-custom-deck-value deck :proto + custom-values)))) + gnosis-algorithm-proto))) + (gnosis-proto-max-values proto-values))) (defun gnosis-get-date-total-notes (&optional date) "Return total notes reviewed for DATE. -- cgit v1.2.3 From b110a688f4378234bb6fee99a2bfbd8c426d5b74 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 01:40:33 +0300 Subject: New functions: get-note-anagnosis. * Return values for anagnosis from deck & tags. --- gnosis.el | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 7e44dba..cb08581 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2105,6 +2105,26 @@ CUSTOM-VALUES: Specify values for tags." custom-values)))) gnosis-algorithm-proto))) (gnosis-proto-max-values proto-values))) + +(defun gnosis-get-note-tag-anagnosis (id &optional custom-tags custom-values) + "Return the minimum anagnosis tag value for note ID." + (let ((anagnosis-values (gnosis-get-custom-tag-values id :anagnosis custom-tags custom-values))) + (if anagnosis-values + (apply #'min anagnosis-values) + gnosis-algorithm-anagnosis-value))) + +(defun gnosis-get-note-deck-anagnosis (id &optional custom-deck custom-values) + "Return anagnosis deck value for note ID." + (let ((deck (or (gnosis-get-note-deck-name id) custom-deck))) + (or (gnosis-get-custom-deck-value deck :anagnosis custom-values) + gnosis-algorithm-anagnosis-value))) + +(defun gnosis-get-note-anagnosis (id &optional custom-deck custom-tags custom-values) + "Return minimum anagnosis value for note ID." + (let* ((deck-anagnosis (gnosis-get-note-deck-anagnosis id custom-deck custom-values)) + (tag-anagnosis (gnosis-get-note-tag-anagnosis id custom-tags custom-values)) + (note-anagnosis (min deck-anagnosis tag-anagnosis))) + note-anagnosis)) (defun gnosis-get-date-total-notes (&optional date) "Return total notes reviewed for DATE. -- cgit v1.2.3 From 5139170894cddef400c59bcbb244c59466f594ae Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 01:40:59 +0300 Subject: New functions: get-note-lethe. * Return lethe value for note. --- gnosis.el | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index cb08581..310072e 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2125,6 +2125,27 @@ CUSTOM-VALUES: Specify values for tags." (tag-anagnosis (gnosis-get-note-tag-anagnosis id custom-tags custom-values)) (note-anagnosis (min deck-anagnosis tag-anagnosis))) note-anagnosis)) + +(defun gnosis-get-note-deck-lethe (id &optional custom-deck custom-values) + "Return lethe deck value for note ID." + (let ((deck (or (gnosis-get-note-deck-name id) custom-deck))) + (or (gnosis-get-custom-deck-value deck :lethe custom-values) + gnosis-algorithm-lethe-value))) + +(defun gnosis-get-note-tag-lethe (id &optional custom-tags custom-values) + "Return note ID tag lethe values." + (let ((lethe-values (gnosis-get-custom-tag-values id :lethe custom-tags custom-values))) + (if lethe-values + (apply #'min lethe-values) + gnosis-algorithm-lethe-value))) + +(defun gnosis-get-note-lethe (id &optional custom-deck custom-tags custom-values) + "Return note ID lethe value." + (let* ((deck-lethe (gnosis-get-note-deck-lethe id custom-deck custom-values)) + (tag-lethe (gnosis-get-note-tag-lethe id custom-tags custom-values)) + (note-lethe (min deck-lethe tag-lethe))) + note-lethe)) + (defun gnosis-get-date-total-notes (&optional date) "Return total notes reviewed for DATE. -- cgit v1.2.3 From 45079fe53f40a478f928b0a8fc8a5299e5253732 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 01:41:27 +0300 Subject: Update docstrings --- gnosis.el | 3 --- 1 file changed, 3 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 310072e..223e27a 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1848,9 +1848,6 @@ RECURSIVE-EDIT: If t, exit `recursive-edit' after finishing editing. It should only be t when starting a recursive edit, when editing a note during a review session. -DASHBOARD: Dashboard to return after editing. Default value is -Notes. - The buffer automatically indents the expressions for readability. After finishing editing, evaluate the entire expression to apply the changes." -- cgit v1.2.3 From 46938ac464ffa6841b0c02b83f8a88597a39bba3 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 12:24:48 +0300 Subject: db-init: Create db when there are tables<3. --- gnosis.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 223e27a..2839ff6 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2308,7 +2308,7 @@ Return note ids for notes that match QUERY." (defun gnosis-db-init () "Create essential directories & database." (let ((gnosis-curr-version (caar (emacsql gnosis-db (format "PRAGMA user_version"))))) - (unless (length= (emacsql gnosis-db [:select name :from sqlite-master :where (= type table)]) 7) + (unless (length> (emacsql gnosis-db [:select name :from sqlite-master :where (= type table)]) 3) (emacsql-with-transaction gnosis-db ;; Enable foreign keys (emacsql gnosis-db "PRAGMA foreign_keys = ON") -- cgit v1.2.3 From 114d92fa7b2713d12b58101dc650d03b95162ce9 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 12:27:33 +0300 Subject: get-note-tag-amnesia: Return either nil or max amnesia value. --- gnosis.el | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 2839ff6..753d6e4 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2010,9 +2010,7 @@ amnesia i.e next interval to be 0. CUSTOM-TAGS: Specify tags for note id. CUSTOM-VALUES: Specify values for tags." (let ((amnesia-values (gnosis-get-custom-tag-values id :amnesia custom-tags custom-values))) - (if amnesia-values - (apply #'min amnesia-values) - gnosis-algorithm-amnesia-value))) + (and amnesia-values (apply #'max amnesia-values)))) (defun gnosis-get-note-deck-amnesia (id &optional custom-deck custom-values) "Return tag amnesia for note ID. -- cgit v1.2.3 From 4874af540435aa2a1a6bbeb80a1fe7127a1f748e Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 12:28:11 +0300 Subject: get-note-amnesia: Prioritize tags value over deck. * Only return deck value if tags value is nil. --- gnosis.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 753d6e4..366305d 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2029,7 +2029,7 @@ CUSTOM-TAGS: Specify tags for note id. CUSTOM-VALUES: Specify values for tags." (let* ((deck-amnesia (gnosis-get-note-deck-amnesia id custom-deck custom-values)) (tags-amnesia (gnosis-get-note-tag-amnesia id custom-tags custom-values)) - (note-amnesia (min deck-amnesia tags-amnesia))) + (note-amnesia (or tags-amnesia deck-amnesia))) (if (>= note-amnesia 1) (error "Amnesia value must be lower than 1") note-amnesia))) -- cgit v1.2.3 From 4cb2beac3dd00cc6a6d30214b63ed48e357cb2cc Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 12:29:06 +0300 Subject: get-note-tag-epignosis: Return either nil or max epignosis value. --- gnosis.el | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 366305d..a0dce26 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2040,9 +2040,7 @@ CUSTOM-VALUES: Specify values for tags." CUSTOM-TAGS: Specify tags for note id. CUSTOM-VALUES: Specify values for tags." (let* ((epignosis-values (gnosis-get-custom-tag-values id :epignosis custom-tags custom-values))) - (if epignosis-values - (apply #'max epignosis-values) - gnosis-algorithm-epignosis-value))) + (and epignosis-values (apply #'max epignosis-values)))) (defun gnosis-get-note-deck-epignosis (id &optional custom-deck custom-values) "Return deck epignosis for note ID." -- cgit v1.2.3 From 0dbcc95334f8abd810612469577cf40d025b81d1 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 12:30:19 +0300 Subject: get-note-epignosis: Prioritize tags value over deck. * Only return deck value if tags value is nil. --- gnosis.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index a0dce26..58206d3 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2052,7 +2052,7 @@ CUSTOM-VALUES: Specify values for tags." "Return epignosis value for note ID." (let* ((deck-epignosis (gnosis-get-note-deck-epignosis id custom-deck custom-values)) (tag-epignosis (gnosis-get-note-tag-epignosis id custom-tags custom-values)) - (note-epignosis (max deck-epignosis tag-epignosis))) + (note-epignosis (or tag-epignosis deck-epignosis))) (if (>= note-epignosis 1) (error "Epignosis value must be lower than 1") note-epignosis))) -- cgit v1.2.3 From 1a812fe2086fc59d25ebd3b674589c3d3c57b139 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 12:31:17 +0300 Subject: get-note-agnoia: Prioritize tags over decks. * get-note-tag-agnoia: Returns either nil or max agnoia value. * get-note-agnoia: Returns deck value only if tags value is nil. --- gnosis.el | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 58206d3..0b5cd18 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2060,9 +2060,7 @@ CUSTOM-VALUES: Specify values for tags." (defun gnosis-get-note-tag-agnoia (id &optional custom-tags custom-values) "Return agnoia value for note ID." (let ((agnoia-values (gnosis-get-custom-tag-values id :agnoia custom-tags custom-values))) - (if agnoia-values - (apply #'max agnoia-values) - gnosis-algorithm-agnoia-value))) + (and agnoia-values (apply #'max agnoia-values)))) (defun gnosis-get-note-deck-agnoia (id &optional custom-deck custom-values) "Return agnoia value for note ID." @@ -2074,10 +2072,10 @@ CUSTOM-VALUES: Specify values for tags." "Return agnoia value for note ID." (let* ((deck-agnoia (gnosis-get-note-deck-agnoia id custom-deck custom-values)) (tag-agnoia (gnosis-get-note-tag-agnoia id custom-tags custom-values)) - (max-agnoia (max deck-agnoia tag-agnoia))) - (if (>= max-agnoia 1) + (note-agnoia (or tag-agnoia deck-agnoia))) + (if (>= note-agnoia 1) (error "Agnoia value must be lower than 1") - max-agnoia))) + note-agnoia))) (defun gnosis-proto-max-values (proto-values) "Return max values from PROTO-VALUES." -- cgit v1.2.3 From 6cc777bba38e6bcb1bb55f4e633152fb7e79a528 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 12:32:24 +0300 Subject: get-note-proto: Prioritize tags over decks. * Return deck proto value only if tags proto value is nil. --- gnosis.el | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 0b5cd18..0b4b37e 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2088,14 +2088,15 @@ CUSTOM-VALUES: Specify values for tags." (apply #'cl-mapcar #'max padded-lists)))) (defun gnosis-get-note-proto (id &optional custom-tags custom-deck custom-values) - "Return tag proto values for note ID." + "Return tag proto values for note ID. + +CUSTOM-VALUES: Custom values to be used instead. +CUSTOM-TAGS: Custom tags to be used instead. +CUSTOM-DECK: Custom deck to be used instead." (let* ((deck (or custom-deck (gnosis-get-note-deck-name id))) - (tags (or custom-tags (gnosis-get 'tags 'notes `(= id ,id)))) - (proto-values (or (delq nil (append (gnosis-get-custom-tag-values nil :proto tags custom-values) - (list (gnosis-get-custom-deck-value deck :proto - custom-values)))) - gnosis-algorithm-proto))) - (gnosis-proto-max-values proto-values))) + (tags-proto (gnosis-get-custom-tag-values id :proto custom-tags custom-values)) + (decks-proto (gnosis-get-custom-deck-value deck :proto custom-values))) + (if tags-proto (gnosis-proto-max-values tags-proto) (gnosis-proto-max-values decks-proto)))) (defun gnosis-get-note-tag-anagnosis (id &optional custom-tags custom-values) "Return the minimum anagnosis tag value for note ID." -- cgit v1.2.3 From de6fbabe94757f1663a809c2cb72464fc4656fd9 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 12:33:05 +0300 Subject: get-note-anagnosis: Prioritize tags over decks. * get-note-tag-anagnosis: Returns either nil or max anagnosis value. * get-note-anagnosis: Returns deck value only if tags value is nil. --- gnosis.el | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 0b4b37e..cb72f01 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2099,23 +2099,31 @@ CUSTOM-DECK: Custom deck to be used instead." (if tags-proto (gnosis-proto-max-values tags-proto) (gnosis-proto-max-values decks-proto)))) (defun gnosis-get-note-tag-anagnosis (id &optional custom-tags custom-values) - "Return the minimum anagnosis tag value for note ID." + "Return the minimum anagnosis tag value for note ID. + +CUSTOM-VALUES: Custom values to be used instead. +CUSTOM-TAGS: Custom tags to be used instead." (let ((anagnosis-values (gnosis-get-custom-tag-values id :anagnosis custom-tags custom-values))) - (if anagnosis-values - (apply #'min anagnosis-values) - gnosis-algorithm-anagnosis-value))) + (and anagnosis-values (apply #'min anagnosis-values)))) (defun gnosis-get-note-deck-anagnosis (id &optional custom-deck custom-values) - "Return anagnosis deck value for note ID." + "Return anagnosis deck value for note ID. + +CUSTOM-VALUES: Custom values to be used instead. +CUSTOM-DECK: Custom deck to be used instead." (let ((deck (or (gnosis-get-note-deck-name id) custom-deck))) (or (gnosis-get-custom-deck-value deck :anagnosis custom-values) gnosis-algorithm-anagnosis-value))) (defun gnosis-get-note-anagnosis (id &optional custom-deck custom-tags custom-values) - "Return minimum anagnosis value for note ID." + "Return minimum anagnosis value for note ID. + +CUSTOM-VALUES: Custom values to be used instead. +CUSTOM-TAGS: Custom tags to be used instead. +CUSTOM-DECK: Custom deck to be used instead." (let* ((deck-anagnosis (gnosis-get-note-deck-anagnosis id custom-deck custom-values)) (tag-anagnosis (gnosis-get-note-tag-anagnosis id custom-tags custom-values)) - (note-anagnosis (min deck-anagnosis tag-anagnosis))) + (note-anagnosis (or tag-anagnosis deck-anagnosis))) note-anagnosis)) (defun gnosis-get-note-deck-lethe (id &optional custom-deck custom-values) -- cgit v1.2.3 From c3d31ec2133021fbbeb4c5cb7eaf245459ac717c Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 12:33:27 +0300 Subject: get-note-lethe: Prioritize tags over decks. * get-note-tag-lethe: Returns either nil or max lethe value. * get-note-lethe: Returns deck value only if tags value is nil. --- gnosis.el | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index cb72f01..e9d8604 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2127,23 +2127,31 @@ CUSTOM-DECK: Custom deck to be used instead." note-anagnosis)) (defun gnosis-get-note-deck-lethe (id &optional custom-deck custom-values) - "Return lethe deck value for note ID." + "Return lethe deck value for note ID. + +CUSTOM-VALUES: Custom values to be used instead. +CUSTOM-DECK: Custom deck to be used instead." (let ((deck (or (gnosis-get-note-deck-name id) custom-deck))) (or (gnosis-get-custom-deck-value deck :lethe custom-values) gnosis-algorithm-lethe-value))) (defun gnosis-get-note-tag-lethe (id &optional custom-tags custom-values) - "Return note ID tag lethe values." + "Return note ID tag lethe values. + +CUSTOM-VALUES: Custom values to be used instead. +CUSTOM-TAGS: Custom tags to be used instead." (let ((lethe-values (gnosis-get-custom-tag-values id :lethe custom-tags custom-values))) - (if lethe-values - (apply #'min lethe-values) - gnosis-algorithm-lethe-value))) + (and lethe-values (apply #'min lethe-values)))) (defun gnosis-get-note-lethe (id &optional custom-deck custom-tags custom-values) - "Return note ID lethe value." + "Return note ID lethe value. + +CUSTOM-VALUES: Custom values to be used instead. +CUSTOM-TAGS: Custom tags to be used instead. +CUSTOM-DECK: Custom deck to be used instead." (let* ((deck-lethe (gnosis-get-note-deck-lethe id custom-deck custom-values)) (tag-lethe (gnosis-get-note-tag-lethe id custom-tags custom-values)) - (note-lethe (min deck-lethe tag-lethe))) + (note-lethe (or tag-lethe deck-lethe))) note-lethe)) (defun gnosis-get-date-total-notes (&optional date) -- cgit v1.2.3 From 109c47f1dc0fbc47cbd0d37989e5fc0009a5e837 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 14:46:10 +0300 Subject: packaging: Update version & commentary. --- gnosis-algorithm.el | 31 ++++++------------------------- gnosis.el | 25 ++++++++++++++----------- 2 files changed, 20 insertions(+), 36 deletions(-) (limited to 'gnosis.el') diff --git a/gnosis-algorithm.el b/gnosis-algorithm.el index 559bb4d..a8930a3 100644 --- a/gnosis-algorithm.el +++ b/gnosis-algorithm.el @@ -24,26 +24,8 @@ ;;; Commentary: -;; Handles date calculation as well as ef & interval calculations. - -;; Gnosis implements a highly customizable algorithm, inspired by SM-2. -;; Gnosis algorithm does not use user's subjective rating of a note to -;; determine the next review interval, but instead uses the user's -;; success or failure in recalling the answer of a note. - -;; Each gnosis note has an ef (easiness factor), which is a list of 3 -;; values. The last value is the total ef for a note, which will be -;; used to determine the next interval upon a successful answer recall, -;; the second value is the ef-decrease value, this value will be -;; subtracted from the the total ef upon failure to recall the answer of -;; a note, the first value is the ef increase, will be added to the -;; total ef upon a successful recall. - -;; Each gnosis deck has a gnosis-algorithm-ef-threshold, it's an -;; integer value that refers to the consecutive success or failures to -;; recall an answer. Upon reaching the threshold, gnosis-algorithm-ef-decrease -;; or gnosis-algorithm-ef-increase will be applied to the ef-increase or -;; ef-decrease of note. +;; Module that handles date and interval calculation as well as +;; gnosis-score for notes. ;;; Code: @@ -68,19 +50,18 @@ Third item : Total gnosis (gnosis-synolon/totalis) -> Total gnosis score" :type '(list float)) (defcustom gnosis-algorithm-amnesia-value 0.5 - "Gnosis forgetting factor. + "Gnosis amnesia value. -Used to calcuate new interval for failed questions. +Used to calcuate new interval upon a failed recall i.e the memmory loss. -The closer this value is to 0, the closer it is to total amnesia for -each a recall. This value should be less than 1.0." +The closer this value is to 1, the more the memory loss." :group 'gnosis :type 'float) (defcustom gnosis-algorithm-epignosis-value 0.1 "Value to increase gnosis-plus upon anagnosis. -Epignosis means knowledge accuracy.." +Epignosis means knowledge accuracy." :group 'gnosis :type 'float) diff --git a/gnosis.el b/gnosis.el index e9d8604..6b396e3 100644 --- a/gnosis.el +++ b/gnosis.el @@ -5,7 +5,7 @@ ;; Author: Thanos Apollo ;; Keywords: extensions ;; URL: https://thanosapollo.org/projects/gnosis -;; Version: 0.3.2 +;; Version: 0.4.0 ;; Package-Requires: ((emacs "27.2") (emacsql "20240124") (compat "29.1.4.2") (transient "0.7.2")) @@ -24,16 +24,19 @@ ;;; Commentary: -;; Gnosis is a spaced repetition system for note taking and -;; self-testing. Notes are organized in a Question/Answer/Explanation -;; format and reviewed at spaced intervals. Interval durations are -;; based on the success or failure of recalling the answer to each -;; question. - -;; Gnosis uses a highly customizable algorithm. Unlike traditional -;; methods, it doesn't depend on subjective user ratings to determine -;; the next review interval. Instead, it evaluates the user's success -;; or failure in recalling an answer by typing it. +;; Gnosis (γνῶσις) is a spaced repetition system that enhances memory +;; retention through active recall. It employs a Q&A format, where each +;; note consists of a question, answer, and explanation. Notes are +;; reviewed at optimally spaced intervals based on the user's success or +;; failure to recall the answer. Key benefits arise from writing out +;; answers when reviewing notes, fostering deeper understanding +;; and improved memory retention. + +;; Gnosis algorithm is highly adjustable, allowing users to set specific +;; values not just for note decks but for tags as well. Gnosis' +;; adjustability allows users to fine-tune settings not only for entire +;; note collections but also for specific tagged topics, thereby creating +;; a personalized learning environment for each topic. ;;; Code: -- cgit v1.2.3 From db19024b19fa25ad4211a7fdb2ee5f9e60439af9 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 14:48:03 +0300 Subject: New variable: Add custom--valid-values. * List of valid custom keyword values. --- gnosis.el | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 6b396e3..2860464 100644 --- a/gnosis.el +++ b/gnosis.el @@ -217,11 +217,15 @@ When nil, review new notes last." (defvar gnosis-review-notes nil "Review notes.") +;; TODO: Make this as a defcustom (defvar gnosis-custom-values '((:deck "demo" (:proto (0 1 3) :anagnsois 3 :epignosis 0.5 :agnoia 0.3 :amnesia 0.5 :lethe 3)) (:tag "demo" (:proto (1 2) :anagnosis 3 :epignosis 0.5 :agnoia 0.3 :amnesia 0.45 :lethe 3))) "Custom review values for adjusting gnosis algorithm.") +(defvar gnosis-custom--valid-values + '(:proto :anagnosis :epignosis :agnoia :amnesia :lethe)) + ;;; Faces (defgroup gnosis-faces nil -- cgit v1.2.3 From edbfadfec50cefcd956414f96e0be87e7ffde80e Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 14:48:39 +0300 Subject: New function: get-custom-values--validate. * Validate custom keyword values for gnosis. * Update error messages. --- gnosis.el | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 2860464..926c033 100644 --- a/gnosis.el +++ b/gnosis.el @@ -1981,18 +1981,31 @@ SUSPEND: Suspend note, 0 for unsuspend, 1 for suspend" (gnosis-update 'notes `(= ,field ',value) `(= id ,id))) (t (gnosis-update 'notes `(= ,field ,value) `(= id ,id)))))) +(defun gnosis-get-custom-values--validate (plist valid-keywords) + "Verify that PLIST consists of VALID-KEYWORDS." + (let ((keys (let (ks) + (while plist + (setq ks (cons (car plist) ks)) + (setq plist (cddr plist))) + ks))) + (let ((invalid-key (cl-find-if (lambda (key) (not (member key valid-keywords))) keys))) + (if invalid-key + (error "Invalid custom keyword found in: %s" invalid-key) + t)))) + (defun gnosis-get-custom-values (key search-value &optional values) "Return SEARCH-VALUE for KEY from VALUES. VALUES: Defaults to `gnosis-custom-values'." (cl-assert (or (eq key :deck) (eq key :tag)) nil "Key value must be either :tag or :deck") - (cl-assert (stringp search-value) nil "Search-value must be a string, the name of tag or deck.") + (cl-assert (stringp search-value) nil "Search-value must be the name of tag or deck as a string.") (let ((results) (values (or values gnosis-custom-values))) (dolist (rule values) (when (and (plist-get rule key) (equal (plist-get rule key) search-value)) (setq results (append results (nth 2 rule))))) + (gnosis-get-custom-values--validate results gnosis-custom--valid-values) results)) (defun gnosis-get-custom-deck-value (deck value &optional values) -- cgit v1.2.3 From 4726840b4ece588926308b17ef9bf8feeeb3c60c Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 15:02:12 +0300 Subject: [fix] custom-values: Typo. --- gnosis.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 926c033..19d95a5 100644 --- a/gnosis.el +++ b/gnosis.el @@ -219,7 +219,7 @@ When nil, review new notes last." ;; TODO: Make this as a defcustom (defvar gnosis-custom-values - '((:deck "demo" (:proto (0 1 3) :anagnsois 3 :epignosis 0.5 :agnoia 0.3 :amnesia 0.5 :lethe 3)) + '((:deck "demo" (:proto (0 1 3) :anagnosis 3 :epignosis 0.5 :agnoia 0.3 :amnesia 0.5 :lethe 3)) (:tag "demo" (:proto (1 2) :anagnosis 3 :epignosis 0.5 :agnoia 0.3 :amnesia 0.45 :lethe 3))) "Custom review values for adjusting gnosis algorithm.") -- cgit v1.2.3 From caae059a0988cdb08ef01f1adc695972300fe09c Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Wed, 7 Aug 2024 15:02:24 +0300 Subject: [fix] get-note-proto: when deck-proto is nil, use default proto. --- gnosis.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gnosis.el') diff --git a/gnosis.el b/gnosis.el index 19d95a5..8790d5e 100644 --- a/gnosis.el +++ b/gnosis.el @@ -2116,7 +2116,7 @@ CUSTOM-DECK: Custom deck to be used instead." (let* ((deck (or custom-deck (gnosis-get-note-deck-name id))) (tags-proto (gnosis-get-custom-tag-values id :proto custom-tags custom-values)) (decks-proto (gnosis-get-custom-deck-value deck :proto custom-values))) - (if tags-proto (gnosis-proto-max-values tags-proto) (gnosis-proto-max-values decks-proto)))) + (if tags-proto (gnosis-proto-max-values tags-proto) (gnosis-proto-max-values (or decks-proto gnosis-algorithm-proto))))) (defun gnosis-get-note-tag-anagnosis (id &optional custom-tags custom-values) "Return the minimum anagnosis tag value for note ID. -- cgit v1.2.3