summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThanos Apollo <[email protected]>2025-01-03 20:05:47 +0200
committerThanos Apollo <[email protected]>2025-01-03 20:07:35 +0200
commit1ec9e74c7ecdb085b9c92b5c742f27ee800d8a14 (patch)
tree80ce4e7f498bd3e595c39160d4630f4e926ea83f
parent5194b9aa1633fe1aba6b7e4661fccaa1303dc337 (diff)
Rewrite tags & extraction of links.
* We are using a new tags table. * Extraction of links will occur in parathema.
-rw-r--r--gnosis.el133
1 files changed, 56 insertions, 77 deletions
diff --git a/gnosis.el b/gnosis.el
index 79411f6..dc89b86 100644
--- a/gnosis.el
+++ b/gnosis.el
@@ -1041,81 +1041,60 @@ DATE is a list of the form (year month day)."
(time-date (encode-time 0 0 0 (nth 2 date) (nth 1 date) (nth 0 date))))
(not (time-less-p time-now time-date))))
-(cl-defun gnosis-tag-prompt (&key (prompt "Selected tags:") (due nil))
- "PROMPT user to select tags, until they enter `q'.
-
-Prompt user to select tags, generated from `gnosis-get-tags--unique'.
-PROMPT: Prompt string value
-MATCH: Require match, t or nil value
-DUE: if t, return tags for due notes from `gnosis-due-tags'."
- (let ((tags '()))
- (cl-loop for tag = (completing-read
- (concat prompt (format " (%s) (q for quit): " (mapconcat #'identity tags " ")))
- (cons "q" (if due (gnosis-review-get-due-tags)
- (gnosis-get-tags--unique)))
- nil t)
- until (string= tag "q")
- unless (member tag tags)
- do (push tag tags))
- tags))
-
-(defun gnosis-hint-prompt (previous-hint &optional prompt)
- "Prompt user for hint.
-
-PROMPT: Prompt string value
-PREVIOUS-HINT: Previous hint value, if any. If nil, use PROMPT as
-default value."
- (let* ((prompt (or prompt "Hint: "))
- (hint (read-string prompt previous-hint)))
- (setf gnosis-previous-note-hint hint)
- hint))
-
-(defun gnosis-prompt-mcq-input (&optional prompt string)
- "PROMPT for MCQ note content.
-
-STRING: Guidance string."
- (let ((user-input (gnosis-read-string-from-buffer (or prompt (car gnosis-mcq-guidance) "")
- (or string (cdr gnosis-mcq-guidance) ""))))
- (cond ((not (string-match-p gnosis-mcq-separator user-input))
- (gnosis-prompt-mcq-input (format "`gnosis-mcq-separator': %s not found!" gnosis-mcq-separator)
- user-input))
- ((not (string-match "{.*}" user-input))
- (gnosis-prompt-mcq-input (format "Please wrap the right option with {}")
- user-input))
- (t (gnosis-mcq-process-input user-input)))))
-
-(defun gnosis-mcq-process-input (user-input &optional stem-separator option-separator)
- "Process USER-INPUT for MCQ note.
-
-STEM-SEPARATOR: Separator of question stem & options
-OPTION-SEPARATOR: Separator of each option
-
-Return ((QUESTION CHOICES) CORRECT-CHOICE-INDEX)"
- (let* ((stem-separator (or stem-separator gnosis-mcq-separator))
- (option-separator (or option-separator gnosis-mcq-option-separator))
- (input-separated (split-string user-input stem-separator t "[\s\n]"))
- (stem (car input-separated))
- (input (split-string
- (mapconcat 'identity (cdr input-separated) "\n")
- option-separator t "[\s\n]"))
- (correct-choice-index
- ;; Make sure correct choice is given
- (or (cl-position-if (lambda (string) (string-match "{.*}" string)) input)
- (error "Correct choice not found. Use {} to indicate the correct option")))
- (choices (mapcar (lambda (string) (replace-regexp-in-string "{\\|}" "" string)) input)))
- (list (cons stem choices) (+ correct-choice-index 1))))
-
-(defun gnosis-prompt-tags--split (&optional previous-note-tags)
- "Prompt user for tags, split string by space.
-
-Return a list of tags, split by space. If PREVIOUS-NOTE-TAGS is
-provided, use it as the default value."
- (let* ((previous-note-tags (or nil previous-note-tags))
- (tags (split-string (read-from-minibuffer "Tags: " (mapconcat #'identity previous-note-tags " ")) " ")))
- (setf gnosis-previous-note-tags tags)
- (if (equal tags '("")) '("untagged") tags)))
-
-;; Collecting note ids
+(defun gnosis-tags--update (tags)
+ "Update db for TAGS."
+ (emacsql-with-transaction gnosis-db
+ (cl-loop for tag in tags
+ do (gnosis--insert-into 'tags `[,tag]))))
+
+(cl-defun gnosis-tags--prompt (&key (prompt "Tags (seperated by ,): ")
+ (predicate nil)
+ (require-match nil)
+ (initial-input nil))
+ "Prompt user for tags.
+
+Outputs only unique tags."
+ (gnosis-tags-refresh)
+ (let* ((tags (gnosis-tags-get-all))
+ (input (delete-dups
+ (completing-read-multiple
+ prompt tags predicate require-match initial-input))))
+ input))
+
+(cl-defun gnosis-tags-prompt ()
+ "Tag prompt for adding notes.
+
+If you only require a tag prompt, refer to `gnosis-tags--prompt'."
+ (let ((input (gnosis-tags--prompt)))
+ (when input
+ (gnosis-tags--update input)
+ (setf gnosis-previous-note-tags input))
+ (or input '("untagged"))))
+
+(defun gnosis-tags-get-all ()
+ "Output all tags from database."
+ (gnosis-select '* 'tags '1=1 t))
+
+(defun gnosis-tags-refresh ()
+ "Refresh tags value."
+ (let ((tags (gnosis-get-tags--unique)))
+ ;; Delete all values from tags table.
+ (gnosis--delete 'tags '1=1)
+ ;; Insert all unique tags from notes.
+ (emacsql-with-transaction gnosis-db
+ (cl-loop for tag in tags
+ do (gnosis--insert-into 'tags `[,tag])))))
+
+;; Links
+(defun gnosis-extract-id-links (input &optional start)
+ "Extract all link IDs from INPUT string and return them as a list.
+
+START is the search starting position, used internally for recursion."
+ (let ((start (or start 0)))
+ (if (string-match "\\[\\[id:\\([^]]+\\)\\]\\[" input start)
+ (cons (match-string 1 input)
+ (gnosis-extract-id-links input (match-end 0)))
+ nil)))
;; TODO: Rewrite this! Tags should be an input of strings,
;; interactive handling should be done by "helper" funcs
@@ -1137,10 +1116,10 @@ QUERY: String value,"
(gnosis-review-get-due-notes))
;; All notes for tags
((and tags (null due) (null deck))
- (gnosis-select-by-tag (gnosis-tag-prompt)))
+ (gnosis-select-by-tag (gnosis-tags--prompt :require-match t)))
;; All due notes for tags
((and tags due (null deck))
- (gnosis-select-by-tag (gnosis-tag-prompt) t))
+ (gnosis-select-by-tag (gnosis-tags--prompt :require-match t) t))
;; All notes for deck
((and (null tags) (null due) deck)
(gnosis-get-deck-notes deck nil))