From fbb243c45b71853d841fa491efe4558b65178898 Mon Sep 17 00:00:00 2001 From: jao Date: Fri, 16 Feb 2024 11:52:41 +0000 Subject: jao-org-notes: narrow to category, list all tags, refactorings --- lib/doc/jao-org-notes.el | 106 ++++++++++++++++++++++++++--------------------- 1 file changed, 59 insertions(+), 47 deletions(-) diff --git a/lib/doc/jao-org-notes.el b/lib/doc/jao-org-notes.el index 05481b7..a91971e 100644 --- a/lib/doc/jao-org-notes.el +++ b/lib/doc/jao-org-notes.el @@ -30,35 +30,43 @@ (defvar jao-org-notes-dir (expand-file-name "notes" org-directory)) -(defun jao-org-notes--title-or-tags (str) - (let ((ts (split-string str "[:,]+" t))) - (format "^#.(title: .*%s|tags:.*(%s:))" str (mapconcat #'identity ts ":|")))) +(defun jao-org-notes-list () + (directory-files-recursively jao-org-notes-dir "\\.org$")) (defun jao-org-notes--rg-cmd (rgx &rest args) `("rg" "--null" "--line-buffered" "--color=never" "--max-columns=250" - "--no-heading" "--smart-case" ,@args "." "-e" ,rgx)) + "--type=org" "--line-number" "--no-heading" "--smart-case" + ,@args ,default-directory "-e" ,rgx)) (defun jao-org-notes--rg-title-or-tags (str) - (jao-org-notes--rg-cmd (jao-org-notes--title-or-tags str) "-m" "2")) + (let* ((m (string-match "^\\([^/]+\\)/\\(.*\\)" str)) + (d (or (and m (match-string 1 str)) "")) + (str (if m (match-string 2 str) str)) + (default-directory + (if (file-directory-p d) (expand-file-name d) default-directory)) + (ts (mapconcat #'identity (split-string str "[:,]+" t) ":|")) + (rgx (format "^#.(title: .*%s|(tags:.*(%s:)))" str ts))) + (jao-org-notes--rg-cmd rgx "-m" "2"))) (defun jao-org-notes--clean-match (m) - (cons (format "%s %s" - (replace-regexp-in-string "^\\./" "" (car m)) - (replace-regexp-in-string "#\\+\\(title\\|tags\\):" - " (\\1)" (cadr m))) - (expand-file-name (car m) default-directory))) + (list (format "%s %s" + (replace-regexp-in-string default-directory "" (car m) nil t) + (replace-regexp-in-string "[0-9]+:#\\+\\(title\\|tags\\):" + "" (cadr m))) + (expand-file-name (car m) default-directory) + (string-to-number (cadr m)))) (defun jao-org-notes--matches (lines) (mapcar (lambda (l) (jao-org-notes--clean-match (split-string l "\0" t))) lines)) -(defun jao-org-notes--grep-rx (rx) +(defun jao-org-notes--grep-rx (rx &rest rg-args) (let ((default-directory jao-org-notes-dir)) (jao-org-notes--matches - (apply #'jao-shell-cmd-lines (jao-org-notes--rg-cmd rx))))) + (apply #'jao-shell-cmd-lines (apply #'jao-org-notes--rg-cmd rx rg-args))))) (defvar jao-org-notes--grep-history nil) -(defun jao-org-notes--consult-rg (prompt &optional cat no-req) +(defun jao-org-notes--consult-rg (prompt &optional cat no-req cmd) (let ((default-directory (expand-file-name (or cat "") jao-org-notes-dir))) (consult--read (consult--async-command #'jao-org-notes--rg-title-or-tags @@ -69,7 +77,7 @@ :require-match (not no-req) :category 'jao-org-notes-lookup :lookup (lambda (cand cands &rest _) - (or (cdr (assoc cand cands)) (substring cand 1))) + (or (cadr (assoc cand cands)) (substring cand 1))) :history '(:input jao-org-notes--grep-history)))) (defun jao-org-notes-cats () @@ -94,7 +102,10 @@ (insert "#+title: " title "\n") t))))) -(persist-defvar jao-org-notes--tags nil "Tags used so far in notes.") +(defun jao-org-notes--find-tag (tag) + (jao-org-notes--grep-rx (format "^#.tags:.*:%s:" tag) "-m" "1")) + +(defvar jao-org-notes--tags nil) (defvar jao-org-notes--tag-history nil) (defun jao-org-notes--read-tags () @@ -103,18 +114,27 @@ (setq jao-org-notes--tags (seq-union jao-org-notes--tags tags #'string=)) tags)) -(defun jao-org-notes--insert-tags () - (insert "#+tags: :" - (mapconcat #'identity (jao-org-notes--read-tags) ":") - ":\n")) +(defun jao-org-notes--template (k) + `(,k "Note" plain (file jao-org-notes-create) "\n- %a\n %i")) -(defun jao-org-notes--insert-date () - (org-insert-time-stamp (current-time) t t "#+date: " "\n")) +(defun jao-org-notes-all-tags () + (let ((tags nil)) + (dolist (m (jao-org-notes--find-tag ".*")) + (setq tags (seq-union tags (cdr (split-string (car m) ":" t))))) + (sort tags #'string<))) -(defun jao-org-notes--template (k) - `(,k "Note" plain (file jao-org-notes-create) "\n- %a\n %i" :jump-to-captured t)) +(defun jao-org-notes-find-for-pdf (&optional file-name) + "Given a PDF file name, find its org notes counterpart." + (let* ((file-name (or file-name buffer-file-name)) + (bn (file-name-base file-name)) + (rx (format "%s\\.org$" (regexp-quote bn))) + (pred (lambda () (string-prefix-p jao-org-notes-dir buffer-file-name)))) + (save-some-buffers nil pred) + (or (car (directory-files-recursively jao-org-notes-dir rx)) + (let* ((d (completing-read "Notes subdir: " (jao-org-notes-cats) nil t)) + (d (file-name-as-directory d))) + (expand-file-name (concat d bn ".org") jao-org-notes-dir))))) -;;;###autoload (defun jao-org-notes-open () "Search for a note file, matching tags and titles with completion." (interactive) @@ -126,50 +146,41 @@ (interactive) (let* ((tags (jao-org-notes--read-tags)) (fn (lambda () - (prog1 (jao-org-notes--grep-rx (format "^#.tags:.*:%s:" (car tags))) + (prog1 (jao-org-notes--find-tag (car tags)) (setq tags (cdr tags))))) (res (funcall fn))) (while (and res tags) (setq res (seq-intersection res (funcall fn)))) (unless res (user-error "No notes found")) (when-let (f (completing-read "Select file: " (mapcar #'car res))) - (find-file (cdr (assoc f res)))))) + (find-file (cadr (assoc f res)))))) -;;;###autoload (defun jao-org-notes-create () "Create a new note file, matching tags and titles with completion." (interactive) (when (jao-org-notes--insert-title) - (jao-org-notes--insert-date) - (jao-org-notes--insert-tags)) + (org-insert-time-stamp (current-time) t t "#+date: " "\n") + (insert "#+tags: :" + (mapconcat #'identity (jao-org-notes--read-tags) ":") + ":\n")) (save-buffer) (buffer-file-name)) -;;;###autoload -(defun jao-org-notes-find-for-pdf (&optional file-name) - "Given a PDF file name, find its org notes counterpart." - (let* ((file-name (or file-name buffer-file-name)) - (bn (file-name-base file-name)) - (rx (format "%s\\.org$" (regexp-quote bn))) - (pred (lambda () (string-prefix-p jao-org-notes-dir buffer-file-name)))) - (save-some-buffers nil pred) - (or (car (directory-files-recursively jao-org-notes-dir rx)) - (let* ((d (completing-read "Notes subdir: " (jao-org-notes-cats) nil t)) - (d (file-name-as-directory d))) - (expand-file-name (concat d bn ".org") jao-org-notes-dir))))) - -;;;###autoload (defun jao-org-notes-backlinks () "Show a list of note files linking to the current one." (interactive) - (jao-org-notes--grep-rx (concat "\\[\\[file:\\(.*/\\)?" (buffer-name)))) + (if-let* ((res (jao-org-notes--grep-rx + (concat "\\[file:.*" (regexp-quote (buffer-name)) "\\]\\["))) + (file (completing-read "File: " res nil t nil)) + (entry (assoc file res))) + (progn (find-file (cadr entry)) + (when-let (line (caddr entry)) (goto-line line))) + (message "Nobody links here!"))) -;;;###autoload (defun jao-org-notes-insert-tags () "Insert a list of tags at point, with completing read." (interactive) (insert ":" (mapconcat 'identity (jao-org-notes--read-tags) ":") ":")) -;;;###autoload (defun jao-org-notes-insert-link () "Select a note file (with completion) and insert a link to it." (interactive) @@ -186,7 +197,8 @@ (defun jao-org-notes-setup (mnemonic) "Set up the notes system, providing a mnemonic character for its org template." (setq org-capture-templates - (add-to-list 'org-capture-templates (jao-org-notes--template mnemonic))) + (add-to-list 'org-capture-templates (jao-org-notes--template mnemonic)) + jao-org-notes--tags (jao-org-notes-all-tags)) (when (fboundp 'org-capture-upgrade-templates) (org-capture-upgrade-templates org-capture-templates))) -- cgit v1.2.3