cpitclaudel / biblio.el

Browse and import bibliographic references from CrossRef, DBLP, HAL, arXiv, Dissemin, and doi.org from Emacs
GNU General Public License v3.0
180 stars 14 forks source link

Specify custom target-buffer when biblio-lookup is called #54

Open dankessler opened 2 years ago

dankessler commented 2 years ago

For some workflows, it would be convenient to specify (in advance) the value of biblio--target-buffer that will be used during the biblio session.

I can motivate this with a specific example. Suppose I am editing manuscript.tex which declares its reliance on refs.bib by including the command \addbibresource{refs.bib}. I need to insert a citation at point, so I call helm-bibtex-with-local-bibliography (which will make use of the refs.bib file declared in my LaTeX file). I don't see the citation I need in my list, so I use helm-bibtex's "fallback mechanism," which in turn uses biblio, in order to search crossref for the missing citation. I quickly find it, and now I want to insert it into my refs.bib file. However, if I hit i/I, it will insert it into manuscript.tex, not refs.bib. Instead, I'd need to first strike b, select refs.bib, and then hit i/I to insert the citation into the appropriate buffer. However, helm-bibtex-with-local-bibliography knows which bib file I mean to use, so it'd be nice if it could tell biblio about it so I don't have to manually tell biblio where to put the new entry.

As far as I can tell, this isn't currently possible (without some trickery, see PS at end). biblio uses the (private) buffer-local variable biblio--target-buffer to keep track of which buffer will be edited when by insertion commands. biblio--target-buffer gets (locally) set by biblio--make-results-buffer based on the value of target-buffer passed to the function. I think this happens (exclusively?) during biblio--lookup-1 here, where the positional target-argument is set to (current-buffer), so even if I e.g., bind biblio--target-buffer in an enclosing call, it'll get over-written here.

I wonder if instead this line

might be edited from

  (let ((results-buffer (biblio--make-results-buffer (current-buffer) query backend)))

to

  (let ((results-buffer (biblio--make-results-buffer (biblio--get-target-buffer) query backend)))

and then the behavior of biblio--get-target-buffer could be defined to rely on the value of a variable biblio-default-target-buffer. If nil, it'd return (current-buffer), if set to a string or buffer, it'd return that, or if it's a function, it would call the function and use its result.

This potentially exposes a lot of flexibility. The variable could be set globally by a user who always wants biblio to insert new entries into a particular file, or could be exploited with a let form by other tools that call biblio.

If this sounds palatable, I'm happy to do this as a PR, but since I'm new to biblio wanted to make sure that this comports with the overall design (and that I'm not being naive and that there's an easier way to accomplish this).

PS The "trickery" I mentioned would be for the call to biblio to be wrapped in a with-current-buffer form, but that seems a bit messy and may have unpleasant side effects (e.g., if I put it too high in the stack and some part of helm-bibtex that happens between where I put the form and where it calls biblio also wants to know what is the current-buffer.

PPS Currently, ebib accomplishes a similar functionality, but goes about it in a different route, whereby it dumps the entry into a temp buffer and then uses ebib's toolkit to import from that buffer..

dankessler commented 2 years ago

Welp, this is what I get for looking through issues but not PR's before writing this up. It seems this would all be addressed (in nearly the same manner proposed above) by #52