5

I use pdf-tools in Emacs to view PDF documents. I would like to be able to select words (mark their region and then copy them to the kill-ring) in the PDF by double-clicking on them. Is there a function in pdf-tools or elsewhere I could use to obtain this functionality?

More specifically, I want to write a function (unless it already exists in some form)

(defun select-word-on-doubleclick (ev)
    "Set region to the word under the mouse pointer and copy it to the kill-ring"
    (interactive "@e")
    ...  ;; Set region to the word under the pointer
    (pdf-view-kill-ring-save)  ;; Save region to kill-ring
)

and bind it to <double-mouse-1>. I need help filling out the dots above.

In the pdf-tools package there is a function called

(pdf-info-gettext PAGE EDGES &optional SELECTION-STYLE FILE-OR-BUFFER)

which could be useful for this purpose. Based on the event ev, the position of the mouse pointer (when double-clicked) can be obtained. If somehow the edges of the word under the pointer could be determined from this position, the function above would do the trick. I greatly appreciate any hints on how to make this computation.

StarBug
  • 479
  • 4
  • 10

1 Answers1

5

At first, note that pdf-sync binds mouse-double-1 in the minor mode pdf-sync-minor-mode to pdf-sync-backward-search-mouse. So one should probably only bind it in a minor mode that can be deactivated again.

The following code defines a minor mode pdf-sel-mode that binds mouse-double-1 to a new command pdf-sel-mouse. pdf-sel-mouse selects the word below the mouse pointer and copies it to the kill-ring.

(defvar pdf-sel-mode-map nil
  "Keymap for `pdf-sel-mode'.")

(setq pdf-sel-mode-map
      (let ((map (make-sparse-keymap)))
    (define-key map [double-mouse-1] 'pdf-sel-mouse)
    map))

(define-minor-mode pdf-sel-mode
  "\\<pdf-sel-mode-map>Just binding \\[pdf-sel-mouse] to `pdf-sel-mouse'.
`pdf-sel-mouse' selects the text at point and copies it to `kill-ring'."
  :keymap pdf-sel-mode-map)

(defvar pdf-view-active-region) ;; defined in "pdf-view.el"

(defun pdf-sel-mouse (ev)
  "Select word at mouse event EV and copy it to `kill-ring'."
  (interactive "@e")
  (let* ((posn (event-start ev))
     (xy (posn-object-x-y posn))
     (size (pdf-view-image-size))
     (page (pdf-view-current-page))
     (x (/ (car xy) (float (car size))))
         (y (/ (cdr xy) (float (cdr size)))))
    (setq pdf-view-active-region (pdf-info-getselection page (list x y x y) 'word))
    (pdf-view-display-region pdf-view-active-region)
    (kill-new (pdf-info-gettext page (list x y x y) 'word))))

Note, that this function sometimes selects more than a word. But that is what epdfinfo interprets as a word.

Tobias
  • 32,569
  • 1
  • 34
  • 75
  • Works like a charm! Thank you so much. – StarBug Sep 02 '19 at 16:49
  • ["We" would be very happy](https://github.com/vedang/pdf-tools/issues/30#issuecomment-861442250) if you could submit a PR for this to the [new pdf-tools repo](https://github.com/vedang/pdf-tools). In case of no reply, I guess you do not mind that one of us will submit a PR with your code (let us know in case you prefer anyway that we create the PR). – dalanicolai Jun 15 '21 at 14:12
  • @dalanicolai All stuff on the SE network is CC. So feel free to use the code in accordance to CC. (I think you only need to mention the license and the original author somewhere in the code). [But see for yourself.](https://creativecommons.org/licenses/) – Tobias Jun 17 '21 at 11:44
  • @tobias Ah okay, thanks for that info and for the code! – dalanicolai Jun 17 '21 at 13:05
  • @tobias I assume that we can leave out the link to the license (it is only a small snippet, and it is used, and can only be used, in an Emacs package). We will mention your name and a link to this post. B.t.w. do you (or anybody reading this) happen to know how to bind this to a triple click (just replacing double with triple in the vector does not seem to work). – dalanicolai Jun 17 '21 at 13:14
  • when i try our this code i get this error: ```pdf-info-query: epdfinfo: Unable to create synctex scanner, did you run latex with `--synctex=1' ?```. i'm confused as i'm not doing anything with latex or synctex... ```pdf-sel``` minor mode is enabled and the keymap is set. any ideas? – user27075 Apr 24 '22 at 13:58
  • @mooseface The first sentence in the answer gives a hint. Maybe, you should turn off `pdf-sync-minor-mode` and make sure that `pdf-sel-mode` is really turned on. `M-x pdf-sync-minor-mode RET` should toggle `pdf-sync-minor-mode` for testing. – Tobias Apr 24 '22 at 21:13