Function: dnd-handle-multiple-urls

dnd-handle-multiple-urls is a byte-compiled function defined in dnd.el.gz.

Signature

(dnd-handle-multiple-urls WINDOW URLS ACTION)

Documentation

Select a handler for, then open, each element of URLS.

The argument ACTION is the action which must be taken, much as that to dnd-begin-file-drag.

Assign and give each URL to one of the "DND handler" functions listed in the variable dnd-protocol-alist. When multiple handlers matching the same subset of URLs exist, give precedence to the handler assigned the greatest number of URLs.

If a handler is a symbol with the property dnd-multiple-handler, call it with ACTION and a list of every URL it is assigned. Otherwise, call it once for each URL assigned with ACTION and the URL in question.

Subsequently open URLs that don't match any handlers opened with any handler selected by browse-url-select-handler, and failing even that, insert them with dnd-insert-text.

Return a symbol designating the actions taken by each DND handler called. If all DND handlers called return the same symbol, return that symbol; otherwise, or if no DND handlers are called, return private.

Do not rely on the contents of URLS after calling this function, for it will be modified.

Source Code

;; Defined in /usr/src/emacs/lisp/dnd.el.gz
(defun dnd-handle-multiple-urls (window urls action)
  "Select a handler for, then open, each element of URLS.
The argument ACTION is the action which must be taken, much as
that to `dnd-begin-file-drag'.

Assign and give each URL to one of the \"DND handler\" functions
listed in the variable `dnd-protocol-alist'.  When multiple
handlers matching the same subset of URLs exist, give precedence
to the handler assigned the greatest number of URLs.

If a handler is a symbol with the property
`dnd-multiple-handler', call it with ACTION and a list of every
URL it is assigned.  Otherwise, call it once for each URL
assigned with ACTION and the URL in question.

Subsequently open URLs that don't match any handlers opened with
any handler selected by `browse-url-select-handler', and failing
even that, insert them with `dnd-insert-text'.

Return a symbol designating the actions taken by each DND handler
called.  If all DND handlers called return the same symbol,
return that symbol; otherwise, or if no DND handlers are called,
return `private'.

Do not rely on the contents of URLS after calling this function,
for it will be modified."
  (let ((list nil) (return-value nil))
    (with-selected-window window
      (dolist (handler dnd-protocol-alist)
        (let ((pattern (car handler))
              (handler (cdr handler)))
          (dolist (uri urls)
            (when (string-match pattern uri)
              (let ((cell (or (cdr (assq handler list))
                              (let ((cell (cons handler nil)))
                                (push cell list)
                                cell))))
                (unless (memq uri cell)
                  (setcdr cell (cons uri (cdr cell)))))))))
      (setq list (nreverse list))
      ;; While unassessed handlers still exist...
      (while list
        ;; Sort list by the number of URLs assigned to each handler.
        (setq list (sort list (lambda (first second)
                                (> (length (cdr first))
                                   (length (cdr second))))))
        ;; Call the handler in its car before removing each URL from
        ;; URLs.
        (let ((handler (caar list))
              (entry-urls (cdar list)))
          (setq list (cdr list))
          (when entry-urls
            (if (and (symbolp handler)
                     (get handler 'dnd-multiple-handler))
                (progn
                  (let ((value (funcall handler entry-urls action)))
                    (if (or (not return-value)
                            (eq return-value value))
                        (setq return-value value)
                      (setq return-value 'private)))
                  (dolist (url entry-urls)
                    (setq urls (delq url urls))
                    ;; And each handler-URL list after this.
                    (dolist (item list)
                      (setcdr item (delq url (cdr item))))))
              (dolist (url entry-urls)
                (let ((value (funcall handler url action)))
                  (if (or (not return-value) (eq return-value value))
                      (setq return-value value)
                    (setq return-value 'private)))
                (setq urls (delq url urls))
                ;; And each handler-URL list after this.
                (dolist (item list)
                  (setcdr item (delq url (cdr item)))))))))
      ;; URLS should now incorporate only those which haven't been
      ;; assigned their own handlers.
      (dolist (leftover urls)
        (setq return-value 'private)
        (if-let* ((handler (browse-url-select-handler leftover
                                                      'internal)))
            (funcall handler leftover action)
          (dnd-insert-text window action leftover)))
      (or return-value 'private))))