diff options
Diffstat (limited to 'lisp/+browse-url.el')
-rw-r--r-- | lisp/+browse-url.el | 189 |
1 files changed, 0 insertions, 189 deletions
diff --git a/lisp/+browse-url.el b/lisp/+browse-url.el deleted file mode 100644 index b65b6f9..0000000 --- a/lisp/+browse-url.el +++ /dev/null | |||
@@ -1,189 +0,0 @@ | |||
1 | ;;; +browse-url.el -*- lexical-binding: t; -*- | ||
2 | |||
3 | (require 'browse-url) | ||
4 | (require 'cl-lib) | ||
5 | (require 'seq) | ||
6 | (require 'url-util) | ||
7 | |||
8 | (defgroup +browse-url nil | ||
9 | "My `browse-url' extras." | ||
10 | :group 'browse-url) | ||
11 | |||
12 | ;;; External URL handlers | ||
13 | |||
14 | (cl-defmacro +browse-url-make-external-viewer-handler | ||
15 | (viewer | ||
16 | &key | ||
17 | args | ||
18 | (prompt "URL: ") | ||
19 | (program (executable-find (format "%s" viewer))) | ||
20 | (name (intern (format "+browse-url-with-%s" viewer))) | ||
21 | doc | ||
22 | (var (intern (format "%s-args" name))) | ||
23 | vardoc | ||
24 | (custom-group '+browse-url) | ||
25 | (fallback '(function browse-url-generic))) | ||
26 | "Create a `browse-url' handler function calling PROGRAM on the URL. | ||
27 | This macro also creates a `customize' setting in CUSTOM-GROUP for | ||
28 | PROGRAM's command-line arguments. ARGS specifies the | ||
29 | default arguments for this user option. | ||
30 | |||
31 | PROGRAM defaults to the result of calling `executable-find' on VIEWER. | ||
32 | |||
33 | PROMPT is shown to the user in the function's `interactive' spec, as an argument | ||
34 | to `browse-url-interactive-arg'. | ||
35 | |||
36 | The resulting function is named NAME, which defaults to | ||
37 | `+browse-url-with-VIEWER'. The custom variable is named VAR, which defaults | ||
38 | to `NAME-args'. If DOC or VARDOC are provided, they'll be the documentation of | ||
39 | the function and variable respectively; otherwise a basic default doc-string is | ||
40 | used. | ||
41 | |||
42 | If FALLBACK is non-nil (the default is `browse-url-generic'), the | ||
43 | generated function will call FALLBACK if unable to start PROGRAM | ||
44 | for some reason." | ||
45 | (declare (indent 1)) | ||
46 | `(progn | ||
47 | (defcustom ,var ,args | ||
48 | ,(or vardoc (format "Arguments to pass to %s in `%s'." | ||
49 | viewer name)) | ||
50 | :type '(repeat :tag "Command-line argument" string) | ||
51 | :group ',custom-group) | ||
52 | (defun ,name (url &optional new-window) | ||
53 | ,(or doc (format "Open URL in %s." viewer)) | ||
54 | (interactive (browse-url-interactive-arg ,prompt)) | ||
55 | (let* ((url (browse-url-encode-url url)) | ||
56 | (process-environment (browse-url-process-environment))) | ||
57 | (message ,(format "Opening %%s in %s..." viewer) url) | ||
58 | (unless (ignore-errors (apply #'start-process | ||
59 | (format "%s %s" ',viewer url) | ||
60 | nil | ||
61 | ,program | ||
62 | (append ,var (list url)))) | ||
63 | ,@(cond | ||
64 | (fallback `((funcall ,fallback url new-window))) | ||
65 | (:else `((message "Can't find viewer: %s" ,viewer) | ||
66 | nil)))))))) | ||
67 | |||
68 | ;; Some default handlers | ||
69 | |||
70 | (+browse-url-make-external-viewer-handler mpv | ||
71 | :args '("--cache-pause-wait=15" | ||
72 | "--cache-pause-initial=yes") | ||
73 | :prompt "Video URL: ") | ||
74 | |||
75 | (+browse-url-make-external-viewer-handler mpv-image | ||
76 | :program (executable-find "mpv") | ||
77 | :args '("--image-display-duration=inf") | ||
78 | :prompt "Image URL: ") | ||
79 | |||
80 | ;;; Downloading | ||
81 | |||
82 | (defcustom +browse-url-download-open t | ||
83 | "Whether to open downloaded files after downloading." | ||
84 | :type 'boolean) | ||
85 | |||
86 | (defun +browse-url-download (url &rest _) | ||
87 | "Download URL to `eww-download-directory'." | ||
88 | (interactive "sDownload URL: ") | ||
89 | (let ((dir eww-download-directory)) | ||
90 | (when (functionp dir) (setq dir (funcall dir))) | ||
91 | (make-directory dir :parents) | ||
92 | (url-retrieve url | ||
93 | (lambda (s u d) | ||
94 | (let ((file (+browse-url-download-callback s u d))) | ||
95 | (when +browse-url-download-open | ||
96 | (browse-url-xdg-open file)))) | ||
97 | (list url dir)))) | ||
98 | |||
99 | (defun +browse-url-download-callback (status url dir) | ||
100 | ;; A slight change to `eww-download-callback' that returns the downloaded | ||
101 | ;; filename. | ||
102 | (unless (plist-get status :error) | ||
103 | (let* ((obj (url-generic-parse-url url)) | ||
104 | (path (directory-file-name (car (url-path-and-query obj)))) | ||
105 | (file (eww-make-unique-file-name | ||
106 | (eww-decode-url-file-name (file-name-nondirectory path)) | ||
107 | dir))) | ||
108 | (goto-char (point-min)) | ||
109 | (re-search-forward "\r?\n\r?\n") | ||
110 | (let ((coding-system-for-write 'no-conversion)) | ||
111 | (write-region (point) (point-max) file)) | ||
112 | (message "Saved %s" file) | ||
113 | file))) | ||
114 | |||
115 | ;;; URL matcher generators | ||
116 | |||
117 | (defun +browse-url-matches (&rest regexps) | ||
118 | "Return a lambda that will determine if a url matches REGEXPS. | ||
119 | Each regexp will be tested in turn. The first one that matches | ||
120 | is returned by the lambda. | ||
121 | |||
122 | This is a good function to use in key positions in `browse-url-handlers'." | ||
123 | `(lambda (url &optional new-window) | ||
124 | (cl-loop for regexp in ',regexps | ||
125 | if (string-match-p regexp url) | ||
126 | return regexp))) | ||
127 | |||
128 | ;;; External domains | ||
129 | ;; Some domains just don't open well in `eww'. The following function and user | ||
130 | ;; option define an easy way to automatically open those. | ||
131 | |||
132 | (defcustom +browse-url-external-domains nil | ||
133 | "Domains to open in `browse-url-secondary-browser-function'. | ||
134 | This is just a list of strings. They'll be regexp-escaped and | ||
135 | passed to `+browse-url-external-url-p', which is a good function | ||
136 | to put in `browse-url-handlers'. | ||
137 | |||
138 | If an item in this list is a list itself, it should contain one string, a valid | ||
139 | regexp that will not be regexp-quoted when matching against a url." | ||
140 | :type '(repeat (choice | ||
141 | (list :tag "Regexp" regexp) | ||
142 | (string :tag "Literal string")))) | ||
143 | |||
144 | (defun +browse-url-external-url-p (url) | ||
145 | "Return t if URL is a member of `+browse-url-external-domains'. | ||
146 | This function only tests URL's domain." | ||
147 | (let ((host (url-host (url-generic-parse-url url)))) | ||
148 | (cl-loop for domain in +browse-url-external-domains | ||
149 | if (string-match-p (if (stringp domain) | ||
150 | (regexp-quote domain) | ||
151 | (car domain)) | ||
152 | host) | ||
153 | return t))) | ||
154 | |||
155 | ;;; Switch to an external browser from an Emacs browser | ||
156 | |||
157 | (defmacro +browse-url-switch-external-browser (mode url-fetcher-form) | ||
158 | "Create a function for MODE to open an external browser. | ||
159 | URL-FETCHER-FORM will be used to get the URL of the current visited page." | ||
160 | (declare (indent 1)) | ||
161 | `(defun ,(intern (format "+browse-url-external-from-%s" mode)) | ||
162 | (&optional url) | ||
163 | "Browse URL with `browse-url-secondary-browser-function'. | ||
164 | This will close the current buffer." | ||
165 | (interactive nil ,mode) | ||
166 | (condition-case e | ||
167 | (funcall browse-url-secondary-browser-function | ||
168 | (or url ,url-fetcher-form)) | ||
169 | (:success (when (null url) (quit-window))) ; Interactive use | ||
170 | (t (signal (car e) (cdr e)))))) | ||
171 | |||
172 | ;;; Mark `browse-url-browser-function' as safe | ||
173 | |||
174 | (defcustom +browse-url-other-safe-browser-functions nil | ||
175 | "Other safe browser functions." | ||
176 | :type '(repeat function)) | ||
177 | |||
178 | (defun +browse-url-browser-function-safe-p (f) | ||
179 | "Return t if F is a safe browser function." | ||
180 | (memq f (append +browse-url-other-safe-browser-functions | ||
181 | (mapcar (lambda (i) | ||
182 | (plist-get (cdr i) :value)) | ||
183 | (seq-filter (lambda (i) | ||
184 | (eq (car i) 'function-item)) | ||
185 | (cdr (get 'browse-url-browser-function | ||
186 | 'custom-type))))))) | ||
187 | |||
188 | (provide '+browse-url) | ||
189 | ;;; +browse-url.el ends here | ||