tmalsburg / helm-bibtex

Search and manage bibliographies in Emacs
GNU General Public License v2.0
464 stars 74 forks source link

Open directory with the same key name if exists #334

Closed ghost closed 4 years ago

ghost commented 4 years ago

Hi,

Is it possible to specify a directory with the same key as the PDF file, so that when Action is to open the PDF, if directory exists with the same key, then both will be given as options to open?

Or search recursively inside folder with the same key.

Thanks.

tmalsburg commented 4 years ago

Hi, the feature you describe does not currently exist. In the future there will be a plug-in based method for finding associated files, and the way I envision it, it would also support finding directories instead of files. Having said that, the chances that I will find time to implement this system in the near future are rather slim.

ghost commented 4 years ago

I was thinking just adding a new action which opens a key-filtered helm file finder in the PDF direcotry. I am pretty basic with Elisp but will give it a shot.

tmalsburg commented 4 years ago

Adding a custom action should be relatively easy. You can use bibtex-completion-open-pdf as a starting point. But the icons indicating whether the article is present or not would not reflect the state of affairs. Fixing that is perhaps a bit more difficult.

ghost commented 3 years ago

So, I've overridden the default action function. This is mostly because some references contain lots of associated files that I usually put them in the folder with the same name as the key, and I keep all bibliography files in the same folder.

;; Customise `helm-bibtex' actions
(defconst iceberg-bibliography-dir
  (file-name-as-directory (expand-file-name "~/library/bibliography"))
  "Bibliography directory that should contain all bibliography files.")

(defun iceberg//helm-bibtex-key-files (key)
  "List files in `iceberg-bibliography-dir' associated with KEY.
  Search for files starting with KEY and/or files in directory
  named KEY within `iceberg-bibliography-dir'."
  (let* ((files (directory-files iceberg-bibliography-dir t key))
         (kfiles (f-uniquify-alist
                  ;; Remove directory named KEY if present, process it
                  ;; separately; or, if no files were found and
                  ;; `directory-files' listed all files in
                  ;; `iceberg-bibliography-dir', remove all files not matching
                  ;; KEY
                  (delq nil
                        (mapcar (lambda (x) (and (and (not (file-directory-p x))
                                                      (string-match-p key x))
                                                 x))
                                files))))
         ;; Process directory named KEY if it exists
         (kdir (concat iceberg-bibliography-dir key))
         (dfiles (if (file-directory-p kdir)
                     (--map (cons it (replace-regexp-in-string
                                      iceberg-bibliography-dir
                                      "" it))
                            (directory-files-recursively kdir "."))
                   nil)))
    (append kfiles dfiles)))

;; Override the default action function to list all files
(defun bibtex-completion-open-pdf (keys &optional fallback-action)
  "Open files with KEY prefix and/or in KEY directory."
  (if (= (length keys) 1)
      (let* ((key (car keys))
             (files (iceberg//helm-bibtex-key-files key)))
        (cond
         ((> (length files) 1)
          (let* ((choice (completing-read "File: " (mapcar 'cdr files) nil t))
                 (file (car (rassoc choice files))))
            (funcall bibtex-completion-pdf-open-function file)))
         (files
          (funcall bibtex-completion-pdf-open-function (car files)))
         (fallback-action
          (funcall fallback-action (list key)))
         (t
          (message "No files found for key: %s" key))))
    (message "Please select only one entry.")))

I've added a few more actions like opening files with Evince and listing files in dired. I use use-package and put all of these in :config, but it seems the action list is constructed only when helm-bibtex is called for the first time, so added actions appear as second and third as opposed to being last.

tmalsburg commented 3 years ago

but it seems the action list is constructed only when helm-bibtex is called for the first time, so added actions appear as second and third as opposed to being last.

I don't use use-package but a plain (and somewhat messy) configuration script. So I can't help with this. Sorry.