-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Display local and global bibliographies simultaneously #272
base: master
Are you sure you want to change the base?
Conversation
This makes the helm-bibtex and ivy-bibtex commands show both local and global bibliography entries simultaneously. Commands helm-bibtex-with-global-bibliography, helm-bibtex-with-local-bibliography, and similarly for ivy-bibtex, show only the global or local entries, respectively. If a file is both in the local and global bibliographies, it is considered a global bibliography file only. In helm-bibtex, the local and global entries are shown in separate sources. In ivy-bibtex, a different face is used for local entries (since ivy does not display sources separately). This face is customizable through the variable ivy-bibtex-local-bibliography-face. Also, a new variable bibtex-completion-reverse-order allows to customize whether the order of files and/or entries are reversed in the list of candidates (the default behavior is unchanged: entries are reversed but not files). Finally, ivy-bibtex accepts an additional argument input as is already the case for helm-bibtex. The simultaneous display of local and global entries is implemented as follows. The optional argument local-bib of helm-bibtex and ivy-bibtex is now more generallly named scope and be either 'global or 'local to show only the global or local entries, respectively, or nil to show both. This scope argument is first passed to the function bibtex-completion-init, which initializes the newly introduced variable bibtex-completion-bibliography-internal accordingly: it is a cons whose car and cdr are the the global and local bibliiography bibliographies currently in use. If scope is nil, the car of this cons is the value of bibtex-completion-bibliography and its cdr is the list returned by bibtex-completion-find-local-bibliography from which the files in bibtex-completion-bibliography are removed. If scope is 'global or 'local then the cdr or car of this cons is nil, respectively. Then bibtex-completion-candidates parses the bibliography as needed and now returns a cons of two lists of entries, one corresponding to the car and one to the cdr of bibtex-completion-bibliography-internal. These two lists are used as candidates list in the global and local sources that helm-bibtex now has. Then when the selected candidates or the set of marked candidates is passed to an action function by helm-bibtex, a property scope is added to the key strings, with value 'global or 'global depending on the source. This is done by modifying the macro helm-bibtex-helmify-action. For ivy-bibtex we need to append the two lists of candidates, but the number of local candidates is first recorded. This allows to determine if a given candidate is local or global. The function ivy-bibtex-display-transformer uses this to fontify the local candidates, and the macro ivy-bibtex-ivify-action is also modified to propertize the key string passed to the action functions with the scope property (ivy does not support marking several candidates). Finally, the function bibtex-completion-get-entry1 is modified to read the scope property of the key string and get the entry from the corresponding bibliography. This is sufficient to make most action functions able to distinguish between local and global bibliography entries. The only exception is the function bibtex-completion-show-entry, which is modified directly. Other actions, such as bibtex-completion-insert-citation, simply ignore the scope property since they don't need to make this distinction.
Hi Eric, thanks for this fantastic PR and sorry for the silence. My wife and I had a baby recently and it's become difficult to find time for side projects. This looks really interesting but before I comment on some of the technical details, could you please explain a bit which problem this PR is addressing? I realize that this may be obvious for users of both local and global bibliographies, but I'm using just one global bibliography for everything. |
I completely understand, congratulations! The local bibliography is typically made of the bibtex file(s) associated with a latex document. My main use case is when I'm working with coauthors on an paper and each of us adds entries (possibly copied from their global bibliography) to the paper's local bibliography. Currently I can call Please let me know if you need any further clarification. |
Thanks, I was just wondering which other future feature requests this might entail. For instance, I imagine that someone using local and global bibliographies might also want to have actions for moving entries from one to the other. E.g. add an entry to the shared (local) bibliography or import a co-author's entry to the global bibliography. One big question for me is whether we should go in this direction. So far helm/ivy-bibtex were just for reading bibliographies and not for modifying them. My own philosophy is that bibtex-files should be edited by hand. After all, Emacs is a terrific text editor and it already has multiple facilities for maintaining BibTeX files. But more importantly I think that helm and ivy have terrible UIs for implementing a full-blown bibliography manager. Everything would basically have to be an action and selecting the appropriate action becomes tedious as their number increases. Anyway, coming back to the specific issue. I think showing entries from local and global bibliographies is a useful addition, which I might end up using as well. However, looking at your PR I realize that my data structures are woefully inadequate for this because they do not keep track of where an entry is coming from. If there is an entry with BibTeX key XYZ in both the local and the global bibliography, an action has no way of knowing which of the two it is supposed to act on. It's really starting to show that helm-bibtex started as a quick hack and that I didn't think ahead when I laid its foundations. I haven't tried your code but I looks as if it would work flawlessly (within the limits you mention). So we could merge this as is I guess. I hesitate, though, because I worry that the code base is becoming harder and harder to understand for potential contributors and also for myself. Do you think that it would be worth rethinking the data structures such that they allow for a more complete and more elegant solution? For instance, would it make sense to introduce an internal identifier for entries that is composed of BibTeX key plus path of source file? This wouldn't magically solve all our problems (e.g. those related to notes) but it might put us in a better position for solving these issuesl. I would be interested to hear your thoughts on this. |
Re future feature requests, yes I guess an additional action for moving entries would be a natural one, but I agree with you I would better do this by hand. What I've done is simply add an action to copy the bibtex entry and I think having this could safely be added to the bibtex-completion code. Then having both the local and global bibliographies displayed simultaneously makes things convenient enough: I can apply this action without leaving the session and then choose a (local or global) bibliography from the fallback actions and paste the copied entry there. Re data structure, I think I remember having asked once about the possibility to add the source file path as an additional field in the entry alist (or an alternative could be as you suggest to concatenate it with the entry key), and that your answer was that the amount of stored information would better be kept to a minimum so as not to increasing loading time for large bibliographies like crypto.bib. So in this PR I went for another strategy: wait until entry keys are passed to an action function and add the string property 'local or 'global to these keys only. So actions are able to distinguish between an local and a global entry with the same key, and there should be no impact on performance for large bibliographies (the commit message explains how all this is done but do let me know if it is not clear). My impression is that bibtex-completion generally tries to optimize performance for large bibliographies and that this can make the code more complicated than systematically caching a priori all the information that might be needed at some point, so the best approach should depend on your trade-off between performance and simplicity. |
This makes the helm-bibtex and ivy-bibtex commands show both local and global bibliography entries simultaneously. Commands helm-bibtex-with-global-bibliography, helm-bibtex-with-local-bibliography, and similarly for ivy-bibtex, show only the global or local entries, respectively. If a file is both in the local and global bibliographies, it is considered a global bibliography file only.
In helm-bibtex, the local and global entries are shown in separate sources. In ivy-bibtex, a different face is used for local entries (since ivy does not display sources separately). This face is customizable through the variable ivy-bibtex-local-bibliography-face.
Also, a new variable bibtex-completion-reverse-order allows to customize whether the order of files and/or entries are reversed in the list of candidates (the default behavior is unchanged: entries are
reversed but not files). Finally, ivy-bibtex accepts an additional argument input as is already the case for helm-bibtex.
The commit message explains in more details how this is implemented.
Some action functions related to pdf or notes files may need some more work. Imagine for instance that a user edits notes for a local entry that is not in the global bibliography. Currently that would create a notes files for this entry, which perhaps not desirable. Several options to prevent this:
Similarly for bibtex-completion-add-pdf-to-library. Perhaps as well bibtex-completion-open-pdf and bibtex-completion-add-PDF-attachment. Please let me know what you think, If you'd like to completely disable the notes/pdf related actions for local entries, a possibility would be to not look for pdf and notes at all when these files are parsed.
Also the readme would need to be updated.