diff options
author | Thanos Apollo <[email protected]> | 2025-01-03 20:05:47 +0200 |
---|---|---|
committer | Thanos Apollo <[email protected]> | 2025-01-03 20:07:35 +0200 |
commit | 1ec9e74c7ecdb085b9c92b5c742f27ee800d8a14 (patch) | |
tree | 80ce4e7f498bd3e595c39160d4630f4e926ea83f | |
parent | 5194b9aa1633fe1aba6b7e4661fccaa1303dc337 (diff) |
Rewrite tags & extraction of links.
* We are using a new tags table.
* Extraction of links will occur in parathema.
-rw-r--r-- | gnosis.el | 133 |
1 files changed, 56 insertions, 77 deletions
@@ -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)) |