Drag images and files onto org-mode and insert a link to them

| categories: video, emacs | tags:

I want to drag and drop an image onto an org mode file and get a link to that file. This would be used for finding images in Finder, and then dragging them to the Emacs buffer. There is org-download.el which looks like it should do something like this too, but it did not work out of the box for me, and I want to add a few wrinkles to it. For a simple drag-n-drop, I just want the link to appear. With ctrl-drag-n-drop I want to add an attr_org line to set the image size, add a caption line, insert the image at the beginning of the line where the mouse cursor is, put the cursor on the caption line and then refresh the inline images in org-mode so the image is immediately visible.

While we are at let us also make it possible to drag file links onto org-files, instead of having the files open. Again, for a simple drag-n-drop, I want a link inserted. For ctrl-drag-n-drop we open the file, and for Meta (alt) drag-n-drop, we insert an attachfile link. You can also define s-drag-n-drop (Super/command) and C-s and M-s drag-n-drop if you can think of things to do with that.

Here is the code to make those things happen. Or watch the video: https://www.youtube.com/watch?v=ahqKXbBVjpQ

(defun my-dnd-func (event)
  (interactive "e")
  (goto-char (nth 1 (event-start event)))
  (x-focus-frame nil)
  (let* ((payload (car (last event)))
         (type (car payload))
         (fname (cadr payload))
         (img-regexp "\\(png\\|jp[e]?g\\)\\>"))
    (cond
     ;; insert image link
     ((and  (eq 'drag-n-drop (car event))
            (eq 'file type)
            (string-match img-regexp fname))
      (insert (format "[[%s]]" fname))
      (org-display-inline-images t t))
     ;; insert image link with caption
     ((and  (eq 'C-drag-n-drop (car event))
            (eq 'file type)
            (string-match img-regexp fname))
      (insert "#+ATTR_ORG: :width 300\n")
      (insert (concat  "#+CAPTION: " (read-input "Caption: ") "\n"))
      (insert (format "[[%s]]" fname))
      (org-display-inline-images t t))
     ;; C-drag-n-drop to open a file
     ((and  (eq 'C-drag-n-drop (car event))
            (eq 'file type))
      (find-file fname))
     ((and (eq 'M-drag-n-drop (car event))
           (eq 'file type))
      (insert (format "[[attachfile:%s]]" fname)))
     ;; regular drag and drop on file
     ((eq 'file type)
      (insert (format "[[%s]]\n" fname)))
     (t
      (error "I am not equipped for dnd on %s" payload)))))


(define-key org-mode-map (kbd "<drag-n-drop>") 'my-dnd-func)
(define-key org-mode-map (kbd "<C-drag-n-drop>") 'my-dnd-func)
(define-key org-mode-map (kbd "<M-drag-n-drop>") 'my-dnd-func)
my-dnd-func

jkitchin.json

Copyright (C) 2015 by John Kitchin. See the License for information about copying.

org-mode source

Org-mode version = 8.2.10

Discuss on Twitter