From 68f6902e3b112d204d0d56525e927cb2e233db48 Mon Sep 17 00:00:00 2001 From: Grant Rosson Date: Thu, 16 Dec 2021 16:08:42 +0200 Subject: [PATCH 1/8] Add completing-read to citar--open-note, when multiple notes --- citar-file.el | 26 ++++++++++++-------------- citar.el | 20 ++++++++++++++------ 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/citar-file.el b/citar-file.el index 1a1c74d9..c048e8c7 100644 --- a/citar-file.el +++ b/citar-file.el @@ -311,20 +311,18 @@ of files found in two ways: nil 0 nil file))) -(defun citar-file--get-note-filename (key dirs extensions) - "Return existing or new filename for KEY in DIRS with extension in EXTENSIONS. - -This is for use in a note function where notes are one-per-file, -with citekey as filename. - -Returns the filename whether or not the file exists, to support a -function that will open a new file if the note is not present." - (let ((files (citar-file--directory-files dirs (list key) extensions - citar-file-additional-files-separator))) - (or (car (gethash key files)) - (when-let ((dir (car dirs)) - (ext (car extensions))) - (expand-file-name (concat key "." ext) dir))))) +(defun citar-file--get-note-filenames (key dirs extensions) + "Return list of existing notes or a new filename for KEY in DIRS with extension in EXTENSIONS. + +If no notes exist, returns a filename to support a function that +will open a new file if the note is not present." + (if-let* ((files + (gethash key (citar-file--directory-files dirs + (list key) + extensions + citar-file-additional-files-separator)))) + files + (list (concat (car dirs) "/" key "." (car extensions))))) (provide 'citar-file) ;;; citar-file.el ends here diff --git a/citar.el b/citar.el index 5f7abc9d..d8651ed2 100644 --- a/citar.el +++ b/citar.el @@ -964,12 +964,20 @@ With prefix, rebuild the cache before offering candidates." (defun citar--open-note (key entry) "Open a note file from KEY and ENTRY." - (if-let* ((file (citar-file--get-note-filename key - citar-notes-paths - citar-file-note-extensions)) - (file-exists (file-exists-p file))) - (find-file file) - (funcall citar-format-note-function key entry file))) + (if-let* ((raw-files (citar-file--get-note-filenames key + citar-notes-paths + citar-file-note-extensions)) + (files + (mapcar + (lambda (file) + (abbreviate-file-name file)) + raw-files)) + (file (when (= (length files) 1) + (car files)))) + (if (file-exists-p file) + (find-file (expand-file-name file)) + (funcall citar-format-note-function key entry (expand-file-name file))) + (find-file (expand-file-name (completing-read "Open note: " files nil t))))) ;;;###autoload (defun citar-open-entry (keys-entries) From 90cc61598103379afac44d9f46b94ccb3adc5f97 Mon Sep 17 00:00:00 2001 From: Grant Rosson Date: Thu, 16 Dec 2021 17:26:31 +0200 Subject: [PATCH 2/8] Add citar-select-resources, to replace citar-select-files --- citar-file.el | 2 +- citar.el | 67 +++++++++++++++++++++++++++++---------------------- 2 files changed, 39 insertions(+), 30 deletions(-) diff --git a/citar-file.el b/citar-file.el index c048e8c7..82a73094 100644 --- a/citar-file.el +++ b/citar-file.el @@ -296,7 +296,7 @@ of files found in two ways: (defun citar-file-open (file) "Open FILE." - (funcall citar-file-open-function file)) + (funcall citar-file-open-function (expand-file-name file))) (defun citar-file-open-external (file) "Open FILE with external application." diff --git a/citar.el b/citar.el index d8651ed2..b8929c94 100644 --- a/citar.el +++ b/citar.el @@ -419,26 +419,36 @@ documentation for the return value and the meaning of REBUILD-CACHE and FILTER." (citar-select-ref :rebuild-cache rebuild-cache :multiple t :filter filter)) -(defun citar-select-files (files) - "Select file(s) from a list of FILES." - ;; TODO add links to candidates - (completing-read-multiple - "Open related file(s): " - (lambda (string predicate action) - (if (eq action 'metadata) - `(metadata - ; (group-function . citar-select-group-related-sources) - (category . file)) - (complete-with-action action files string predicate))))) - -(defun citar-select-group-related-sources (file transform) - "Group by FILE by source, TRANSFORM." - (let ((extension (file-name-extension file))) - (when transform file - ;; Transform for grouping and group title display. +(defun citar-select-resources (files &optional links) + "Select resource(s) from a list of FILES, and optionally LINKS." + ;; DONE Add links to candidates + ;; DONE Add group-function + ;; FIX: set category metadata depending on type (differentiate links and files); possible? + (let* ((resources (append + (mapcar + (lambda (file) + (abbreviate-file-name file)) + files) + (remq nil links)))) + (completing-read-multiple + "Select resources: " + (lambda (string predicate action) + (if (eq action 'metadata) + `(metadata + (group-function . citar-select-group-related-resources) + ;; FIX: currently sets category "file" for all candidates + (category . file)) + (complete-with-action action resources string predicate)))))) + +(defun citar-select-group-related-resources (resource transform) + "Group RESOURCE by type or TRANSFORM." + (let ((extension (file-name-extension resource))) + (if transform + resource (cond - ((string= extension (or "org" "md")) "Notes") - (t "Library Files"))))) + ((member extension citar-file-note-extensions) "Notes") + ((string-match "http" resource 0) "Links") + (t "Files"))))) (defun citar--get-major-mode-function (key &optional default) "Return KEY from 'major-mode-functions'." @@ -903,15 +913,14 @@ into the corresponding reference key. Return (lambda (key-entry) (citar-get-link (cdr key-entry))) key-entry-alist)) - (resource-candidates (delete-dups (append files (remq nil links)))) - (resources - (when resource-candidates - (completing-read-multiple "Related resources: " resource-candidates)))) - (if resource-candidates - (dolist (resource resources) - (cond ((string-match "http" resource 0) - (browse-url resource)) - (t (citar-file-open resource)))) + (resources)) + (if files + (progn + (setq resources (citar-select-resources files links)) + (dolist (resource resources) + (cond ((string-match "http" resource 0) + (browse-url resource)) + (t (citar-file-open resource))))) (message "No associated resources")))) (defun citar--library-files-action (keys-entries action) @@ -927,7 +936,7 @@ into the corresponding reference key. Return (if (and citar-file-open-prompt (> (length files) 1)) (let ((selected-files - (citar-select-files files))) + (citar-select-resources files))) (dolist (file selected-files) (funcall fn file))) (dolist (file files) From 297ee595a9d1bc54dced85b73cc4a4b7fa07ee2e Mon Sep 17 00:00:00 2001 From: Grant Rosson Date: Mon, 20 Dec 2021 14:44:33 +0200 Subject: [PATCH 3/8] Use consult-multi category to set categories depending on type - change 'citar-select-resources' to completing-read --- citar.el | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/citar.el b/citar.el index b8929c94..883ddc9f 100644 --- a/citar.el +++ b/citar.el @@ -423,22 +423,26 @@ REBUILD-CACHE and FILTER." "Select resource(s) from a list of FILES, and optionally LINKS." ;; DONE Add links to candidates ;; DONE Add group-function - ;; FIX: set category metadata depending on type (differentiate links and files); possible? - (let* ((resources (append - (mapcar - (lambda (file) - (abbreviate-file-name file)) - files) - (remq nil links)))) - (completing-read-multiple + ;; DONE: set category metadata depending on type (differentiate links and files) + (let* ((files (mapcar + (lambda (cand) + (abbreviate-file-name cand)) + files)) + (resources (append files (remq nil links)))) + (dolist (item resources) + (cond ((string-match "http" item 0) + (add-text-properties 0 (length item) `(consult-multi (url . ,item)) item)) + (t + (add-text-properties 0 (length item) `(consult-multi (file . ,item)) item))) + (push item resources)) + (completing-read "Select resources: " (lambda (string predicate action) (if (eq action 'metadata) `(metadata (group-function . citar-select-group-related-resources) - ;; FIX: currently sets category "file" for all candidates - (category . file)) - (complete-with-action action resources string predicate)))))) + (category . consult-multi)) + (complete-with-action action (delete-dups resources) string predicate)))))) (defun citar-select-group-related-resources (resource transform) "Group RESOURCE by type or TRANSFORM." From 23fedc281bbfed462c88e2a4d6da56be760b4178 Mon Sep 17 00:00:00 2001 From: Grant Rosson Date: Mon, 20 Dec 2021 16:45:49 +0200 Subject: [PATCH 4/8] Use 'citar-select-resources' for 'citar--open-note' - simplify 'citar-open' - edit doc strings --- citar.el | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/citar.el b/citar.el index 883ddc9f..4506a59f 100644 --- a/citar.el +++ b/citar.el @@ -421,9 +421,6 @@ REBUILD-CACHE and FILTER." (defun citar-select-resources (files &optional links) "Select resource(s) from a list of FILES, and optionally LINKS." - ;; DONE Add links to candidates - ;; DONE Add group-function - ;; DONE: set category metadata depending on type (differentiate links and files) (let* ((files (mapcar (lambda (cand) (abbreviate-file-name cand)) @@ -436,7 +433,7 @@ REBUILD-CACHE and FILTER." (add-text-properties 0 (length item) `(consult-multi (file . ,item)) item))) (push item resources)) (completing-read - "Select resources: " + "Select resource: " (lambda (string predicate action) (if (eq action 'metadata) `(metadata @@ -452,7 +449,7 @@ REBUILD-CACHE and FILTER." (cond ((member extension citar-file-note-extensions) "Notes") ((string-match "http" resource 0) "Links") - (t "Files"))))) + (t "Library Files"))))) (defun citar--get-major-mode-function (key &optional default) "Return KEY from 'major-mode-functions'." @@ -899,7 +896,7 @@ into the corresponding reference key. Return ;;;###autoload (defun citar-open (keys-entries) - "Open related resources (links or files) for KEYS-ENTRIES." + "Open any related resources (links, files, or notes) for KEYS-ENTRIES." (interactive (list (citar-select-refs :rebuild-cache current-prefix-arg))) (when (and citar-library-paths @@ -917,14 +914,11 @@ into the corresponding reference key. Return (lambda (key-entry) (citar-get-link (cdr key-entry))) key-entry-alist)) - (resources)) + (selection (citar-select-resources files links))) (if files - (progn - (setq resources (citar-select-resources files links)) - (dolist (resource resources) - (cond ((string-match "http" resource 0) - (browse-url resource)) - (t (citar-file-open resource))))) + (cond ((string-match "http" selection 0) + (browse-url selection)) + (t (citar-file-open selection))) (message "No associated resources")))) (defun citar--library-files-action (keys-entries action) @@ -939,12 +933,9 @@ into the corresponding reference key. Return citar-file-extensions))) (if (and citar-file-open-prompt (> (length files) 1)) - (let ((selected-files - (citar-select-resources files))) - (dolist (file selected-files) - (funcall fn file))) - (dolist (file files) - (funcall fn file))) + (let ((selection (citar-select-resources files))) + (funcall fn selection)) + (funcall fn files)) (message "No associated file"))) ;;;###autoload @@ -987,10 +978,10 @@ With prefix, rebuild the cache before offering candidates." raw-files)) (file (when (= (length files) 1) (car files)))) - (if (file-exists-p file) + (if (file-exists-p file) (find-file (expand-file-name file)) (funcall citar-format-note-function key entry (expand-file-name file))) - (find-file (expand-file-name (completing-read "Open note: " files nil t))))) + (find-file (citar-select-resources files)))) ;;;###autoload (defun citar-open-entry (keys-entries) From df3c13b23ca3fad4ce66bd9a3a54b9c1e537e981 Mon Sep 17 00:00:00 2001 From: Grant Rosson Date: Mon, 20 Dec 2021 23:00:49 +0200 Subject: [PATCH 5/8] Bug fix and change 'citar-select-resources' to 'citar-select-resource' --- citar.el | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/citar.el b/citar.el index 4506a59f..d59194e6 100644 --- a/citar.el +++ b/citar.el @@ -419,8 +419,8 @@ documentation for the return value and the meaning of REBUILD-CACHE and FILTER." (citar-select-ref :rebuild-cache rebuild-cache :multiple t :filter filter)) -(defun citar-select-resources (files &optional links) - "Select resource(s) from a list of FILES, and optionally LINKS." +(defun citar-select-resource (files &optional links) + "Select resource from a list of FILES, and optionally LINKS." (let* ((files (mapcar (lambda (cand) (abbreviate-file-name cand)) @@ -914,7 +914,7 @@ into the corresponding reference key. Return (lambda (key-entry) (citar-get-link (cdr key-entry))) key-entry-alist)) - (selection (citar-select-resources files links))) + (selection (citar-select-resource files links))) (if files (cond ((string-match "http" selection 0) (browse-url selection)) @@ -933,9 +933,9 @@ into the corresponding reference key. Return citar-file-extensions))) (if (and citar-file-open-prompt (> (length files) 1)) - (let ((selection (citar-select-resources files))) + (let ((selection (citar-select-resource files))) (funcall fn selection)) - (funcall fn files)) + (funcall fn (car files))) (message "No associated file"))) ;;;###autoload @@ -981,7 +981,7 @@ With prefix, rebuild the cache before offering candidates." (if (file-exists-p file) (find-file (expand-file-name file)) (funcall citar-format-note-function key entry (expand-file-name file))) - (find-file (citar-select-resources files)))) + (find-file (citar-select-resource files)))) ;;;###autoload (defun citar-open-entry (keys-entries) @@ -1043,7 +1043,6 @@ directory as current buffer." "Open URL or DOI link associated with the KEYS-ENTRIES in a browser. With prefix, rebuild the cache before offering candidates." - ;; (browse-url-default-browser "https://google.com") (interactive (list (citar-select-refs :rebuild-cache current-prefix-arg))) (dolist (key-entry (citar--ensure-entries keys-entries)) From 34190bf63e1da6c74bd16f814f491dadc50722d1 Mon Sep 17 00:00:00 2001 From: Grant Rosson Date: Tue, 21 Dec 2021 12:18:46 +0200 Subject: [PATCH 6/8] Fix 'open' commands for use with embark-act all - Let-bind 'embark-default-action-overrides' for each command - Add 'citar-open-multi' function, so files are handled appropriately when type is 'consult-multi' --- citar.el | 46 ++++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/citar.el b/citar.el index d59194e6..978524d1 100644 --- a/citar.el +++ b/citar.el @@ -896,13 +896,16 @@ into the corresponding reference key. Return ;;;###autoload (defun citar-open (keys-entries) - "Open any related resources (links, files, or notes) for KEYS-ENTRIES." + "Open any related resource (links, files, or notes) for KEYS-ENTRIES." (interactive (list (citar-select-refs :rebuild-cache current-prefix-arg))) (when (and citar-library-paths (stringp citar-library-paths)) (message "Make sure 'citar-library-paths' is a list of paths")) - (let* ((key-entry-alist (citar--ensure-entries keys-entries)) + (let* ((embark-default-action-overrides '((consult-multi . citar-open-multi) + (file . citar-file-open) + (url . browse-url))) + (key-entry-alist (citar--ensure-entries keys-entries)) (files (citar-file--files-for-multiple-entries key-entry-alist @@ -921,6 +924,14 @@ into the corresponding reference key. Return (t (citar-file-open selection))) (message "No associated resources")))) +(defun citar-open-multi (selection) + "Act appropriately on SELECTION when type is 'consult-multi'. + +For use with 'embark-act-all'." + (cond ((string-match "http" selection 0) + (browse-url selection)) + (t (citar-file-open selection)))) + (defun citar--library-files-action (keys-entries action) "Run ACTION on files associated with KEYS-ENTRIES." (if-let ((fn (pcase action @@ -945,10 +956,11 @@ into the corresponding reference key. Return With prefix, rebuild the cache before offering candidates." (interactive (list (citar-select-refs :rebuild-cache current-prefix-arg))) + (let ((embark-default-action-overrides '((file . citar-file-open)))) (when (and citar-library-paths (stringp citar-library-paths)) (message "Make sure 'citar-library-paths' is a list of paths")) - (citar--library-files-action keys-entries 'open)) + (citar--library-files-action keys-entries 'open))) (make-obsolete 'citar-open-pdf 'citar-open-library-files "1.0") @@ -959,12 +971,13 @@ With prefix, rebuild the cache before offering candidates." With prefix, rebuild the cache before offering candidates." (interactive (list (citar-select-refs :rebuild-cache current-prefix-arg))) - (when (and (null citar-notes-paths) - (equal citar-format-note-function - 'citar-org-format-note-default)) - (error "You must set 'citar-notes-paths' to open notes with default notes function")) - (dolist (key-entry (citar--ensure-entries keys-entries)) - (funcall citar-open-note-function (car key-entry) (cdr key-entry)))) + (let ((embark-default-action-overrides '((file . find-file)))) + (when (and (null citar-notes-paths) + (equal citar-format-note-function + 'citar-org-format-note-default)) + (error "You must set 'citar-notes-paths' to open notes with default notes function")) + (dolist (key-entry (citar--ensure-entries keys-entries)) + (funcall citar-open-note-function (car key-entry) (cdr key-entry))))) (defun citar--open-note (key entry) "Open a note file from KEY and ENTRY." @@ -1045,12 +1058,12 @@ directory as current buffer." With prefix, rebuild the cache before offering candidates." (interactive (list (citar-select-refs :rebuild-cache current-prefix-arg))) - (dolist (key-entry (citar--ensure-entries keys-entries)) - (let ((link (citar-get-link (cdr key-entry)))) - (if link - (browse-url-default-browser link) - (message "No link found for %s" (car key-entry)))))) - + (let ((embark-default-action-overrides '((url . browse-url)))) + (dolist (key-entry (citar--ensure-entries keys-entries)) + (let ((link (citar-get-link (cdr key-entry)))) + (if link + (browse-url-default-browser link) + (message "No link found for %s" (car key-entry))))))) ;;;###autoload (defun citar-insert-citation (keys-entries &optional arg) @@ -1129,10 +1142,11 @@ With prefix, rebuild the cache before offering candidates." With prefix, rebuild the cache before offering candidates." (interactive (list (citar-select-refs :rebuild-cache current-prefix-arg))) + (let ((embark-default-action-overrides '((file . mml-attach-file)))) (when (and citar-library-paths (stringp citar-library-paths)) (message "Make sure 'citar-library-paths' is a list of paths")) - (citar--library-files-action keys-entries 'attach)) + (citar--library-files-action keys-entries 'attach))) (make-obsolete 'citar-add-pdf-attachment 'citar-attach-library-files "0.9") From c9b544631345bf3f60bc7e674657297202788f3e Mon Sep 17 00:00:00 2001 From: Grant Rosson Date: Tue, 21 Dec 2021 14:30:43 +0200 Subject: [PATCH 7/8] Unify open-link behavior; add prompt to 'citar--open-note' - changes 'browse-url-default-browser' to 'browse-url', which defaults to 'browse-url-default-browser' anyway, but might be set otherwise in user's config - sets 'citar--open-note' to prompt for yes or no before creating a new note --- citar.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/citar.el b/citar.el index 978524d1..8d67da9b 100644 --- a/citar.el +++ b/citar.el @@ -993,7 +993,8 @@ With prefix, rebuild the cache before offering candidates." (car files)))) (if (file-exists-p file) (find-file (expand-file-name file)) - (funcall citar-format-note-function key entry (expand-file-name file))) + (when (yes-or-no-p (format "No note associated with %s. Create one?" key)) + (funcall citar-format-note-function key entry (expand-file-name file)))) (find-file (citar-select-resource files)))) ;;;###autoload @@ -1062,7 +1063,7 @@ With prefix, rebuild the cache before offering candidates." (dolist (key-entry (citar--ensure-entries keys-entries)) (let ((link (citar-get-link (cdr key-entry)))) (if link - (browse-url-default-browser link) + (browse-url link) (message "No link found for %s" (car key-entry))))))) ;;;###autoload From 9d763d4298249561935ecc0374298b51807af063 Mon Sep 17 00:00:00 2001 From: Bruce D'Arcus Date: Tue, 21 Dec 2021 12:05:37 -0500 Subject: [PATCH 8/8] Declare embark-default-action-overrides --- citar.el | 1 + 1 file changed, 1 insertion(+) diff --git a/citar.el b/citar.el index 8d67da9b..1bcb7bf8 100644 --- a/citar.el +++ b/citar.el @@ -55,6 +55,7 @@ (defvar embark-meta-map) (defvar embark-transformer-alist) (defvar embark-multitarget-actions) +(defvar embark-default-action-overrides) (defvar citar-org-open-note-function) ;;; Variables