abo-abo / org-download

Drag and drop images to Emacs org-mode
1.08k stars 79 forks source link

Integration with emacs 29 and native drag and drop support #215

Open vonpupp opened 9 months ago

vonpupp commented 9 months ago

Hello,

I used this for a while flawlessly integrated with org-roam (I am not sure where I got the config snippet). The idea is: my org-roam home is in ~/org/exobrain. That directory is managed by git and text files only. I have another folder for the attachments: ~/org-media.

When I dragged anything into an org roam buffer titled for example "Books to read", then a folder under ~/org-media would be created with the buffer filename as the name of the folder, for instance ~/org-media/20200822194657-books_to_read/ and the file would be copied there.

That is the exact behavior that I would want to continue with but now with the native drag and drop support added to emacs 29, org-download doesn't seem to work anymore.

Here is my actual config that used to work:

(use-package! org-download
  :after org
  :commands
  org-download-dnd
  org-download-yank
  org-download-screenshot
  org-download-dnd-base64
  :init
  (map! :map org-mode-map
        "s-<print>" #'org-download-screenshot
        "s-y" #'org-download-yank)
  (pushnew! dnd-protocol-alist
            '("^\\(?:https?\\|ftp\\|file\\|nfs\\):" . org-download-dnd)
            '("^data:" . org-download-dnd-base64))
  (advice-add #'org-download-enable :override #'ignore)

  (after! org
    ;; A shorter link to attachments
    (+org-define-basic-link "download" (lambda () (or org-download-image-dir org-attach-id-dir "."))
      :image-data-fun #'+org-image-file-data-fn
      :requires 'org-download)
    (org-add-link-type "xdg" (lambda (path) (browse-url-xdg-open path))))
  :config
  (defun +org/org-download-method (link)
    (let* ((filename
            (file-name-nondirectory
             (car (url-path-and-query
                   (url-generic-parse-url link)))))
           ;; Create folder name with current buffer name, and place in root dir
           (dirname (concat "~/org-media/"
                            (replace-regexp-in-string " " "_"
                                                      (downcase (file-name-base buffer-file-name))))))
      (make-directory dirname t)
      (expand-file-name filename dirname)))
  (setq org-download-screenshot-method
        (cond (IS-MAC "screencapture -i %s")
              (IS-LINUX
               ;(cond ((executable-find "maim")  "maim -u -s %s")
               (cond ;((executable-find "flameshot")  "flameshot gui --raw > %s")
                     ((executable-find "scrot") "scrot -s %s")))))
  (setq org-download-method '+org/org-download-method)
  )

Any ideas/help please? Thank you.

sovereignyy99 commented 9 months ago

same question...

cuprum commented 4 months ago

To make org-download work, add the code in init.el:

(add-hook 'org-mode-hook
      (lambda ()
        (kill-local-variable 'dnd-protocol-alist)))
akashpal-21 commented 1 month ago

@cuprum This solution will only half-work, I think there is a better way rather than to unset the local variable. In emacs > 29 there has been an overhaul of the api - therefore this package will stop working - especially org-download-image function is now redundant - it cannot anymore paste image directly from the browser - the api has changed significantly

(defun org-download--dnd-xds-function (need-name filename)
  (if need-name
      (let ((method (if (eq org-yank-dnd-method 'ask)
                        (org--dnd-rmc
                         "What to do with dropped file?"
                         '((?a "attach" attach)
                           (?o "open" open)
                           (?f "insert file: link" file-link)))
                      org-yank-dnd-method)))
        (setq-local org--dnd-xds-method method)
        (pcase method
          (`attach (expand-file-name filename (org-attach-dir 'create)))
          (`open (expand-file-name (make-temp-name "emacs.") temporary-file-directory))
      ;; Save file specified by org-download--dir
          (`file-link (expand-file-name (org-download-file-format-default filename)
                    (funcall #'org-download--dir)))))
    (pcase org--dnd-xds-method
      (`attach (insert (org-link-make-string
                        (concat "attachment:" (file-name-nondirectory filename)))))
      (`file-link
       ; Insert the attributes from `org-download-image-attr-list`
       (mapc (lambda (attr) (insert attr "\n")) org-download-image-attr-list)
       (insert (org-link-make-string (concat "file:" filename)))
       (setq org-download-path-last-file filename))
      (`open (find-file filename)))
    (setq-local org--dnd-xds-method nil)))

(advice-add 'org--dnd-xds-function :override #'org-download--dnd-xds-function)
(advice-add 'org--dnd-local-file-handler :override #'org-download-dnd)

Use this config - this will keep things running for now, I have tried to merge the functionality - if some functionality is not working tell me, i will fix it. The problem is I have to reverse engineer the code, and a lot of functions especially relating to downloading files are now redundant - emacs does it internally.