about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorCase Duckworth2023-01-20 13:14:49 -0600
committerCase Duckworth2023-01-20 13:14:49 -0600
commit71b97e7871ed5eed8e03202daaf8124c3a2b7e1e (patch)
tree9133fa453a19356ce1c2468b02a5ee6d349b94fa
parentchanges (diff)
downloademacs-71b97e7871ed5eed8e03202daaf8124c3a2b7e1e.tar.gz
emacs-71b97e7871ed5eed8e03202daaf8124c3a2b7e1e.zip
Add link-hint
-rw-r--r--lisp/+link-hint.el146
-rw-r--r--lisp/acdw-web.el73
2 files changed, 218 insertions, 1 deletions
diff --git a/lisp/+link-hint.el b/lisp/+link-hint.el new file mode 100644 index 0000000..469ed15 --- /dev/null +++ b/lisp/+link-hint.el
@@ -0,0 +1,146 @@
1;;; +link-hint.el -*- lexical-binding: t; -*-
2
3;;; Code:
4
5(require 'cl-lib)
6(require 'link-hint)
7
8(defgroup +link-hint nil
9 "Extra customizations for `link-hint'."
10 :group 'link-hint)
11
12(defcustom +link-hint-open-secondary-types '(gnus-w3m-image-url
13 gnus-w3m-url
14 markdown-link
15 mu4e-attachment
16 mu4e-url
17 notmuch-hello
18 nov-link
19 org-link
20 shr-url
21 text-url
22 w3m-link
23 w3m-message-link)
24 "Link types to define `:open-secondary' for.")
25
26(defvar +link-hint-map (make-sparse-keymap)
27 "Keymap for `link-hint' functionality.")
28
29(cl-defmacro +link-hint-define-keyword (keyword handler docstring
30 &optional (types 'link-hint-types)
31 &rest rest
32 &key multiple &allow-other-keys)
33 "Set up a `link-hint' KEYWORD, with optional TYPES.
34If TYPES is not present, use `link-hint-types'.
35
36KEYWORD defines the link-hint type. It will be used to create a
37function for opening links of the form \"link-hint-openKEYWORD\".
38
39HANDLER is the function to open a link with.
40
41DOCSTRING is the macro's documentation.
42
43Keyword arguments are passed to `link-hint-define-type' prefixed
44with the KEYWORD."
45 (declare (indent 2)
46 (doc-string 3))
47 (let ((types (symbol-value types))
48 (func-sym (intern (format "+link-hint-open%s" keyword)))
49 (mult-sym (intern (format "%s-multiple" keyword)))
50 (expr))
51 ;; Define the type
52 (push `(dolist (type ',types)
53 (link-hint-define-type type
54 ,keyword ,handler
55 ,@(mapcar (lambda (el)
56 (if (eq el :multiple)
57 mult-sym
58 el))
59 rest)))
60 expr)
61 ;; Define an opener
62 (push `(defun ,func-sym ()
63 ,(format "%s\n\nDefined by `+link-hint-define'." docstring)
64 (interactive)
65 (avy-with link-hint-open-link
66 (link-hint--one ,keyword)))
67 expr)
68 ;; Handle `:multiple'
69 (when multiple
70 (push `(defun ,(intern (format "+link-hint-open-multiple%s" keyword)) ()
71 ,(format "Open multiple links with `%s'.\n\nDefined by `+link-hint-define'."
72 func-sym)
73 (avy-with link-hint-open-multiple-links
74 (link-hint--multiple ,keyword)))
75 expr)
76 (push `(defun ,(intern (format "+link-hint-open-all%s" keyword)) ()
77 ,(format "Open all visible links with `%s'.\n\nDefined by `+link-hint-define'."
78 func-sym)
79 (avy-with link-hint-open-all-links
80 (link-hint--all ,keyword)))
81 expr))
82 ;; Return the built expression
83 `(progn ,@(nreverse expr))))
84
85(+link-hint-define-keyword :secondary browse-url-secondary-browser-function
86 "Open a link in the secondary browser."
87 +link-hint-open-secondary-types
88 :multiple t)
89
90(defun +link-hint-open-secondary-setup (&optional types)
91 "Define the `:open-secondary' link-hint type for TYPES.
92If TYPES is nil, define it for `+link-hint-open-secondary-types'."
93 (dolist (type (or types +link-hint-open-secondary-types))
94 (link-hint-define-type type
95 :open-secondary browse-url-secondary-browser-function
96 :open-secondary-multiple t)))
97
98(defun +link-hint-open-secondary ()
99 "Open a link in the secondary browser."
100 (interactive)
101 (avy-with link-hint-open-link
102 (link-hint--one :open-secondary)))
103
104(defun +link-hint-open-chrome-setup (&optional types)
105 "Define the `:open-chrome' link-hint type for TYPES.
106If TYPES is nil, define it for `+link-hint-open-secondary-types'."
107 (dolist (type (or types +link-hint-open-secondary-types))
108 (link-hint-define-type type
109 :open-chrome #'browse-url-chrome
110 :open-chrome-multiple t)))
111
112(defun +link-hint-open-chrome ()
113 "Open a link with chrome."
114 (interactive)
115 (avy-with link-hint-open-link
116 (link-hint--one :open-chrome)))
117
118(defun +link-hint-open-link (prefix)
119 "Open a link.
120Without a PREFIX, open using `browse-url-browser-function'; with
121a PREFIX, use `browse-url-secondary-browser-function'."
122 (interactive "P")
123 (let ((current-prefix-arg nil))
124 (avy-with link-hint-open-link
125 (link-hint--one (if prefix :open-secondary :open)))))
126
127;; test: https://www.acdw.net
128
129(defun +link-hint-open-multiple-links (prefix)
130 "Open multiple links.
131Without a PREFIX, open using `browse-url-browser-function'; with
132a PREFIX, use `browse-url-secondary-browser-function'."
133 (interactive "P")
134 (avy-with link-hint-open-multiple-links
135 (link-hint--one (if prefix :open-secondary :open))))
136
137(defun +link-hint-open-all-links (prefix)
138 "Open all visible links.
139Without a PREFIX, open using `browse-url-browser-function'; with
140a PREFIX, use `browse-url-secondary-browser-function'."
141 (interactive "P")
142 (avy-with link-hint-open-all-links
143 (link-hint--one (if prefix :open-secondary :open))))
144
145(provide '+link-hint)
146;;; +link-hint.el ends here
diff --git a/lisp/acdw-web.el b/lisp/acdw-web.el index 28fcd02..36a5ba4 100644 --- a/lisp/acdw-web.el +++ b/lisp/acdw-web.el
@@ -2,6 +2,8 @@
2 2
3;;; Code: 3;;; Code:
4 4
5(require 'cl-lib)
6
5(defcustom +browse-url-other-safe-browser-functions nil 7(defcustom +browse-url-other-safe-browser-functions nil
6 "Other safe browser functions." 8 "Other safe browser functions."
7 :type '(repeat function)) 9 :type '(repeat function))
@@ -162,6 +164,25 @@ This function only tests URL's domain."
162 164
163;;; Packages 165;;; Packages
164 166
167(use-package eww
168 :config
169 (setopt eww-use-browse-url ".")
170 (add-hook 'eww-mode-hook
171 (defun eww-mode@setup ()
172 (add-hook 'visual-fill-column-mode-hook
173 (defun visual-fill-column@eww-reload ()
174 (eww-reload :local))))
175 nil :local)
176 (keymap-set eww-mode-map "&"
177 (defun eww-browse-url-external (&optional url)
178 (interactive nil eww-mode)
179 (condition-case e
180 (funcall
181 browse-url-secondary-browser-function
182 (or url (plist-get eww-data :url)))
183 (:success (when (null url) (quit-window))) ; Interactive use
184 (t (signal (car e) (cdr e)))))))
185
165(use-package browse-url 186(use-package browse-url
166 :demand t 187 :demand t
167 :config 188 :config
@@ -171,8 +192,9 @@ This function only tests URL's domain."
171 ;; Dispatch browser based on URL 192 ;; Dispatch browser based on URL
172 browse-url-handlers 193 browse-url-handlers
173 `(;; Videos 194 `(;; Videos
174 (,(+browse-url-matches "youtube\\.com" "yoiutu\\.be" 195 (,(+browse-url-matches "youtube\\.com" "youtu\\.be"
175 "invidious" "yewtu\\.be" 196 "invidious" "yewtu\\.be"
197 "twitch\\.tv"
176 (rx "." (or "mp4" "gif" "mov" "MOV" "webm") 198 (rx "." (or "mp4" "gif" "mov" "MOV" "webm")
177 eos)) 199 eos))
178 . +browse-url-with-mpv) 200 . +browse-url-with-mpv)
@@ -218,5 +240,54 @@ This function only tests URL's domain."
218 (setopt browse-url-chrome-program chrome 240 (setopt browse-url-chrome-program chrome
219 browse-url-generic-program chrome))) 241 browse-url-generic-program chrome)))
220 242
243(use-package browse-url-transform
244 :after browse-url
245 :load-path "~/src/emacs/browse-url-transform/"
246 :config
247 (setopt browse-url-transform-alist
248 `(;; Privacy-respecting alternatives
249 ("twitter\\.com" . "nitter.snopyta.org")
250 ("\\(?:\\(?:old\\.\\)?reddit\\.com\\)" . "libreddit.de")
251 ("medium\\.com" . "scribe.rip")
252 (".*substack\\.com.*" . ,substack-proxy)
253 ;; Text-mode of non-text-mode sites
254 ("www\\.npr\\.org" . "text.npr.org")
255 ;; Ask for raw versions of paste sites
256 ("^.*dpaste\\.com.*$" . "\\&.txt")
257 ("bpa\\.st/\\(.*\\)" . "bpa.st/raw/\\1")
258 ("\\(paste\\.debian\\.net\\)/\\(.*\\)" . "\\1/plain/\\2")
259 ("\\(pastebin\\.com\\)/\\\(.*\\)" . "\\1/raw/\\2")
260 ("\\(paste\\.centos\\.org/view\\)/\\(.*\\)" . "\\1/raw/\\2")))
261 (browse-url-transform-mode))
262
263;;; Link hint
264
265(use-package link-hint
266 :ensure t :demand t
267 :preface (keymap-global-unset "M-l")
268 :bind
269 (("M-l M-l" . +link-hint-open-link)
270 ("M-l l" . +link-hint-open-link)
271 ("M-l M-o" . +link-hint-open-secondary)
272 ("M-l o" . +link-hint-open-secondary)
273 ("M-l M-m" . +link-hint-open-multiple-links)
274 ("M-l m" . +link-hint-open-multiple-links)
275 ("M-l M-w" . link-hint-copy-link)
276 ("M-l w" . link-hint-copy-link)
277 ("M-l M-c" . +link-hint-open-chrome)
278 ("M-l c" . +link-hint-open-chrome))
279 :config
280 (require '+link-hint)
281 (setopt link-hint-avy-style 'at-full
282 link-hint-avy-all-windows t)
283 ;; For some reason, `link-hint-completion-list-candidate' freezes Emacs.
284 ;; Removing it fixes the problem, so ... that's what I've done. It's quite
285 ;; possible this problem isn't caused by `link-hint' at all, but rather by
286 ;; another package's configuration, but I don't care enough to fix it.
287 (setq link-hint-types
288 (delq 'link-hint-completion-list-candidate link-hint-types))
289 (+link-hint-open-secondary-setup)
290 (+link-hint-open-chrome-setup))
291
221(provide 'acdw-web) 292(provide 'acdw-web)
222;;; acdw-web.el ends here 293;;; acdw-web.el ends here