* Popup tips on bibtex links in org-mode :PROPERTIES: :date: 2014/04/12 14:15:45 :updated: 2014/04/12 14:15:45 :END: I want to explore using popup tips to display richer information about org-mode links. The idea is to have something like a tooltip that displays the bibtex entry when you hover over it, or click on it. https://github.com/auto-complete/popup-el/blob/master/popup.el Here is a canonical example of a popup. #+BEGIN_SRC emacs-lisp (popup-tip "Hello, World!") #+END_SRC #+RESULTS: : t [[./images/hello-world-popup.png]] All I need to do is figure out a simple way to get the bibtex entry as a string, and pop it up when a link is clicked on. #+BEGIN_SRC emacs-lisp (org-add-link-type "test" ;; this function is run when you click (lambda (link-string) (popup-tip link-string)) ;; formatting (lambda (keyword desc format) (cond ((eq format 'html) (format "
%s:%s" keyword desc))))) #+END_SRC #+RESULTS: | lambda | (link-string) | (popup-tip link-string) | | lambda | (keyword desc format) | (cond ((eq format (quote html)) (format
%s:%skeyword desc))) | Now we give it a try. test:show-me-the-popup [[./images/test-link-popup.png]] That looks good. Ok, the penultimate step will be to lookup a bibtex entry, and show the entry in a popup. We will hardcode the path to the bibtex file. #+BEGIN_SRC emacs-lisp (org-add-link-type "test" ;; this function is run when you click (lambda (bibtex-key) (let ((entry (with-temp-buffer (insert-file-contents "~/Dropbox/bibliography/references.bib") (goto-char (point-min)) (re-search-forward bibtex-key) (bibtex-narrow-to-entry) (buffer-string)))) (popup-tip entry)))) #+END_SRC #+RESULTS: | lambda | (bibtex-key) | (let ((cb (current-buffer)) (entry (with-temp-buffer (insert-file-contents ~/Dropbox/bibliography/references.bib) (goto-char (point-min)) (re-search-forward bibtex-key) (bibtex-narrow-to-entry) (buffer-string)))) (popup-tip entry)) | test:mehta-2014-ident-poten And here is what appears for me: [[./images/bibtex-popup-entry.png]] The final step is to connect this to an [[http://www.gnu.org/software/emacs/manual/html_node/elisp/Idle-Timers.html][idle timer]]. We want a popup to occur when our mouse is idle. I am setting this up to run one time, after 5 seconds of idleness. #+BEGIN_SRC emacs-lisp (run-with-idle-timer 5 nil (lambda () (popup-tip "You are being idle"))) #+END_SRC #+RESULTS: : [nil 0 5 0 nil (lambda nil (popup-tip "You are being idle")) nil idle 0] [[./images/idle-timer-popup.png]] So, we need to setup an idle timer that runs on some interval. When the cursor is on the right kind of link, we want to get a popup. I adapted the following code from http://www.emacswiki.org/emacs/IdleTimers. #+BEGIN_SRC emacs-lisp ;; variable for the timer object (defvar idle-timer-bibtex-timer nil) ;; callback function (defun idle-timer-bibtex-callback () "displays a popup of the bibtex entry in a test link" (interactive) (let ((object (org-element-context))) (when (and (equal (org-element-type object) 'link) (equal (org-element-property :type object) "test")) (let* ((bibtex-key (org-element-property :path object)) (entry (with-temp-buffer (insert-file-contents "~/Dropbox/bibliography/references.bib") (goto-char (point-min)) (re-search-forward bibtex-key) (bibtex-narrow-to-entry) (buffer-string)))) (popup-tip entry))))) ;; start functions (defun idle-timer-bibtex-start () (interactive) (when (timerp idle-timer-bibtex-timer) (cancel-timer idle-timer-bibtex-timer)) (setq idle-timer-bibtex-timer (run-with-timer 1 1 #'idle-timer-bibtex-callback))) ;; stop function (defun idle-timer-bibtex-stop () (interactive) (when (timerp idle-timer-bibtex-timer) (cancel-timer idle-timer-bibtex-timer)) (setq idle-timer-bibtex-timer nil)) (idle-timer-bibtex-start) #+END_SRC #+RESULTS: : idle-timer-bibtex-stop test:kitchin-2008-alloy Now, whenever the cursor is on the link, and there is an idle of about a sec, I get a popup window of the bibtex entry. It looks like this: [[./images/bibtex-popup2.png]] There are still some limitations to this code. It does not handle multiple citations in a link (like the cite links I normally use do). That will take a little work to fixup. I cannot figure out how to get mouse-over tooltips; this only works when the cursor is on the link. I do not know what the optimal timer setting is. This one runs every second. I do not see any issues in performance with that. Another issue might be making the timer a file local variable. It would be nice if the timer quit running when the file was closed. I do not know how easy that would be to implement, or if there should be one timer running for org-mode. Finally, this code is hard-coded to use my reference file. For a real module, we would probably provide some customization to choose other bibtex files. Overall though, this might be a handy way to quickly peruse the citations in an org-file.