diff options
-rw-r--r-- | CONTRIBUTING.org | 19 | ||||
-rw-r--r-- | doc/gnosis.info | 185 | ||||
-rw-r--r-- | doc/gnosis.org | 100 | ||||
-rw-r--r-- | doc/gnosis.texi | 140 | ||||
-rw-r--r-- | gnosis-algorithm.el | 3 | ||||
-rw-r--r-- | gnosis-test.el | 2 | ||||
-rw-r--r-- | gnosis.el | 143 |
7 files changed, 321 insertions, 271 deletions
diff --git a/CONTRIBUTING.org b/CONTRIBUTING.org index 2f91e3d..eda1a7e 100644 --- a/CONTRIBUTING.org +++ b/CONTRIBUTING.org @@ -32,13 +32,26 @@ $ git format-patch HEAD^1 ** TODO Algorithm: changes for ef increase/decrease factors + After 3 successful in a row reviews increase ef increase factor by 5% & vice versa -** TODO Refactor =completing-read= UI choices +** DONE Refactor =completing-read= UI choices +CLOSED: [2024-02-17 Sat 21:59] +/DONE on version 0.1.7/ + =completing-read= is not an ideal solution as a UI. If user has not enabled a completion system, such as vertico, this would make gnosis unusable. -One possible solution is to create defcustom =gnosis-completing-read= +One possible solution is to create defcustom =gnosis-completing-read-function= that has ido-completing-read by default if vertico/ivy/helm is not enabled -** TODO Use vc instead git shell commands +*** Fix + +Implemented =gnosis-completing-read-function= + +** DONE Use vc instead git shell commands +CLOSED: [2024-02-17 Sat 21:59] + +/DONE on version 0.1.7/ + +Implemented =gnosis-git-*= functions to handle git commands. + diff --git a/doc/gnosis.info b/doc/gnosis.info index 712033c..348e70a 100644 --- a/doc/gnosis.info +++ b/doc/gnosis.info @@ -15,12 +15,11 @@ Gnosis (γνῶσις), pronounced "noh-sis", _meaning knowledge in Greek_, is a spaced repetition system implementation for note taking and self testing. -This manual is written for Gnosis version 0.1.5, released on 2023-01-29. +This manual is written for Gnosis version 0.1.7, released on 2023-02-18. • Official manual: <https://thanosapollo.org/user-manual/gnosis> • Git repositories: - • main: <https://git.thanosapollo.org/gnosis> - • sourcehut (mirror): <https://git.sr.ht/~thanosapollo/gnosis> + • <https://git.thanosapollo.org/gnosis> * Menu: @@ -29,6 +28,7 @@ This manual is written for Gnosis version 0.1.5, released on 2023-01-29. * Adding notes:: * Note Types:: * Customization & Extension:: +* Gnosis Algorithm:: -- The Detailed Node Listing -- @@ -47,16 +47,15 @@ Note Types Customization & Extension -* Adjust string comparison:: +* Adjust for typos | String Comparison:: * Creating Custom Note Types:: -* Customizing Gnosis Algorithm:: -* Auto push changes:: -Customizing Gnosis Algorithm +Gnosis Algorithm -* Gnosis Algorithm Initial Interval:: -* Gnosis Algorithm Easiness Factor:: -* Gnosis Algorithm Forgetting Factor:: +* Initial Interval:: +* Easiness Factor:: +* Forgetting Factor:: +* Auto push changes:: @@ -79,10 +78,8 @@ File: gnosis.info, Node: Installation, Next: Adding notes, Prev: Introduction 2 Installation ************** -Gnosis is not currently available in any ELPA, the recommended way to -install gnosis is via straight.el: - - <https://github.com/radian-software/straight.el> +Gnosis is available via MELPA + • <https://melpa.org/#/gnosis> * Menu: @@ -256,43 +253,41 @@ the ANSWER must be either 121 (‘y’) or 110 (‘n’), as those correspond to the character values used to represent them. -File: gnosis.info, Node: Customization & Extension, Prev: Note Types, Up: Top +File: gnosis.info, Node: Customization & Extension, Next: Gnosis Algorithm, Prev: Note Types, Up: Top 5 Customization & Extension *************************** To make development and customization easier, gnosis comes with -‘gnosis-dev’ module, that should be used to create a custom database for -testing. +‘gnosis-test’ module, that should be used to create a custom database +for testing. - To use ‘gnosis-dev’, first you have to ‘(require 'gnosis-dev)’ & run -‘M-x gnosis-dev-test’. This will create a new directory 'testing' with -a new database. + To use ‘gnosis-test’, first you have to ‘(require 'gnosis-test)’ & +run ‘M-x gnosis-test-start’. This will create a new database 'testing' +with random inputs. - To exit the testing environment, rerun ‘M-x gnosis-dev-test’ and then -enter ‘n’ (no) at the prompt "Start development env?" + To exit the testing environment, rerun ‘M-x gnosis-test-start’ and +then enter ‘n’ (no) at the prompt "Start development env?" * Menu: -* Adjust string comparison:: +* Adjust for typos | String Comparison:: * Creating Custom Note Types:: -* Customizing Gnosis Algorithm:: -* Auto push changes:: -File: gnosis.info, Node: Adjust string comparison, Next: Creating Custom Note Types, Up: Customization & Extension +File: gnosis.info, Node: Adjust for typos | String Comparison, Next: Creating Custom Note Types, Up: Customization & Extension -5.1 Adjust string comparison -============================ +5.1 Adjust for typos | String Comparison +======================================== -You may adjust ‘gnosis-string-difference’, this is a threshold value for +You can adjust ‘gnosis-string-difference’, this is a threshold value for string comparison that determines the maximum acceptable Levenshtein distance between two strings, which identifies their similarity Let's illustrate with an example: (setf gnosis-string-difference 1) - In this scenario, we set 'gnosis-string-difference' to 1. This + In this scenario, we set ‘gnosis-string-difference’ to 1. This implies that two strings will be recognized as similar if they exhibit a difference of at most one character edit. @@ -301,7 +296,7 @@ similar, considering that the latter involves just one additional character." -File: gnosis.info, Node: Creating Custom Note Types, Next: Customizing Gnosis Algorithm, Prev: Adjust string comparison, Up: Customization & Extension +File: gnosis.info, Node: Creating Custom Note Types, Prev: Adjust for typos | String Comparison, Up: Customization & Extension 5.2 Creating Custom Note Types ============================== @@ -333,22 +328,23 @@ should be done. ‘gnosis-display’ functions -File: gnosis.info, Node: Customizing Gnosis Algorithm, Next: Auto push changes, Prev: Creating Custom Note Types, Up: Customization & Extension +File: gnosis.info, Node: Gnosis Algorithm, Prev: Customization & Extension, Up: Top -5.3 Customizing Gnosis Algorithm -================================ +6 Gnosis Algorithm +****************** * Menu: -* Gnosis Algorithm Initial Interval:: -* Gnosis Algorithm Easiness Factor:: -* Gnosis Algorithm Forgetting Factor:: +* Initial Interval:: +* Easiness Factor:: +* Forgetting Factor:: +* Auto push changes:: -File: gnosis.info, Node: Gnosis Algorithm Initial Interval, Next: Gnosis Algorithm Easiness Factor, Up: Customizing Gnosis Algorithm +File: gnosis.info, Node: Initial Interval, Next: Easiness Factor, Up: Gnosis Algorithm -5.3.1 Gnosis Algorithm Initial Interval ---------------------------------------- +6.1 Initial Interval +==================== ‘gnosis-algorithm-interval’ is a list of 2 numbers, representing the first two initial intervals for successful reviews. @@ -362,85 +358,92 @@ you will see it again tomorrow, if you successfully review said note again, the next review will be after 3 days. -File: gnosis.info, Node: Gnosis Algorithm Easiness Factor, Next: Gnosis Algorithm Forgetting Factor, Prev: Gnosis Algorithm Initial Interval, Up: Customizing Gnosis Algorithm +File: gnosis.info, Node: Easiness Factor, Next: Forgetting Factor, Prev: Initial Interval, Up: Gnosis Algorithm -5.3.2 Gnosis Algorithm Easiness Factor --------------------------------------- +6.2 Easiness Factor +=================== -‘gnosis-algorithm-ef’ is a list that consists of 3 items. +The ‘gnosis-algorithm-ef’ is a list that consists of three items: - The first item is the increase factor, used to increase the easiness -factor upon successful review. + 1. Easiness factor increase value: Added to the easiness factor upon a + successful review. - Second item refers to the decrease factor, used to decrease the -easiness factor upon an unsuccessful review. + 2. Easiness factor decrease value: Subtracted from the total easiness + factor upon a failed review. - The third item is the initial total easiness factor, used to -calculate the next interval. + 3. Initial total easiness factor: Used to calculate the next interval. - The basic's of how this is used is that it's being multiplied with -the last interval upon a successful review, e.g if you last reviewed a -note 6 days ago, and the easiness factor of this note is 2.0, your next -interval would be 6 * 2.0 & the total easiness factor would be 2.0 + -increase-factor as well. + 4. How this is used: - Example: + Multiplies the last interval by the easiness factor after a +successful review. - (setq gnosis-algorithm-ef '(0.3 0.3 1.3)) + For example, if the last review was 6 days ago with an easiness +factor of 2.0, the next interval would be calculated as 6 * 2.0, and the +total easiness factor would be updated by adding the increase factor. + + Configuration example: + + (setq gnosis-algorithm-ef '(0.30 0.25 1.3)) -File: gnosis.info, Node: Gnosis Algorithm Forgetting Factor, Prev: Gnosis Algorithm Easiness Factor, Up: Customizing Gnosis Algorithm +File: gnosis.info, Node: Forgetting Factor, Next: Auto push changes, Prev: Easiness Factor, Up: Gnosis Algorithm -5.3.3 Gnosis Algorithm Forgetting Factor ----------------------------------------- +6.3 Forgetting Factor +===================== ‘gnosis-algorithm-ff’ is a floating number below 1. - It's used to calculate the next interval upon an unsuccessful review, -by being multiplied with last interval. + Used to determine the next interval after an unsuccessful review. - Example: + Multiplied with the last interval to calculate the next interval. +For example, if ‘gnosis-algorithm-ff’ is set to 0.5 and the last +interval was 6 days, the next interval will be 6 * 0.5 = 3 days. - (setq gnosis-algorithm-ff 0.5) + Example configuration: - For a note with a value of last-interval of 6 days and a ff of 0.5, -upon an unsuccessful review the next interval will be 6 * 0.5 + (setq gnosis-algorithm-ff 0.5) -File: gnosis.info, Node: Auto push changes, Prev: Customizing Gnosis Algorithm, Up: Customization & Extension +File: gnosis.info, Node: Auto push changes, Prev: Forgetting Factor, Up: Gnosis Algorithm -5.4 Auto push changes +6.4 Auto push changes ===================== -When setting ‘gnosis-auto-push’ to ‘t’, at the end of every review -session the changes to ‘gnosis-db’ will be pushed to the pre-configured -push remote. You have to set your push remote manually. +You can interactively use ‘gnosis-vc-push’ & ‘gnosis-vc-pull’. + + As the name suggests, they rely on ‘vc’ to work properly. + + Make sure you have setup a git remote for gnosis. + cd ~/<your-emacs-directory>/gnosis # default location for gnosis + git remote add <remote_name> <remote_url> # - (setf gnosis-auto-push t) + Depending on your setup, ‘vc’ might require an external package for +the ssh passphrase dialog, such as ‘x11-ssh-askpass’. Tag Table: Node: Top246 -Node: Introduction1419 -Node: Installation1899 -Node: Using straightel2268 -Node: Installing manually from source2780 -Node: Adding notes3469 -Node: Note Types4885 -Node: Cloze5109 -Node: Basic Type6082 -Node: Double6360 -Node: MCQ (Multiple Choice Question)6706 -Node: y-or-n7115 -Node: Customization & Extension7541 -Node: Adjust string comparison8267 -Node: Creating Custom Note Types9063 -Node: Customizing Gnosis Algorithm10198 -Node: Gnosis Algorithm Initial Interval10540 -Node: Gnosis Algorithm Easiness Factor11131 -Node: Gnosis Algorithm Forgetting Factor12135 -Node: Auto push changes12713 +Node: Introduction1277 +Node: Installation1757 +Node: Using straightel2034 +Node: Installing manually from source2546 +Node: Adding notes3235 +Node: Note Types4651 +Node: Cloze4875 +Node: Basic Type5848 +Node: Double6126 +Node: MCQ (Multiple Choice Question)6472 +Node: y-or-n6881 +Node: Customization & Extension7307 +Node: Adjust for typos | String Comparison8020 +Node: Creating Custom Note Types8856 +Node: Gnosis Algorithm9966 +Node: Initial Interval10190 +Node: Easiness Factor10697 +Node: Forgetting Factor11602 +Node: Auto push changes12162 End Tag Table diff --git a/doc/gnosis.org b/doc/gnosis.org index c2ffcf1..b10af7a 100644 --- a/doc/gnosis.org +++ b/doc/gnosis.org @@ -4,9 +4,9 @@ #+language: en #+options: ':t toc:nil author:t email:t num:t #+startup: content -#+macro: stable-version 0.1.5 -#+macro: release-date 2023-01-29 -#+macro: development-version 0.1.6-dev +#+macro: stable-version 0.1.7 +#+macro: release-date 2023-02-18 +#+macro: development-version 0.1.8-dev #+macro: file @@texinfo:@file{@@$1@@texinfo:}@@ #+macro: space @@texinfo:@: @@ #+macro: kbd @@texinfo:@kbd{@@$1@@texinfo:}@@ @@ -32,8 +32,7 @@ This manual is written for Gnosis version {{{stable-version}}}, released on {{{r + Official manual: <https://thanosapollo.org/user-manual/gnosis> + Git repositories: - + main: <https://git.thanosapollo.org/gnosis> - + sourcehut (mirror): <https://git.sr.ht/~thanosapollo/gnosis> + + <https://git.thanosapollo.org/gnosis> #+texinfo: @insertcopying @@ -48,10 +47,8 @@ your notes & review sessions, making it easier to study. * Installation -Gnosis is not currently available in any ELPA, the recommended way to -install gnosis is via straight.el: - - <https://github.com/radian-software/straight.el> +Gnosis is available via MELPA ++ <https://melpa.org/#/gnosis> ** Using straight.el If you have not installed straight.el, follow the instructions here: @@ -178,17 +175,18 @@ character values used to represent them. * Customization & Extension To make development and customization easier, gnosis comes with -=gnosis-dev= module, that should be used to create a custom database for +=gnosis-test= module, that should be used to create a custom database for testing. -To use =gnosis-dev=, first you have to =(require 'gnosis-dev)= & run =M-x -gnosis-dev-test=. This will create a new directory 'testing' with a new -database. +To use =gnosis-test=, first you have to =(require 'gnosis-test)= & run +=M-x gnosis-test-start=. This will create a new database 'testing' +with random inputs. + +To exit the testing environment, rerun =M-x gnosis-test-start= and +then enter =n= (no) at the prompt "Start development env?" -To exit the testing environment, rerun =M-x gnosis-dev-test= and then -enter =n= (no) at the prompt "Start development env?" -** Adjust string comparison -You may adjust =gnosis-string-difference=, this is a threshold value +** Adjust for typos | String Comparison +You can adjust =gnosis-string-difference=, this is a threshold value for string comparison that determines the maximum acceptable Levenshtein distance between two strings, which identifies their similarity @@ -198,7 +196,7 @@ Let's illustrate with an example: (setf gnosis-string-difference 1) #+end_src -In this scenario, we set `gnosis-string-difference` to 1. This implies +In this scenario, we set =gnosis-string-difference= to 1. This implies that two strings will be recognized as similar if they exhibit a difference of at most one character edit. @@ -207,6 +205,7 @@ similar, considering that the latter involves just one additional character." ** Creating Custom Note Types + Creating custom note types for gnosis is a fairly simple thing to do + First add your NEW-TYPE to =gnosis-note-types= @@ -233,8 +232,8 @@ this should be done. + Optionally, you might want to create your own custom =gnosis-display= functions -** Customizing Gnosis Algorithm -*** Gnosis Algorithm Initial Interval +* Gnosis Algorithm +** Initial Interval =gnosis-algorithm-interval= is a list of 2 numbers, representing the first two initial intervals for successful reviews. @@ -249,56 +248,61 @@ Using the above example, after first successfully reviewing a note, you will see it again tomorrow, if you successfully review said note again, the next review will be after 3 days. -*** Gnosis Algorithm Easiness Factor +** Easiness Factor -=gnosis-algorithm-ef= is a list that consists of 3 items. +The =gnosis-algorithm-ef= is a list that consists of three items: -The first item is the increase factor, used to increase the easiness -factor upon successful review. +1. Easiness factor increase value: Added to the easiness factor upon a + successful review. + +2. Easiness factor decrease value: Subtracted from the total easiness + factor upon a failed review. + +3. Initial total easiness factor: Used to calculate the next interval. -Second item refers to the decrease factor, used to -decrease the easiness factor upon an unsuccessful review. ++ How this is used: + +Multiplies the last interval by the easiness factor after a successful +review. -The third item is the initial total easiness factor, used to calculate -the next interval. +For example, if the last review was 6 days ago with an easiness factor +of 2.0, the next interval would be calculated as 6 * 2.0, and the +total easiness factor would be updated by adding the increase factor. -The basic's of how this is used is that it's being multiplied with the -last interval upon a successful review, e.g if you last reviewed a -note 6 days ago, and the easiness factor of this note is 2.0, your -next interval would be 6 * 2.0 & the total easiness factor would be -2.0 + increase-factor as well. - -Example: +Configuration example: #+begin_src emacs-lisp - (setq gnosis-algorithm-ef '(0.3 0.3 1.3)) + (setq gnosis-algorithm-ef '(0.30 0.25 1.3)) #+end_src -*** Gnosis Algorithm Forgetting Factor +** Forgetting Factor =gnosis-algorithm-ff= is a floating number below 1. -It's used to calculate the next interval upon an unsuccessful review, -by being multiplied with last interval. +Used to determine the next interval after an unsuccessful review. +Multiplied with the last interval to calculate the next interval. For +example, if =gnosis-algorithm-ff= is set to 0.5 and the last interval +was 6 days, the next interval will be 6 * 0.5 = 3 days. -Example: +Example configuration: #+begin_src emacs-lisp (setq gnosis-algorithm-ff 0.5) #+end_src -For a note with a value of last-interval of 6 days and a ff of 0.5, -upon an unsuccessful review the next interval will be 6 * 0.5 +** Auto push changes +You can interactively use =gnosis-vc-push= & =gnosis-vc-pull=. -** Auto push changes -When setting =gnosis-auto-push= to =t=, at the end of every review -session the changes to ~gnosis-db~ will be pushed to the pre-configured -push remote. You have to set your push remote manually. +As the name suggests, they rely on =vc= to work properly. -#+begin_src emacs-lisp -(setf gnosis-auto-push t) +Make sure you have setup a git remote for gnosis. +#+begin_src bash + cd ~/<your-emacs-directory>/gnosis # default location for gnosis + git remote add <remote_name> <remote_url> # #+end_src +Depending on your setup, =vc= might require an external package for +the ssh passphrase dialog, such as ~x11-ssh-askpass~. diff --git a/doc/gnosis.texi b/doc/gnosis.texi index efb9e18..487a4c1 100644 --- a/doc/gnosis.texi +++ b/doc/gnosis.texi @@ -30,7 +30,7 @@ a spaced repetition system implementation for note taking and self testing. @noindent -This manual is written for Gnosis version 0.1.5, released on 2023-01-29. +This manual is written for Gnosis version 0.1.7, released on 2023-02-18. @itemize @item @@ -39,9 +39,7 @@ Official manual: @uref{https://thanosapollo.org/user-manual/gnosis} Git repositories: @itemize @item -main: @uref{https://git.thanosapollo.org/gnosis} -@item -sourcehut (mirror): @uref{https://git.sr.ht/~thanosapollo/gnosis} +@uref{https://git.thanosapollo.org/gnosis} @end itemize @end itemize @@ -54,6 +52,7 @@ sourcehut (mirror): @uref{https://git.sr.ht/~thanosapollo/gnosis} * Adding notes:: * Note Types:: * Customization & Extension:: +* Gnosis Algorithm:: @detailmenu --- The Detailed Node Listing --- @@ -73,16 +72,15 @@ Note Types Customization & Extension -* Adjust string comparison:: +* Adjust for typos | String Comparison:: * Creating Custom Note Types:: -* Customizing Gnosis Algorithm:: -* Auto push changes:: -Customizing Gnosis Algorithm +Gnosis Algorithm -* Gnosis Algorithm Initial Interval:: -* Gnosis Algorithm Easiness Factor:: -* Gnosis Algorithm Forgetting Factor:: +* Initial Interval:: +* Easiness Factor:: +* Forgetting Factor:: +* Auto push changes:: @end detailmenu @end menu @@ -101,10 +99,11 @@ your notes & review sessions, making it easier to study. @node Installation @chapter Installation -Gnosis is not currently available in any ELPA, the recommended way to -install gnosis is via straight.el: - -@uref{https://github.com/radian-software/straight.el} +Gnosis is available via MELPA +@itemize +@item +@uref{https://melpa.org/#/gnosis} +@end itemize @menu * Using straight.el: Using straightel. @@ -275,27 +274,25 @@ character values used to represent them. @chapter Customization & Extension To make development and customization easier, gnosis comes with -@samp{gnosis-dev} module, that should be used to create a custom database for +@samp{gnosis-test} module, that should be used to create a custom database for testing. -To use @samp{gnosis-dev}, first you have to @samp{(require 'gnosis-dev)} & run @samp{M-x -gnosis-dev-test}. This will create a new directory 'testing' with a new -database. +To use @samp{gnosis-test}, first you have to @samp{(require 'gnosis-test)} & run +@samp{M-x gnosis-test-start}. This will create a new database 'testing' +with random inputs. -To exit the testing environment, rerun @samp{M-x gnosis-dev-test} and then -enter @samp{n} (no) at the prompt ``Start development env?'' +To exit the testing environment, rerun @samp{M-x gnosis-test-start} and +then enter @samp{n} (no) at the prompt ``Start development env?'' @menu -* Adjust string comparison:: +* Adjust for typos | String Comparison:: * Creating Custom Note Types:: -* Customizing Gnosis Algorithm:: -* Auto push changes:: @end menu -@node Adjust string comparison -@section Adjust string comparison +@node Adjust for typos | String Comparison +@section Adjust for typos | String Comparison -You may adjust @samp{gnosis-string-difference}, this is a threshold value +You can adjust @samp{gnosis-string-difference}, this is a threshold value for string comparison that determines the maximum acceptable Levenshtein distance between two strings, which identifies their similarity @@ -305,7 +302,7 @@ Let's illustrate with an example: (setf gnosis-string-difference 1) @end lisp -In this scenario, we set `gnosis-string-difference` to 1. This implies +In this scenario, we set @samp{gnosis-string-difference} to 1. This implies that two strings will be recognized as similar if they exhibit a difference of at most one character edit. @@ -352,17 +349,18 @@ this should be done. Optionally, you might want to create your own custom @samp{gnosis-display} functions @end itemize -@node Customizing Gnosis Algorithm -@section Customizing Gnosis Algorithm +@node Gnosis Algorithm +@chapter Gnosis Algorithm @menu -* Gnosis Algorithm Initial Interval:: -* Gnosis Algorithm Easiness Factor:: -* Gnosis Algorithm Forgetting Factor:: +* Initial Interval:: +* Easiness Factor:: +* Forgetting Factor:: +* Auto push changes:: @end menu -@node Gnosis Algorithm Initial Interval -@subsection Gnosis Algorithm Initial Interval +@node Initial Interval +@section Initial Interval @samp{gnosis-algorithm-interval} is a list of 2 numbers, representing the first two initial intervals for successful reviews. @@ -377,60 +375,72 @@ Using the above example, after first successfully reviewing a note, you will see it again tomorrow, if you successfully review said note again, the next review will be after 3 days. -@node Gnosis Algorithm Easiness Factor -@subsection Gnosis Algorithm Easiness Factor +@node Easiness Factor +@section Easiness Factor -@samp{gnosis-algorithm-ef} is a list that consists of 3 items. +The @samp{gnosis-algorithm-ef} is a list that consists of three items: -The first item is the increase factor, used to increase the easiness -factor upon successful review. +@enumerate +@item +Easiness factor increase value: Added to the easiness factor upon a +successful review. -Second item refers to the decrease factor, used to -decrease the easiness factor upon an unsuccessful review. +@item +Easiness factor decrease value: Subtracted from the total easiness +factor upon a failed review. -The third item is the initial total easiness factor, used to calculate -the next interval. +@item +Initial total easiness factor: Used to calculate the next interval. -The basic's of how this is used is that it's being multiplied with the -last interval upon a successful review, e.g if you last reviewed a -note 6 days ago, and the easiness factor of this note is 2.0, your -next interval would be 6 * 2.0 & the total easiness factor would be -2.0 + increase-factor as well. +@item +How this is used: +@end enumerate -Example: +Multiplies the last interval by the easiness factor after a successful +review. + +For example, if the last review was 6 days ago with an easiness factor +of 2.0, the next interval would be calculated as 6 * 2.0, and the +total easiness factor would be updated by adding the increase factor. + +Configuration example: @lisp -(setq gnosis-algorithm-ef '(0.3 0.3 1.3)) +(setq gnosis-algorithm-ef '(0.30 0.25 1.3)) @end lisp -@node Gnosis Algorithm Forgetting Factor -@subsection Gnosis Algorithm Forgetting Factor +@node Forgetting Factor +@section Forgetting Factor @samp{gnosis-algorithm-ff} is a floating number below 1. -It's used to calculate the next interval upon an unsuccessful review, -by being multiplied with last interval. +Used to determine the next interval after an unsuccessful review. +Multiplied with the last interval to calculate the next interval. For +example, if @samp{gnosis-algorithm-ff} is set to 0.5 and the last interval +was 6 days, the next interval will be 6 * 0.5 = 3 days. -Example: +Example configuration: @lisp (setq gnosis-algorithm-ff 0.5) @end lisp -For a note with a value of last-interval of 6 days and a ff of 0.5, -upon an unsuccessful review the next interval will be 6 * 0.5 - @node Auto push changes @section Auto push changes -When setting @samp{gnosis-auto-push} to @samp{t}, at the end of every review -session the changes to @code{gnosis-db} will be pushed to the pre-configured -push remote. You have to set your push remote manually. +You can interactively use @samp{gnosis-vc-push} & @samp{gnosis-vc-pull}. -@lisp -(setf gnosis-auto-push t) -@end lisp +As the name suggests, they rely on @samp{vc} to work properly. + +Make sure you have setup a git remote for gnosis. +@example +cd ~/<your-emacs-directory>/gnosis # default location for gnosis +git remote add <remote_name> <remote_url> # +@end example + +Depending on your setup, @samp{vc} might require an external package for +the ssh passphrase dialog, such as @code{x11-ssh-askpass}. @bye diff --git a/gnosis-algorithm.el b/gnosis-algorithm.el index 16f13db..e850c9f 100644 --- a/gnosis-algorithm.el +++ b/gnosis-algorithm.el @@ -113,9 +113,6 @@ Returns a list of: (INTERVAL N EF) where, (error "Value of total-ef from `gnosis-algorithm-ef' must be above 1.3"))) ;; Calculate the next easiness factor. (let* ((next-ef (gnosis-algorithm-e-factor ef success)) - ;; Calculate the next interval. - ;; ef should not be > 3.0 unless the card is imported/edited, - ;; thus ignore initial intervals (interval (cond ;; TODO: Rewrite this! diff --git a/gnosis-test.el b/gnosis-test.el index c168e25..92ee5c1 100644 --- a/gnosis-test.el +++ b/gnosis-test.el @@ -91,7 +91,7 @@ by the thoracodorsal nerve." (when (y-or-n-p "Add note with multiple clozes?") (dotimes (_ num) (gnosis-add-note--cloze :deck testing-deck - :note "this is a {c1:note} with multiple {c1:clozes}" + :note "this is a {c1:note}, a note with multiple {c1:clozes}" :hint "note" :tags (gnosis-test-random-items gnosis-test-tags 2) :extra "extra"))) @@ -64,20 +64,28 @@ between two strings to consider them as similar." :type 'integer :group 'gnosis) -(defcustom gnosis-auto-push nil - "Automatically run `gnosis-auto-push-command' at the end of every review session." +(defcustom gnosis-auto-vc-push nil + "Run `vc-push' at the end of every review session." :type 'boolean :group 'gnosis) -(defcustom gnosis-auto-push-command "push" - "Git shell command to run at the end of a review session. +(defcustom gnosis-mcq-display-choices t + "When t, display choices for mcq notes during review. -Command specified will be executed when `gnosis-auto-push' is enabled. +Users that use a completion framework like ivy/helm/vertico may want +to set this to nil, as the choices will be displayed in the completion +framework's minibuffer." + :type 'boolean + :group 'gnosis) -It should be provided as a string without the `git' prefix, assuming -that git is available in the system's PATH. For example, setting it -to \"push\" will execute the command 'git push'." - :type 'string +(defcustom gnosis-completing-read-function + (cond ((or (bound-and-true-p ivy-mode) + (bound-and-true-p helm-mode) + (bound-and-true-p vertico-mode)) + #'completing-read) + (t #'ido-completing-read)) + "Function to use for `completing-read'." + :type 'function :group 'gnosis) (defvar gnosis-images-dir (expand-file-name "images" gnosis-dir) @@ -97,9 +105,12 @@ to \"push\" will execute the command 'git push'." (defconst gnosis-db-version 1 "Gnosis database version.") -(defvar gnosis-note-types '(MCQ Cloze Basic Double y-or-n) +(defvar gnosis-note-types '("MCQ" "Cloze" "Basic" "Double" "y-or-n") "Gnosis available note types.") +(defvar gnosis-previous-note-tags '() + "Tags input from previously added note.") + ;;; Faces (defgroup gnosis-faces nil @@ -199,29 +210,6 @@ Example: "From TABLE use where to delete VALUE." (emacsql gnosis-db `[:delete :from ,table :where ,value])) -(cl-defun gnosis-completing-read (prompt options info &optional (face-for-info 'font-lock-doc-face)) - "A version of `completing-read' with text properties, padding & choosable face. -Returns selected option from OPTIONS. - -WARNING: Do NOT use htis functions as is now! - -PROMPT is a string to prompt with; normally it ends in a colon and a space. -OPTIONS is a list of strings. -INFO is a list of strings, which will be displayed as additional info for option -FACE-FOR-INFO is the face used to display info for option." - (let* ((choices (cl-mapcar 'cons options info)) - (max-choice-length (apply #'max (mapcar #'length options))) - (formatted-choices - (mapcar (lambda (choice) - (cons (concat (format "%s" (car choice)) - (make-string (- max-choice-length (length (car choice))) ? ) - " " - (propertize (format "%s" (cdr choice)) 'face face-for-info)) - (car choice))) - choices))) - (cdr (assoc (completing-read prompt formatted-choices nil t) - formatted-choices)))) - (defun gnosis-replace-item-at-index (index new-item list) "Replace item at INDEX in LIST with NEW-ITEM." (cl-loop for i from 0 for item in list @@ -234,6 +222,15 @@ FACE-FOR-INFO is the face used to display info for option." (erase-buffer) (fill-paragraph (insert "\n" (propertize question 'face 'gnosis-face-main))))) +(defun gnosis-display-mcq-options (id) + "Display answer options for mcq note ID." + (let ((options (apply #'append (gnosis-select 'options 'notes `(= id 1) t))) + (option-num 1)) + (insert "\n\n" (propertize "Options:" 'face 'gnosis-face-directions)) + (cl-loop for option in options + do (insert (format "\n%s. %s" option-num option)) + (setf option-num (1+ option-num))))) + (defun gnosis-display-cloze-sentence (sentence clozes) "Display cloze sentence for SENTENCE with CLOZES." (erase-buffer) @@ -370,7 +367,7 @@ Set SPLIT to t to split all input given." "Return name from table DECKS." (when (equal (gnosis-select 'name 'decks) nil) (error "No decks found")) - (completing-read "Deck: " (gnosis-select 'name 'decks))) + (funcall gnosis-completing-read-function "Deck: " (gnosis-select 'name 'decks))) (cl-defun gnosis--get-deck-id (&optional (deck (gnosis--get-deck-name))) "Return id for DECK name." @@ -416,7 +413,7 @@ When called with a prefix, unsuspends all notes for tag." (defun gnosis-suspend () "Suspend note(s) with specified values." (interactive) - (let ((item (completing-read "Suspend by: " '("Deck" "Tag")))) + (let ((item (funcall gnosis-completing-read-function "Suspend by: " '("Deck" "Tag")))) (pcase item ("Deck" (gnosis-suspend-deck)) ("Tag" (gnosis-suspend-tag)) @@ -559,7 +556,8 @@ Refer to `gnosis-add-note--double' for more." :question (read-string "Question: ") :answer (read-string "Answer: ") :image (when (y-or-n-p "Add image to display during review?") - (completing-read "Select image: " (gnosis-directory-files))) + (funcall gnosis-completing-read-function "Select image: " + (gnosis-directory-files))) :hint (read-string "Hint: ") :extra (read-string "Extra: ") :tags (gnosis-tag-prompt))))) @@ -667,7 +665,7 @@ See `gnosis-add-note--cloze' for more reference." ;;;###autoload (defun gnosis-add-note (type) "Create note(s) as TYPE interactively." - (interactive (list (completing-read "Type: " gnosis-note-types nil t))) + (interactive (list (funcall gnosis-completing-read-function "Type: " gnosis-note-types nil t))) (when gnosis-testing (unless (y-or-n-p "You are using a testing environment! Continue?") (error "Aborted"))) @@ -680,7 +678,7 @@ See `gnosis-add-note--cloze' for more reference." "Choose the correct answer, from mcq choices for question ID." (let ((choices (gnosis-get 'options 'notes `(= id ,id))) (history-add-new-input nil)) ;; Disable history - (completing-read "Answer: " choices))) + (funcall gnosis-completing-read-function "Answer: " choices))) (defun gnosis-cloze-remove-tags (string) "Replace cx-tags in STRING. @@ -756,7 +754,7 @@ By default, DIR value is `gnosis-images-dir' & REGEX value is \"^[^.]\"" Optionally, add cusotm PROMPT." (let* ((prompt (or prompt "Select image: ")) - (image (completing-read prompt (gnosis-directory-files gnosis-images-dir)))) + (image (funcall gnosis-completing-read-function prompt (gnosis-directory-files gnosis-images-dir)))) image)) (defun gnosis-get-tags--unique () @@ -808,14 +806,19 @@ MATCH: Require match, t or nil value DUE: if t, return tags for due notes from `gnosis-due-tags'. Returns a list of unique tags." (let* ((tags '()) - (tag "")) - (while (not (string= tag "q")) - (setf tag (completing-read (concat prompt (format " %s (q for quit): " tags)) - (cons "q" (if due (gnosis-review-get-due-tags) - (gnosis-get-tags--unique))) - nil match)) - (unless (or (string= tag "q") (member tag tags)) - (push tag tags))) + (tag "") + (use-prev (when gnosis-previous-note-tags + (y-or-n-p (format "Use tags from previous note %s?" gnosis-previous-note-tags))))) + (if use-prev + (setf tags gnosis-previous-note-tags) + (while (not (string= tag "q")) + (setf tag (funcall gnosis-completing-read-function (concat prompt (format " %s (q for quit): " tags)) + (cons "q" (if due (gnosis-review-get-due-tags) + (gnosis-get-tags--unique))) + nil match)) + (unless (or (string= tag "q") (member tag tags)) + (push tag tags)))) + (setf gnosis-previous-note-tags (if use-prev tags (reverse tags))) (reverse tags))) ;; Review @@ -910,8 +913,10 @@ SUCCESS is a boolean value, t for success, nil for failure." ;; Update review (gnosis-update 'review `(= ef ',ef) `(= 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)))) `(= id ,id)) + (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)))) + `(= 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)) @@ -921,6 +926,8 @@ SUCCESS is a boolean value, t for success, nil for failure." "Display multiple choice answers for question ID." (gnosis-display-image id) (gnosis-display-question id) + (when gnosis-mcq-display-choices + (gnosis-display-mcq-options id)) (let* ((choices (gnosis-get 'options 'notes `(= id ,id))) (answer (nth (- (gnosis-get 'answer 'notes `(= id ,id)) 1) choices)) (user-choice (gnosis-mcq-answer id))) @@ -1018,6 +1025,21 @@ Used to reveal all clozes left with `gnosis-face-cloze-unanswered' face." (funcall func-name id))) (error "Malformed note type: '%s'" type)))) + +;;;###autoload +(cl-defun gnosis-vc-push (&optional (dir gnosis-dir)) + "Run `vc-push' in DIR." + (interactive) + (let ((default-directory dir)) + (vc-push))) + +;;;###autoload +(cl-defun gnosis-vc-pull (&optional (dir gnosis-dir)) + "Run `vc-pull' in DIR." + (interactive) + (let ((default-directory dir)) + (vc-pull))) + (defun gnosis-review-commit (note-num) "Commit review session on git repository. @@ -1033,11 +1055,11 @@ NOTE-NUM: The number of notes reviewed in the session." (unless (file-exists-p (expand-file-name ".git" gnosis-dir)) (vc-create-repo 'Git)) ;; TODO: Redo this using vc - (shell-command (concat git " add " (shell-quote-argument "gnosis.db"))) - (shell-command (concat git " commit -m " - (shell-quote-argument (concat (format "Total notes for session: %d " note-num))))) - (when gnosis-auto-push - (shell-command (concat git " " gnosis-auto-push-command))) + (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)))) + (when gnosis-auto-vc-push + (gnosis-vc-push)) (message "Review session finished. %d notes reviewed." note-num))) (defun gnosis-review--session (notes) @@ -1070,7 +1092,7 @@ NOTES: List of note ids" (defun gnosis-edit-note (id) "Edit note with value of id ID." - (pcase (completing-read "Edit: " '(contents ef) nil t) + (pcase (funcall gnosis-completing-read-function "Edit: " '("contents" "ef") nil t) ("contents" (gnosis-edit-note-contents id)) ("ef" (gnosis-edit-ef id)) (_ (message "No such value.")))) @@ -1078,7 +1100,8 @@ NOTES: List of note ids" (defun gnosis-edit-ef (id) "Edit easiness factor values for note with id value ID." (let ((ef-full (caar (gnosis-select 'ef 'review `(= id ,id)))) - (old-value-index (pcase (completing-read "Change Factor: " '("Increase" "Decrease" "Total")) + (old-value-index (pcase (funcall gnosis-completing-read-function "Change Factor: " + '("Increase" "Decrease" "Total")) ("Total" 2) ("Decrease" 1) ("Increase" 0))) @@ -1334,10 +1357,10 @@ review." (defun gnosis-review () "Start gnosis review session." (interactive) - (let ((review-type (completing-read "Review: " '("Due notes" - "Due notes of deck" - "Due notes of specified tag(s)" - "All notes of tag(s)")))) + (let ((review-type (funcall gnosis-completing-read-function "Review: " '("Due notes" + "Due notes of deck" + "Due notes of specified tag(s)" + "All notes of tag(s)")))) (pcase review-type ("Due notes" (gnosis-review--session (gnosis-review-get-due-notes))) ("Due notes of deck" (gnosis-review--session (gnosis-get-deck-due-notes))) |