summary refs log tree commit diff stats
path: root/lisp/+browse-url.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/+browse-url.el')
-rw-r--r--lisp/+browse-url.el88
1 files changed, 88 insertions, 0 deletions
diff --git a/lisp/+browse-url.el b/lisp/+browse-url.el new file mode 100644 index 0000000..12e433c --- /dev/null +++ b/lisp/+browse-url.el
@@ -0,0 +1,88 @@
1;;; +browse-url.el -*- lexical-binding: t -*-
2
3(require 'browse-url)
4
5(cl-defmacro +browse-url-make-external-viewer-handler
6 (viewer default-args
7 &optional (prompt "URL: ")
8 &key
9 (custom-group 'browse-url)
10 (name (intern (format "+browse-url-with-%s" viewer)))
11 doc vardoc
12 (varname (intern (format "%s-args" name)))
13 (fallback t))
14 "Create a `browse-url' handler function calling VIEWER on the url.
15This macro also creates a `customize' setting in CUSTOM-GROUP for
16VIEWER's command-line arguments. DEFAULT-ARGS specifies the
17default arguments for that setting.
18
19PROMPT is shown to the user in the function's `interactive' spec,
20as an argument to `browse-url-interactive-arg'.
21
22The resulting function is named NAME, which defaults to
23`+browse-url-wth-VIEWER'. The custom variable is named VARNAME,
24which defaults to `NAME-args'. If DOC or VARDOC are provided,
25they'll be the documentation of the function and variable
26respectively; otherwise, basic docstrings are used.
27
28Finally, if FALLBACK is non-nil (by default, it's
29`browse-url-generic'), the function will call that if unable to
30start VIEWER."
31 (declare (indent 1))
32 `(progn
33 (defcustom ,varname ,default-args
34 ,(or doc (format "Arguments to pass to %s in `%s'." viewer name))
35 :type '(repeat :tag "Command-line argument" string)
36 :group ',custom-group)
37 (defun ,name (url &optional new-window)
38 ,(or vardoc (format "Open URL in %s." viewer))
39 (interactive (browse-url-interactive-arg ,prompt))
40 (let* ((url (browse-url-encode-url url))
41 (process-environment (browse-url-process-environment)))
42 (message ,(format "Opening %%s in %s..." viewer) url)
43 (unless (ignore-errors (apply #'start-process
44 (format "%s %s" ,viewer url) nil
45 ,viewer
46 (append ,varname (list url))))
47 ,@(cond
48 ((eq fallback t) '((browse-url-generic url new-window)))
49 (fallback `((funcall ,fallback url new-window)))
50 (:else `((message "Can't find viewer: `%s'" ,viewer)
51 nil))))))))
52
53(defcustom +browse-url-download-open t
54 "Whether to open downloaded files afterward."
55 :group 'browse-url
56 :type 'boolean)
57
58(defun +browse-url-download-callback (status url dir)
59 ;; A slight change to `eww-download-callback' that returns the downloaded
60 ;; filename.
61 (unless (plist-get status :error)
62 (let* ((obj (url-generic-parse-url url))
63 (path (directory-file-name (car (url-path-and-query obj))))
64 (file (eww-make-unique-file-name
65 (eww-decode-url-file-name (file-name-nondirectory path))
66 dir)))
67 (goto-char (point-min))
68 (re-search-forward "\r?\n\r?\n")
69 (let ((coding-system-for-write 'no-conversion))
70 (write-region (point) (point-max) file))
71 (message "Saved %s" file)
72 file)))
73
74(defun +browse-url-download (url &rest _)
75 "Download URL to `eww-download-directory'."
76 (interactive "sDownload URL: ")
77 (let ((dir eww-download-directory))
78 (when (functionp dir) (setq dir (funcall dir)))
79 (make-directory dir :parents)
80 (url-retrieve url
81 (lambda (s u d)
82 (let ((file (+browse-url-download-callback s u d)))
83 (when +browse-url-download-open
84 (browse-url-xdg-open file))))
85 (list url dir))))
86
87(provide '+browse-url)
88;;; +browse-url.el ends here