diff --git a/bibtex-completion.el b/bibtex-completion.el index 87a0881..294ed54 100644 --- a/bibtex-completion.el +++ b/bibtex-completion.el @@ -56,9 +56,26 @@ (declare-function org-element-property "org-element") (defgroup bibtex-completion nil - "Helm plugin for searching entries in a BibTeX bibliography." + "Provides searching of entries in a BibTeX bibliography, and running actions on them." :group 'completion) +(defvar bibtex-completion-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "o") 'bibtex-completion-open-any) + (define-key map (kbd "p") 'bibtex-completion-open-pdf) + (define-key map (kbd "u") 'bibtex-completion-open-url-or-doi) + (define-key map (kbd "c") 'bibtex-completion-insert-citation) + (define-key map (kbd "r") 'bibtex-completion-insert-reference) + (define-key map (kbd "k") 'bibtex-completion-insert-key) + (define-key map (kbd "b") 'bibtex-completion-insert-bibtex) + (define-key map (kbd "a") 'bibtex-completion-add-pdf-attachment) + (define-key map (kbd "e") 'bibtex-completion-edit-notes) + (define-key map (kbd "s") 'bibtex-completion-show-entry) + (define-key map (kbd "l") 'bibtex-completion-add-pdf-to-library) + map) + "Keymap for bibtex-completion commands" + ) + (defcustom bibtex-completion-bibliography nil "The BibTeX file or list of BibTeX files. Org-bibtex users can also specify org mode bibliography files, in @@ -348,6 +365,10 @@ Only entries of these types are checked in order to resolve cross-references. The default list is usually sufficient; adding more types can slow down resolution for large biblioraphies.") +;; one can reset the backend function using fset; maybe there's a +;; more elegant way to do this? +(fset 'bibtex-completion-read-backend `bibtex-completion--completing-read) + (defvar bibtex-completion-display-formats-internal nil "Stores `bibtex-completion-display-formats' together with the \"used width\" of each format string. This is set internally.") @@ -364,7 +385,6 @@ bibliography file is reparsed.") (defvar bibtex-completion-string-hash-table nil "A hash table used for string replacements.") - (defun bibtex-completion-normalize-bibliography (&optional type) "Return a list of bibliography file(s) in `bibtex-completion-bibliography'. If there are org mode bibliography-files, their corresponding @@ -478,6 +498,37 @@ for string replacement." (defvar bibtex-completion-cached-notes-keys nil "A cache storing notes keys obtained when the bibliography was last parsed.") +(defun bibtex-completion--read () + "Select BibTeX entries in completion system." + ;; define a completion function that defaults to completing-read, but can be overridden + (list (bibtex-completion-read-backend))) + +(defun bibtex-completion--completing-read () + "Read bibtex-completion entries for completion using completing-read." + (bibtex-completion-init) + (when-let ((candidates (bibtex-completion--get-candidates)) + (chosen + (completing-read + "BibTeX entries: " + (lambda (string predicate action) + (if (eq action 'metadata) + '(metadata + ;; (annotation-function . bibtex-completion--annotation) + (category . bibtex)) + (complete-with-action action candidates string predicate)))))) + (cdr (assoc chosen candidates)))) + +(defun bibtex-completion--get-candidates () + "Return all keys from bibtex-completion-candidates." + (cl-loop + for candidate in (bibtex-completion-candidates) + collect + (cons + ;; Here use one string for display, and the other for search. + (propertize + (car candidate) 'display (bibtex-completion-format-entry candidate (1- (frame-width)))) + (cdr (assoc "=key=" candidate))))) + (defun bibtex-completion-candidates () "Read the BibTeX files and return a list of conses, one for each entry. The first element of these conses is a string containing authors, @@ -910,6 +961,7 @@ governed by the variable `bibtex-completion-display-formats'." If multiple PDFs are found for an entry, ask for the one to open using `completion-read'. If FALLBACK-ACTION is non-nil, it is called in case no PDF is found." + (interactive (list (bibtex-completion--read))) (dolist (key keys) (let ((pdf (bibtex-completion-find-pdf key bibtex-completion-find-additional-pdfs))) (cond @@ -928,6 +980,7 @@ called in case no PDF is found." (defun bibtex-completion-open-url-or-doi (keys) "Open the URL or DOI associated with entries in KEYS in a browser." + (interactive (list (bibtex-completion--read))) (dolist (key keys) (let* ((entry (bibtex-completion-get-entry key)) (url (bibtex-completion-get-value "url" entry)) @@ -947,6 +1000,7 @@ called in case no PDF is found." If multiple PDFs are found for an entry, ask for the one to open using `completion-read'. If no PDF is found, try to open a URL or DOI in the browser instead." + (interactive (list (bibtex-completion--read))) (bibtex-completion-open-pdf keys 'bibtex-completion-open-url-or-doi)) (defun bibtex-completion-format-citation-default (keys) @@ -1087,6 +1141,7 @@ The format depends on (let ((format-function (cdr (or (assoc major-mode bibtex-completion-format-citation-functions) (assoc 'default bibtex-completion-format-citation-functions))))) + (interactive (list (bibtex-completion--read))) (insert (funcall format-function keys)))) @@ -1096,6 +1151,7 @@ The format depends on (s-word-wrap fill-column (concat "\n- " (bibtex-completion-apa-format-reference it))) keys))) + (interactive (list (bibtex-completion--read))) (insert "\n" (s-join "\n" refs) "\n"))) (defun bibtex-completion-apa-format-reference (key) @@ -1296,11 +1352,13 @@ Surrounding curly braces are stripped." (defun bibtex-completion-insert-key (keys) "Insert BibTeX KEYS at point." + (interactive (list (bibtex-completion--read))) (insert (funcall 'bibtex-completion-format-citation-default keys))) (defun bibtex-completion-insert-bibtex (keys) "Insert BibTeX entries for entries in KEYS at point." + (interactive (list (bibtex-completion--read))) (insert (s-join "\n" (--map (bibtex-completion-make-bibtex it) keys)))) (defun bibtex-completion-make-bibtex (key) @@ -1321,6 +1379,13 @@ Self-contained means that cross-referenced entries are merged." concat (format " %s = {%s},\n" name value))))) +(defun bibtex-completion-add-pdf-attachment (keys) + ; this is basically a lowercase command alias for the function + ; ideally, that name should be deprecated in favor of this one + "Attach the PDFs of the entries with the given KEYS where available." + (interactive (list (bibtex-completion--read))) + (bibtex-completion-add-PDF-attachment)) + (defun bibtex-completion-add-PDF-attachment (keys) "Attach the PDFs of the entries with the given KEYS where available." (dolist (key keys) @@ -1445,10 +1510,12 @@ Creates new notes where none exist yet." (defun bibtex-completion-edit-notes (keys) "Open the notes associated with KEYS using `bibtex-completion-edit-notes-function'." + (interactive (list (bibtex-completion--read))) (funcall bibtex-completion-edit-notes-function keys)) (defun bibtex-completion-show-entry (keys) "Show the first entry in KEYS in the relevant BibTeX file." + (interactive (list (bibtex-completion--read))) (catch 'break (dolist (bib-file (bibtex-completion-normalize-bibliography 'main)) (let ((key (car keys)) @@ -1478,6 +1545,7 @@ Creates new notes where none exist yet." "Add a PDF to the library for the first entry in KEYS. The PDF can be added either from an open buffer, a file, or a URL." + (interactive (list (bibtex-completion--read))) (let* ((key (car keys)) (source (char-to-string (read-char-choice "Add pdf from [b]uffer, [f]ile, or [u]rl? " '(?b ?f ?u))))